Lisp解释器的实现--解释器基本结构的实现(5)

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

思路

一个解释器的执行主要靠两个函数: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()

Lisp解释器的实现--简介(1)

本系列文章,我们将用 python 实现一个简易的 lisp 解释器,其中选定 lisp 的方言为 scheme。本文的主要内容参考于 sicp。

主要工作

要实现一个 scheme 解释器,我们要做以下内容:

  • 格式化输入的表达式字符串,转化成较容易处理的格式
  • 根据格式确定表达式的类型
  • 解析表达式并运行

我们会逐步完成这些工作,最后实现一个 scheme 解释器。