用Lisp解释Lisp

最近在读《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-action将quote, lambda, cond之外函数交由*application处理。*application对函数和参数列表分别进行处理,按函数类型将primitive交给apply-primitive,而将non-primitive交给apply-closure处理。

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

 

evcon用于对cond求值。

剩下的各位还是看书吧^_^

 

你可能感兴趣的:(Lisp)