[Prev][Next][Index][Thread]
Re: Crash course on macros?
On 5 May 2000, Nolan Darilek wrote:
> 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 [?theBody:body] can be translated as:
> theBody is a variable of type body?
Yes and, for each possible constraint, you can have one occurency per
left-hand side where you omit the name (before the ':'), in which case
it's understood to be the same as the constraint name.
> What about:
> ?other:*
>
> Does that mean 'other' matches anything which hasn't matched yet?
Basically, yes. There are some rules whose details I can never quite
remember, about how "hungry" the parser is but "*" means "anything"
(provided you keep brackets balanaced). The set of possible constraints
is (from Chapter 10 of the DRM -- hopefully FunO will have the online
distribtion out soon :-)::
Constraint Grammar accepted
expression /expression/
variable /variable/
name NAME
token TOKEN
body /body_opt/
case-body /case-body_opt/
macro /macro/
* (wildcard)
The other magic characters apart from ':' are
? NAME On LHS, binds NAME according to constraint. On RHS inserts
the fragment bound to NAME
?? NAME On LHS, after #key only, binds NAME to sequence of all values
of all occurences of keyword NAME; constraints apply to each
occurence individually. On RHS, "??NAME, ..." inserts all
bound values separated by ',' (can use ';' or
BINARY-OPERATOR).
... On LHS/RHS matches/inserts fragment matching the current
aux-rule. (In aux-rule "foo:" it's a shorthand for ?:foo".)
?= NAME On RHS only, inserts reference to NAME in the lexical context
where the macro was called (i.e., breaks macro hygiene).
The best thing is to read Chapter 10 of the DRM, when you can get hold of
one :-)
> Rob> Can you give examples of macros using the constructs that are
> Rob> problematic so people can take a look and go through them?
>
> ... The [collectors] library includes the following macro:
>
> define macro collecting
> [...]
> { collecting (?vars) ?:body end }
> => { ?vars;
> ?body }
> vars:
> { }
> => { }
> { ?var, ... }
> => { ?var; ... }
> var:
> [...]
> { ?base-name:name ?options:* }
> => { let (?base-name) = collector-protocol(<list>, ?options);
> assert-collector-protocol-ok(?base-name) }
> [...]
>
> 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?
>From a quick reading of the DRM macro grammar, I'd say the above isn't
actually correct Dylan! I think you ought to have to put '\' before the
'=', since you're mentioning an operator in a non-infix-call way. (You
have to do the same to write methods on '='.) If that doesn't work, you
could try "lifting" the "options:" aux-rules into the "var:" aux-rules.
That means you'd have 12 (4*3) "var:" rules instead of 4 but it might do
until (a) d2c is fixed; or (b) the above sources are fixed ;-)
HTH,
Hugh
Follow-Ups:
References: