fix varref' in compiler/zo-structs', etc.

and sync docs better with implementation
This commit is contained in:
Matthew Flatt 2011-05-09 09:42:43 -06:00
parent 553d9ff4c6
commit a4da2a3f4c
9 changed files with 619 additions and 587 deletions

View File

@ -195,7 +195,7 @@
(match expr (match expr
[(struct toplevel (depth pos const? ready?)) [(struct toplevel (depth pos const? ready?))
(decompile-tl expr globs stack closed #f)] (decompile-tl expr globs stack closed #f)]
[(struct varref (tl)) [(struct varref (tl dummy))
`(#%variable-reference ,(decompile-tl tl globs stack closed #t))] `(#%variable-reference ,(decompile-tl tl globs stack closed #t))]
[(struct topsyntax (depth pos midpt)) [(struct topsyntax (depth pos midpt))
(list-ref/protect (glob-desc-vars globs) (+ midpt pos) 'topsyntax)] (list-ref/protect (glob-desc-vars globs) (+ midpt pos) 'topsyntax)]

View File

@ -120,8 +120,9 @@
[(struct beg0 (seq)) [(struct beg0 (seq))
(for-each (lambda (f) (build-graph! lhs f)) (for-each (lambda (f) (build-graph! lhs f))
seq)] seq)]
[(struct varref (tl)) [(struct varref (tl dummy))
(build-graph! lhs tl)] (build-graph! lhs tl)
(build-graph! lhs dummy)]
[(and f (struct assign (id rhs undef-ok?))) [(and f (struct assign (id rhs undef-ok?)))
(build-graph! lhs id) (build-graph! lhs id)
(build-graph! lhs rhs)] (build-graph! lhs rhs)]
@ -252,8 +253,8 @@
(update body))] (update body))]
[(struct beg0 (seq)) [(struct beg0 (seq))
(make-beg0 (map update seq))] (make-beg0 (map update seq))]
[(struct varref (tl)) [(struct varref (tl dummy))
(make-varref (update tl))] (make-varref (update tl) (update dummy))]
[(and f (struct assign (id rhs undef-ok?))) [(and f (struct assign (id rhs undef-ok?)))
(struct-copy assign f (struct-copy assign f
[id (update id)] [id (update id)]

View File

@ -68,8 +68,8 @@
(update body))] (update body))]
[(struct beg0 (seq)) [(struct beg0 (seq))
(make-beg0 (map update seq))] (make-beg0 (map update seq))]
[(struct varref (tl)) [(struct varref (tl dummy))
(make-varref (update tl))] (make-varref (update tl) (update dummy))]
[(and f (struct assign (id rhs undef-ok?))) [(and f (struct assign (id rhs undef-ok?)))
(struct-copy assign f (struct-copy assign f
[id (update id)] [id (update id)]

View File

@ -671,9 +671,9 @@
(protect-quote val) (protect-quote val)
(protect-quote body)) (protect-quote body))
out)] out)]
[(struct varref (expr)) [(struct varref (expr dummy))
(out-marshaled varref-form-type-num (out-marshaled varref-form-type-num
expr (cons expr dummy)
out)] out)]
[(protected-symref v) [(protected-symref v)
(out-anything ((out-shared-index out) v #:error? #t) out)] (out-anything ((out-shared-index out) v #:error? #t) out)]

View File

@ -207,7 +207,7 @@
(define (read-require v) (define (read-require v)
(make-req (cdr v) (car v))) (make-req (cdr v) (car v)))
(define (read-#%variable-ref v) (define (read-#%variable-ref v)
(make-varref v)) (make-varref (car v) (cdr v)))
(define (read-apply-values v) (define (read-apply-values v)
(make-apply-values (car v) (cdr v))) (make-apply-values (car v) (cdr v)))
(define (read-splice v) (define (read-splice v)

View File

@ -29,7 +29,7 @@
[struct id ([field-id field-contract] ...)]))) [struct id ([field-id field-contract] ...)])))
(define-struct zo () #:prefab) (define-struct zo () #:prefab)
(provide zo?) (provide (struct-out zo))
(define-syntax define-form-struct (define-syntax define-form-struct
(syntax-rules () (syntax-rules ()
@ -167,7 +167,7 @@
[body (or/c expr? seq? any/c)])) ; `with-continuation-mark' [body (or/c expr? seq? any/c)])) ; `with-continuation-mark'
(define-form-struct (beg0 expr) ([seq (listof (or/c expr? seq? any/c))])) ; `begin0' (define-form-struct (beg0 expr) ([seq (listof (or/c expr? seq? any/c))])) ; `begin0'
(define-form-struct (splice form) ([forms (listof (or/c form? any/c))])) ; top-level `begin' (define-form-struct (splice form) ([forms (listof (or/c form? any/c))])) ; top-level `begin'
(define-form-struct (varref expr) ([toplevel toplevel?])) ; `#%variable-reference' (define-form-struct (varref expr) ([toplevel toplevel?] [dummy toplevel?])) ; `#%variable-reference'
(define-form-struct (assign expr) ([id toplevel?] [rhs (or/c expr? seq? any/c)] [undef-ok? boolean?])) ; top-level or module-level set! (define-form-struct (assign expr) ([id toplevel?] [rhs (or/c expr? seq? any/c)] [undef-ok? boolean?])) ; top-level or module-level set!
(define-form-struct (apply-values expr) ([proc (or/c expr? seq? any/c)] [args-expr (or/c expr? seq? any/c)])) ; `(call-with-values (lambda () ,args-expr) ,proc) (define-form-struct (apply-values expr) ([proc (or/c expr? seq? any/c)] [args-expr (or/c expr? seq? any/c)])) ; `(call-with-values (lambda () ,args-expr) ,proc)
(define-form-struct (primval expr) ([id exact-nonnegative-integer?])) ; direct preference to a kernel primitive (define-form-struct (primval expr) ([id exact-nonnegative-integer?])) ; direct preference to a kernel primitive

View File

@ -141,3 +141,7 @@ Consumes a representation of bytecode and writes it to @racket[out].}
Consumes a representation of bytecode and generates a byte string for Consumes a representation of bytecode and generates a byte string for
the marshaled bytecode.} the marshaled bytecode.}
@; ------------------------------------------------------------
@include-section["zo-struct.scrbl"]

View File

@ -12,6 +12,10 @@
@defmodule[compiler/zo-parse] @defmodule[compiler/zo-parse]
The @racketmodname[compiler/zo-parse] module re-exports
@racketmodname[compiler/zo-structs] in addition to
@racket[zo-parse].
@defproc[(zo-parse [in input-port? (current-input-port)]) compilation-top?]{ @defproc[(zo-parse [in input-port? (current-input-port)]) compilation-top?]{
Parses a port (typically the result of opening a @filepath{.zo} file) Parses a port (typically the result of opening a @filepath{.zo} file)
containing bytecode. Beware that the structure types used to containing bytecode. Beware that the structure types used to
@ -71,578 +75,3 @@
or @racket[mod] structure indicates the list of global variables and or @racket[mod] structure indicates the list of global variables and
quoted syntax that need to be instantiated (and put into an array on quoted syntax that need to be instantiated (and put into an array on
the stack) before evaluating expressions that might use them.} the stack) before evaluating expressions that might use them.}
@; --------------------------------------------------
@section{Prefix}
@defstruct+[zo ()]{
A supertype for all zo objects that can appear in compiled code.}
@defstruct+[(compilation-top zo)
([max-let-depth exact-nonnegative-integer?]
[prefix prefix?]
[code (or/c form? any/c)])]{
Wraps compiled code. The @racket[max-let-depth] field indicates the
maximum stack depth that @racket[code] creates (not counting the
@racket[prefix] array). The @racket[prefix] field describes top-level
variables, module-level variables, and quoted syntax-objects accessed
by @racket[code]. The @racket[code] field contains executable code;
it is normally a @racket[form], but a literal value is represented as
itself.}
@defstruct+[(prefix zo)
([num-lifts exact-nonnegative-integer?]
[toplevels (listof (or/c #f symbol? global-bucket?
module-variable?))]
[stxs (listof stx?)])]{
Represents a ``prefix'' that is pushed onto the stack to initiate
evaluation. The prefix is an array, where buckets holding the
values for @racket[toplevels] are first, then the buckets for the
@racket[stxs], then a bucket for another array if @racket[stxs] is
non-empty, then @racket[num-lifts] extra buckets for lifted local
procedures.
In @racket[toplevels], each element is one of the following:
@itemize[
@item{a @racket[#f], which indicates a dummy variable that is used
to access the enclosing module/namespace at run time;}
@item{a symbol, which is a reference to a variable defined in the
enclosing module;}
@item{a @racket[global-bucket], which is a top-level variable (appears
only outside of modules); or}
@item{a @racket[module-variable], which indicates a variable imported
from another module.}
]
The variable buckets and syntax objects that are recorded in a prefix
are accessed by @racket[toplevel] and @racket[topsyntax] expression
forms.}
@defstruct+[(global-bucket zo) ([name symbol?])]{
Represents a top-level variable, and used only in a @racket[prefix].}
@defstruct+[(module-variable zo)
([modidx module-path-index?]
[sym symbol?]
[pos exact-integer?]
[phase (or/c 0 1)])]{
Represents a top-level variable, and used only in a @racket[prefix].
The @racket[pos] may record the variable's offset within its module,
or it can be @racket[-1] if the variable is always located by name.
The @racket[phase] indicates the phase level of the definition within
its module.}
@defstruct+[(stx zo) ([encoded wrapped?])]{
Wraps a syntax object in a @racket[prefix].}
@; --------------------------------------------------
@section{Forms}
@defstruct+[(form zo) ()]{
A supertype for all forms that can appear in compiled code (including
@racket[expr]s), except for literals that are represented as
themselves.}
@defstruct+[(def-values form)
([ids (listof toplevel?)]
[rhs (or/c expr? seq? any/c)])]{
Represents a @racket[define-values] form. Each element of
@racket[ids] will reference via the prefix either a top-level variable
or a local module variable.
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs].}
@deftogether[(
@defstruct+[(def-syntaxes form) ([ids (listof symbol?)]
[rhs (or/c expr? seq? any/c)]
[prefix prefix?]
[max-let-depth exact-nonnegative-integer?])]
@defstruct+[(def-for-syntax form)
([ids (listof toplevel?)]
[rhs (or/c expr? seq? any/c)]
[prefix prefix?]
[max-let-depth exact-nonnegative-integer?])]
)]{
Represents a @racket[define-syntaxes] or
@racket[define-values-for-syntax] form. The @racket[rhs] expression
has its own @racket[prefix], which is pushed before evaluating
@racket[rhs]; the stack is restored after obtaining the result values.
The @racket[max-let-depth] field indicates the maximum size of the
stack that will be created by @racket[rhs] (not counting
@racket[prefix]).}
@defstruct+[(req form) ([reqs stx?]
[dummy toplevel?])]{
Represents a top-level @racket[#%require] form (but not one in a
@racket[module] form) with a sequence of specifications @racket[reqs].
The @racket[dummy] variable is used to access to the top-level
namespace.}
@defstruct+[(seq form) ([forms (listof (or/c form? any/c))])]{
Represents a @racket[begin] form, either as an expression or at the
top level (though the latter is more commonly a @racket[splice] form).
When a @racket[seq] appears in an expression position, its
@racket[forms] are expressions.
After each form in @racket[forms] is evaluated, the stack is restored
to its depth from before evaluating the form.}
@defstruct+[(splice form) ([forms (listof (or/c form? any/c))])]{
Represents a top-level @racket[begin] form where each evaluation is
wrapped with a continuation prompt.
After each form in @racket[forms] is evaluated, the stack is restored
to its depth from before evaluating the form.}
@defstruct+[(mod form)
([name symbol?]
[srcname symbol?]
[self-modidx module-path-index?]
[prefix prefix?]
[provides (listof (list/c (or/c exact-integer? #f)
(listof provided?)
(listof provided?)))]
[requires (listof (cons/c (or/c exact-integer? #f)
(listof module-path-index?)))]
[body (listof (or/c form? any/c))]
[syntax-body (listof (or/c def-syntaxes? def-for-syntax?))]
[unexported (list/c (listof symbol?)
(listof symbol?)
(listof symbol?))]
[max-let-depth exact-nonnegative-integer?]
[dummy toplevel?]
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
[internal-context (or/c #f #t stx?)])]{
Represents a @racket[module] declaration. The @racket[body] forms use
@racket[prefix], rather than any prefix in place for the module
declaration itself (and each @racket[syntax-body] has its own prefix).
The @racket[provides] and @racket[requires] lists are each an
association list from phases to exports or imports. In the case of
@racket[provides], each phase maps to two lists: one for exported
variables, and another for exported syntax. In the case of
@racket[requires], each phase maps to a list of imported module paths.
The @racket[body] field contains the module's run-time code, and
@racket[syntax-body] contains the module's compile-time code. After
each form in @racket[body] or @racket[syntax-body] is evaluated, the
stack is restored to its depth from before evaluating the form.
The @racket[unexported] list contains lists of symbols for unexported
definitions that can be accessed through macro expansion. The first
list is phase-0 variables, the second is phase-0 syntax, and the last
is phase-1 variables.
The @racket[max-let-depth] field indicates the maximum stack depth
created by @racket[body] forms (not counting the @racket[prefix]
array). The @racket[dummy] variable is used to access to the
top-level namespace.
The @racket[lang-info] value specifies an optional module path that
provides information about the module's implementation language.
The @racket[internal-module-context] value describes the lexical
context of the body of the module. This value is used by
@racket[module->namespace]. A @racket[#f] value means that the
context is unavailable or empty. A @racket[#t] value means that the
context is computed by re-importing all required modules. A
syntax-object value embeds an arbitrary lexical context.}
@defstruct+[provided
([name symbol?]
[src (or/c module-path-index? #f)]
[src-name symbol?]
[nom-mod (or/c module-path-index? #f)]
[src-phase (or/c 0 1)]
[protected? boolean?]
[insp (or #t #f void?)])]{
Describes an individual provided identifier within a @racket[mod]
instance.}
@; --------------------------------------------------
@section{Expressions}
@defstruct+[(expr form) ()]{
A supertype for all expression forms that can appear in compiled code,
except for literals that are represented as themselves and some
@racket[seq] structures (which can appear as an expression as long as
it contains only other things that can be expressions).}
@defstruct+[(lam expr)
([name (or/c symbol? vector?)]
[flags (listof (or/c 'preserves-marks 'is-method 'single-result
'only-rest-arg-not-used 'sfs-clear-rest-args))]
[num-params exact-nonnegative-integer?]
[param-types (listof (or/c 'val 'ref 'flonum))]
[rest? boolean?]
[closure-map (vectorof exact-nonnegative-integer?)]
[closure-types (listof (or/c 'val/ref 'flonum))]
[toplevel-map (or/c #f (set/c exact-nonnegative-integer?))]
[max-let-depth exact-nonnegative-integer?]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[lambda] form. The @racket[name] field is a name
for debugging purposes. The @racket[num-params] field indicates the
number of arguments accepted by the procedure, not counting a rest
argument; the @racket[rest?] field indicates whether extra arguments
are accepted and collected into a ``rest'' variable. The
@racket[param-types] list contains @racket[num-params] symbols
indicating the type of each argumet, either @racket['val] for a normal
argument, @racket['ref] for a boxed argument (representing a mutable
local variable), or @racket['flonum] for a flonum argument.
The
@racket[closure-map] field is a vector of stack positions that are
captured when evaluating the @racket[lambda] form to create a closure.
The @racket[closure-types] field provides a corresponding list of
types, but no distinction is made between normal values and boxed
values; also, this information is redundant, since it can be inferred
by the bindings referenced though @racket[closure-map].
Which a closure captures top-level or module-level variables, they
are represented in the closure by capturing a prefix (in the sense
of @racket[prefix]). The @racket[toplevel-map] field indicates
which top-level and lifted variables are actually used by the
closure (so that variables in a prefix can be pruned by the run-time
system if they become unused). A @racket[#f] value indicates either
that no prefix is captured or all variables in the prefix should be
considered used. Otherwise, numbers in the set indicate which
variables and lifted variables are used. Variables are numbered
consecutively by position in the prefix starting from
@racket[0]. Lifted variables are numbered immediately
afterward---which means that, if the prefix contains any syntax
objects, lifted-variable numbers are shifted down relative to a
@racket[toplevel] by the number of syntax object in the prefix plus
one (which makes the @racket[toplevel-map] set more compact).
When the function is called, the rest-argument list (if any) is pushed
onto the stack, then the normal arguments in reverse order, then the
closure-captured values in reverse order. Thus, when @racket[body] is
run, the first value on the stack is the first value captured by the
@racket[closure-map] array, and so on.
The @racket[max-let-depth] field indicates the maximum stack depth
created by @racket[body] plus the arguments and closure-captured
values pushed onto the stack. The @racket[body] field is the
expression for the closure's body.}
@defstruct+[(closure expr)
([code lam?] [gen-id symbol?])]{
A @racket[lambda] form with an empty closure, which is a procedure
constant. The procedure constant can appear multiple times in the
graph of expressions for bytecode, and the @racket[code] field can be
a cycle for a recursive constant procedure; the @racket[gen-id] is
different for each such constant.}
@defstruct+[(case-lam expr) ([name (or/c symbol? vector?)]
[clauses (listof lam?)])]{
Represents a @racket[case-lambda] form as a combination of
@racket[lambda] forms that are tried (in order) based on the number of
arguments given.}
@defstruct+[(let-one expr)
([rhs (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)]
[flonum? boolean?]
[unused? boolean?])]{
Pushes an uninitialized slot onto the stack, evaluates @racket[rhs]
and puts its value into the slot, and then runs @racket[body]. If
@racket[flonum?] is @racket[#t], then @racket[rhs] must produce a
flonum, and the slot must be accessed by @racket[localref]s that
expect a flonum. If @racket[unused?] is @racket[#t], then the slot
must not be used, and the value of @racket[rhs] is not actually pushed
onto the stack (but @racket[rhs] is constrained to produce a single
value).
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs]. Note that the new slot is
created before evaluating @racket[rhs].}
@defstruct+[(let-void expr)
([count exact-nonnegative-integer?]
[boxes? boolean?]
[body (or/c expr? seq? any/c)])]{
Pushes @racket[count] uninitialized slots onto the stack and then runs
@racket[body]. If @racket[boxes?] is @racket[#t], then the slots are
filled with boxes that contain @|undefined-const|.}
@defstruct+[(install-value expr)
([count exact-nonnegative-integer?]
[pos exact-nonnegative-integer?]
[boxes? boolean?]
[rhs (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)])]{
Runs @racket[rhs] to obtain @racket[count] results, and installs them
into existing slots on the stack in order, skipping the first
@racket[pos] stack positions. If @racket[boxes?] is @racket[#t], then
the values are put into existing boxes in the stack slots.
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs].}
@defstruct+[(let-rec expr) ([procs (listof lam?)]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[letrec] form with @racket[lambda] bindings. It
allocates a closure shell for each @racket[lambda] form in
@racket[procs], installs each onto the stack in previously allocated
slots in reverse order (so that the closure shell for the last element
of @racket[procs] is installed at stack position @racket[0]), fills
out each shell's closure (where each closure normally references some
other just-created closures, which is possible because the shells have
been installed on the stack), and then evaluates @racket[body].}
@defstruct+[(boxenv expr)
([pos exact-nonnegative-integer?]
[body (or/c expr? seq? any/c)])]{
Skips @racket[pos] elements of the stack, setting the slot afterward
to a new box containing the slot's old value, and then runs
@racket[body]. This form appears when a @racket[lambda] argument is
mutated using @racket[set!] within its body; calling the function
initially pushes the value directly on the stack, and this form boxes
the value so that it can be mutated later.}
@defstruct+[(localref expr)
([unbox? boolean?]
[pos exact-nonnegative-integer?]
[clear? boolean?]
[other-clears? boolean?]
[flonum? boolean?])]{
Represents a local-variable reference; it accesses the value in the
stack slot after the first @racket[pos] slots. If @racket[unbox?] is
@racket[#t], the stack slot contains a box, and a value is extracted
from the box. If @racket[clear?] is @racket[#t], then after the value
is obtained, the stack slot is cleared (to avoid retaining a reference
that can prevent reclamation of the value as garbage). If
@racket[other-clears?] is @racket[#t], then some later reference to
the same stack slot may clear after reading. If @racket[flonum?] is
@racket[#t], the slot holds to a flonum value.}
@defstruct+[(toplevel expr)
([depth exact-nonnegative-integer?]
[pos exact-nonnegative-integer?]
[const? boolean?]
[ready? boolean?])]{
Represents a reference to a top-level or imported variable via the
@racket[prefix] array. The @racket[depth] field indicates the number
of stack slots to skip to reach the prefix array, and @racket[pos] is
the offset into the array.
If @racket[const?] is @racket[#t], then the variable definitely will
be defined, and its value stays constant. If @racket[ready?] is
@racket[#t], then the variable definitely will be defined (but its
value might change in the future). If @racket[const?] and
@racket[ready?] are both @racket[#f], then a check is needed to
determine whether the variable is defined.}
@defstruct+[(topsyntax expr)
([depth exact-nonnegative-integer?]
[pos exact-nonnegative-integer?]
[midpt exact-nonnegative-integer?])]{
Represents a reference to a quoted syntax object via the
@racket[prefix] array. The @racket[depth] field indicates the number
of stack slots to skip to reach the prefix array, and @racket[pos] is
the offset into the array. The @racket[midpt] value is used
internally for lazy calculation of syntax information.}
@defstruct+[(application expr)
([rator (or/c expr? seq? any/c)]
[rands (listof (or/c expr? seq? any/c))])]{
Represents a function call. The @racket[rator] field is the
expression for the function, and @racket[rands] are the argument
expressions. Before any of the expressions are evaluated,
@racket[(length rands)] uninitialized stack slots are created (to be
used as temporary space).}
@defstruct+[(branch expr)
([test (or/c expr? seq? any/c)]
[then (or/c expr? seq? any/c)]
[else (or/c expr? seq? any/c)])]{
Represents an @racket[if] form.
After @racket[test] is evaluated, the stack is restored to its depth
from before evaluating @racket[test].}
@defstruct+[(with-cont-mark expr)
([key (or/c expr? seq? any/c)]
[val (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[with-continuation-mark] expression.
After each of @racket[key] and @racket[val] is evaluated, the stack is
restored to its depth from before evaluating @racket[key] or
@racket[val].}
@defstruct+[(beg0 expr) ([seq (listof (or/c expr? seq? any/c))])]{
Represents a @racket[begin0] expression.
After each expression in @racket[seq] is evaluated, the stack is
restored to its depth from before evaluating the expression.}
@defstruct+[(varref expr) ([toplevel toplevel?])]{
Represents a @racket[#%variable-reference] form.}
@defstruct+[(assign expr)
([id toplevel?]
[rhs (or/c expr? seq? any/c)]
[undef-ok? boolean?])]{
Represents a @racket[set!] expression that assigns to a top-level or
module-level variable. (Assignments to local variables are represented
by @racket[install-value] expressions.)
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs].}
@defstruct+[(apply-values expr)
([proc (or/c expr? seq? any/c)]
[args-expr (or/c expr? seq? any/c)])]{
Represents @racket[(call-with-values (lambda () args-expr) proc)],
which is handled specially by the run-time system.}
@defstruct+[(primval expr)
([id exact-nonnegative-integer?])]{
Represents a direct reference to a variable imported from the run-time
kernel.}
@; --------------------------------------------------
@section{Syntax Objects}
@defstruct+[(wrapped zo)
([datum any/c]
[wraps (listof wrap?)]
[certs (or/c certificate? #f)])]{
Represents a syntax object, where @racket[wraps] contain the lexical
information and @racket[certs] is certificate information. When the
@racket[datum] part is itself compound, its pieces are wrapped, too.}
@defstruct+[(certificate zo) ()]{
A supertype for syntax certificates.}
@defstruct+[(certificate:nest certificate)
([nested (listof number? module-path-index? ...)]
[map (listof number? module-path-index? ...)])]{
A nested certificate.}
@defstruct+[(certificate:ref certificate)
([val any/c]
[map (listof number? module-path-index? ...)])]{
A reference certificate.}
@defstruct+[(certificate:plain certificate)
([map (listof number? module-path-index? ...)])]{
A plain certificate.}
@defstruct+[(wrap zo) ()]{
A supertype for lexical-information elements.}
@defstruct+[(top-level-rename wrap) ([flag boolean?])]{
A top-level renaming.}
@defstruct+[(mark-barrier wrap) ([value symbol?])]{
A mark barrier.}
@defstruct+[(free-id-info zo)
([path0 module-path-index?]
[symbol0 symbol?]
[path1 module-path-index?]
[symbol1 symbol?]
[phase0 (or/c exact-integer? #f)]
[phase1 (or/c exact-integer? #f)]
[phase2 (or/c exact-integer? #f)]
[use-current-inspector? boolean?])]{
Information about a free identifier.}
@defstruct+[(lexical-rename wrap)
([has-free-id-info? boolean?]
[bool2 boolean?]
[alist
(listof
(cons/c symbol?
(or/c symbol?
(cons/c symbol?
(or/c (cons/c symbol? (or/c symbol? #f))
free-id-info?)))))])]{
A local-binding mapping from symbols to binding-set names.}
@defstruct+[(phase-shift wrap)
([amt exact-integer?]
[src module-path-index?]
[dest module-path-index?])]{
Shifts module bindings later in the wrap set.}
@defstruct+[(module-rename wrap)
([phase exact-integer?]
[kind (or/c 'marked 'normal)]
[set-id any/c]
[unmarshals (listof make-all-from-module?)]
[renames (listof module-binding?)]
[mark-renames any/c]
[plus-kern? boolean?])]{
Represents a set of module and import bindings.}
@defstruct+[(all-from-module zo)
([path module-path-index?]
[phase (or/c exact-integer? #f)]
[src-phase (or/c exact-integer? #f)]
[exceptions (listof (or/c symbol? number?))]
[prefix (or/c symbol? #f)])]{
Represents a set of simple imports from one module within a
@racket[module-rename].}
@defstruct+[(module-binding zo) ()]{
A supertype for module bindings.}
@defstruct+[(simple-module-binding module-binding)
([path module-path-index?])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(phased-module-binding module-binding)
([path module-path-index?]
[phase exact-integer?]
[export-name any/c]
[nominal-path nominal-path?]
[nominal-export-name any/c])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(exported-nominal-module-binding module-binding)
([path module-path-index?]
[export-name any/c]
[nominal-path nominal-path?]
[nominal-export-name any/c])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(nominal-module-binding module-binding)
([path module-path-index?]
[nominal-path nominal-path?])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(exported-module-binding module-binding)
([path module-path-index?]
[export-name any/c])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(nominal-path zo) ()]{
A supertype for nominal paths.}
@defstruct+[(simple-nominal-path nominal-path)
([value module-path-index?])]{
Represents a simple nominal path.}
@defstruct+[(imported-nominal-path nominal-path)
([value module-path-index?]
[import-phase exact-integer?])]{
Represents an imported nominal path.}
@defstruct+[(phased-nominal-path nominal-path)
([value module-path-index?]
[import-phase (or/c false/c exact-integer?)]
[phase exact-integer?])]{
Represents a phased nominal path.}

View File

@ -0,0 +1,598 @@
#lang scribble/doc
@(require scribble/manual
(for-label racket/base
racket/contract
compiler/zo-structs
compiler/zo-parse
compiler/zo-marshal
compiler/decompile
racket/set))
@(define-syntax-rule (defstruct+ id fields . rest)
(defstruct id fields #:prefab . rest))
@title{Bytecode Representation}
@defmodule[compiler/zo-structs]
The @racketmodname[compiler/zo-structs] library defines the bytecode
structures that are produced by @racket[zo-parse] and consumed by
@racket[decompile] and @racket[zo-marshal].
@defstruct+[zo ()]{
A supertype for all forms that can appear in compiled code.}
@; --------------------------------------------------
@section{Prefix}
@defstruct+[(compilation-top zo)
([max-let-depth exact-nonnegative-integer?]
[prefix prefix?]
[code (or/c form? any/c)])]{
Wraps compiled code. The @racket[max-let-depth] field indicates the
maximum stack depth that @racket[code] creates (not counting the
@racket[prefix] array). The @racket[prefix] field describes top-level
variables, module-level variables, and quoted syntax-objects accessed
by @racket[code]. The @racket[code] field contains executable code;
it is normally a @racket[form], but a literal value is represented as
itself.}
@defstruct+[(prefix zo)
([num-lifts exact-nonnegative-integer?]
[toplevels (listof (or/c #f symbol? global-bucket?
module-variable?))]
[stxs (listof stx?)])]{
Represents a ``prefix'' that is pushed onto the stack to initiate
evaluation. The prefix is an array, where buckets holding the
values for @racket[toplevels] are first, then the buckets for the
@racket[stxs], then a bucket for another array if @racket[stxs] is
non-empty, then @racket[num-lifts] extra buckets for lifted local
procedures.
In @racket[toplevels], each element is one of the following:
@itemize[
@item{a @racket[#f], which indicates a dummy variable that is used
to access the enclosing module/namespace at run time;}
@item{a symbol, which is a reference to a variable defined in the
enclosing module;}
@item{a @racket[global-bucket], which is a top-level variable (appears
only outside of modules); or}
@item{a @racket[module-variable], which indicates a variable imported
from another module.}
]
The variable buckets and syntax objects that are recorded in a prefix
are accessed by @racket[toplevel] and @racket[topsyntax] expression
forms.}
@defstruct+[(global-bucket zo) ([name symbol?])]{
Represents a top-level variable, and used only in a @racket[prefix].}
@defstruct+[(module-variable zo)
([modidx module-path-index?]
[sym symbol?]
[pos exact-integer?]
[phase (or/c 0 1)])]{
Represents a top-level variable, and used only in a @racket[prefix].
The @racket[pos] may record the variable's offset within its module,
or it can be @racket[-1] if the variable is always located by name.
The @racket[phase] indicates the phase level of the definition within
its module.}
@defstruct+[(stx zo) ([encoded wrapped?])]{
Wraps a syntax object in a @racket[prefix].}
@; --------------------------------------------------
@section{Forms}
@defstruct+[(form zo) ()]{
A supertype for all forms that can appear in compiled code (including
@racket[expr]s), except for literals that are represented as
themselves.}
@defstruct+[(def-values form)
([ids (listof toplevel?)]
[rhs (or/c expr? seq? any/c)])]{
Represents a @racket[define-values] form. Each element of
@racket[ids] will reference via the prefix either a top-level variable
or a local module variable.
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs].}
@deftogether[(
@defstruct+[(def-syntaxes form) ([ids (listof symbol?)]
[rhs (or/c expr? seq? any/c)]
[prefix prefix?]
[max-let-depth exact-nonnegative-integer?])]
@defstruct+[(def-for-syntax form)
([ids (listof toplevel?)]
[rhs (or/c expr? seq? any/c)]
[prefix prefix?]
[max-let-depth exact-nonnegative-integer?])]
)]{
Represents a @racket[define-syntaxes] or
@racket[define-values-for-syntax] form. The @racket[rhs] expression
has its own @racket[prefix], which is pushed before evaluating
@racket[rhs]; the stack is restored after obtaining the result values.
The @racket[max-let-depth] field indicates the maximum size of the
stack that will be created by @racket[rhs] (not counting
@racket[prefix]).}
@defstruct+[(req form) ([reqs stx?]
[dummy toplevel?])]{
Represents a top-level @racket[#%require] form (but not one in a
@racket[module] form) with a sequence of specifications @racket[reqs].
The @racket[dummy] variable is used to access to the top-level
namespace.}
@defstruct+[(seq form) ([forms (listof (or/c form? any/c))])]{
Represents a @racket[begin] form, either as an expression or at the
top level (though the latter is more commonly a @racket[splice] form).
When a @racket[seq] appears in an expression position, its
@racket[forms] are expressions.
After each form in @racket[forms] is evaluated, the stack is restored
to its depth from before evaluating the form.}
@defstruct+[(splice form) ([forms (listof (or/c form? any/c))])]{
Represents a top-level @racket[begin] form where each evaluation is
wrapped with a continuation prompt.
After each form in @racket[forms] is evaluated, the stack is restored
to its depth from before evaluating the form.}
@defstruct+[(mod form)
([name symbol?]
[srcname symbol?]
[self-modidx module-path-index?]
[prefix prefix?]
[provides (listof (list/c (or/c exact-integer? #f)
(listof provided?)
(listof provided?)))]
[requires (listof (cons/c (or/c exact-integer? #f)
(listof module-path-index?)))]
[body (listof (or/c form? any/c))]
[syntax-body (listof (or/c def-syntaxes? def-for-syntax?))]
[unexported (list/c (listof symbol?)
(listof symbol?)
(listof symbol?))]
[max-let-depth exact-nonnegative-integer?]
[dummy toplevel?]
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
[internal-context (or/c #f #t stx?)])]{
Represents a @racket[module] declaration. The @racket[body] forms use
@racket[prefix], rather than any prefix in place for the module
declaration itself (and each @racket[syntax-body] has its own prefix).
The @racket[provides] and @racket[requires] lists are each an
association list from phases to exports or imports. In the case of
@racket[provides], each phase maps to two lists: one for exported
variables, and another for exported syntax. In the case of
@racket[requires], each phase maps to a list of imported module paths.
The @racket[body] field contains the module's run-time code, and
@racket[syntax-body] contains the module's compile-time code. After
each form in @racket[body] or @racket[syntax-body] is evaluated, the
stack is restored to its depth from before evaluating the form.
The @racket[unexported] list contains lists of symbols for unexported
definitions that can be accessed through macro expansion. The first
list is phase-0 variables, the second is phase-0 syntax, and the last
is phase-1 variables.
The @racket[max-let-depth] field indicates the maximum stack depth
created by @racket[body] forms (not counting the @racket[prefix]
array). The @racket[dummy] variable is used to access to the
top-level namespace.
The @racket[lang-info] value specifies an optional module path that
provides information about the module's implementation language.
The @racket[internal-module-context] value describes the lexical
context of the body of the module. This value is used by
@racket[module->namespace]. A @racket[#f] value means that the
context is unavailable or empty. A @racket[#t] value means that the
context is computed by re-importing all required modules. A
syntax-object value embeds an arbitrary lexical context.}
@defstruct+[provided
([name symbol?]
[src (or/c module-path-index? #f)]
[src-name symbol?]
[nom-mod (or/c module-path-index? #f)]
[src-phase (or/c 0 1)]
[protected? boolean?]
[insp (or #t #f void?)])]{
Describes an individual provided identifier within a @racket[mod]
instance.}
@; --------------------------------------------------
@section{Expressions}
@defstruct+[(expr form) ()]{
A supertype for all expression forms that can appear in compiled code,
except for literals that are represented as themselves and some
@racket[seq] structures (which can appear as an expression as long as
it contains only other things that can be expressions).}
@defstruct+[(lam expr)
([name (or/c symbol? vector?)]
[flags (listof (or/c 'preserves-marks 'is-method 'single-result
'only-rest-arg-not-used 'sfs-clear-rest-args))]
[num-params exact-nonnegative-integer?]
[param-types (listof (or/c 'val 'ref 'flonum))]
[rest? boolean?]
[closure-map (vectorof exact-nonnegative-integer?)]
[closure-types (listof (or/c 'val/ref 'flonum))]
[toplevel-map (or/c #f (set/c exact-nonnegative-integer?))]
[max-let-depth exact-nonnegative-integer?]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[lambda] form. The @racket[name] field is a name
for debugging purposes. The @racket[num-params] field indicates the
number of arguments accepted by the procedure, not counting a rest
argument; the @racket[rest?] field indicates whether extra arguments
are accepted and collected into a ``rest'' variable. The
@racket[param-types] list contains @racket[num-params] symbols
indicating the type of each argumet, either @racket['val] for a normal
argument, @racket['ref] for a boxed argument (representing a mutable
local variable), or @racket['flonum] for a flonum argument.
The
@racket[closure-map] field is a vector of stack positions that are
captured when evaluating the @racket[lambda] form to create a closure.
The @racket[closure-types] field provides a corresponding list of
types, but no distinction is made between normal values and boxed
values; also, this information is redundant, since it can be inferred
by the bindings referenced though @racket[closure-map].
Which a closure captures top-level or module-level variables, they
are represented in the closure by capturing a prefix (in the sense
of @racket[prefix]). The @racket[toplevel-map] field indicates
which top-level and lifted variables are actually used by the
closure (so that variables in a prefix can be pruned by the run-time
system if they become unused). A @racket[#f] value indicates either
that no prefix is captured or all variables in the prefix should be
considered used. Otherwise, numbers in the set indicate which
variables and lifted variables are used. Variables are numbered
consecutively by position in the prefix starting from
@racket[0]. Lifted variables are numbered immediately
afterward---which means that, if the prefix contains any syntax
objects, lifted-variable numbers are shifted down relative to a
@racket[toplevel] by the number of syntax object in the prefix plus
one (which makes the @racket[toplevel-map] set more compact).
When the function is called, the rest-argument list (if any) is pushed
onto the stack, then the normal arguments in reverse order, then the
closure-captured values in reverse order. Thus, when @racket[body] is
run, the first value on the stack is the first value captured by the
@racket[closure-map] array, and so on.
The @racket[max-let-depth] field indicates the maximum stack depth
created by @racket[body] plus the arguments and closure-captured
values pushed onto the stack. The @racket[body] field is the
expression for the closure's body.}
@defstruct+[(closure expr)
([code lam?] [gen-id symbol?])]{
A @racket[lambda] form with an empty closure, which is a procedure
constant. The procedure constant can appear multiple times in the
graph of expressions for bytecode, and the @racket[code] field can be
a cycle for a recursive constant procedure; the @racket[gen-id] is
different for each such constant.}
@defstruct+[(case-lam expr) ([name (or/c symbol? vector?)]
[clauses (listof lam?)])]{
Represents a @racket[case-lambda] form as a combination of
@racket[lambda] forms that are tried (in order) based on the number of
arguments given.}
@defstruct+[(let-one expr)
([rhs (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)]
[flonum? boolean?]
[unused? boolean?])]{
Pushes an uninitialized slot onto the stack, evaluates @racket[rhs]
and puts its value into the slot, and then runs @racket[body]. If
@racket[flonum?] is @racket[#t], then @racket[rhs] must produce a
flonum, and the slot must be accessed by @racket[localref]s that
expect a flonum. If @racket[unused?] is @racket[#t], then the slot
must not be used, and the value of @racket[rhs] is not actually pushed
onto the stack (but @racket[rhs] is constrained to produce a single
value).
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs]. Note that the new slot is
created before evaluating @racket[rhs].}
@defstruct+[(let-void expr)
([count exact-nonnegative-integer?]
[boxes? boolean?]
[body (or/c expr? seq? any/c)])]{
Pushes @racket[count] uninitialized slots onto the stack and then runs
@racket[body]. If @racket[boxes?] is @racket[#t], then the slots are
filled with boxes that contain @|undefined-const|.}
@defstruct+[(install-value expr)
([count exact-nonnegative-integer?]
[pos exact-nonnegative-integer?]
[boxes? boolean?]
[rhs (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)])]{
Runs @racket[rhs] to obtain @racket[count] results, and installs them
into existing slots on the stack in order, skipping the first
@racket[pos] stack positions. If @racket[boxes?] is @racket[#t], then
the values are put into existing boxes in the stack slots.
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs].}
@defstruct+[(let-rec expr) ([procs (listof lam?)]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[letrec] form with @racket[lambda] bindings. It
allocates a closure shell for each @racket[lambda] form in
@racket[procs], installs each onto the stack in previously allocated
slots in reverse order (so that the closure shell for the last element
of @racket[procs] is installed at stack position @racket[0]), fills
out each shell's closure (where each closure normally references some
other just-created closures, which is possible because the shells have
been installed on the stack), and then evaluates @racket[body].}
@defstruct+[(boxenv expr)
([pos exact-nonnegative-integer?]
[body (or/c expr? seq? any/c)])]{
Skips @racket[pos] elements of the stack, setting the slot afterward
to a new box containing the slot's old value, and then runs
@racket[body]. This form appears when a @racket[lambda] argument is
mutated using @racket[set!] within its body; calling the function
initially pushes the value directly on the stack, and this form boxes
the value so that it can be mutated later.}
@defstruct+[(localref expr)
([unbox? boolean?]
[pos exact-nonnegative-integer?]
[clear? boolean?]
[other-clears? boolean?]
[flonum? boolean?])]{
Represents a local-variable reference; it accesses the value in the
stack slot after the first @racket[pos] slots. If @racket[unbox?] is
@racket[#t], the stack slot contains a box, and a value is extracted
from the box. If @racket[clear?] is @racket[#t], then after the value
is obtained, the stack slot is cleared (to avoid retaining a reference
that can prevent reclamation of the value as garbage). If
@racket[other-clears?] is @racket[#t], then some later reference to
the same stack slot may clear after reading. If @racket[flonum?] is
@racket[#t], the slot holds to a flonum value.}
@defstruct+[(toplevel expr)
([depth exact-nonnegative-integer?]
[pos exact-nonnegative-integer?]
[const? boolean?]
[ready? boolean?])]{
Represents a reference to a top-level or imported variable via the
@racket[prefix] array. The @racket[depth] field indicates the number
of stack slots to skip to reach the prefix array, and @racket[pos] is
the offset into the array.
If @racket[const?] is @racket[#t], then the variable definitely will
be defined, and its value stays constant. If @racket[ready?] is
@racket[#t], then the variable definitely will be defined (but its
value might change in the future). If @racket[const?] and
@racket[ready?] are both @racket[#f], then a check is needed to
determine whether the variable is defined.}
@defstruct+[(topsyntax expr)
([depth exact-nonnegative-integer?]
[pos exact-nonnegative-integer?]
[midpt exact-nonnegative-integer?])]{
Represents a reference to a quoted syntax object via the
@racket[prefix] array. The @racket[depth] field indicates the number
of stack slots to skip to reach the prefix array, and @racket[pos] is
the offset into the array. The @racket[midpt] value is used
internally for lazy calculation of syntax information.}
@defstruct+[(application expr)
([rator (or/c expr? seq? any/c)]
[rands (listof (or/c expr? seq? any/c))])]{
Represents a function call. The @racket[rator] field is the
expression for the function, and @racket[rands] are the argument
expressions. Before any of the expressions are evaluated,
@racket[(length rands)] uninitialized stack slots are created (to be
used as temporary space).}
@defstruct+[(branch expr)
([test (or/c expr? seq? any/c)]
[then (or/c expr? seq? any/c)]
[else (or/c expr? seq? any/c)])]{
Represents an @racket[if] form.
After @racket[test] is evaluated, the stack is restored to its depth
from before evaluating @racket[test].}
@defstruct+[(with-cont-mark expr)
([key (or/c expr? seq? any/c)]
[val (or/c expr? seq? any/c)]
[body (or/c expr? seq? any/c)])]{
Represents a @racket[with-continuation-mark] expression.
After each of @racket[key] and @racket[val] is evaluated, the stack is
restored to its depth from before evaluating @racket[key] or
@racket[val].}
@defstruct+[(beg0 expr) ([seq (listof (or/c expr? seq? any/c))])]{
Represents a @racket[begin0] expression.
After each expression in @racket[seq] is evaluated, the stack is
restored to its depth from before evaluating the expression.}
@defstruct+[(varref expr) ([toplevel toplevel?] [dummy toplevel?])]{
Represents a @racket[#%variable-reference] form. The @racket[dummy] field
accesses a variable bucket that strongly references its namespace (as
opposed to a normal variable bucket, which only weakly references its
namespace).}
@defstruct+[(assign expr)
([id toplevel?]
[rhs (or/c expr? seq? any/c)]
[undef-ok? boolean?])]{
Represents a @racket[set!] expression that assigns to a top-level or
module-level variable. (Assignments to local variables are represented
by @racket[install-value] expressions.)
After @racket[rhs] is evaluated, the stack is restored to its depth
from before evaluating @racket[rhs].}
@defstruct+[(apply-values expr)
([proc (or/c expr? seq? any/c)]
[args-expr (or/c expr? seq? any/c)])]{
Represents @racket[(call-with-values (lambda () args-expr) proc)],
which is handled specially by the run-time system.}
@defstruct+[(primval expr)
([id exact-nonnegative-integer?])]{
Represents a direct reference to a variable imported from the run-time
kernel.}
@; --------------------------------------------------
@section{Syntax Objects}
@defstruct+[(wrapped zo)
([datum any/c]
[wraps (listof wrap?)]
[certs (or/c certificate? #f)])]{
Represents a syntax object, where @racket[wraps] contain the lexical
information and @racket[certs] is certificate information. When the
@racket[datum] part is itself compound, its pieces are wrapped, too.}
@defstruct+[(certificate zo) ()]{
A supertype for syntax certificates.}
@defstruct+[(certificate:nest certificate)
([nested (listof number? module-path-index? ...)]
[map (listof number? module-path-index? ...)])]{
A nested certificate.}
@defstruct+[(certificate:ref certificate)
([val any/c]
[map (listof number? module-path-index? ...)])]{
A reference certificate.}
@defstruct+[(certificate:plain certificate)
([map (listof number? module-path-index? ...)])]{
A plain certificate.}
@defstruct+[(wrap zo) ()]{
A supertype for lexical-information elements.}
@defstruct+[(top-level-rename wrap) ([flag boolean?])]{
A top-level renaming.}
@defstruct+[(mark-barrier wrap) ([value symbol?])]{
A mark barrier.}
@defstruct+[(free-id-info zo)
([path0 module-path-index?]
[symbol0 symbol?]
[path1 module-path-index?]
[symbol1 symbol?]
[phase0 (or/c exact-integer? #f)]
[phase1 (or/c exact-integer? #f)]
[phase2 (or/c exact-integer? #f)]
[use-current-inspector? boolean?])]{
Information about a free identifier.}
@defstruct+[(lexical-rename wrap)
([has-free-id-info? boolean?]
[bool2 boolean?]
[alist
(listof
(cons/c symbol?
(or/c symbol?
(cons/c symbol?
(or/c (cons/c symbol? (or/c symbol? #f))
free-id-info?)))))])]{
A local-binding mapping from symbols to binding-set names.}
@defstruct+[(phase-shift wrap)
([amt exact-integer?]
[src module-path-index?]
[dest module-path-index?])]{
Shifts module bindings later in the wrap set.}
@defstruct+[(module-rename wrap)
([phase exact-integer?]
[kind (or/c 'marked 'normal)]
[set-id any/c]
[unmarshals (listof make-all-from-module?)]
[renames (listof module-binding?)]
[mark-renames any/c]
[plus-kern? boolean?])]{
Represents a set of module and import bindings.}
@defstruct+[(all-from-module zo)
([path module-path-index?]
[phase (or/c exact-integer? #f)]
[src-phase (or/c exact-integer? #f)]
[exceptions (listof (or/c symbol? number?))]
[prefix (or/c symbol? #f)])]{
Represents a set of simple imports from one module within a
@racket[module-rename].}
@defstruct+[(module-binding zo) ()]{
A supertype for module bindings.}
@defstruct+[(simple-module-binding module-binding)
([path module-path-index?])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(phased-module-binding module-binding)
([path module-path-index?]
[phase exact-integer?]
[export-name any/c]
[nominal-path nominal-path?]
[nominal-export-name any/c])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(exported-nominal-module-binding module-binding)
([path module-path-index?]
[export-name any/c]
[nominal-path nominal-path?]
[nominal-export-name any/c])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(nominal-module-binding module-binding)
([path module-path-index?]
[nominal-path nominal-path?])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(exported-module-binding module-binding)
([path module-path-index?]
[export-name any/c])]{
Represents a single identifier import within a
@racket[module-rename].}
@defstruct+[(nominal-path zo) ()]{
A supertype for nominal paths.}
@defstruct+[(simple-nominal-path nominal-path)
([value module-path-index?])]{
Represents a simple nominal path.}
@defstruct+[(imported-nominal-path nominal-path)
([value module-path-index?]
[import-phase exact-integer?])]{
Represents an imported nominal path.}
@defstruct+[(phased-nominal-path nominal-path)
([value module-path-index?]
[import-phase (or/c false/c exact-integer?)]
[phase exact-integer?])]{
Represents a phased nominal path.}