Add a New Comment (Rich Markup)
Comment Type & Canned Response: None No canned response available
I just noticed another problem with the renaming: it doesn't appear to do anything to guarantee the generated name didn't appear in the input.
(let ((.x.1-0 123)) (define-syntax foo (syntax-rules () ((foo y) (lambda (x) y)))) ((foo .x.1-0) 456)) ;Value: 456
Value should be 123. Problem is that the macro expander blithely generates exactly the same symbol as the input was using, .x.1-0:
(pp (syntax '(let ((.x.1-0 123)) (define-syntax foo (syntax-rules () ((foo y) (lambda (x) y)))) ((foo .x.1-0) 456)) (nearest-repl/environment))) (let ((.x.1-0 123)) (let ((.x.1-0 456)) .x.1-0))
The attached patch seems to fix this particular case. I haven't tried a full build. It seems to do the right thing for other cases involving shadowing like this too:
(pp (syntax '(let () (define-syntax foo (syntax-rules () ((foo 0) (foo 1 x)) ((foo 1 y) (lambda (x y) (list (list x y) (lambda (y) (list x y))))))) (foo 0)) (nearest-repl/environment))) (let () (lambda (.x.1-0 .x.1-1) (list (list .x.1-0 .x.1-1) (lambda (.x.2-0) (list .x.1-0 .x.2-0)))))
The trouble with the code as is is that when two different values of original with the same underlying symbol are interned in uninterned-table, they will both have empty buckets in uninterned-table. So the output of (symbol "." (identifier->symbol original) "." frame-id "-" (length (cdr bucket))) collides.
The patch reverses the indexing so that (length (cdr bucket)) counts the number of bindings in the same frame, meaning if two have the same symbol, they will be renamed differently. I suspect that there's no danger of the opposite kind of collision happening from this reversal of indexing because frame ids correspond to distinct shadowings (but I don't understand this code well enough to be sure).
(file #54044)
I see. Thank you for the clarification.
This looks like a problem with the syntax renaming postpass.
I don't think syntax-rules is the problem. Same thing with er-macro-transformer:
(define-syntax foo (er-macro-transformer (lambda (f r c) (case (cadr f) ((0) `(,(car f) 1 ,(r 'x))) ((1) `(,(car f) 2 ,(caddr f) ,(r 'x))) ((2) `(lambda ,(cddr f) (list ,@(cddr f)))) (else (syntax-error 'foo)))))) ;Value: foo
(foo 0) ;duplicate parameters (.x.1-0) in (.x.1-0 .x.1-0)
I'm in the process of a complete rewrite of syntax-rules. I'll make sure that there's a test case for this.
(define-syntax foo (syntax-rules () ((foo 0) (foo 1 (x))) ((foo 1 (x0)) (foo 2 (x0 x))) ((foo 2 (x0 x1)) (lambda (x0 x1) (list x0 x1))))) ;Value: foo
The identifiers `x' generated by distinct macro invocation should not collide, but they do.
(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)
Attach Files: Comment:
Depends on the following items: None found
Items that depend on this one: None found
There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.
Only logged-in users can vote.
Please enter the title of George Orwell's famous dystopian book (it's a date):
Follow 3 latest changes.
Copyright © 2023 Free Software Foundation, Inc. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. The Levitating, Meditating, Flute-playing Gnu logo is a GNU GPL'ed image provided by the Nevrax Design Team. Source Code
Powered by Savane 3.9