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 _is_macro_call(ast, env): first = ast[0] return is_macro(first) \ or is_macro(env.get(first, False))