首页 文章

嵌入ocaml解释器

提问于
浏览
2

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

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

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

  • toplevel显然是主要发行版的一部分 . 虽然有一个带有必要功能的toplevel.mli甚至是.mllib,但我找不到顶层作为打包库 - 是否需要进一步的配置调整来获取"interpreter-as-a-library"包?

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

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

1 回答

  • 1

    最简单的方法是使用字节码编译器将提供的代码编译到模块,然后使用 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"

相关问题