;;; -*- Mode:Lisp; Package:(NC LISP); Readtable:CL; Base:10 -*- ;;; 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 (zl:defsubst lambda-contour (node) (lambda-env node)) (defun close-analyze-top (top-node) (close-analyze-lambda (call-arg-n 1 (lambda-body top-node)) 0)) ;;; do something about Y nodes (defun close-analyze-lambda (node contour-num) (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) (eq 'T (variable-closed var))) (lambda-used node)))) (when need-closing (incf contour-num) (let ((offset 0)) (dolist (var need-closing) (setf (variable-closed var) (cons contour-num (incf offset)))))))))) (let ((closed-setqed (remove-if-not #'(lambda (var) (and var (variable-closed var) (variable-setqs var))) (lambda-variables node)))) (when closed-setqed (incf contour-num) (let ((offset 0)) (dolist (var closed-setqed) (setf (variable-closed var) (cons contour-num (incf offset))))))) (setf (lambda-contour node) contour-num) (close-analyze-call (lambda-body node) contour-num)) (defun close-analyze-call (node contour-num) (dolist (arg (call-proc+args node)) (if (lambda-node? arg) (close-analyze-lambda arg contour-num)))) (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))))