fix varref' in
compiler/zo-structs', etc.
and sync docs better with implementation
This commit is contained in:
parent
553d9ff4c6
commit
a4da2a3f4c
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
||||||
|
|
|
@ -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.}
|
|
||||||
|
|
598
collects/scribblings/raco/zo-struct.scrbl
Normal file
598
collects/scribblings/raco/zo-struct.scrbl
Normal 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.}
|
Loading…
Reference in New Issue
Block a user