(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)