Fw: [plt-scheme] Struggling with macro...
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
>