(load "record.ss") ;;; Expression records (define-record num (val)) (define-record varref (var)) (define-record lambda (formals body)) (define-record app (operator operands)) (define-record if (test then else)) (define-record varassign (var exp)) (define-record let (vars exps body)) (define-record begin (exps)) ;;; Recordifier (aka Parser) (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 (cons 'begin (cddr 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 (cons 'begin (cddr exp))))))) ((set!) (make-varassign (cadr exp) (recordify (caddr exp)))) ((begin) (make-begin (map recordify (cdr exp)))) (else (make-app (recordify (car exp)) (map recordify (cdr exp))))))))) ;;; Value records (define-record closure (formals body env)) ;;; Environment ADT (define create-empty-env (lambda () '())) (define extend-env (lambda (vars vals env) (append (map cons vars vals) env))) (define apply-env (lambda (env var) (cond ((assq var env) => cdr) (else (error 'apply-env "variable ~s is undefined" var))))) ;;; 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)))))