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:<div><br></div><div>(commands</div><div> player "Please Sir! Can I have some more?"</div>
<div> show-item "soup"</div><div> play-sound "sfx_aghast"</div><div> skip-next-wait</div><div> npc "MORE!?!?"</div><div> show-item "scowl"</div><div> wait-input)</div>
<div><br></div><div>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.</div>
<div>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:</div><div><br></div><div>(define-syntax (commands stx)</div>
<div> (syntax-case stx ()</div><div> [(_ unary arg rest ...)</div><div> (eq? 1 (procedure-arity (syntax-object->datum (syntax unary))))</div><div> (syntax (cons (unary arg) (_ rest ...)))]</div><div> [(_ nullary rest ...)</div>
<div> (eq? 0 (procedure-arity (syntax-object->datum (syntax nullary))))</div><div> (syntax (cons (nullary) (_ rest ...)))]</div><div> [(_ '()) (syntax '())])) </div><div><br></div><div><br></div><div>
<br></div><div>but that gives me the error:</div><div> </div><div>procedure-arity: expects argument of type <procedure>; given player</div><div><br></div><div>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:</div>
<div><br></div><div><div>(define-syntax (start stx)</div><div> (syntax-case stx ()</div><div> [(_ unary arg rest ...)</div><div> (or (string? (syntax-object->datum (syntax arg)))</div><div> (number? (syntax-object->datum (syntax arg))))</div>
<div> (syntax (cons (unary arg) (_ rest ...)))]</div><div> [(_ nullary rest ...)</div><div> (syntax (cons (nullary) (_ rest ...)))]</div><div> [(_ '()) (syntax '())]))</div></div><div><br></div><div>
but that gives me the error:</div><div><br></div><div>commands: bad syntax in: commands</div><div><br></div><div>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.</div>
<div><br></div><div>So basically I'm flummoxed, and any help would be appreciated.</div><div><br></div><div>Cheers,</div><div>Killian</div>