3 Macro Transformer Helpers
3.1 Extracting Inferred Names
Similar to
syntax-local-name except that
stx is
checked for an
'inferred-name property (which overrides any
inferred name). If neither
syntax-local-name nor
'inferred-name produce a name, or if the
'inferred-name property value is
#<void>, then a name
is constructed from the source-location information in
stx,
if any. If no name can be constructed, the result is
#f.
Returns a list suitable for use as a context argument to
local-expand for an internal-definition context. The
v argument represents the immediate context for
expansion. The context list builds on
(syntax-local-context)
if it is a list.
3.3 Parsing define-like Forms
Takes a definition form whose shape is like
define (though
possibly with a different name) and returns two values: the defined
identifier and the right-hand side expression.
To generate the right-hand side, this function may need to insert uses
of lambda. The lambda-id-stx argument provides a
suitable lambda identifier.
If the definition is ill-formed, a syntax error is raised. If
check-context? is true, then a syntax error is raised if
(syntax-local-context) indicates that the current context is
an expression context. The default value of check-context? is
#t.
If opt-kws? is #t, then arguments of the form
[id expr], keyword id, and keyword [id expr] are allowed, and they are preserved in the expansion.
3.4 Flattening begin Forms
Extracts the sub-expressions from a
begin-like form,
reporting an error if
stx does not have the right shape
(i.e., a syntax list). The resulting syntax objects have annotations
transferred from
stx using
syntax-track-origin.
Parses
stx as a
define-struct form, but uses
orig-stx to report syntax errors (under the assumption that
orig-stx is the same as
stx, or that they at least share
sub-forms). The result is four values: an identifier for the struct
type name, a identifier or #f for the super-name, a list of
identifiers for fields, and a syntax object for the inspector
expression.
Generates the names bound by
define-struct given an
identifier for the struct type name and a list of identifiers for the
field names. The result is a list of identifiers:
struct:name-id
ctr-name, or make-name-id if ctr-name is #f
name-id?
name-id-field, for each
field in field-ids.
set-name-id-field!
(getter and setter names alternate).
....
If omit-sel? is true, then the selector names are omitted from the
result list. If omit-set? is true, then the setter names are omitted
from the result list.
The default src-stx is #f; it is used to provide a
source location to the generated identifiers.
Takes the same arguments as
build-struct-names and generates
an S-expression for code using
make-struct-type to generate
the structure type and return values for the identifiers created by
build-struct-names. The optional
super-type,
prop-value-list, and
immutable-k-list parameters take
S-expressions that are used as the corresponding argument expressions to
make-struct-type.
Takes mostly the same arguments as
build-struct-names, plus a parent
identifier/
#t/
#f and a list of accessor and mutator
identifiers (possibly ending in
#f) for a parent type, and
generates an S-expression for expansion-time code to be used in the
binding for the structure name.
If no-ctr? is true, then the constructor name is omitted from
the expansion-time information. Similarly, if no-type? is
true, then the structure-type name is omitted.
A #t for the base-name means no super-type,
#f means that the super-type (if any) is unknown, and an
identifier indicates the super-type identifier.
The generate-struct-declaration procedure is called by a
macro expander to generate the expansion, where the name-id,
super-id-or-false, and field-id-list arguments
provide the main parameters. The current-context argument is
normally the result of syntax-local-context. The
orig-stx argument is used for syntax errors. The optional
omit-sel? and omit-set? arguments default to
#f; a #t value suppresses definitions of field
selectors or mutators, respectively.
The make-struct-type procedure is called to generate the
expression to actually create the struct type. Its arguments are
orig-stx, name-id-stx, defined-name-stxes,
and super-info. The first two are as provided originally to
generate-struct-declaration, the third is the set of names
generated by build-struct-names, and the last is super-struct
info obtained by resolving super-id-or-false when it is not
#f, #f otherwise.
The result should be an expression whose values are the same as the
result of make-struct-type. Thus, the following is a basic
make-make-struct-type:
but an actual make-make-struct-type will likely do more.
3.6 Resolving include-like Paths
Resolves the syntactic path specification path-spec-stx as
for include.
The source-stx specifies a syntax object whose
source-location information determines relative-path resolution. The
expr-stx is used for reporting syntax errors. The
build-path-stx is usually #'build-path; it provides
an identifier to compare to parts of path-spec-stx to
recognize the build-path keyword.
3.7 Controlling Syntax Templates
(transform-template | | template-stx | | | | #:save save-proc | | | | #:restore-stx restore-proc-stx | | | [ | #:leaf-save leaf-save-proc | | | | #:leaf-restore-stx leaf-restore-proc-stx | | | | #:leaf-datum-stx leaf-datum-proc-stx | | | | #:pvar-save pvar-save-proc | | | | #:pvar-restore-stx pvar-restore-stx | | | | #:cons-stx cons-proc-stx | | | | #:ellipses-end-stx ellipses-end-stx | | | | #:constant-as-leaf? constant-as-leaf?]) | |
|
→ syntax? |
template-stx : syntax? |
save-proc : (syntax? . -> . any/c) |
restore-proc-stx : syntax? |
leaf-save-proc : (syntax? . -> . any/c) = save-proc |
leaf-restore-proc-stx : syntax? = #'(lambda (data stx) stx) |
leaf-datum-proc-stx : syntax? = #'(lambda (v) v) |
pvar-save-proc : (identifier? . -> . any/c) = (lambda (x) #f) |
pvar-restore-stx : syntax? = #'(lambda (d stx) stx) |
cons-proc-stx : syntax? = cons |
ellipses-end-stx : syntax? = #'values |
constant-as-leaf? : boolean? = #f |
Produces an representation of an expression similar to
#`(syntax #,template-stx), but functions like
save-proc can collect information that might otherwise be
lost by
syntax (such as properties when the syntax object is
marshaled within bytecode), and run-time functions like the one
specified by
restore-proc-stx can use the saved information or
otherwise process the syntax object that is generated by the template.
The save-proc is applied to each syntax object in the
representation of the original template (i.e., in
template-stx). If constant-as-leaf? is #t,
then save-proc is applied only to syntax objects that contain
at least one pattern variable in a sub-form. The result of
save-proc is provided back as the first argument to
restore-proc-stx, which indicates a function with a contract
(-> any/c syntax any/c any/c); the second argument to
restore-proc-stx is the syntax object that syntax
generates, and the last argument is a datum that have been processed
recursively (by functions such as restore-proc-stx) and that
normally would be converted back to a syntax object using the second
argument’s context, source, and properties. Note that
save-proc works at expansion time (with respect to the
template form), while restore-proc-stx indicates a function
that is called at run time (for the template form), and the data that
flows from save-proc to restore-proc-stx crosses
phases via quote.
The leaf-save-proc and leaf-restore-proc-stx procedures
are analogous to save-proc and
restore-proc-stx, but they are applied to leaves, so
there is no third argument for recursively processed sub-forms. The
function indicated by leaf-restore-proc-stx should have the
contract (-> any/c syntax? any/c).
The leaf-datum-proc-stx procedure is applied to leaves that
are not syntax objects, which can happen because pairs and the empty
list are not always individually wrapped as syntax objects. The
function should have the contract (-> any/c any/c). When
constant-as-leaf? is #f, the only possible argument
to the procedure is null.
The pvar-save and pvar-restore-stx procedures are
analogous to save-proc and restore-proc-stx,
but they are applied to pattern variables. The
pvar-restore-stx procedure should have the contract
(-> any/c syntax? any/c), where the second argument
corresponds to the substitution of the pattern variable.
The cons-proc-stx procedure is used to build intermediate
pairs, including pairs passed to restore-proc-stx and pairs
that do not correspond to syntax objects.
The ellipses-end-stx procedure is an extra filter on the
syntax object that follows a sequence of ... ellipses in the
template. The procedure should have the contract (-> any/c any/c).
The following example illustrates a use of transform-template
to implement a syntax/shape form that preserves the
'paren-shape property from the original template, even if the
template code is marshaled within bytecode.