返回
Python打造Lisp解释器(二):揭秘运算符的黑魔法
闲谈
2024-02-29 01:42:44
日拱一卒,我是梁唐。欢迎来到伯克利YYDS系列,这一篇,我将揭开Lisp运算符的黑魔法,带你踏上Python Lisp解释器之路!
回顾前尘
在上一篇中,我们建立了Lisp解释器的基础设施,包括词法分析器、解析器和求值器。今天,我们将深入运算符的王国,赋予我们的解释器处理运算符的魔力。
运算符的奥义
Lisp中的运算符既强大又灵活。它们可以是前缀、中缀或后缀,具体取决于运算符的类型和操作数的个数。为了让我们的解释器无所不能,我们需要掌握各种运算符的用法。
前缀运算符
前缀运算符出现在操作数前面,如+
或-
。在Python中,我们可以使用一元运算符来实现它们:
def negate(exp):
return -exp
中缀运算符
中缀运算符位于两个操作数之间,如+
或*
。我们可以使用Python中的二元运算符来处理它们:
def add(exp1, exp2):
return exp1 + exp2
后缀运算符
后缀运算符出现在操作数之后,Lisp中没有这种运算符,因此我们也不需要在Python中实现它。
运算符的魔法
了解了运算符的类型,我们来揭开它们运作的秘密。对于前缀运算符,我们只需将其应用于操作数即可。对于中缀运算符,我们需要将操作数传递给运算符函数,然后返回结果。
def eval_prefix(exp):
op = exp[0]
if op == '+':
return add(exp[1], exp[2])
elif op == '-':
return negate(exp[1])
def eval_infix(exp):
op = exp[1]
if op == '+':
return add(exp[0], exp[2])
elif op == '*':
return multiply(exp[0], exp[2])
释放运算符的力量
现在,我们拥有了处理运算符所需的知识和代码,是时候释放它们的力量了。我们将扩展我们的求值器,使其能够处理运算符表达式:
def eval(exp):
if is_number(exp):
return int(exp)
elif is_var(exp):
return env[exp]
elif is_prefix(exp):
return eval_prefix(exp)
elif is_infix(exp):
return eval_infix(exp)