【问题标题】:Treating a String as a Haskell Program将字符串视为 Haskell 程序
【发布时间】:2012-12-23 20:47:50
【问题描述】:

作为一个大型大学项目的一小部分,我需要编写一个本质上极其简陋的 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 个其他函数的上下文的函数,这会扩展吗?

【问题讨论】:

  • 你可能想看看github.com/shapr/ghclive的ghclive
  • 你真的详细看过hint吗?它不仅仅是一个表达式求值器——它更接近 GHCi,具有模块加载和一切功能。
  • 根据另一个 Stackoverflow,How to Handle "panic the impossible happend" ... 问题你应该报告一个错误。问题,你是想简单地评估盒子里的东西还是想把它从 ghcMonad 中拿出来?

标签: haskell gtk ghc dynamic-compilation ghc-api


【解决方案1】:

作为 C.A. McCann 指出,hint 为您做了很多这样的工作。它是 GHC api 的包装器,而不仅仅是像 mueval 这样的独立评估器。

即使它缺少你需要的东西,学习和扩展它也比从头开始容易得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    相关资源
    最近更新 更多