11.1 Pattern-Based Syntax Matching
|
|
clause | | = | | [pattern result-expr] | | | | | | [pattern fender-expr result-expr] | | | | | | pattern | | = | | _ | | | | | | id | | | | | | (pattern ...) | | | | | | (pattern ...+ . pattern) | | | | | | (pattern ... pattern ellipses pattern ...) | | | | | | (pattern ... pattern ellipses pattern ... . pattern) | | | | | | #(pattern ...) | | | | | | #(pattern ... pattern ellipses pattern ...) | | | | | | #s(key-datum pattern ...) | | | | | | #s(key-datum pattern ... pattern ellipses pattern ...) | | | | | | (ellipses stat-pattern) | | | | | | const | | | | | | stat-pattern | | = | | id | | | | | | (stat-pattern ...) | | | | | | (stat-pattern ...+ . stat-pattern) | | | | | | #(stat-pattern ...) | | | | | | const | | | | | | ellipses | | = | | ... |
|
Finds the first
pattern that matches the syntax object
produced by
stx-expr, and for which the corresponding
fender-expr (if any) produces a true value; the result is
from the corresponding
result-expr, which is in tail position
for the
syntax-case form. If no
clause matches, then
the
exn:fail:syntax exception is raised; the exception is generated by calling
raise-syntax-error with
#f as the “name” argument,
a string with a generic error message, and the result of
stx-expr.
A syntax object matches a pattern as follows:
A _ pattern (i.e., an identifier with the same binding as
_) matches any syntax object.
An id matches any syntax object when it is not bound to
... or _ and does not have the same binding as
any literal-id. The id is further bound as
pattern variable for the corresponding fender-expr
(if any) and result-expr. A pattern-variable binding is a
transformer binding; the pattern variable can be reference only
through forms like syntax. The binding’s value is the syntax
object that matched the pattern with a depth marker of
0.
An id that has the same binding as a literal-id
matches a syntax object that is an identifier with the same binding
in the sense of free-identifier=?. The match does not
introduce any pattern variables.
A (pattern ...) pattern matches a syntax object whose datum
form (i.e., without lexical information) is a list with as many
elements as sub-patterns in the pattern, and where each
syntax object that corresponding to an element of the list matches
the corresponding sub-pattern.
Any pattern variables bound by the sub-patterns are
bound by the complete pattern; the bindings must all be distinct.
The last pattern must not be a (pattern ...),
(pattern ...+ . pattern), (pattern ... pattern ellipses pattern ...), or (pattern ... pattern ellipses pattern ... . pattern) form.
Like the previous kind of pattern, but matches syntax objects that
are not necessarily lists; for n sub-patterns before
the last sub-pattern, the syntax object’s datum must be a
pair such that n-1 cdrs produce pairs. The last
sub-pattern is matched against the syntax object
corresponding to the nth cdr (or the
datum->syntax coercion of the datum using the nearest
enclosing syntax object’s lexical context and source location).
(pattern ... pattern ellipses pattern ...) |
Like the (pattern ...) kind of pattern, but matching a
syntax object with any number (zero or more) elements that match the
sub-pattern followed by ellipses in the
corresponding position relative to other sub-patterns.
For each pattern variable bound by the sub-pattern followed
by ellipses, the larger pattern binds the same pattern
variable to a list of values, one for each element of the syntax
object matched to the sub-pattern, with an incremented
depth marker. (The sub-pattern itself may contain
ellipses, leading to a pattern variables bound to lists of
lists of syntax objects with a depth marker of 2, and
so on.)
(pattern ... pattern ellipses pattern ... . pattern) |
Like the previous kind of pattern, but with a final
sub-pattern as for (pattern ...+ . pattern). The
final pattern never matches a syntax object whose datum is a
pair.
Like a (pattern ...) pattern, but matching a vector syntax object
whose elements match the corresponding sub-patterns.
#(pattern ... pattern ellipses pattern ...) |
Like a (pattern ... pattern ellipses pattern ...) pattern,
but matching a vector syntax object whose elements match the
corresponding sub-patterns.
#s(key-datum pattern ...) |
Like a (pattern ...) pattern, but matching a prefab
structure syntax object whose fields match the corresponding
sub-patterns. The key-datum must correspond to a
valid first argument to make-prefab-struct.
#s(key-datum pattern ... pattern ellipses pattern ...) |
Like a (pattern ... pattern ellipses pattern ...) pattern,
but matching a prefab structure syntax object whose elements
match the corresponding sub-patterns.
Matches the same as stat-pattern, which is like a pattern,
but identifiers with the binding ... are treated the same as
other ids.
A const is any datum that does not match one of the
preceding forms; a syntax object matches a const pattern
when its datum is equal? to the quoted
const.
Examples: |
> (require (for-syntax racket/base)) |
|
> (let ([x 5] [y 10]) | (swap x y) | (list x y)) |
|
'(10 5) |
|
#<syntax:4:0 (+ 1 2 3)> |
(syntax-case* stx-expr (literal-id ...) id-compare-expr | clause ...) |
|
Like
syntax-case, but
id-compare-expr must produce a
procedure that accepts two arguments. A
literal-id in a
pattern matches an identifier for which the procedure
returns true when given the identifier to match (as the first argument)
and the identifier in the
pattern (as the second argument).
In other words, syntax-case is like syntax-case* with
an id-compare-expr that produces free-identifier=?.
Similar to
syntax-case, in that it matches a
pattern
to a syntax object. Unlike
syntax-case, all
patterns
are matched, each to the result of a corresponding
stx-expr,
and the pattern variables from all matches (which must be distinct)
are bound with a single
body sequence. The result of the
with-syntax form is the result of the last
body,
which is in tail position with respect to the
with-syntax
form.
If any pattern fails to match the corresponding
stx-expr, the exn:fail:syntax exception is raised.
A with-syntax form is roughly equivalent to the following
syntax-case form:
However, if any individual stx-expr produces a
non-syntax object, then it is converted to one using
datum->syntax and the lexical context and source location of
the individual stx-expr.
Examples: |
|
> (hello jon utah) |
> (jon 2) |
|
> (utah 2) |
|
|
> (math 3 1 4 1 5 9) |
got 4 | got 2 | got 5 | got 2 | got 6 | got 10 |
|
(syntax template) |
|
template | | = | | id | | | | | | (template-elem ...) | | | | | | (template-elem ...+ . template) | | | | | | #(template-elem ...) | | | | | | #s(key-datum template-elem ...) | | | | | | (ellipses stat-template) | | | | | | const | | | | | | template-elem | | = | | template ellipses ... | | | | | | stat-template | | = | | id | | | | | | (stat-template ...) | | | | | | (stat-template ... . stat-template) | | | | | | #(stat-template ...) | | | | | | #s(key-datum stat-template ...) | | | | | | const | | | | | | ellipses | | = | | ... |
|
Template forms produce a syntax object as follows:
If id is bound as a pattern variable, then
id as a template produces the pattern variable’s
match result. Unless the id is a sub-template that is
replicated by ellipses in a larger template, the
pattern variable’s value must be a syntax object with a
depth marker of 0 (as opposed to a list of
matches).
More generally, if the pattern variable’s value has a depth
marker n, then it can only appear within a template where it
is replicated by at least n ellipseses. In that case,
the template will be replicated enough times to use each match result
at least once.
If id is not bound as a pattern variable, then id
as a template produces (quote-syntax id).
Produces a syntax object whose datum is a list, and where the
elements of the list correspond to syntax objects producesd by the
template-elems.
A template-elem is a sub-template replicated by any
number of ellipseses:
If the sub-template is replicated by no
ellipseses, then it generates a single syntax object to
incorporate into the result syntax object.
If the sub-template is replicated by one
ellipses, then it generates a sequence of syntax objects
that is “inlined” into the resulting syntax object.
The number of generated elements depends the values of
pattern variables referenced within the
sub-template. There must be at least one pattern
variable whose value is has a depth marker less than the
number of ellipseses after the pattern variable within the
sub-template.
If a pattern variable is replicated by more
ellipseses in a template than the depth
marker of its binding, then the pattern variable’s result
is determined normally for inner ellipseses (up to the
binding’s depth marker), and then the result is replicated
as necessary to satisfy outer ellipseses.
For each ellipses after the first one, the preceding
element (with earlier replicating ellipsess) is
conceptually wrapped with parentheses for generating output, and
then the wrapping parentheses are removed in the resulting syntax
object.
(template-elem ... . template) |
Like the previous form, but the result is not necessarily a list;
instead, the place of the empty list in resulting syntax object’s
datum is taken by the syntax object produced by template.
Like the (template-elem ...) form, but producing a syntax
object whose datum is a vector instead of a list.
#s(key-datum template-elem ...) |
Like the (template-elem ...) form, but producing a syntax
object whose datum is a prefab structure instead of a list.
The key-datum must correspond to a valid first argument of
make-prefab-struct.
Produces the same result as stat-template, which is like a
template, but ... is treated like a id
(with no pattern binding).
A const template is any form that does not match the
preceding cases, and it produces the result (quote-syntac const).
A (syntax template) form is normally
abbreviated as #'template; see also
Reading Quotes. If template contains no pattern
variables, then #'template is equivalent to
(quote-syntax template).
Like
syntax, but
(unsyntax expr) and
(unsyntax-splicing expr)
escape to an expression within the
template.
The expr must produce a syntax object (or syntax list) to be
substituted in place of the unsyntax or
unsyntax-splicing form within the quasiquoting template, just
like unquote and unquote-splicing within
quasiquote. (If the escaped expression does not generate a
syntax object, it is converted to one in the same was as for the
right-hand sides of with-syntax.) Nested
quasisyntaxes introduce quasiquoting layers in the same way
as nested quasiquotes.
Also analogous quasiquote, the reader converts #`
to quasisyntax, #, to unsyntax, and
#,@ to unsyntax-splicing. See also
Reading Quotes.
Like
syntax, except that the immediate resulting syntax
object takes its source-location information from the result of
stx-expr (which must produce a syntax object), unless the
template is just a pattern variable or both the source and
position of
stx-expr are
#f.
Like
quote-syntax, but the lexical context of
id is
pruned via
identifier-prune-lexical-context to including
binding only for the symbolic name of
id and for
'#%top. Use this form to quote an identifier when its lexical
information will not be transferred to other syntax objects (except
maybe to
'#%top for a top-level binding).
(syntax-rules (literal-id ...) | [(id . pattern) template] ...) |
|
Equivalent to
(lambda (stx) |
(syntax-case stx (literal-id ...) |
[(generated-id . pattern) #'template] ...)) |
where each generated-id binds no identifier in the
corresponding template.
Equivalent to
Equivalent to
The
... transformer binding prohibits
... from
being used as an expression. This binding useful only in syntax
patterns and templates, where it indicates repetitions of a pattern or
template. See
syntax-case and
syntax.
The
_ transformer binding prohibits
_ from being
used as an expression. This binding useful only in syntax patterns,
where it indicates a pattern that matches any syntax object. See
syntax-case.
Return
#t if
v is a value that, as a
transformer-binding value, makes the bound variable as pattern
variable in
syntax and other forms. To check whether an
identifier is a pattern variable, use
syntax-local-value to
get the identifier’s transformer value, and then test the value with
syntax-pattern-variable?.
The syntax-pattern-variable? procedure is provided
for-syntax by racket/base.