[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


Posted on the users mailing list.