!(defrec ev (lambda (exp env) (if (atom exp) (env exp) (if (eq 'lambda (car exp)) (let ((param (car (car (cdr exp)))) (body (car (cdr (cdr exp))))) (lambda (arg) (ev body (lambda (x) (if (eq x param) arg (env x)))))) (if (eq 'letrec (car exp)) (let ((bindings (car (cdr exp))) (body (car (cdr (cdr exp)))) (binding (car bindings)) (lhs (car binding)) (rhs (car (cdr binding))) (rhs-param (car (car (cdr rhs)))) (rhs-body (car (cdr (cdr rhs))))) (letrec ((f (lambda (arg) (ev rhs-body (lambda (x) (if (eq x rhs-param) arg (if (eq x lhs) f (env x)))))))) (ev body (lambda (x) (if (eq x lhs) f (env x)))))) (if (eq 'if (car exp)) (if (ev (car (cdr exp)) env) (ev (car (cdr (cdr exp))) env) (ev (car (cdr (cdr (cdr exp)))) env)) (if (eq '* (car exp)) (* (ev (car (cdr exp)) env) (ev (car (cdr (cdr exp))) env)) (if (eq '- (car exp)) (- (ev (car (cdr exp)) env) (ev (car (cdr (cdr exp))) env)) (if (eq 'eq (car exp)) (eq (ev (car (cdr exp)) env) (ev (car (cdr (cdr exp))) env)) (let ((fun (ev (car exp) env)) (arg (ev (car (cdr exp)) env))) (fun arg))))))))))) !(def eval (lambda (exp) (ev exp (lambda (x) x))))