git.fiddlerwoaroof.com
Raw Blame History
;;; 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