;;;---------------------------------------------------------------------------- ;;; CLOSURIZE.SCM ;;; ;;; A closure converter that makes flat closures for all LAMBDAs and FUNRECs. ;;; Writing CLOSURIZE-FUNREC is left as an exercise. ;;; ;;;---------------------------------------------------------------------------- (define (closurize node) (cond ((application-node? node) (closurize-application node)) ((named-primop-node? 'procedure? node) (closurize-procedure? node)) ((lambda-node? node) (closurize-lambda node)) ((funrec-node? node) (closurize-funrec node)) (else (subnode-map closurize node)))) (define (closurize-application node) `(CALL-CLOSURE ,(closurize (call-rator node)) ,@(map closurize (call-rands node)))) (define (closurize-procedure? node) `(PRIMOP CLOSURE? ,@(map closurize (primop-args node)))) (define (closurize-lambda node) (let ((formals (lambda-formals node)) (body (lambda-body node)) (frees (free-vars node)) (closure-var (make-var (fresh-name 'closure)))) `(PRIMOP CLOSURE (LAMBDA (,closure-var ,@formals) ,(rewrite (list->set frees) ;; Ref-rewriting procedure (lambda (var) (make-primop 'closure-ref (list closure-var ;; Need 1+ to pass over code (1+ (position var frees))))) ;; SET!-rewriting procedure (lambda (var body) (make-primop 'closure-set! (list closure-var ;; Need 1+ to pass over code (1+ (position var frees)) body))) (closurize body))) ,@frees)))