(load "record.ss") ;;; Expression records (define-record num (val)) (define-record varref (var)) (define-record lambda (formals body)) (define-record delta (formals body)) (define-record app (operator operands)) (define-record if (test then else)) (define-record letrecproc (procdecls body)) (define-record procdecl (var formals body)) (define-record let (vars exps body)) ;;; Recordifier (aka Parser) (define recordify-procdecl (lambda (decl) (make-procdecl (car decl) (cadr decl) (recordify (caddr decl))))) (define recordify (lambda (exp) (cond ((number? exp) (make-num exp)) ((symbol? exp) (make-varref exp)) ((atom? exp) (error 'recordify "illegal expression ~s" exp)) (else (case (car exp) ((lambda) (make-lambda (cadr exp) (recordify (caddr exp)))) ((delta) (make-delta (cadr exp) (recordify (caddr exp)))) ((if) (make-if (recordify (cadr exp)) (recordify (caddr exp)) (recordify (cadddr exp)))) ((let) (let ((vars (map car (cadr exp))) (exps (map cadr (cadr exp)))) (let ((exps (map recordify exps))) (make-let vars exps (recordify (caddr exp)))))) ((letrecproc) (make-letrecproc (map recordify-procdecl (cadr exp)) (recordify (caddr exp)))) (else (make-app (recordify (car exp)) (map recordify (cdr exp))))))))) ;;; Value records (define-record closure (formals body env)) (define-record deltacl (formals body)) ;;; Finite function ADT (define create-empty-ff (lambda () '())) (define extend-ff* (lambda (vars vals env) (append (map cons vars vals) env))) (define apply-ff (lambda (env var) (cond ((assq var env) => cdr) (else (error 'apply-ff "variable ~s is undefined" var)))))