
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.
SyntaxElements 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 SyntaxElements. 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. SyntaxElements 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.