LINUX.ORG.RU

CMake, Haskell и С++

 , ,


0

4

Все привет, у меня основной проект написан на C++ и некоторые части хотелось бы реализовать на Haskell, т.к. он больше для данных задач подходит, для сборки использую CMake, каким образом можно скрестить C++ и Haskell?

★★★

Для примера, нужно в данный момент экспортировать функцию parseExpr:

import Text.Parsec
import Text.Parsec.String
import Text.Parsec.Token
import Text.Parsec.Language
import Text.Parsec.Expr

lexer :: TokenParser ()
lexer = makeTokenParser (javaStyle { opStart  = oneOf "+-*/^",
                                     opLetter = oneOf "+-*/^" })

parseNumber :: Parser Double
parseNumber = do
    val <- naturalOrFloat lexer

    case val of
        Left  i -> return $ fromIntegral i
        Right n -> return $ n

parseExpr :: Parser Double
parseExpr = (flip buildExpressionParser) parseTerm $ [
        [ Prefix (reservedOp lexer "-" >> return negate),
          Prefix (reservedOp lexer "+" >> return id) ],

        [ Infix  (reservedOp lexer "*" >> return (*) ) AssocLeft,
          Infix  (reservedOp lexer "/" >> return (/) ) AssocLeft,
          Infix  (reservedOp lexer "^" >> return (**)) AssocLeft],

        [ Infix  (reservedOp lexer "+" >> return (+)) AssocLeft,
          Infix  (reservedOp lexer "-" >> return (-)) AssocLeft ]
    ]

parseTerm :: Parser Double
parseTerm = parens lexer parseExpr <|> parseNumber

parseInput :: Parser Double
parseInput = do
    whiteSpace lexer
    n <- parseExpr
    eof
    return n

calculate :: String -> String
calculate s =
    case ret of
        Left  e -> "error"
        Right n -> show n
    where
        ret = parse parseInput "" s

Int64 ★★★
() автор топика
Ответ на: комментарий от Int64
calculate :: String -> String
calculate s =
    case ret of
        Left  e -> "error"
        Right n -> show n
    where
        ret = parse parseInput "" s

Типобезопасность? Какая типобезопасность?

P.S. Используй Text. Parsec его умеет.

anonymous
()
Ответ на: комментарий от Int64

Вау, без однобуквенных переменных Haskell даже по-человечески выглядит. Только в конце у автора дрогнула рука.

Есть ещё вариант использовать межпроцессное взаимодействие. Если нужен разбор арифметических выражений, то можно можно через Haskell проверить правильность и преобразовать в обратную польскую нотацию, а через C++ читать упрощённый хаскелем код.

quiet_readonly ★★★★
()

Добавлю про cmake.

Если использовать SOURCES в add_custom_command.

То порядочная ide, даже покажет их как сорцы, и цель будет пересобираться по правке исходников.

Если немного пошаманить, можно написать нормальную макрообёртку для работы с какой нить имплементацией хаскеля.

Я так делал для питона в qtc - было удобно. Только там насколько я знаю нету плагина для сабжа (но при должном радиусе кривизны можно и запилить).

Возможно, code::blocks что то умеет в этом направлении (ох никогда не думал что посоветую кому то это поделие).

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Спасибо, да я в принципе IDE не использую, привык к командной строке уже, пробовал пользоваться CLion, не понравились шрифты и размеры их, попытался все это настроить, получилась ерунда какая-то ))

Int64 ★★★
() автор топика
Ответ на: комментарий от quiet_readonly

Да надо переименовать переменные )) Думаю через FFI все же сделать.

Int64 ★★★
() автор топика
Ответ на: комментарий от Int64

Мне CLion тоже не понравился. Попробуй qtc (тема там только стандартная говно, но с darcula например всё более менее) или KDevelop :)

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Удалось вроде скрестить с CMake, все компилируется, но не линкуется :(
выдает куча ошибок:

Undefined symbols for architecture x86_64:
  "_base_DataziFunctorziIdentity_zdfMonadIdentity_closure", referenced from:
      _r3KO_info in libe2dit-ui.a(expr.o)
      _s3Mm_info in libe2dit-ui.a(expr.o)
      _S3MC_srt in libe2dit-ui.a(expr.o)
  "_base_ForeignziCziString_newCString_closure", referenced from:
      _c41J_info in libe2dit-ui.a(expr.o)
      _S3MC_srt in libe2dit-ui.a(expr.o)
  ....
ld: symbol(s) not found for architecture x86_64
libFFI вроде как подключил... может как-то компилирую не так?
add_custom_target  (uihs DEPENDS expr.o)
add_custom_command (OUTPUT expr.o
                    COMMAND ghc --make ${CMAKE_SOURCE_DIR}/src/ui/expr.hs
                    DEPENDS ${CMAKE_SOURCE_DIR}/src/ui/expr.hs)

...

add_library(e2dit-ui STATIC ${SOURCES} ${FFI_LIBRARIES} expr.o)
add_dependencies(e2dit-ui uihs)

Int64 ★★★
() автор топика
Последнее исправление: Int64 (всего исправлений: 1)
Ответ на: комментарий от Int64

С точки зрения CMake выглядит все верно.

Возможно либа x86 версии, как собирал ее?

Я не умею в хаскель, пока что( :) ), поэтому лучше спросить тех, кто прыгал по граблям.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

я ее не собирал, сейчас на маке работаю, т.к. в отпуске, основная машина дома, через brew install ))
Попробую собрать вручную.

Int64 ★★★
() автор топика
Последнее исправление: Int64 (всего исправлений: 1)
Ответ на: комментарий от pon4ik

Попробовал скомпилировать сам, та же самая фигня :( Пойду спрошу на офф. форуме

Int64 ★★★
() автор топика
Ответ на: комментарий от pon4ik

Разобрался почему не работает, получается код где вызовы Haskell'а есть нужно компилировать Haskell'ем, наверное еще ко всему нужно не большие обертки делать для каждого исходника.

Int64 ★★★
() автор топика
Ответ на: комментарий от Int64

Звучит странно. Если шаришь - тебе надо выяснить две вещи (легко выяснить собрав просто либу на хаскеле):

  • Под какую архитектуру оно собирает
  • Какой abi используется, крестовый(какая версия, с каким gcc совместим), сишный или ещё какой то.

Выяснить это можно с помощью утилит objdump и nm. Под маком они должны быть, objdump точно был.

pon4ik ★★★★★
()
Последнее исправление: pon4ik (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.