自循环直译器
自循环直译器(英语:Meta-circular evaluator)是元直译器(Metainterpreter,或Self-interpreter)的一种。自循环直译器不仅是在直译语言中写成(如Scheme的自循环直译器是在Scheme中写成),而且通过底层语言的功能来实现直译语言的功能。因此,自循环直译器不需担心如何具体实现任何功能,而只需处理语言读入与直译,所以尤其适合作为教育用途。自循环直译器一般在同像(即程式与资料为同一格式,如Lisp)的语言中出现。
自循环直译器最早出现于约翰·麦卡锡的Lisp 1.5版定义,其中麦卡锡以Lisp语言的功能来描述Lisp的直译规则[1]。
Eval/Apply循环
著名电脑科学教科书《计算机程序的构造和解释》详细研究了一个Scheme语言的自循环直译器[2]。此书中的直译器包含两个主要元素:
- Eval,即将一个表示式转换为其取值的函数。
- Apply,即将一个函数呼叫转换为其返回值的函数。
这两个元素互相呼叫,并最终将整个程式转换为其取值。
实例
例如以下简单的Scheme表示式(假设square
是一个内建函数,其返回值为参数的平方):
(+ (square 2) (square 3))
其直译过程如下:
- 直译器首先将整个程式传入Eval,而Eval辨认出整个程式是一个函数呼叫(被呼叫的函数是“+”,或加法函数)。因此,Eval会呼叫Apply来处理这一呼叫。
- Apply收到被呼叫函数为“+”,参数分别为
(square 2)
与(square 3)
。因此,Apply分别呼叫Eval来处理这两个参数。 - Eval收到表示式为
(square 2)
,这是一个函数呼叫。因此Eval调用Apply。 - Apply收到被呼叫函数为“square”,参数为2(注意:这里的“2”仅仅是一个符号,而不是数字)。现在Apply会呼叫Eval,将符号“2”转换为数值2。Apply随后呼叫square函数,并返回4。同样地,Eval处理
(square 3)
并返回9。 - 现在直译器回到了Apply函数,处理“+”的呼叫。现在Apply函数有了参数的具体取值(分别为4和9),并呼叫“+”函数而返回13。
- Eval函数收到返回值13,这个值是整个表示式的取值。注意以上过程中自循环直译器并没有关心具体如何实现“+”函数与“square”函数,这些细节都由底层的Scheme来处理。
参见
注释
- ^ EVALQUOTE的定义,原文在 Lisp 1.5 Programmer's Manual (页面存档备份,存于互联网档案馆)
- ^ Harold Abelson and Gerald Jay Sussman with Julie Sussman. Structure and Interpretation of Computer Programs. Cambridge, MA: MIT Press. 1996 [2011]. ISBN 0-262-01153-0. (原始内容存档于2018年3月9日) (英语).