Рассматривая строку как программу на Haskell

Как небольшая часть более крупного университетского проекта, мне нужно написать то, что по сути является чрезвычайно сырой IDE. Идея состоит в том, чтобы взять ввод из текстового поля gtk, обработать эту строку, как будто она находится в файле.hs, и оценить функцию внутри нее.

Мой основной подход состоял в том, чтобы использовать GHC API для компиляции и оценки тестовой функции. Мне уже удалось получить игрушечный пример работы для компиляции из файла.hs. Тип данных GHC Target имел необязательный конструктор для получения цели из StringBuffer, поэтому я решил попробовать и изменить свой код, чтобы он работал из String Buffer:

compileText :: SourceView -> IO ()
compileText tview = do

txtBuff <- textViewGetBuffer tview
startIt <- textBufferGetStartIter txtBuff
endIt <- textBufferGetEndIter txtBuff
compTime <- getClockTime
srcString <- textBufferGetText txtBuff startIt endIt False


defaultErrorHandler defaultLogAction $ do
  func <- runGhc (Just libdir) $ do
    dflags <- getSessionDynFlags
    setSessionDynFlags dflags
    addTarget $ haskellFileFromText srcString compTime
    r <- load LoadAllTargets
    case r of
      Failed -> error "Compilation failed"
      Succeeded -> do
        m <- findModule (mkModuleName "Test") Nothing
        setContext [IIModule m]
        value <- compileExpr ("Test.print")
        do let value' = (unsafeCoerce value) :: String -> IO ()
           return value'
  func "Hello"
  return ()

haskellFileFromText :: String -> ClockTime -> GHC.Target
haskellFileFromText codeStr cTime = GHC.Target (TargetModule (mkModuleName "Test")) False (Just ((stringToStringBuffer codeStr), cTime))

Следующий код находится в текстовом поле в то время:

module Test (Test.print) where

print :: String -> IO ()
print x = putStrLn x 

Тем не менее, это не похоже на работу. Я получаю ошибку:

textEdit: panic! (the 'impossible' happened)
  (GHC version 7.4.1 for x86_64-unknown-linux):
    Could not find module `Test'
Use -v to see a list of the files searched for.


Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

Что я делаю неправильно? Я чувствую, что совершенно не понимаю, как работает этот код.

Альтернатива этому методу, который был мне предложен, - это использовать что-то вроде подсказки или mueval для оценки текста в текстовом поле. Казалось бы, это работает нормально, если я просто хочу оценить отдельную функцию в отдельности, но будет ли это масштабироваться, если я захочу оценить функцию, которая зависит от контекста запуска 4 других функций, определенных в том же исходном файле?

1 ответ

Как отмечает К. Макканн, hint делает много этой работы для вас. Это обертка вокруг API GHC, а не просто автономный оценщик, как Mueval.

Даже если вам чего-то не хватает, вам будет намного легче учиться и расширять его, чем начинать с нуля.

Другие вопросы по тегам