在自己编写扩展之前要在 C 中实现多少 lisp?

How much lisp to implement in C before writing extension in itself?

我正在用 C 实现一个 lisp 解释器,我已经实现了一些原语,如 cons 、 car 、 cdr 、 eq 、基本算术东西。

就在我开始实施 define 和 lambda 之前,我突然想到我需要实施一个环境。我不确定我是否可以在 lisp 本身中实现它。

我的意图是实现最少量的 lisp,以便我可以编写语言本身的扩展。我不确定有多少是最小的,实施 FFI 是否符合最小要求?

您问题的答案取决于您赋予“最小”一词的含义。

鉴于你的问题,并假设你不想让一个实现与当今 Common Lisp 和 Schema 的优秀实现竞争,我的假设是你打算使用“最小”:Turing complete,能够表达任何可用通用编程语言表达的计算。

根据这个假设,您还需要实现另外三件事:

  1. 条件形式 (cond)
  2. lambda 表达式 (lambda)
  3. 一种定义递归lambda表达式的方式(labelsdefun

然后您的口译员应该能够评估表格。这应该足以让语言等同于最初的LISP,允许用语言表达任何可计算的函数。

首先,您是在谈论首先编写一个 LISP 解释器。当涉及范围界定时,您有很多选择,LISP1 与 LISP2,因为这些问题改变了实现核心。解释器是读取和评估代码的通用程序。它可以支持抽象,但不会通过制作更多本地内容来扩展自己。

如果你对这些东西感兴趣,你也许可以制作一个编译器。例如。有许多类似 Sceme 的子集可以编译为 C 或 Java 代码,但您可以制作自己的 VM。因此,如果您使用的所有表单和过程都是使用编译器支持的原语实现的,它确实可以在自己的目标机器(自托管)上将自己编译为 运行。

制作一个愚蠢的编译器与制作一个解释器没有太大区别。如果你看过 SICP videos 就很清楚了(10A 是关于编译,7A-B 是关于解释器)

环境可以是一对链,就像在 LISP 解释器中一样。如果不使它成为一种非常难用的 Lisp 语言,就很难在 LISP 中实现其自身的环境(除非它是经过编译的) 不过,您可以使用 lisp 的数据结构和 C 代码中的原语。

制作 FFI 是为您的语言提供许多功能的快速方法。它通过在您的语言中使用其他人的作品来解决先有鸡还是先有蛋的问题。 In 融合了系统的顶层(原语和语法)和底层(运行时间)。它是最终的原语,您可以将其视为 运行 时间的系统调用或消息总线。

强烈建议阅读Queinnec's book: Lisp In Small Pieces。这是一本完全致力于回答您的问题的书,它通过给出许多 Lisp 解释器和编译器的解释示例,详细解释了 Lisp 实现和定义的许多权衡和内部结构。

您也可以考虑使用 libffi. You could be interested in the internals of M.Serrano's Bigloo & Hop implementations. You might even look inside my MELT lisp-like language to customize the GCC 编译器。

您还需要了解更多 garbage collection (you might read the GC handbook). You could use Boehm's conservative Garbage Collector (or something else, e.g. my Qish or MPS) 或编写自己的 GC。

您可能想了解有关 Chicken, Scheme 48, Guile 的更多信息并阅读他们的论文并查看他们的代码。

另见 J.Pitrat's blog:它不是关于 Lisp(而是关于引导强大的 AI)并且有几个与引导相关的引人入胜的条目。