(defmacro or (a b) `(if ,a t ,b)) (define map (lambda (f xs) (if (eq nil xs) nil (cons (f (car xs)) (map f (cdr xs)))))) (define cadr (lambda (xs) (car (cdr xs)))) (define caddr (lambda (xs) (car (cdr (cdr xs))))) (define cadddr (lambda (xs) (car (cdr (cdr (cdr xs)))))) (define let-bindings cadr) (define let-body caddr) (define lambda-params cadr) (define lambda-body caddr) (define lookup (lambda (e env success failure) (if (eq nil env) (failure) (if (eq nil (atom (car (car env)))) (lookup e (car env) success (lambda () (lookup e (cdr env) success failure))) (if (eq e (car (car env))) (success (cdr (car env))) (lookup e (cdr env) success failure)))))) (define member (lambda (e xs) (if (eq nil xs) nil (if (eq e (car xs)) xs (member e (cdr xs)))))) (define compile-closure (lambda (e params ram env) (let ((init-params (append `(if current-env current-ram eval begin atom car cdr emit quote macroexpand + - / * = eq cons) params)) (rec (lambda (e) (compile-closure e init-params ram env))) (rec-params (lambda (e params) (compile-closure e (append init-params params) ram env)))) (if (atom e) (if (member e params) e (lookup e env (lambda (v) ;;(if (functionp v) e v) v ) (lambda () (lookup e ram (lambda (v) v) (lambda () e))))) (let ((tag (car e))) (if (or (eq 'let tag) (eq 'letrec tag)) ;; NOTE: this over approximates params in the right-hand sides (let ((all-params (append (map (lambda (b) (car b)) (let-bindings e)) params))) `(,tag ,(map (lambda (b) `(,(car b) ,(rec-params (cadr b) all-params))) (let-bindings e)) ,(rec-params (let-body e) all-params))) (if (eq 'lambda tag) `(,tag ,(lambda-params e) ,(rec-params (lambda-body e) (append (lambda-params e) params))) (if (eq 'quote tag) e ;; NOTE: this is post-expansion, so no macros! (map rec e)))))))))