Chapter 10
Macros
Pattern Variable Constraints
Each pattern-variable in the left-hand side of a rule in a macro definition has a constraint associated with it. This prevents the pattern from matching unless the fragment matched to the pattern-variable satisfies the constraint. In most cases it also controls how the matching fragment is parsed.
You specify a constraint in a pattern-variable by suffixing a colon and the
constraint name to the pattern variable name. Intervening whitespace is not allowed. As an
abbreviation, if a pattern variable has the same name as its constraint,
the pattern-variable can be written ?:the-name
instead
of ?the-name:the-name
.
The available constraints are listed in Table 10-1.
Constraint name |
Grammar accepted |
Binds pattern variable to |
---|---|---|
|
expression |
parsed expression fragment(1) |
|
variable |
fragment(2) |
|
name |
one-token fragment |
|
token |
one-token fragment |
|
bodyopt (3) |
parsed expression fragment(4) |
|
case-bodyopt (3) |
fragment(2) |
|
macro |
fragment(5) |
|
(wildcard) |
fragment |
Notes:
- Parsed expression fragments are described on page 146.
- Where expression, operand, constituents or body appears in the grammar that this constraint accepts, the bound fragment contains a parsed expression fragment, not the original elementary fragments.
- Parsing stops at an intermediate word.
- The body is wrapped in
begin … end
to make it an expression, using the standard binding ofbegin
in the Dylan module. An empty body defaults to#f
. - A pattern-variable with a
macro
constraint accepts exactly one elementary fragment, which must be a macro call fragment. It binds the pattern variable to the expansion of the macro.
Some implementations and a future version of the Dylan language specification might add more constraint choices to this table.
When a pattern variable has the same name as an auxiliary rule-set, its constraint defaults to wildcard and can be omitted. Otherwise a constraint must be specified in every pattern-variable and pattern-keyword.
A constraint applies only to the specific pattern variable occurrence to which it is attached. It does not constrain other pattern variable occurrences with the same name.
Intermediate Words
When a pattern-variable has a constraint of body
or case-body
, its parsing of the fragment stops before any token that is an
intermediate word. This allows intermediate words to delimit clauses that have separate
bodies, like else
and elseif
in an if
statement. The
intermediate words of a macro are identified as follows:
- Define a body-variable to be a pattern variable that either has a constraint
of
body
orcase-body
, or names an auxiliary rule-set where some left-hand side in that rule-set ends in a body-variable. This is a least fixed point, so a recursive auxiliary rule-set does not automatically make its name into a body-variable. Note that an ellipsis that stands for a pattern variable is a body-variable when that pattern variable is one. - Define an intermediate-variable to be a pattern variable that either immediately follows a body-variable in a left-hand side, or appears at the beginning of a left-hand side in an auxiliary rule-set named by an intermediate-variable.
- An intermediate word is a name that either immediately follows
a body-variable in a left-hand side, or occurs at the beginning of a left-hand side in an
auxiliary rule-set named by an intermediate-variable. Intermediate words are not reserved,
they are just used as delimiters during the parsing for a pattern-variable with
a
body
orcase-body
constraint.