racket/pkgs/racket-doc/scribblings/reference/stx-expand.scrbl
Matthew Flatt c0fa2eecd5 add module-compiled-indirect-exports and co.
That information is needed sometimes to compile expanded syntax to
bytecode form.
2016-05-18 13:13:15 -06:00

190 lines
6.9 KiB
Racket

#lang scribble/doc
@(require "mz.rkt")
@title{Expanding Top-Level Forms}
@defproc[(expand [top-level-form any/c]) syntax?]{
Expands all non-primitive syntax in @racket[top-level-form], and
returns a syntax object for the expanded form that contains only core
forms, matching the grammar specified by @secref["fully-expanded"].
Before @racket[top-level-form] is expanded, its lexical context is
enriched with @racket[namespace-syntax-introduce], just as for
@racket[eval]. Use @racket[syntax->datum] to convert the returned
syntax object into a printable datum.}
Here's an example of using @racket[expand] on a module:
@racketblock[
(parameterize ([current-namespace (make-base-namespace)])
(expand
(datum->syntax
#f
'(module foo scheme
(define a 3)
(+ a 4)))))]
Here's an example of using @racket[expand] on a non-top-level form:
@racketblock[
(define-namespace-anchor anchor)
(parameterize ([current-namespace
(namespace-anchor->namespace anchor)])
(expand
(datum->syntax
#f
'(delay (+ 1 2)))))]
@defproc[(expand-syntax [stx syntax?]) syntax?]{
Like @racket[(expand stx)], except that the argument must be a
@tech{syntax object}, and its lexical context is not enriched before
expansion.}
@defproc[(expand-once [top-level-form any/c]) syntax?]{
Partially expands @racket[top-level-form] and returns a syntax object
for the partially-expanded expression. Due to limitations in the
expansion mechanism, some context information may be lost. In
particular, calling @racket[expand-once] on the result may produce a
result that is different from expansion via @racket[expand].
Before @racket[top-level-form] is expanded, its lexical context is
enriched with @racket[namespace-syntax-introduce], as for
@racket[eval].}
@defproc[(expand-syntax-once [stx syntax?]) syntax?]{
Like @racket[(expand-once stx)], except that the argument
must be a @tech{syntax object}, and its lexical context is not
enriched before expansion.}
@defproc[(expand-to-top-form [top-level-form any/c]) syntax?]{
Partially expands @racket[top-level-form] to reveal the outermost
syntactic form. This partial expansion is mainly useful for detecting
top-level uses of @racket[begin]. Unlike the result of
@racket[expand-once], expanding the result of
@racket[expand-to-top-form] with @racket[expand] produces the same
result as using @racket[expand] on the original syntax.
Before @racket[stx-or-sexpr] is expanded, its lexical context is
enriched with @racket[namespace-syntax-introduce], as for
@racket[eval].}
@defproc[(expand-syntax-to-top-form [stx syntax?]) syntax?]{
Like @racket[(expand-to-top-form stx)], except that the argument must
be a @tech{syntax object}, and its lexical context is not enriched
before expansion.}
@;------------------------------------------------------------------------
@section[#:tag "modinfo"]{Information on Expanded Modules}
Information for an expanded @racket[module] declaration is stored in a
set of @tech{syntax properties} (see @secref["stxprops"]) attached
to the syntax object:
@itemize[
@item{@indexed-racket['module-direct-requires] --- a list of
@tech{module path index}es (or symbols) representing the modules
explicitly imported into the module.}
@item{@indexed-racket['module-direct-for-syntax-requires] --- a list
of @tech{module path index}es (or symbols) representing the modules
explicitly for-syntax imported into the module.}
@item{@indexed-racket['module-direct-for-template-requires] --- a
list of @tech{module path index}es (or symbols) representing the
modules explicitly for-template imported into the module.}
@item{@indexed-racket['module-direct-for-meta-requires] --- a list of
lists: each list is an integer or @racket[#f] representing a
@tech{phase level} followed by a list of @tech{module path index}es
(or symbols) representing the modules explicitly imported into the
module at the corresponding phase.
@history[#:added "6.4.0.1"]}
@item{@indexed-racket['module-variable-provides] --- a list of
provided items, where each item is one of the following:
@itemize[
@item{@racket[symbol] --- represents a locally defined variable that
is provided with its defined name.}
@item{@racket[(cons _provided-sym _defined-sym)] --- represents a
locally defined variable that is provided with renaming; the first
symbol is the exported name, and the second symbol is the defined
name.}
@item{@racket[(list* module-path-index _provided-sym _defined-sym)]
--- represents a re-exported and possibly re-named variable from the
specified module; @racket[module-path-index] is either a
@tech{module path index} or symbol (see @secref["modpathidx"]),
indicating the source module for the binding. The
@racket[_provided-sym] is the external name for the re-export, and
@racket[_defined-sym] is the originally defined name in the module
specified by @racket[module-path-index].}
]}
@item{@indexed-racket['module-syntax-provides] --- like
@racket['module-variable-provides], but for syntax exports instead of
variable exports.}
@item{@indexed-racket['module-indirect-provides] --- a list of symbols for
variables that are defined in the module but not exported; they may
be exported indirectly through macro expansions. Definitions of
macro-generated identifiers create uninterned symbols in this list.
The order of identifiers in the list corresponds to an order for
access from bytecode.}
@item{@indexed-racket['module-indirect-for-meta-provides] --- similar
to @racket['module-indirect-provides]: an association list from a
phase level to a list of symbols for variables that are defined in
the module at phases higher than @racket[0] and not exported.
@history[#:added "6.5.0.5"]}
@item{@indexed-racket['module-body-context] --- a syntax
object whose @tech{lexical information} corresponds to the inside of
the module, so it includes the expansion's @tech{outside-edge scope}
and its @tech{inside-edge scope}; that is, the syntax object
simulates an identifier that is present in the original module body
and inaccessible to manipulation by any macro, so that its lexical
information includes bindings for the module's imports and
definitions.
@history[#:added "6.4.0.1"]}
@item{@indexed-racket['module-body-inside-context] --- a syntax
object whose @tech{lexical information} corresponds to an identifier
that starts with no lexical context and is moved into the macro, so
that it includes only the expansions's @tech{inside-edge scope}.
@history[#:added "6.4.0.1"]}
@item{@indexed-racket['module-body-context-simple?] --- a boolean,
where @racket[#t] indicates that the bindings of the module's body
(as recorded in the @tech{lexical information} of the value of the
@racket['module-body-inside-context] property) can be directly
reconstructed from the values of @racket['module-direct-requires],
@racket['module-direct-for-syntax-requires],
@racket['module-direct-for-template-requires], and
@racket['module-direct-for-meta-requires].
@history[#:added "6.4.0.1"]}
]