(define toExit #f) (define eval-one-exp (lambda (exp) (let* ([parse-tree (parse-expression exp)] [initial-environment (init-env)] [result (eval-expression parse-tree initial-environment)]) (if toExit toExit result))))) (define eval-expression (lambda (exp env) (cases expression exp [var-exp (id) (apply-env env id)] [lit-exp (val) val] [exit-exp (val) (let ([v (eval-expression val env)]) (set! toExit v) v)] [if-exp (conditional if-true if-false) (if (eval-expression conditional env) (eval-expression if-true env) (eval-expression if-false env))] [lambda-exp (ids body) (make-closure ids body env)] [app-exp (exps) (let ([vals (map (lambda (x) (eval-expression x env)) exps)]) (apply-proc (car vals) (cdr vals)))] [else (eopl:error 'eval-expression "Received bad expression ~s" exp)]))) (define make-closure (lambda (ids body env) (closure-record ids body env))) (define-datatype closure closure? [closure-record (ids (list-of symbol?)) (body expression?) (env environment?)]) (define apply-proc (lambda (proc args) (if (closure? proc) (cases closure proc [closure-record (ids body env) (eval-expression body (extend-env ids args env))]) (proc args))))