Hi Tim, Danny explains the problem well. To accumulate a result, one must stay in the same same dynamic extent. One way to solve the problem is to use local-expand. In some cases one can write expanders for the forms, that needs analysing and call them directlye (rather than write a macro for the subform and then let the expander call a macro transformer).
Below is a short example, which incidently shows an alternative solution the local-expand problem, I had the other day (see http://www.mail-archive.com/users@racket-lang.org/msg15937.html ). If you need local-expand, then see Matthews answer on how to use definition contexts with local-expand. /Jens Axel #lang racket ;;; Consider the following grammar where upper case ;;; symbols stand for literal identifiers (in lowercase). ; program ::= (PROGRAM var-decl-part body) ; var-decl-part ::= (VAR-DECL-PART var-decl ...) ; var-decl ::= (VAR-DECL DEF id type expr) ; body ::= (BODY expr ...) ; type ::= identifier ;;; The program ; (program ; (var-decl-part ; (var-decl (def x int 42)) ; (var-decl (def y str "foo")) ; (body (list x y))) ;;; expands to (let () (define x 42) (define y "foo") (list x y)) ;;; During the expansion, type information is ;;; collected. ;;; The goal is to define one macro for each grammar rule. ;;; In the expansion of the body, type information ;;; from the expansion of the var-decl-part must be present ;;; to signal error for, say, (+ x y). ;;; The program macro thus uses local-expand to expand ;;; the var-decl-part. (require racket/stxparam racket/splicing (for-syntax syntax/parse syntax/context racket/syntax)) (begin-for-syntax (define *types* '()) (define (add-type id type) (set! *types* (cons (cons (syntax->datum id) (syntax->datum type)) *types*)))) (define-syntax (program stx) ; program ::= (PROGRAM var-decl-part body) (syntax-parse stx [(_ var-decl-part body) (define expanded-var-decls (expand-var-decl-part #'var-decl-part)) (displayln (list "Type information: " *types*)) (with-syntax ([(def ...) expanded-var-decls]) (syntax/loc stx (begin def ... body)))])) (begin-for-syntax (define (expand-var-decl-part stx) ; var-decl-part ::= (VAR-DECL-PART var-decl ...) (syntax-parse stx [(_ var-decl ...) (define expanded-var-decls (map expand-var-decl (syntax->list #'(var-decl ...)))) expanded-var-decls])) (define (expand-var-decl stx) ; var-decl ::= (VAR-DECL DEF id type expr) (displayln stx) (syntax-parse stx [(_ (def id type expr)) (add-type #'id #'type) (syntax/loc stx (define id expr))]))) (define-syntax (body stx) ; body ::= (BODY expr ...) (syntax-parse stx [(_ expr ...) (syntax/loc stx (begin expr ...))])) (program (var-decl-part (var-decl (def x int 42)) (var-decl (def y str "foo"))) (body (list x y))) > > Tim > > =================================================================================== > "counted-defines.rkt" (similar to what's on the 17.1.2 Using #lang s-exp > Guide Page) > =================================================================================== > #lang racket > (provide (except-out (all-from-out racket) #%module-begin define) > (rename-out (module-begin #%module-begin) (my-define define))) > > (require (for-syntax syntax/parse)) > (define-for-syntax counter 0) > > (define-syntax (my-define stx) > (syntax-parse > stx > [(_ i v) (set! counter (add1 counter)) #`(define i v)] > [(_ (i args ...) v ...+) (set! counter (add1 counter)) > #`(define (i args ...) v ...)])) > > (define-syntax (module-begin stx) > (syntax-parse > stx > [(_ expr ...) > #`(#%module-begin expr ... > (define defines-count #,counter) > (provide defines-count))])) > > > ========================== > "test-counted-defines.rkt" > ========================== > #lang s-exp "counted-defines.rkt" > (define woo 2) ; should have pushed counter up by one? > > > ========================== > I then run: racket -e '(require "test-counted-defines.rkt") defines-count' > Which returns me "0" > > > > -- > Tim Brown <tim.br...@cityc.co.uk> | City Computing Limited | > T: +44 20 8770 2110 | City House, Sutton Park Road | > F: +44 20 8770 2130 | Sutton, Surrey, SM1 2AE, GB | > -----------------------------------------------------------------------| > BEAUTY: What's in your eye when you have a bee in your hand | > -----------------------------------------------------------------------' > City Computing Limited registered in London No. 1767817. > Registered Office: City House, Sutton Park Road, Sutton, Surrey, SM1 2AE > VAT number 372 8290 34. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- -- Jens Axel Søgaard ____________________ Racket Users list: http://lists.racket-lang.org/users