我有一个小语言,它基本上是OCaml的扩展(实际上它是OCaml子集的扩展,但这几乎不重要)。为了简化事情我有一个"逃避"将OCaml文字传输到我的语言中的表达式(因此您可以将任意OCaml代码嵌入到该语言中)。将这样的表达式编译成OCaml只是意味着打开字符串,但是如何评估它呢?
当然我理解OCaml是一种静态类型语言,以及该类型系统的工作原理。因此,我还需要能够提供一个环境并检查表达式的推断类型(或者至少应对类型错误)。我也知道需要管理解释器状态等。让我们暂时假设嵌入式表达式是无副作用的。
显然这是可能的,因为utop和顶层都是在OCaml中实现的。所以我的第一个想法就是选择其中一个并根据我的需要调整它们。现在我的问题:
toplevel显然是主要发行版的一部分。虽然有一个带有必要功能的toplevel.mli甚至是.mllib,但我找不到像打包的库那样 - 是否需要进一步的配置调整来获得"解释器作为a -library"封装
utop似乎做了更奇怪的事情。根据我从源代码中可以看出,它在构建时将一些编译器库复制到其源目录中。这似乎很奇怪:如果它在构建时知道如何找到这些编译器库,为什么不简单地链接?
那么有没有合理的方法将OCaml解释器嵌入到OCaml程序中?
答案 0 :(得分:1)
afaik最简单的方法是使用字节码编译器将提供的代码编译到模块,然后使用dynlink
加载并执行。您也可以通过本机编译器对其进行编译,但这需要您使用inst。
您可以以任何方式编译文件,包括system
命令,但您也可以直接调用编译器接口[1]:
Compile.implementation Format.std_formatter "test.ml" "test";;
这将使用“test.ml”文件在同一目录中创建test.cmo
和test.cmi
个文件。之后,您可以使用Dynlink
Dynlink.loadfile "test.cmo";;
[1]此模块位于compiler-libs
库中的某个位置,可能是"compiler-libs.bytecomp"