ir-macro-transformer added by liao on Tue Oct 19 14:48:36 2021

(define-syntax check-type-locative
  (ir-macro-transformer
   (lambda (e i c)
     (let* ((type (strip-syntax (cadr e)))
	    (inits (cddr e))
	    (size (length inits))
	    (construct type)
	    (make (i (symbol-append 'make- type)))
	    (ref (i (symbol-append type '-ref))))
       `(let* ((old (,construct ,@inits))
	       (new (,make ,size)))
	  ;; Copy first
	  (do ((i 0 (add1 i)))
	      ((= i ,size))
	    (let ((loc-src (make-locative old i))
		  (loc-dst (make-locative new (- ,size i 1))))
	      (assert (locative? loc-src))
	      (assert (locative? loc-dst))
	      (locative-set! loc-dst (locative-ref loc-src))))
	  (printf "\nold: ~S\nnew: ~S\n" old new)
	  ;; Now compare (unroll loop for better error reporting)
	  ,@(let lp ((i 0) (res '()))
	      (if (= i size)
		  res
		  (lp (add1 i)
		      ;; Note: we must use eqv? because extraction
		      ;; may cause fresh object allocation.
		      (cons `(assert (eqv? (,ref old ,i)
					   (,ref new ,(- size i 1))))
			    res)))))))))

(check-type-locative string #\nul #\y #\o #\xff)