;;; Imperative Interpreter from Lecture 8b, Tue Nov 16 15:47:40 1993 (define eval-toplevel (lambda (exp env) (set! exp-reg exp) (set! env-reg env) (set! k-reg (make-final-value-cont)) (eval-exp))) (define eval-exp (lambda () ; uses exp-reg, env-reg, k-reg (record-case exp-reg (lit-exp (constant) ;; (apply-continuation k constant) (set! val-reg constant) (apply-continuation)) (var-exp (id) ;; (apply-continuation k (apply-env env id)) (set! val-reg (apply-env env-reg id)) (apply-continuation)) (proc-exp (formals body) ;; (apply-continuation k (make-closure formals body env)) (set! val-reg (make-closure formals body env-reg)) (apply-continuation)) (if-exp (test-exp exp1 exp2) ;; (eval-exp test-exp env ;; (make-test-value-cont exp1 exp2 env k)) (set! exp-reg test-exp) (set! k-reg (make-test-value-cont exp1 exp2 env-reg k-reg)) (eval-exp)) (app-exp (rator rands) ;; (eval-exp rator env ;; (make-proc-value-cont rands env k)) (set! exp-reg rator) (set! k-reg (make-proc-value-cont rands env-reg k-reg)) (eval-exp)) (else (error 'eval-exp "Bad abstract syntax: ~s" exp))))) (define eval-rands (lambda () ; uses rands-reg, env-reg, k-reg (if (null? rands-reg) (begin ;; (apply-continuation k '()) (set! val-reg '()) (apply-continuation)) (begin ;; (eval-exp (car rands) env ;; (make-first-arg-cont rands env k)) (set! exp-reg (car rands)) (set! k-reg (make-first-arg-cont rands env-reg k-reg)) (eval-exp))))) (define apply-proc (lambda () ; uses proc-reg, args-reg, k-reg (record-case proc-reg (primitive-proc (primop) ;; (apply-continuation k (apply-primop primop args)) (set! val-reg (apply-primop primop args-reg)) (apply-continuation)) (closure (formals body env) ;; (eval-exp body (extend-env formals args env) k) (set! exp-reg body) (set! env-reg (extend-env formals args-reg env-reg)) (eval-exp)) (else (error 'apply-proc "Bad Procedure: ~s" proc))))) (define apply-continuation (lambda () ; uses k-reg, val-reg (let ((frame (car k-reg))) (set! k-reg (cdr k-reg)) (record-case frame (exit-frame () val-reg) (test-value-cont-frame (exp1 exp2 env) ;; (let ((v val)) ;; (if (true-value? v) ;; (eval-exp exp1 env k) ;; (eval-exp exp2 env k))) (if (true-value? val-reg) (set! exp-reg exp1) (set! exp-reg exp2)) (set! env-reg env) (eval-exp)) (proc-value-cont-frame (rands env) (let ((proc val-reg)) ;; (eval-rands rands env ;; (make-args-cont proc k)) (set! rands-reg rands) (set! env-reg env) (set! k-reg (make-args-cont proc k-reg)) (eval-rands))) (args-cont-frame (proc) (let ((args val-reg)) ;; (apply-proc proc args k) (set! proc-reg proc) (set! args-reg args) (apply-proc))) (first-arg-cont-frame (rands env) (let ((first-arg val-reg)) ;; (eval-rands (cdr rands) env ;; (make-other-args-cont first-arg k)) (set! rands-reg (cdr rands)) (set! env-reg env) (set! k-reg (make-other-args-cont first-arg k-reg)) (eval-rands))) (other-args-cont-frame (first-arg) (let ((other-args val-reg)) ;; (apply-continuation k ;; (cons first-arg other-args)) (set! val-reg (cons first-arg other-args)) (apply-continuation))) (else (error 'apply-cont "Bad Continuation Frame: ~s" frame)))))) ;;; That's all, folks!