2015-04-13 14:40 GMT+02:00 Matthew Flatt <mfl...@cs.utah.edu>: > The new macro expander is ready for you to try: ...
> * A macro that uses `syntax-local-get-shadower` like will have to be > revised, and it should be revised to avoid that function. A macro > that uses `syntax-local-make-delta-introducer` definitely will have > to be revised, because that function is no longer supported. Most > macros don't use such obscure functions. The following example shows two macros declare and vars that work together. The declare macro is used to declare identifiers (have some property) and the macro vars shows how a macro can access the declared identifiers that are in scope. Here vars simply expands to a list of the declared identifiers. Example: (declare a) ; module level declaration (display (vars)) (let () (display (vars)) ; (1) (declare x) ; here (1) and (2) are to display the same variables (same scope) (display (vars)) ; (2) (let () (display (vars)) (declare s) (declare t) (display (vars))) (declare y) (display (vars))) ; check that s and t are no longer in scope (declare b) ; displays: (b a)(y x b a)(y x b a)(t s y x b a)(t s y x b a)(y x b a) My solution in the old macro system used syntax-local-get-shadower together with syntax-local-introduce to "refresh" the vars identifier in order to redefine its meaning in each new scope. In what direction should I look to fix this example? [The error message with the new macro expander is: internal definition: duplicate binding name in: vars] #lang racket (require (for-syntax syntax/parse racket/format)) (begin-for-syntax (define module-level-variables '()) ; each internal definition contexts is given an index (define intdefs (make-hasheq)) ; each index is associated to a list of declared names (define local-variables (make-hash)) (define (new-intdef? intdef) (hash-has-key? intdefs intdef)) (define (index-of-intdef intdef) (hash-ref! intdefs intdef (hash-count intdefs))) (define (add-local-var! index var) (hash-update! local-variables index (λ (old-vars) (cons var old-vars)) '()))) (define-syntax (vars stx) (with-syntax ([vs module-level-variables]) #''vs)) (begin-for-syntax (define refresh-identifier (compose syntax-local-introduce syntax-local-get-shadower))) (define-syntax (declare stx) (syntax-parse stx [(_ id) (define var (syntax->datum #'id)) (define ctx (syntax-local-context)) (cond [(eq? ctx 'module) (set! module-level-variables (cons var module-level-variables)) #'(begin)] [(list? ctx) ; internal definition context (define old-scope? (new-intdef? ctx)) (define index (index-of-intdef ctx)) (add-local-var! index var) (cond [old-scope? #'(begin)] [else (with-syntax ([vars (refresh-identifier #'vars)] [old-vars (syntax-local-get-shadower #'vars)] [index index] [.... #'(... ...)]) #'(define-syntax (vars st) (define locals (hash-ref local-variables index)) (define others (local-expand #'(old-vars) (syntax-local-context) #f)) ; others = (quote (var ...)) so we skip the quote here: (with-syntax ([(local ....) locals] [(_ (other ....)) others]) #`'(local .... other ....))))])] [else (error 'declare (~a "declarations are only allowed at the module level " "and in internal definition contexts"))])])) (declare a) (display (vars)) (let () (display (vars)) (declare x) (display (vars)) (let () (display (vars)) (declare s) (declare t) (display (vars))) (declare y) (display (vars))) (declare b) ; displays: (b a)(y x b a)(y x b a)(t s y x b a)(t s y x b a)(y x b a) -- You received this message because you are subscribed to the Google Groups "Racket Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-dev+unsubscr...@googlegroups.com. To post to this group, send email to racket-dev@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/CABefVgzTZ7DoHLJSZVgKm6EHBgirhXaoYkD%3D%2BVU7KvuyaLHi_w%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.