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

Re: Crash course on macros?



Great and informative! Thanks.

>>>>> "Rob" == Rob Myers <robm@tdv.com> writes:

    Rob> The only really confusing thing to macros (apart from #key
    Rob> and #rest macro parameters...) is the ?:body syntax. There
    Rob> *should* be a name before :body, ie:

    Rob> define macro begin { begin ?theBody:body end } => { ?theBody
    Rob> }; end;

Ah, so that can be translated as:
theBody is a variable of type body?

What about:
?other:*

Does that mean 'other' matches anything which hasn't matched yet?

    Rob> Can you give examples of macros using the constructs that are
    Rob> problematic so people can take a look and go through them?

Sure.

I'm trying to port dood to Gwydion. It seems to rely on a collectors
library which I've tried to compile. The library includes the
following macro:

define macro collecting
  { collecting () ?:body end }
    => { collecting (?=_collector)
           ?body;
           collected(?=_collector)
         end }
  { collecting (as ?type:expression = ?init:expression ?source-options:*) 
      ?:body
    end }
    => { collecting (?=_collector :: ?type = ?init ?source-options)
           ?body;
           collected(?=_collector)
         end }
  { collecting (as ?type:expression ?source-options:*) ?:body end }
    => { collecting (?=_collector :: ?type ?source-options)
           ?body;
           collected(?=_collector)
         end }
  { collecting (?vars) ?:body end }
    => { ?vars;
         ?body }
vars:
  { }
    => { }
  { ?var, ... }
    => { ?var; ... }
var:
  { ?base-name:name :: ?:expression ?options:* using ?protocol:expression}
    => { let (?base-name) = ?protocol(?expression, ?options);
         assert-collector-protocol-ok(?base-name) }

  { ?base-name:name :: ?:expression ?options:* }
    => { let (?base-name) = collector-protocol(?expression, ?options);
         assert-collector-protocol-ok(?base-name) }

  { ?base-name:name ?options:* using ?protocol:expression}
    => { let (?base-name) = ?protocol(<list>, ?options);
         assert-collector-protocol-ok(?base-name) }

  { ?base-name:name ?options:* }
    => { let (?base-name) = collector-protocol(<list>, ?options);
         assert-collector-protocol-ok(?base-name) }

base-name:
  { ?:name }
    => { ?name ## "-collector",
         ?name ## "-add-first",
         ?name ## "-add-last",
         ?name ## "-add-sequence-first",
         ?name ## "-add-sequence-last",
         ?name ## "-collection" }

options:
  { }
    => { }
  { ?:name ?:expression ... }
    => { as-keyword(?#"name"), ?expression, ... }
// Problem here!
  { = ?:expression ... }
    => { from:, ?expression, ... }
end macro;

I don't quite understand how the { = ... } works, and I seem to
remember someone stating that d2c can't handle that at the moment. Is
it somehow possible to rewrite that in a different way?

Thanks.



Follow-Ups: References: