返回

Python打造Lisp解释器(二):揭秘运算符的黑魔法

闲谈

日拱一卒,我是梁唐。欢迎来到伯克利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)