问题标签 [ghc-api]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
haskell - 使用 GHC API 将 Haskell 源代码编译为 CORE 和 CORE 为二进制
理念
你好!我想创建一个程序,它将生成 Haskell Core 并使用 GHC API 将其进一步编译成可执行文件。但在我开始之前,我想构建一个非常基本的示例,展示我们如何将 Haskell 源代码编译成 CORE,然后编译成二进制文件。
问题
我已经阅读了很多文档并尝试了 GHC Api 的许多方法,但现在没有成功。我从官方 GHC Api 介绍开始,并成功编译了示例。这些示例显示了以下函数的用法:parseModule
、typecheckModule
、和 ,desugarModule
但不包括最终编译步骤。另一方面,api 中有一些函数,其名称看起来与问题相关,例如HscMain.{hscCompileOneShot, hscCompileBatch}或GHC.{compileToCoreModule, compileCoreToObj}。我尝试使用它们,但出现运行时错误,如下例所示:getNamesInScope
getModuleGraph
可以使用它进行编译,ghc -package ghc Main.hs
并且在运行时会导致以下错误:
这当然可能是错误 API 使用的结果,特别是因为 line compileCoreToObj False coreMod "foo" "bar"
,其中字符串只是随机字符串,因为文档对它们没有太多说明。如果我们查看来源,似乎第一个是输出名称,第二个是“extCore_filename”,无论它可能是什么。
另一个令人担忧的事情是该函数旁边的文档中的注释compileCoreToObj
:
[...] 到目前为止,这仅使用一个独立的模块进行了测试。
但我希望它不会带来任何进一步的问题。
问题
创建此解决方案的最佳方法是什么?我们如何创建一个最小的工作示例,它将加载 haskell 源,将它们编译到 CORE 中,然后将核心编译为最终的可执行文件(使用 GHC API)。需要中间步骤来进一步替换自定义 CORE。
作为一个附带问题 - 目前是否可以为 GHC 提供外部核心文件,或者此功能尚未实现,我将不得不使用 GHC.Api 手动构建核心(相关:编译到 GHC 核心)
更新
我终于能够创建一个小示例,允许加载模块并将其编译为.hi
文件.o
。这不是问题的解决方案,因为它不允许我替换 CORE 并且它还没有将目标文件链接到可执行文件中:
haskell - 使用 ghc api 获取重命名的(具有完全限定的导入)haskell AST
我可以让以下 ghc 编译器使用 ghc api 编译单个文件。我想获得重命名的 haskell 源 AST(所有函数调用完全限定的 AST)
从这个简单的演示中,重命名过程应该在“加载”函数中完成。
来源在这里
(文件:///usr/local/haskell/ghc-7.10.2-x86_64/share/doc/ghc/html/libraries/ghc-7.10.2/src/GhcMake.html#load)
该函数实现了 GHC 的 --make 模式的核心。它预处理、编译和加载指定的模块,尽可能避免重新编译。根据目标(参见 hscTarget),编译和加载可能会导致在磁盘上创建文件。
上面的代码片段检查模块依赖是否正常,但之后似乎直接跳转到链接?我找不到链接功能在哪里。
相关职位:
haskell - Haskell,GHC 8:动态加载/导入模块
我需要有类似的东西
使用类似的插件
但是,我需要将插件与主应用程序一起编译。它们需要一起部署。只有模块的导入(而不是编译)应该动态发生。
我发现动态加载已编译的 Haskell 模块 - GHC 7.6,它与 GHC 8.0.2 一起工作得很好,除了它要求插件的源文件在执行应用程序时位于当前工作目录中。
编辑 (07.12.2017)
是否可以使用 GHC API 从字符串而不是文件加载模块?http://hackage.haskell.org/package/ghc-8.2.1/docs/GHC.html#t:Target建议这是可能的,但文档有很多漏洞,我找不到真正做到这一点的方法. 如果可以做到这一点,我可以使用file-embed将插件源文件包含到编译后的二进制文件中。例子:
然而,这会导致
编辑 (08.12.2017)
我可以通过将源代码写入临时文件然后像在链接的帖子中一样加载它(动态加载已编译的 Haskell 模块 - GHC 7.6),将“插件”直接编译到最终的二进制文件中。但是,如果插件从 Hackage 导入包,这将无法正常工作:
例如,当MyPlugin
包含语句时,有没有办法加载包import Data.Aeson
?如果我将它添加到插件字符串,它会失败
我请求的原因是数据库支持:我们使用 Persistent 访问数据库,需要动态导入以支持多个数据库(MySQL、PostgreSQL 和 SQLite),同时仍然允许最终用户只安装三个数据库服务器之一(使用换句话说:如果他们只使用例如 PostgreSQL,则不需要用户安装所有这些)。只有当用户实际配置主应用程序以使用该模块时,才应加载特定于数据库的模块。
如果我不这样做import Database.Persist.MySQL
,则该应用程序不需要安装 MySQL。否则,应用程序将失败,例如,
在 macOS 上。
haskell - 使用 GHC API 编译优化程序
我想将 Haskell 模块编译为 GHC Core,并应用优化,并使用生成的核心输出。但是,当我使用compileToCoreSimplified
它时,它似乎并没有运行所有正常的优化。参加节目:
通过运行时,ghc -ddump-simple
我得到了最佳输出:
但是,当使用编译时,compileToCoreSimplified
我得到输出:
我正在调用compileToCoreSimplified
:
如何驱动 GHC API 应用完整优化?
haskell - Haskell:可以编译函数吗?
考虑一个简单的 Haskell Brainf*ck解释器。只看interpret
功能。
所以我有一个像interpret "[->+<]"
. 这给了我一个IO ()
执行给定程序的单子动作。它具有成为main
某些程序的正确类型。
假设我想将此操作编译为可执行文件,也就是说,我想生成一个可执行文件,其结果为interpret ...
main 函数。当然,这个可执行文件必须包含 GHC 运行时系统(用于无限列表、整数运算等)。
问题:
- 我认为根本不可能只采取单子动作并将其保存为新文件。这是真的?
- 一个人怎么能找到一个类似的解决方案呢?GHC Api 和提示有帮助吗?
编辑
抱歉,我在原始问题中过于简单化了。当然,我可以像这样写一个文件:
但这不是我们在尝试编译某些东西时通常会做的事情,所以请考虑一下interpretFile :: FilePath -> IO ()
。让BF程序保存在一个文件中(helloworld.bf
)。
我将如何创建一个可执行文件,该可执行文件在helloworld.bf
实际上不需要该文件的情况下执行该文件的内容?
haskell - 使用 GHC 插件解析类型
我正在开发一个编译器插件,如果声明没有作为插件参数给出的类型,它应该中止编译。
我认为该功能Unify.tcMatchTy :: Type -> Type -> Maybe TCvSubstS
可以解决问题。我可以从类型检查器插件的输入中找到其中一种参数类型,但另一种作为插件参数出现。也就是说,作为一个String
.
我如何在类型检查器插件中Type
从 a 中获取 a String
?我尝试使用parseType
后跟调用rnHsType
and tcLHsType
,它确实将 a 转换String
为Type
. 这似乎适用于简单类型,但是当字符串包含类型变量时会导致这种错误:
我可能在这里遗漏了一些(或者可能是一大块)工作,但是我应该在哪里寻找呢?
(在输入前加上 a 会forall a b.
导致编译器恐慌)
haskell - GHC API:查找实例函数的实现
我正在使用 GHC 为 Haskell 编写一个符号执行引擎,并且经常需要instance
在程序中找到各种函数的实现。但是,在浏览了类型检查器生成的许多 AST 之后,我看不出有任何方法可以将函数调用与instance
块中的实现联系起来。AST 没有支持匹配Unique
键的明显解决方案的信息。与顶级函数定义不同,Unique
实例函数绑定中的 s 都不匹配Unique
调用站点的。例如,在这个简单的程序中:
在body中bar
,foo
有唯一的id rrZ
。在HsBind
实例定义中,有以下 varName-varUnique 对:
- 在顶级
AbsBind
:$cfoo
:a1dd
foo
:a1de
- 在嵌套
AbsBind
foo
:a1dg
由于它们都不匹配调用站点,因此我采用了一种间接方法,将调用站点的类型与所有具有相同名称的类型进行匹配,但这需要我为顶级函数的实例编写单独的逻辑。是否有统一的方法来查找某些功能的实现?
haskell - 如何编写代码来修改 Haskell 源文件的 AST 而不会丢失编译指示?
我需要对现有的 Haskell 源文件进行一些更改,并写出修改后的源代码。我想为此使用 GHC API,以便结果与当前的 Haskell 一致。我目前的方法在这里,类似于:
这工作......几乎!它去除了 LANGUAGE 和 OPTIONS_GHC pragma,因此有时较早编译的文件在往返后会失败。
有一个更好的方法吗?
我注意到这ghc-exactprint
看起来很相关,但我不知道如何让它很好地工作。看起来它与 GHC 会话相关联,该会话可能DynFlags
从命令行初始化,以及许多我不想要的其他垃圾。如果这是正确的方向,我可以使用一些帮助来提炼要做什么,尤其是使用我自己DynFlags
已经可以构建并且不会将 GHC 命令行处理等泄漏到代码中的帮助。
haskell - 调用 GHC API 时出现警告“hptSomeThingsBelowUs 中的警告,缺少模块……”的原因是什么以及如何摆脱它?
我试图使用 GHC API 动态加载多个.hs
文件。我写了两个.hs
文件,test.hs
和Module.hs
,并将它们放入/tmp
文件夹中。这两个文件非常简单。Module.hs
定义了一个名为Module
包含Int
值test.hs
的模块,并定义了将值Test
导入Module
和复制Int
到自身的模块。它们的内容如下所示。
Module.hs
:
test.hs
:
然后在另一个文件中,我编写了以下代码来调用 GHC API 并加载这两个文件。
程序运行,但输出如下。
我们可以注意到程序成功地计算了表达式print value
,并输出1234
了,但是函数core2core
发出了上面的警告消息。一对注释之间的六行似乎与程序的其余部分无关,因为这只是我从另一个更大的项目中提取的一个最小的可重现示例。警告信息在这里也没有什么坏处,但它会在该项目中引起更严重的问题。GHC API 似乎没有很好的文档记录,所以经过大量搜索后我无法解决问题。谁能解释警告消息的原因,并帮助我使用 GHC API 处理多个文件?提前致谢。