On the topic of "state" propagation across macros by extending the expansion environment (or whatever the terminology would be). I have an example where a macro is used to define a layout of a fixed offset text file. Then a second macro expands into a mini field parser based on the layout definition. Frankly my first macro beyond a basic syntax-rules sort, so it's rough and assuredly less than optimal. It can be found here.
https://github.com/RayRacine/racketlib/blob/mapred/RpR/format/layout-types.rkt https://github.com/RayRacine/racketlib/blob/mapred/RpR/format/layout.rkt https://github.com/RayRacine/racketlib/blob/mapred/RpR/format/parser.rkt On Wed, Jan 16, 2013 at 10:33 AM, Danny Yoo <d...@hashcollision.org> wrote: > On Wed, Jan 16, 2013 at 7:24 AM, Tim Brown <tim.br...@cityc.co.uk> wrote: > > Folks, > > > > I would like to write a module that uses a macro to transform "define"s > > and accumulate a value based on those transformations. > > > > In a fairly simple way, I want to do something like the below. However, > it > > seems the module-begin is being transformed before the my-defines. How do > > I get counter to be incremented before I need it? > > The transformation happens top-down, so you'll see that the body of > your program expands in the following steps (to a first > approximation): > > > (#%your-module-begin (your-define woo 2)) > > ==> > > (#%racket-module-begin (your-define woo 2) > (define defines-counter 0) > (provide defines-counter)) > > ==> > > (#%racket-module-begin (racket-define woo 2) > (define defines-counter 0) > (provide defines-counter)) > > > One possible workaround is the the following: add one level of > indirection in installing the value of the defines-counter. You can > do something like: > > (define-syntax (get-counter stx) > (datum->syntax stx counter)) > > and use (get-counter) in place of #,counter in your module-begin. > This way, we delays the lookup of counter until the macro expander > finally reaches that expression, and by that time, it should have hit > all the defines already. > > > If you need to control the order of expansion more explicitly, you may > need to look into local-expand: > > > http://docs.racket-lang.org/reference/stxtrans.html#(def._((quote._~23~25kernel)._local-expand)) > > ---- > > Modified code below: > > #lang racket/base > > (provide (except-out (all-from-out racket) #%module-begin define) > (rename-out (module-begin #%module-begin) (my-define define))) > > (require (for-syntax racket/base > 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 (get-counter stx ) > (datum->syntax stx counter)) > > (define-syntax (module-begin stx) > (syntax-parse > stx > [(_ expr ...) > #`(#%module-begin expr ... > (define defines-count (get-counter)) > (provide defines-count))])) > ____________________ > Racket Users list: > http://lists.racket-lang.org/users >
____________________ Racket Users list: http://lists.racket-lang.org/users