[plt-scheme] Macro troubles

From: Killian McCutcheon (entarter at gmail.com)
Date: Mon Jun 23 15:53:27 EDT 2008

I'm having a bit of trouble re-implementing a DSL using macros (I'm a macro
newbie). The DSL is very simple, looks like this:
    player "Please Sir! Can I have some more?"
    show-item "soup"
    play-sound "sfx_aghast"
    npc "MORE!?!?"
    show-item "scowl"

Its a script for a game, with lists of commands that are performed in
certain situations. Some of the commands take a string or a number as a
parameter, others have no parameters. Now, the script is not written by a
programmer, so to make it easier for the designer, I offered him this syntax
where there are only parentheses around the whole form, and not around each
individual command in the list. My solution without macros was to define
commands as evaluating to symbols of the same name, and just pass all
arguments to the commands function to a parsing function. It worked well,
but there was a lot of repetitive code.
Now as an exercise I'm reimplementing the DSL using macros. The commands are
defined using a macro, which seems to work fine. Then I try to define
the commands form like this:

(define-syntax (commands stx)
  (syntax-case stx ()
    [(_ unary arg rest ...)
     (eq? 1 (procedure-arity (syntax-object->datum (syntax unary))))
     (syntax (cons (unary arg) (_ rest ...)))]
    [(_ nullary rest ...)
     (eq? 0 (procedure-arity (syntax-object->datum (syntax nullary))))
     (syntax (cons (nullary) (_ rest ...)))]
    [(_ '()) (syntax '())]))

but that gives me the error:

procedure-arity: expects argument of type <procedure>; given player

So Im guessing either the definitions of my commands aren't available in the
compile-environment, or I have to jump through extra syntax hoops to get at
them. I try to make do with second best:

(define-syntax (start stx)
  (syntax-case stx ()
    [(_ unary arg rest ...)
     (or (string? (syntax-object->datum (syntax arg)))
          (number? (syntax-object->datum (syntax arg))))
     (syntax (cons (unary arg) (_ rest ...)))]
    [(_ nullary rest ...)
     (syntax (cons (nullary) (_ rest ...)))]
    [(_ '()) (syntax '())]))

but that gives me the error:

commands: bad syntax in: commands

and highlights the recursive call to the macro in the first template. Thing
is I don't know why, and the Dybvig paper "Writing Hygienic Macros in Scheme
with Syntax-Case" seems to contain very similar code in the cond macros.

So basically I'm flummoxed, and any help would be appreciated.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20080623/2234e3d0/attachment.html>

Posted on the users mailing list.