(module interp (lib "eopl.ss" "eopl") (require "drscheme-init.scm") (require "lang.scm") (require "data-structures.scm") (require "environments.scm") (provide value-of-program value-of/k) ;;;;;;;;;;;;;;;; the interpreter ;;;;;;;;;;;;;;;; ;; value-of-program : program -> expval (define value-of-program (lambda (pgm) (cases program pgm (a-program (body) (value-of/k body (init-env) (end-cont)))))) ;; value-of : expression * environment * continuation -> final-expval (define value-of/k (lambda (exp env cont) (cases expression exp (const-exp (num) (apply-cont cont (num-val num))) (var-exp (id) (apply-cont cont (apply-env env id))) (diff-exp (exp1 exp2) (value-of/k exp1 env (diff1-cont exp2 env cont))) (proc-exp (bvar body) (apply-cont cont (proc-val (procedure bvar body env)))) (call-exp (rator rand) (value-of/k rator env (rator-cont rand env cont)))))) ;; apply-cont : continuation * expval -> final-expval (define apply-cont (lambda (cont val) (cases continuation cont (end-cont () (register-value-with-test-harness val)) (diff1-cont (exp2 env cont) (value-of/k exp2 env (diff2-cont val cont))) (diff2-cont (val1 cont) (let ((n1 (expval->num val1)) (n2 (expval->num val))) (apply-cont cont (num-val (- n1 n2))))) (rator-cont (rand env cont) (value-of/k rand env (rand-cont val cont))) (rand-cont (val1 cont) (let ((proc (expval->proc val1))) (apply-procedure proc val cont))) ))) ;; apply-procedure : procedure * expval -> expval (define apply-procedure (lambda (proc1 arg cont) (cases proc proc1 (procedure (bvar body saved-env) (value-of/k body (extend-env bvar arg saved-env) cont))))) ;; trace has to be in the module where the procedure is defined. (trace value-of/k apply-cont) )