The SyntaxElement
class is used to represent a single
line of syntax, or a portion thereof. It effectively implements the
pattern portion of a syntax-rules
declaration.
SyntaxElement
s form a tree, usually with symbols and literal
values as the leaves and with lists and vectors forming the leaves.
They are matched in a top-down, left-to-right fashion, following the
R5RS rules. An element may be one of several types: a Literal (matching
a single value), an EmptyList (matching null), a BoundSymbol (matching
anything and binding to a symbol), a List (matching a list of items) or
a Vector (matching a vector of items).
Lists and Vectors match multiple elements: they are described as a
collection of SyntaxElement
s. They both have an
additional ellipsis form: in this form, the final element is
matched 0 or more times. Lists also have an improper form: this affects
the final element as well: this is matched against the cdr of the
previous element. Note that while vector elements can be empty,
list elements must contain at least one item (at least two items for
the improper case).
The usual way to create a SyntaxElement
is through the
MakeElementFromScheme
factory method rather than
constructing it directly. This can take a scheme object and a collection
of literal symbols, or scheme as a string and produce SyntaxElement
that would match that as a pattern as for syntax-rules
.
The Match
method matches a SyntaxElement against
some scheme. This requires a CompileState
object in
order to check bindings for literal symbols (recall that in scheme,
a literal symbol is only matched against a symbol with the same binding).
Literal symbol bindings are established through the ISymbolic
method Location
. SyntaxElement
s that use
literal symbols that bind to environments other than the top-level
environment should use ISymbolic
symbols that specify
an environment (such as the LiteralSymbol
class does).
SyntaxElements maintain information about the tree. This imposes a limitation on how they can be constructed: an element must have at most one parent element - you cannot construct a subtree and use it in more than one place. This information can be used to query the tree, which is useful when building pattern transformers - the structure of the SyntaxElements correspond closely to the structure of the output tree.
The Syntax
object is used to collate several SyntaxElement
objects, and find the first of them that matches a given scheme object.