嵌入ocaml解释器

时间:2014-10-14 08:39:03

标签: embed ocaml interpreter staging

我有一个小语言,它基本上是OCaml的扩展(实际上它是OCaml子集的扩展,但这几乎不重要)。为了简化事情我有一个"逃避"将OCaml文字传输到我的语言中的表达式(因此您可以将任意OCaml代码嵌入到该语言中)。将这样的表达式编译成OCaml只是意味着打开字符串,但是如何评估它呢?

当然我理解OCaml是一种静态类型语言,以及该类型系统的工作原理。因此,我还需要能够提供一个环境并检查表达式的推断类型(或者至少应对类型错误)。我也知道需要管理解释器状态等。让我们暂时假设嵌入式表达式是无副作用的。

显然这是可能的,因为utop和顶层都是在OCaml中实现的。所以我的第一个想法就是选择其中一个并根据我的需要调整它们。现在我的问题:

  • toplevel显然是主要发行版的一部分。虽然有一个带有必要功能的toplevel.mli甚至是.mllib,但我找不到像打包的库那样 - 是否需要进一步的配置调整来获得"解释器作为a -library"封装

  • utop似乎做了更奇怪的事情。根据我从源代码中可以看出,它在构建时将一些编译器库复制到其源目录中。这似乎很奇怪:如果它在构建时知道如何找到这些编译器库,为什么不简单地链接?

那么有没有合理的方法将OCaml解释器嵌入到OCaml程序中?

1 个答案:

答案 0 :(得分:1)

afaik最简单的方法是使用字节码编译器将提供的代码编译到模块,然后使用dynlink加载并执行。您也可以通过本机编译器对其进行编译,但这需要您使用inst。

更新

您可以以任何方式编译文件,包括system命令,但您也可以直接调用编译器接口[1]:

Compile.implementation Format.std_formatter "test.ml" "test";;

这将使用“test.ml”文件在同一目录中创建test.cmotest.cmi个文件。之后,您可以使用Dynlink

加载它
Dynlink.loadfile "test.cmo";;

[1]此模块位于compiler-libs库中的某个位置,可能是"compiler-libs.bytecomp"