首页投稿(暂停使用,暂停投稿)

用 Lisp 解释 Lisp (2010-12-09)

2017-12-11  本文已影响67人  Pope怯懦懦地

最近在读《The Little Schemer》,一到七章都还好,到第八章就开始云里雾里了。书读不透,那么看代码吧。好在已经有了把示例都整理好了。那么开始吧。

我们期望能写出一个能对任意表达式求值的函数,一般叫它eval。不过,这里为了强调是我们自己的求值函数,叫它 value

我们先来看两个求值过程:

(value 6)  
(value '(add1 6))    ; 7  

我们不禁要问,这么多函数是必要的吗?它们起什么作用?

显然,value是个入口函数,因为它只用到了一次。

meaning需要一个表达式和一张记录变量名和其值的对照表(上下文环境)。这就引出一个问题,什么时候改写对照表?(*application)

接着,由expression-to-action判断表达式是否为原子( atom ),是的话交给atom-to-action(如果是数字、真假、cons, car, cdr, null?, eq?, atom?, zero?, add1, sub1, number?,就交给*const;其他交给*identifier);否则交给list-to-action

函数分为内置函数( primitive )和自定义函数( non-primitive )两类。语言规定了内置函数的行为,但对于自定义函数,我们只能在运行时确定,所以需要在定义时把它们的相关信息(如:参数、函数体)写进对照表。
它们分别是这么存储的:

(primitive primitive-name)
(non-primitive (table formals body)) (上下文 形参 函数体)

如,

(lambda (x) (cons x y))  

对照表的内容是

((( y  z)
  ((8) 9)))

那么,解释器内部是这么存储的:

其中,list (table formals body)叫做 closure record .

list-to-actionquote, lambda, cond之外函数交由*application处理。*application对函数和参数列表分别进行处理,按函数类型将primitive交给apply-primitive,而将non-primitive交给apply-closure处理。

evlis对 list 中的各个元素依次求值,把结果合成一个 list 返回。

evcon用于对cond求值。

剩下的各位还是看书吧😊

上一篇下一篇

猜你喜欢

热点阅读