Chapter 10

Macros

Templates

Approximately speaking, a template has the same structure as what it constructs, but contains pattern variables that will be replaced by fragments extracted from the macro call. Thus a template in the main-rule-set looks like the macro expansion.

However, templates do not have a full grammar. A template is essentially any sequence of tokens and substitutions in which all of Dylan's brackets are balanced: (), [], {}, #(), and #[]. Substitution for pattern variables produces a sequence of tokens and other elementary fragments.

Note that using unparsed token sequences as templates allows a macro expansion to contain macro calls without creating any inter-dependencies between macros. Since the template is not parsed at macro definition time, any macros called in the template do not have to be defined first, and macros can be compiled independently of each other. This simplifies the implementation at the minor cost of deferring some error checking from when a macro is defined until the time when the macro is called.

The grammar for templates is the definition of template in Templates on page 429.

All template-elements other than substitution are copied directly into the macro expansion. The various kinds of substitution insert something else into the macro expansion, as follows:

? name

The fragment bound to the pattern variable named name.

name-prefixopt ? name-string-or-symbol name-suffixopt

The fragment bound to the pattern variable named name-string-or-symbol, converted to a string or symbol and/or concatenated with a prefix and/or suffix. Note that this rule applies only when the first rule does not. The fragment must be a name. Concatenate the prefix, if any, the characters of the fragment, and the suffix, if any. The alphabetic case of the characters of the fragment is unspecified. Convert this to the same grammatical type (name, string, or symbol) as name-string-or-symbol. When the result is a name, its hygiene context is the same as that of the fragment.

?? name separatoropt ...

The sequence of fragments bound to the pattern variable named name, with separator inserted between each pair of fragments. The pattern variable must have been bound by a ?? pattern-keyword. Separator can be a binary operator, comma, or semicolon. If the size of the sequence is 1 or separator is omitted, no separator is inserted. If the sequence is empty, nothing is inserted.

...

The fragment bound to the pattern variable that names this rule set; this is only valid in an auxiliary rule set.

?= name

A reference to name, in the lexical context where the macro was called.

It is an error for a single question-mark substitution to use a pattern variable that was bound by a double question-mark pattern-keyword.

It is an error for a double question-mark substitution to use a pattern variable that was bound by a single question-mark pattern-variable or pattern-keyword.

It is an error for a substitution to use a pattern variable that does not appear on the left-hand side of the same rule.

When a template contains a separator immediately followed by a substitution, and the fragment inserted into the macro expansion by the substitution is empty, the separator is removed from the macro expansion.