(in-package "CL-USER") ;; COMP-2: write elimination (defun comp-2 (e sl) (labels ((comp-2-number (e sl) e) (comp-2-string (e sl) e) (comp-2-other (e sl) e)) (cond ((null e) e) ((symbolp e) (comp-2-symbol e sl)) ((numberp e) (comp-2-number e sl)) ((stringp e) (comp-2-string e sl)) ((characterp e) (comp-2-other e sl)) ((listp e) (cond ((is-quote e) e) ((is-special-form e) (comp-2-nohead e sl)) ((is-primitive e) (comp-2-nohead e sl)) ((is-setq e) (comp-2-setq e sl)) ((is-lambda (car e)) (comp-2-let e sl)) ((is-lambda e) (comp-2-lambda e sl)) ((is-labels e) (comp-2-labels e sl)) (t (comp-2-generic e sl))))))) (defun comp-2-symbol (e sl) (let ((subs (assoc e sl))) (if (and subs (not (numberp (cdr subs)))) (cdr subs) e))) (defun comp-2-setq (e sl) (let ((v (cadr e)) (e1 (caddr e))) (setf v (comp-2 v sl)) (setf e1 (comp-2 e1 sl)) (if (atom v) (list 'setq v e1) (list '%set-svref (cadr v) (caddr v) e1)))) (defun comp-2-generic (e sl) (mapcar #'(lambda (z) (comp-2 z sl)) e)) (defun comp-2-nohead (e sl) (let ((head (car e))) (cons head (comp-2-generic (cdr e) sl)))) (defun comp-2-lambda (e sl) (let* ((lam-vars (lambda-vars e)) (subs-vars (annotate-prop e 'cl-wrqs)) (diff-vars (set-difference lam-vars subs-vars)) (sl-1 sl) (new-var nil)) (setf sl-1 (append (enumerate diff-vars 0) sl-1)) (if (not (null subs-vars)) (let () (setf new-var (get-closure-write-sl-var)) (let ((subs-vars-l (enumerate subs-vars 0))) (setf subs-vars-l (mapcar #'(lambda (z) (cons (car z) (list '%svref new-var (cdr z)))) subs-vars-l)) (setf sl-1 (append subs-vars-l sl-1))))) (let ((lam-body (lambda-body e))) (setf lam-body (comp-2-generic lam-body sl-1)) (if (not (null subs-vars)) (setf lam-body (list (make-let (list new-var) (list (cons 'vector subs-vars)) lam-body)))) (make-lambda lam-vars lam-body)))) (defun comp-2-let (e sl) (comp-2-generic e sl)) (defun comp-2-labels (e sl) (let ((e1 (un-annotate e))) (let ((e-body (labels-body e1)) (fn-defs (cadr e1))) ; (format t "e-body = ~A~%" e-body) (let ((fn-lis (mapcar #'(lambda (z) (list 'lambda (cadr z) (caddr z) (cadddr z))) fn-defs)) (fn-vars (mapcar #'car fn-defs))) (let ((fn-res (mapcar #'(lambda (z) (comp-2 z sl)) fn-lis)) (e-body-res (comp-2-generic e-body sl))) (make-labels-lambda fn-vars fn-res e-body-res))))))