Opened 8 years ago
Closed 7 years ago
#1362 closed defect (fixed)
A case when composing with ir-macro-transformer
Reported by: | megane | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 4.13.0 |
Component: | expander | Version: | 4.12.0 |
Keywords: | ir-macro-transformer | Cc: | |
Estimated difficulty: | hard |
Description
I ran into this unexpected behaviour when using ir macros in ir macros. I don't think this should happen:
(I have tested this with 4.12, not with 5. )
First macro:
(define-syntax bind-pair (ir-macro-transformer (lambda (e i c) (let* ((b (second e)) (exp (third e)) (body (drop e 3))) `(let* ((x ,exp) (,(first b) (car x)) (,(second b) (cdr x))) ,@body)))))
Testing:
(bind-pair (x y) (cons 1 2) (print y)) => prints 2
Now a second macro using bind-pair:
(define-syntax foo (ir-macro-transformer (lambda (e i c) `(bind-pair (x y) (cons 'foo-car 'b) (print y)))))
Running (foo) gives the error:
Error: (cdr) bad argument type: foo-car
The expansion of (foo) looks like this:
;; (##core#let ;; ((x40 (cons42 (quote43 foo-car44) (quote43 b45)))) ;; (##core#let ;; ((x40 (car48 x40))) ;; (##core#let ((y41 (cdr49 x40))) (##core#let () (print46 y41)))))
As you can see, the x in bind-pair and foo macros refer to the same
variable in the expansion. You can confirm this happens by changing the
x in foo to, say z.
Attachments (1)
Change History (4)
Changed 8 years ago by
comment:1 Changed 8 years ago by
Estimated difficulty: | → hard |
---|---|
Milestone: | someday → 4.13.0 |
Priority: | not urgent at all → major |
comment:2 Changed 8 years ago by
comment:3 Changed 7 years ago by
Keywords: | ir-macro-transformer added; ir-macro-trasformer removed |
---|---|
Resolution: | → fixed |
Status: | new → closed |
Fixed by 9473076e and 0d7f83f4.
Note: See
TracTickets for help on using
tickets.
Essentially, the bug is this:
That's because
ir-macro-transformer
will rename the entire input form, which may contain identifiers which already have been renamed by another macro, resulting in an "undo" of the renaming of those double-renamed identifiers.You can test the above snippet in Chibi, MIT Scheme or Scheme48 (remove the
er-macro-transformer
wrapper from the lambda to test it in the latter), they all print 1. I've sent a patch to chicken-hackers which fixes this.