A compatible low-level macro facility

Although the pattern language provided by syntax-rules is the preferred way to specify macro transformers, other low-level facilities may be provided to specify more complex macro transformers. In fact, syntax-rules can itself be defined as a macro using the low-level facilities described in this section.

The low-level macro facility described here introduces syntax as a new syntactic keyword analogous to quote, and allows a transformer spec to be any expression. This is accomplished by adding the following two productions to the productions in section [*] and in section [*] above.


\begin{grammar}%
\meta{expression} \: (syntax \hyper{datum})
\meta{transformer spec} \: \meta{expression}%
\end{grammar}

The low-level macro system also adds the following procedures:


\begin{scheme}
unwrap-syntax identifier->symbol
identifier? generate-identifier
free-identifier=? construct-identifier
bound-identifier=?
\end{scheme}

Evaluation of a program proceeds in two logical steps. First the program is converted into an intermediate language via macro-expansion, and then the result of macro expansion is evaluated. When it is necessary to distinguish the second stage of this process from the full evaluation process, it is referred to as ``execution.''

Syntax definitions, either lexical or global, cause an identifier to be treated as a keyword within the scope of the binding. The keyword is associated with a transformer, which may be created implicitly using the pattern language of syntax-rules or explicitly using the low-level facilities described below.

Since a transformer spec must be fully evaluated during the course of expansion, it is necessary to specify the environment in which this evaluation takes place. A transformer spec is expanded in the same environment as that in which the program is being expanded, but is executed in an environment that is distinct from the environment in which the program is executed. This execution environment distinction is important only for the resolution of global variable references and assignments. In what follows, the environment in which transformers are executed is called the standard transformer environment and is assumed to be a standard Scheme environment.

Since part of the task of hygienic macro expansion is to resolve identifier references, the fact that transformers are expanded in the same environment as the program means that identifier bindings in the program can shadow identifier uses within transformers. Since variable bindings in the program are not available at the time the transformer is executed, it is an error for a transformer to reference or assign them. However, since keyword bindings are available during expansion, lexically visible keyword bindings from the program may be used in macro uses in a transformer.

When a macro use is encountered, the macro transformer associated with the macro keyword is applied to a representation of the macro expression. The result returned by the macro transformer replaces the original expression and is expanded once again. Thus macro expansions may themselves be or contain macro uses.

The syntactic representation passed to a macro transformer encapsulates information about the structure of the represented form and the bindings of the identifiers it contains. These syntax objects can be traversed and examined using the procedures described below. The output of a transformer may be built up using the usual Scheme list constructors, combining pieces of the input with new syntactic structures.


\begin{entry}{%
\proto{syntax}{ \hyper{datum}}{\exprtype}}
\par
\syntax
The \hyp...
...f syntax}
that {\cf quasiquote} bears to {\cf quote}.
\end{note}\par
\end{entry}


\begin{entry}{%
\proto{identifier?}{ syntax-object}{procedure}}
\par
Returns \sc...
...ote x)) \ev \schfalse
(identifier? 3) \ev \schfalse \end{scheme}\par
\end{entry}


\begin{entry}{%
\proto{unwrap-syntax}{ syntax-object}{procedure}}
\par
If \var{s...
...syntax (cdr (unwrap-syntax (syntax (x)))))
\ev ()%
\end{scheme}\par
\end{entry}


\begin{entry}{%
\proto{free-identifier=?}{ \vari{id} \varii{id}}{procedure}}
\pa...
...ntax x))
(syntax alpha)))))
(alpha)) \ev \schtrue \end{scheme}\par
\end{entry}


\begin{entry}{%
\proto{bound-identifier=?}{ \vari{id} \varii{id}}{procedure}}
\p...
...tax x))
(syntax alpha)))))
(alpha)) \ev \schfalse \end{scheme}\par
\end{entry}


\begin{entry}{%
\proto{identifier->symbol}{ \var{id}}{procedure}}
\par
Returns a...
...\ev \schtrue
(identifier->symbol (syntax x))
\ev x\end{scheme}\par
\end{entry}


\begin{entry}{%
\proto{generate-identifier}{}{procedure}
\proto{generate-identif...
...tax set!) ,id ,temp))
ids
temps)
\schfalse))))))
\end{scheme}\par
\end{entry}


\begin{entry}{%
\proto{construct-identifier}{ \var{id} \var{symbol}}{procedure}}...
...x 3))
(set! y (- y 1)))
(exit x)))) \evalsto 3000
\end{scheme}\par
\end{entry}