Fw: [plt-scheme] Struggling with macro...

From: Jos K oot (jos.koot at telefonica.net)
Date: Wed May 23 12:15:22 EDT 2007

Ok an example:

(define-syntax (machine stx)
 (syntax-case stx ()
  ((machine name subform ...)
   (let
    ((expand-subform
      (lambda (mc sub-stx)
       (syntax-case sub-stx (event variable)
        ((variable id v) #`(add-variable #,mc 'id v))
        ((event . args) #`(machine-event #,mc . args))))))
  #`(let ((mc (make-machine))) #,@(map (lambda (form) (expand-subform #'mc 
form)) (syntax->list #'(subform ...))) mc)))))

; or if all variables must come before all events:

(define-syntax (machine stx)
 (syntax-case stx ()
  ((machine name subform ...)
   (let*
    ((var-forms ())
     (event-forms ())
     (expand-subform
      (lambda (mc sub-stx)
       (syntax-case sub-stx (event variable)
        ((variable id v) (set! var-forms (cons #`(add-variable #,mc 'id v) 
var-forms)))
        ((event . args) (set! event-forms (cons #`(machine-event #,mc . 
args) event-forms)))))))
    (let
     ((result
     #`(let ((mc (make-machine)))
     #,@(begin
         (for-each (lambda (form) (expand-subform #'mc form)) (syntax->list 
#'(subform ...)))
         (append (reverse var-forms) (reverse event-forms)))
        mc)))
     (printf "result: ~s~n" (syntax-object->datum result)) ; showing the 
expansion
     result)))))

(define make-machine void)
(define add-variable void)
(define machine-event void)

(machine hello
 (variable a 1)
 (variable b 2)
 (event "who-cares?")
 (variable c 3)
 (event "the end"))

; result: (let ((mc (make-machine))) (add-variable mc 'a 1) (add-variable mc 
'b 2) (add-variable mc 'c 3) (machine-event mc "who-cares?") (machine-event 
mc "the end") mc)

The same thing can be done with syntax-rules only! (see R5RS section 7.3 
'Derived expression types' and look for the word 'trick')
Jos Koot

----- Original Message ----- 
From: "Paulo J. Matos" <pocm at soton.ac.uk>
To: "Jos K oot" <jos.koot at telefonica.net>
Cc: "PLT-list" <plt-scheme at list.cs.brown.edu>
Sent: Wednesday, May 23, 2007 5:22 PM
Subject: Re: Fw: [plt-scheme] Struggling with macro...


> On 5/23/07, Jos K oot <jos.koot at telefonica.net> wrote:
>> Hi,
>> Your original question was
>>
>> ;(machine hello ;       (variables (x 1)
>> ;                         (y 2)
>> ;                         (z 3)))
>> ;
>> ;to
>> ;(let ([mc (make-mc () () () () ())])
>> ;     (add-variable-to-mc x 1)
>> ;     (add-variable-to-mc z 3)
>> ;     mc)
>>
>> (BTW, the name 'hello' is not used and I guess that (add-variable-to-mc x 
>> 1)
>> must be (add-variable-to-mc mc x 1))
>>
>
> You're right, name will be used... :) This is just the first part of
> the macro. and yes, mc was missing in that call to add-variable-to-mc.
>
>> For this I would write:
>>
>> (define-syntax machine
>> (syntax-rules (variables)
>>  ((machine name (variables (id v)) ...)
>>   (let ((mc (make-mc () () () () ())))
>>    (add-variable-to-mc mc id v) ...
>>    mc))))
>>
>
> Yes, I understand, still it would not allow multiple (id v). Even if
> you somehow do that with this framework it would not help me.
>
> I will have in the end something like:
> (machine name
>   (variables (var val) ...)
>   (event name ... ) ...
>   )
>
> I want to be able to create the code associated with (variables ...)
> and (event ...) inside an environment where mc is defined so I have
> there the initial let.
> Then I define another macro inside to parse variables, events (only
> variables now, I'm ignoring events) which has mc in scope but things
> are definitely getting trickier. Defining everything in one go as you
> did is not good because I want to have patterns for variables, events,
> etc where order doesn't matter.
>
> I currently have:
> (define-syntax (machine stx)
>    (syntax-case stx ()
>      [(_ mname sexps ...)
>       (identifier? #'mname) ; fender
>       #'(let ([mc (make-mc () () () () ())])
>           (letrec-syntax ((defs (λ (x)
>                                   (syntax-case x (variables)
>                                     [(variables (name value) (... ...))
>                                      (andmap identifier #'name (... ...))
>                                      (begin
>                                        (add-variable-to-mc #'mc
> #'name #'value) (... ...))]))))
>               (defs sexps) ...
>               mc))]))
>
> which, grrrr, is not working. Again, due to name inside the defs macro
> (which seems to be expanding only when machine is called and I
> understand why). I'm getting:
> syntax: missing ellipses with pattern variable in template in: name
>
> :( Any ideas?
>
>
>
>> I probably dont grasp your problem. Can you be more specific?
>> Jos Koot
>>
>
>
>
> -- 
> Paulo Jorge Matos - pocm at soton.ac.uk
> http://www.personal.soton.ac.uk/pocm
> PhD Student @ ECS
> University of Southampton, UK
> 



Posted on the users mailing list.