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
definespecial 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-macrospecial forms expand into calls to these procedures.
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 table, or
#f; usually it is specified as the value of
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.
Change the current parser-macro table to table, which must satisfy
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
parser-macros?, and thunk must be a procedure of no arguments.