[plt-scheme] The Swine Before Perl
From: Jaime Vargas (jev at mac.com)
Date: Mon Jul 10 01:06:46 EDT 2006 |
|
After listening to the excellent presentation by Shriram, I asked
myself, what it will take to extent the automaton to perform actions
on each state transition. So starting with:
(automaton init
(init : (c -> loop))
(loop : (a -> loop)
(d -> loop)
(r -> end))
(end : (r -> end)))
I wanted,
(automaton init
(init : (c -> loop))
(loop : (a -> loop do count)
(d -> loop)
(r -> end))
(end : (r -> end)))
I turns out that this change is not that easy (at least for me). So I
tried something uglier first:
(automaton init
(init : (c -> loop do nop))
(loop : (a -> loop do count)
(d -> loop do nop)
(r -> end do nop))
(end : (r -> end do nop)))
That was simple. But far from what I wanted.
(define-syntax automaton
(syntax-rules(-> : do)
((_ init-state
(state : (cndn -> new-state do action) ...)
...)
(letrec ([state
(lambda (stream)
(or (empty? stream)
(case (first stream)
[(cndn) (action) (new-state (rest stream))]
...
[else false])))]
...)
init-state))))
So in search for answer, I read a bit about syntax-case and cousins,
and I arrived to something that almost works.
(define-syntax automaton
(lambda (stx)
(syntax-case stx ()
[(_ init transitions ...)
(with-syntax
([bindings
(letrec
([lot (syntax->list (syntax (transitions ...)))]
[create-bindings
(lambda (t)
(if (null? t)
'()
(cons
(syntax-case (car t) (-> : do)
[(state : (cndn -> new-state do
action) ...)
(syntax
[state
(lambda (stream)
(or (empty? stream)
(case (first stream)
[(cndn) (action) (new-state
(rest stream))]
...
[else false])))])]
[(state : (cndn -> new-state) ...)
(syntax
[state
(lambda (stream)
(or (empty? stream)
(case (first stream)
[(cndn) (new-state (rest
stream))]
...
[else false])))])])
(create-bindings (cdr t)))))])
(create-bindings lot))])
(syntax
(letrec bindings init)))])))
However, it is not handling the transition.
(automaton init
(init : (c -> loop))
(loop : (a -> loop do count)
(d -> loop)
(r -> end))
(end : (r -> end)))
which fails with "loop: bad syntax in: (loop : (a -> loop do count)
(d -> loop) (r -> end))".
It seems that the transition ... is not being handle correctly, or am
I missing something? Also, Is there a simpler way to write this type
automaton macro?
Thanks for the help. -- Jaime