在上文中,我们提到了 Evaluator 有默认的操作符,本文将实现这些操作符。

默认操作符的实现

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
def accumulate(proc,init,args):
result = init
for i in args:
result = proc(result,i)
return result

def add(*args):
return accumulate(lambda a,b:a + b,0,args)
def subtract(*args):
return accumulate(lambda a,b:a - b,0,args)
def multiply(*args):
return accumulate(lambda a,b:a * b,1,args)
def divide(*args):
return accumulate(lambda a,b:a / b,1,args)

def to_list(*args):
return accumulate(lambda a,b:a + [b],[],args)

def cons(first,second):
return [first] + [second]
def car(pair):
return pair[0]
def cdr(pair):
if len(pair) == 2:
return pair[1]
return pair[1:]
def null(seq):
return seq == []

在 Evaluator 里设置默认操作符

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
40
class Evaluator:
def __init__(self):
self._exp_parser = ExpressionParser()
self._init_primitives()
def eval(self,exp,env):
if exp == []: return

if isinstance(exp,Expression) == False:
exp = self._exp_parser.parse(exp)

if isinstance(exp,Expression) == False:
if len(exp) == 1:
exp = VariableExpression(exp)
else:
args = list(map(lambda arg: self.eval(arg,env),exp[1:]))
proc = env.get_variable(exp[0])
if proc == None:
proc = self._primitives[exp[0]]

if isinstance(proc,ProcedureExpression):
for i in range(len(proc.args)):
proc.env.define_variable(proc.args[i],args[i])
return self.apply(proc,args)
return exp.eval(self,env)
def apply(self,proc,args):
if proc in self._primitives.values():
return proc(*args)
return self.eval(proc.proc,proc.env)
def _init_primitives(self):
self._primitives = {
"+": add,
"-": subtract,
"*": multiply,
"/": divide,
"list": to_list,
"cons": cons,
"car": car,
"cdr": cdr,
"null?": null
}