用python實現一個簡易的lisp解釋器--默認操作符的實現(6)

在上文中,我們提到了 Evaluator 有默認的操作符,本文將實現這些操作符。

默認操作符的實現

def accumulate(proc,init,args): result = init for i in args: result = proc(result,i) return resultdef 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 里設置默認操作符

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 }

推薦閱讀:

怎麼理解從lambda運算元到實際的函數式程序設計語言?
(如何(用Python)寫一個(Lisp)解釋器(下))
Haskell 和 Scheme, 哪一個更適合用於生產環境?
使用宏給racket加類型
能不能用DrRacket代替GUN/MIT Scheme去實現SICP中的習題?DrRacket和GNU/MIT Scheme有什麼區別?

TAG:Scheme | 解釋器 | SICP |