本文我们将实现一个解释器的基本结构。

思路

一个解释器的执行主要靠两个函数:evalapply

eval 会把你输入的表达式分解成更小的表达式并逐个执行,而 apply 会执行你的表达式。基本流程是这样的,例如你输入一个表达式 (+ 1 2 (/ 3 3)),首先 eval 会把 (+ 1 2 (/ 3 3)) 视为一整个表达式,然后会递归执行 eval 解析 (/ 3 3) ,最后 (/ 2 3) 这个表达式已经不可再分解了,就会调用 apply 执行 / 的操作,最后返回结果给上一个表达式,得 (+ 1 2 1),再执行 apply 得出最终结果 4

其中 primitive 为默认的操作符,例如 +-*/,我们之后再实现。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Evaluator:
def __init__(self,primitives):
self._exp_parser = ExpressionParser()
self._primitives = primitives
def eval(self,exp,env):
if exp == []: return

if isinstance(exp,Expression) == False:
exp = self._exp_parser.parse(exp,env)
return exp.eval(self,env)
def apply(self,proc,args):
if isinstance(proc,ProcedureExpression):
proc.env = Environment.extend_environment(dict(zip(proc.args, args)),proc.env)
return proc.eval(self,proc.env)
return proc(*args)

def init_primitives():
global_env.get_frame().set_variables(primitives)

def run_evaluator():
run_evaluator()

if __name__ == '__main__':
global_env = Environment()
exp_formattor = ExpressionFormattor()
primitives = {
"+": add,
"-": subtract,
"*": multiply,
"/": divide,
"=": equal,
"list": to_list,
"cons": cons,
"car": car,
"cdr": cdr,
"null?": null}
init_primitives()
evaluator = Evaluator(primitives)
run_evaluator()