[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

define tag macro



I could use a little help with a macro.  The first example below
expands correctly, but the ones with #key in the macro call don't.
I think the examples show pretty clearly what I want to happen.
Basically if there are any args other than the required page,
response, and body args, I want to require #key to be specified.
Is there something special about #key in the left-hand side of 
a pattern?

/*
// A tag with no body or args, e.g., <bt:current-username/>
define tag simple (page, response) do-stuff; end;
=> define method simple-tag
       (page, response, #all-keys) do-stuff; end;
   register-tag("simple", simple-tag, body: #f);

// A tag with no body and one arg.  e.g., <xx:show-it key1="blah"/>
define tag foo (page, response, #key key1) do-stuff; end;
=> define method foo-tag
       (page, response, #key key1, #all-keys) ... end;
   register-tag("foo", foo-tag, body: #f);

define tag foo (page, response, key1) ... end;
=> parse error, no #key supplied before key1

// A tag with body and one arg, e.g., <xx:when test="blah">...</xx:when>
define body tag bar (page, response, body, #key test) ... end;
=> define method bar-tag
      (page, response, body, #key test, #all-keys) ... end;
   register-tag("bar", bar-tag, body: #t);

define body tag bar (page, response, body, key1) ... end;
=> parse error, no #key supplied before key1
*/

define macro tag-definer
  // Basic tags, no do-body arg
  { define tag ?tag:name (?page:variable, ?response:variable ?arguments)
      ?:body
    end }
    => { define method ?tag ## "-tag" (?page, ?response ?arguments,
                                       #all-keys)
           ?body
         end;
         register-tag(?"tag", ?tag ## "-tag");
       }
  // Same as above but with the "body" modifier.
  { define body tag ?tag:name (?page:variable,
                               ?response:variable,
                               ?do-body:variable ?arguments)
      ?:body
    end }
    => { define method ?tag ## "-tag" (?page, ?response,
                                       ?do-body ?arguments, #all-keys)
           ?body
         end;
         register-tag(?"tag", ?tag ## "-tag");
       }
  arguments:
    { } => { }
    { , #key ?more:* } => { , #key ?more }
end;