def evaluate(ast, env): """Evaluate an Abstract Syntax Tree in the specified environment.""" if is_symbol(ast): return env[ast] elif is_atom(ast): return ast elif is_list(ast): if ast[0] == 'atom': return eval_atom(ast, env) elif ast[0] == 'eq': return eval_eq(ast, env) elif ast[0] == 'macro': return eval_macro(ast, env) elif ast[0] == 'expand': return eval_expand(ast, env) elif ast[0] == 'expand-1': return eval_expand_1(ast, env) elif ast[0] == 'cond': return eval_cond(ast, env) elif ast[0] == 'let': return eval_let(ast, env) elif ast[0] == 'eval': return eval_eval(ast, env) elif ast[0] == 'set!': return eval_set(ast, env) elif ast[0] == 'quote': return eval_quote(ast, env) elif ast[0] == 'quasiquote': return eval_quasiquote(ast, env) elif ast[0] in ('lambda', 'λ'): return eval_lambda(ast, env) elif ast[0] == 'begin': return eval_begin(ast, env) elif ast[0] == 'define': return eval_define(ast, env) else: fn = evaluate(ast[0], env) if is_macro(fn): return apply_macro(ast, env) elif is_lambda(fn): return apply_lambda(ast, env) elif is_builtin(fn): return apply_builtin(ast, env) else: raise LispTypeError("Call to: " + unparse(ast[0])) else: raise LispSyntaxError(ast)
def eval_eq(ast, env): _assert_exp_length(ast, 3) v1, v2 = evaluate(ast[1], env), evaluate(ast[2], env) return boolean(True) if v1 == v2 and is_atom(v1) else boolean(False)
def eval_atom(ast, env): arg = evaluate(ast[1], env) return boolean(is_atom(arg))