The parser and matcher languages provide a macro facility so that common patterns can be abstracted. The macro facility allows new expression types to be independently defined in the two languages. The macros are defined in hierarchically organized tables, so that different applications can have private macro bindings.
These special forms are used to define macros in the matcher and
parser language, respectively. Formals is like the
formals list of a
define special form, and
expression is a Scheme expression.
If formals is a list (or improper list) of symbols, the first symbol in the list is the name of the macro, and the remaining symbols are interpreted as the formals of a lambda expression. A lambda expression is formed by combining the latter formals with the expression, and this lambda expression, when evaluated, becomes the expander. The defined macro accepts the same number of operands as the expander. A macro instance is expanded by applying the expander to the list of operands; the result of the application is interpreted as a replacement expression for the macro instance.
If formals is a symbol, it is the name of the macro. In this case, the expander is a procedure of no arguments whose body is expression. When the formals symbol appears by itself as an expression in the language, the expander is called with no arguments, and the result is interpreted as a replacement expression for the symbol.
These procedures provide a procedural interface to the
macro-definition mechanism. Identifier must be a symbol, and
expander must be an expander procedure, as defined above.
Instances of the
define-*parser-macro special forms expand into calls to these
The remaining procedures define the interface to the parser-macros table abstraction. Each parser-macro table has a separate binding space for macros in the matcher and parser languages. However, the table inherits bindings from one specified table; it’s not possible to inherit matcher-language bindings from one table and parser-language bindings from another.
Create and return a new parser-macro table that inherits from
parent-table. Parent-table must be either a parser-macro
#f; usually it is specified as the value of
This is a predicate for parser-macro tables.
Return the global parser-macro table. This table is predefined and contains all of the bindings documented here.
There is a “current” table at all times, and macro definitions are always placed in this table. By default, the current table is the global macro table, but the following procedures allow this to be changed.
Return the current parser-macro table.
Change the current parser-macro table to table, which must
Bind the current parser-macro table to table, call thunk
with no arguments, then restore the original table binding. The value
returned by thunk is the returned as the value of this
procedure. Table must satisfy
thunk must be a procedure of no arguments.