def evaluate(e, r, k): if is_atom(e): if is_symbol(e): return evaluate_variable(e, r, k) else: return evaluate_quote(e, r, k) else: first = e.car if first == 'quote': return evaluate_quote(e.cadr, r, k) elif first == 'if': return evaluate_if(e.cadr, e.caddr, e.cadddr, r, k) elif first == 'begin': return evaluate_begin(e.cdr, r, k) elif first == 'set!': return evaluate_set(e.cadr, e.caddr, r, k) elif first == 'lambda': return evaluate_lambda(e.cadr, e.cddr, r, k) elif first == 'catch': return evaluate_catch(e.cadr, e.cddr, r, k) elif first == 'throw': return evaluate_throw(e.cadr, e.caddr, r, k) elif first == 'block': return evaluate_block(e.cadr, e.cddr, r, k) elif first == 'return-from': return evaluate_return_from(e.cadr, e.caddr, r, k) elif first == 'unwind-protect': return evaluate_unwind_protect(e.cadr, e.cddr, r, k) else: return evaluate_application(e.car, e.cdr, r, k)
def extend_env(env, names, values): if is_pair(names) and is_pair(values): return VariableEnv(extend_env(env, names.cdr, values.cdr), names.car, values.car) elif is_null(names) and is_null(values): return env elif is_symbol(names): return VariableEnv(env, names, values) else: raise TypeError("Arity mismatch")
def extend(env, variables, values): if is_pair(variables): if is_pair(values): return cons(cons(variables.car, values.car), extend(env, variables.cdr, values.cdr)) else: raise ValueError("Too few values") elif is_null(variables): if is_null(values): return env else: raise ValueError("Too many values") elif is_symbol(variables): return cons(cons(variables, values), env) else: raise RuntimeError("Branch should be unreachable")
def evaluate(expr, env): if is_atom(expr): if is_symbol(expr): return lookup(expr, env) else: return expr else: first = expr.car if first == 'quote': return expr.cadr elif first == 'if': if evaluate(expr.cadr, env): return evaluate(expr.caddr, env) else: return evaluate(expr.cadddr, env) elif first == 'begin': return eprogn(expr.cdr, env) elif first == 'set!': return update(expr.cadr, env, evaluate(expr.caddr, env)) elif first == 'lambda': return make_function(expr.cadr, expr.cddr, env) else: return invoke(evaluate(expr.car, env), evlis(expr.cdr, env))