;;; -*- Mode:LISP; Package:(NC LISP); Base:10; Readtable:CL -*- ;;; Any used variables in a STRATEGY/HEAP lambda must be closed over. ;;; If they are also used in an enclosing HEAP lambda then they are ;;; already in the environment (defun env-analyze-top (top-node) (env-analyze-lambda (call-arg-n 1 (lambda-body top-node)) '()) (debug :env (format t "~%Env Analysis:") (pp-cps top-node :extra #'lambda-env))) ;;; do something about Y nodes (defun env-analyze-lambda (node env) (case (lambda-strategy node) ((STRATEGY/OPEN STRATEGY/LABEL)) ((STRATEGY/HEAP STRATEGY/PROC) (when (lambda-used node) ;(add-env-variable node) ;??? ;; compute NEED-CLOSING, which is the set of variables ;; which need to be closed and are not in any higher contour (let ((need-closing (remove-if-not #'(lambda (var) (and (eq 'T (variable-closed var)) (not (already-in-env-p var env)))) (lambda-used node)))) (when need-closing (push need-closing env)))))) (let ((closed-setqed (remove-if-not #'(lambda (var) (and var (variable-closed var) (variable-setqs var))) (lambda-variables node)))) (setf (lambda-env node) (cons closed-setqed env)) (when closed-setqed (push closed-setqed env)) (env-analyze-call (lambda-body node) env))) (defun env-analyze-call (node env) (dolist (arg (call-proc+args node)) (if (lambda-node? arg) (env-analyze-lambda arg env)))) (defun already-in-env-p (var env) (some #'(lambda (frame) (member var frame :test #'eq)) env)) ;(defun add-env-variable (lambda) ; (push (create-variable 'env) ; (cdr (lambda-variables lambda))) ; (do ((vars (lambda-all-variables lambda) (cdr vars)) ; (n 0 (1+ n))) ; ((null vars)) ; (if (car vars) ; (setf (variable-number (car vars)) ; n))))