Рассматривая строку как программу на 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.
Даже если вам чего-то не хватает, вам будет намного легче учиться и расширять его, чем начинать с нуля.