git.fiddlerwoaroof.com
flic/copy-flic.scm
4e987026
 ;;; copy-flic.scm -- general copy functions for flic structures
 ;;;
 ;;; author :  Sandra Loosemore
 ;;; date   :  23 Feb 1993
 ;;;
 ;;;
 
 
 ;;; The var-renamings argument is an a-list.  It's used to map local vars
 ;;; in the input expression to new, gensymed vars.
 
 (define-flic-walker copy-flic (object var-renamings))
 
 (define (copy-flic-list objects var-renamings)
   (let ((result  '()))
     (dolist (o objects)
       (push (copy-flic o var-renamings) result))
     (nreverse result)))
 
 
 (define (copy-flic-top object)
   (copy-flic object '()))
 
 
 (define-copy-flic flic-lambda (object var-renamings)
   (let ((new-vars  (map (lambda (v)
 			  (let ((new  (copy-temp-var (def-name v))))
 			    (push (cons v new) var-renamings)
 			    (when (var-force-strict? v)
 			      (setf (var-force-strict? new) '#t))
 			    (init-flic-var new '#f '#f)))
 			(flic-lambda-vars object))))
     (make-flic-lambda
       new-vars
       (copy-flic (flic-lambda-body object) var-renamings))))
 
 
 ;;; Hack to avoid concatenating multiple gensym suffixes.
 
 (define (copy-temp-var sym)
   (if (gensym? sym)
       (let* ((string  (symbol->string sym))
 	     (n       (string-length string))
 	     (root    (find-string-prefix string 0 n)))
 	(create-temp-var root))
       (create-temp-var sym)))
 
 (define (find-string-prefix string i n)
   (declare (type string string) (type fixnum i n))
   (cond ((eqv? i n)
 	 string)
 	((char-numeric? (string-ref string i))
 	 (substring string 0 i))
 	(else
 	 (find-string-prefix string (+ i 1) n))))
 
 
 (define-copy-flic flic-let (object var-renamings)
   (let ((new-vars  (map (lambda (v)
 			  (let ((new  (copy-temp-var (def-name v))))
 			    (when (var-force-inline? v)
 			      (setf (var-force-inline? new) '#t))
 			    (push (cons v new) var-renamings)
 			    new))
 			(flic-let-bindings object))))
     (for-each
       (lambda (new old)
 	(init-flic-var new (copy-flic (var-value old) var-renamings) '#f))
       new-vars
       (flic-let-bindings object))
     (make-flic-let
       new-vars
       (copy-flic (flic-let-body object) var-renamings)
       (flic-let-recursive? object))))
 
 (define-copy-flic flic-app (object var-renamings)
   (make-flic-app
     (copy-flic (flic-app-fn object) var-renamings)
     (copy-flic-list (flic-app-args object) var-renamings)
     (flic-app-saturated? object)))
 
 (define-copy-flic flic-ref (object var-renamings)
   (let* ((var   (flic-ref-var object))
 	 (entry (assq var var-renamings)))
     (if entry
 	(make-flic-ref (cdr entry))
 	(make-flic-ref var))))   ; don't share structure
 
 
 (define-copy-flic flic-const (object var-renamings)
   (declare (ignore var-renamings))
   (make-flic-const (flic-const-value object)))  ; don't share structure
 
 (define-copy-flic flic-pack (object var-renamings)
   (declare (ignore var-renamings))
   (make-flic-pack (flic-pack-con object)))      ; don't share structure
 
 
 ;;; Don't have to gensym new block names; these constructs always
 ;;; happen in pairs.
 
 (define-copy-flic flic-case-block (object var-renamings)
   (make-flic-case-block
     (flic-case-block-block-name object)
     (copy-flic-list (flic-case-block-exps object) var-renamings)))
 
 (define-copy-flic flic-return-from (object var-renamings)
   (make-flic-return-from
     (flic-return-from-block-name object)
     (copy-flic (flic-return-from-exp object) var-renamings)))
 
 (define-copy-flic flic-and (object var-renamings)
   (make-flic-and
     (copy-flic-list (flic-and-exps object) var-renamings)))
 
 (define-copy-flic flic-if (object var-renamings)
   (make-flic-if
     (copy-flic (flic-if-test-exp object) var-renamings)
     (copy-flic (flic-if-then-exp object) var-renamings)
     (copy-flic (flic-if-else-exp object) var-renamings)))
 
 (define-copy-flic flic-sel (object var-renamings)
   (make-flic-sel
     (flic-sel-con object)
     (flic-sel-i object)
     (copy-flic (flic-sel-exp object) var-renamings)))
 
 (define-copy-flic flic-is-constructor (object var-renamings)
   (make-flic-is-constructor
     (flic-is-constructor-con object)
     (copy-flic (flic-is-constructor-exp object) var-renamings)))
 
 (define-copy-flic flic-con-number (object var-renamings)
   (make-flic-con-number
     (flic-con-number-type object)
     (copy-flic (flic-con-number-exp object) var-renamings)))
 
 (define-copy-flic flic-void (object var-renamings)
   (declare (ignore object var-renamings))
   (make-flic-void))   ; don't share structure