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

Re: More macro questions



On 6 May 2000, Nolan Darilek wrote:
> I've begun hacking at the GD c-ffi library again. ...  I'm trying to get
> a basic C-function-definer macro built so that the definitions for
> malloc and free will parse. Here is what I'm trying to match:
> 
> define C-function malloc
>   /* XXX - Need <C-size-t> and <C-raw-pointer> */
>   parameter size :: <C-size-t>;
>   result memory :: <C-raw-pointer>;
>   c-name: "malloc";
> end;
> 
> And here is my broken definition of that macro:
> 
> define macro C-function-definer
>   { define C-function ?dname:name
>       { (parameter ?pname:name :: ?type:name) ... }
>       { (result ?rname:name :: ?type:name) ... }
>       { c-name ?cname:name }
>     end }
>     => { /* XXX - need expansion */ }
> end macro;
> 
> But, this doesn't work. ...

If you put a "{}" pair inside the top-level "{}" for your rule, the macro
will be looking to find literal '{' and '}' in your input.  Looking at the
"\frame-definer" macro in DUIM (frames/frames.dylan) should give you an
idea of how to do this sort of definition, where you have a number of
"lines" which can appear in various combinations, but the basic pattern is

  1) A few main rules to capture any major variations in overall structure
-- often you only need one.
  2) One aux-rule which effectively "iterates" over all the "lines".
  3) Another aux-rule for individual lines, with one or more clauses
for each kind of line.

define macro foo-definer
// (1)
  { define foo ?:name
      ?:slots
    end }
 => { // Sample expansion -- for C-FFI you'll probably need to expand into
      // some compiler "magic".
      define constant ?name :: <foo> =
        make(<foo>, slots); }
// (2)
slots:
  { } => { }
  // Note ';' becomes ',': again this is just an example but you may well
  // want to rebuild the sequence of "?:slot"s with something other than
  // semicolons between them.
  { ?:slot; ... } => { ?slot, ... }
// (3)
slot:
  { parameter ?:name :: ?type:expression }
 => { param(?name, ?type) }
  { result ?:name :: ?type:expression }
 => { result(?name, ?type) }
  { c-name: ?:expression }
 => { c-name(?expression) }
end macro foo-definer;

Note that the above probably isn't the best way to do \c-function-definer:
you probably want to do some macrology to collect all the parameters into
one place separate from the result.  (Can't think how, off the top of my
head, sorry.)

I hope that helps a bit.  Apart from finding yourself a copy of the DRM or
DIRM, you can find lots of example macros in the open source from FunO
(and probably in the Gwydion sources, too, I imagine -- just grep for
"-definer") and, provided you can get it to compile first, you can test
macro expansion in the FunO environment (assuming you have access to a
Win32 machine, for now).

Good luck and keep asking for help as needed :-)
Hugh




References: