document compiler/zo-parse and compiler/decompile

svn: r12947
This commit is contained in:
Matthew Flatt 2008-12-28 18:57:13 +00:00
parent 0cd2537a82
commit 7aec6b8761
6 changed files with 543 additions and 57 deletions

View File

@ -23,7 +23,7 @@
(close-output-port out) (close-output-port out)
in)))]) in)))])
(let ([n (match v (let ([n (match v
[(struct compilation-top (_ prefix (struct primitive (n)))) n] [(struct compilation-top (_ prefix (struct primval (n)))) n]
[else #f])]) [else #f])])
(hash-set! table n (car b))))) (hash-set! table n (car b)))))
table)) table))
@ -77,7 +77,7 @@
lift-ids) lift-ids)
(map (lambda (stx id) (map (lambda (stx id)
`(define ,id ,(if stx `(define ,id ,(if stx
`(#%decode-syntax ,stx #;(stx-encoded stx)) `(#%decode-syntax ,(stx-encoded stx))
#f))) #f)))
stxs stx-ids)))] stxs stx-ids)))]
[else (error 'decompile-prefix "huh?: ~e" a-prefix)])) [else (error 'decompile-prefix "huh?: ~e" a-prefix)]))
@ -126,7 +126,7 @@
`(let () `(let ()
,@defns ,@defns
,(decompile-expr rhs globs '(#%globals) closed))))] ,(decompile-expr rhs globs '(#%globals) closed))))]
[(struct sequence (forms)) [(struct seq (forms))
`(begin ,@(map (lambda (form) `(begin ,@(map (lambda (form)
(decompile-form form globs stack closed)) (decompile-form form globs stack closed))
forms))] forms))]
@ -179,7 +179,7 @@
`(#%checked ,id)))] `(#%checked ,id)))]
[(struct topsyntax (depth pos midpt)) [(struct topsyntax (depth pos midpt))
(list-ref/protect globs (+ midpt pos) 'topsyntax)] (list-ref/protect globs (+ midpt pos) 'topsyntax)]
[(struct primitive (id)) [(struct primval (id))
(hash-ref primitive-table id)] (hash-ref primitive-table id)]
[(struct assign (id rhs undef-ok?)) [(struct assign (id rhs undef-ok?))
`(set! ,(decompile-expr id globs stack closed) `(set! ,(decompile-expr id globs stack closed)
@ -249,7 +249,7 @@
[(struct apply-values (proc args-expr)) [(struct apply-values (proc args-expr))
`(#%apply-values ,(decompile-expr proc globs stack closed) `(#%apply-values ,(decompile-expr proc globs stack closed)
,(decompile-expr args-expr globs stack closed))] ,(decompile-expr args-expr globs stack closed))]
[(struct sequence (exprs)) [(struct seq (exprs))
`(begin ,@(for/list ([expr (in-list exprs)]) `(begin ,@(for/list ([expr (in-list exprs)])
(decompile-expr expr globs stack closed)))] (decompile-expr expr globs stack closed)))]
[(struct beg0 (exprs)) [(struct beg0 (exprs))

View File

@ -7,11 +7,18 @@
;; ---------------------------------------- ;; ----------------------------------------
;; Structures to represent bytecode ;; Structures to represent bytecode
(define-syntax-rule (define-form-struct id (field-id ...)) (define-syntax-rule (define-form-struct* id id+par (field-id ...))
(begin (begin
(define-struct id (field-id ...) #:transparent) (define-struct id+par (field-id ...) #:transparent)
(provide (struct-out id)))) (provide (struct-out id))))
(define-syntax define-form-struct
(syntax-rules ()
[(_ (id sup) . rest)
(define-form-struct* id (id sup) . rest)]
[(_ id . rest)
(define-form-struct* id id . rest)]))
(define-form-struct compilation-top (max-let-depth prefix code)) ; compiled code always wrapped with this (define-form-struct compilation-top (max-let-depth prefix code)) ; compiled code always wrapped with this
(define-form-struct prefix (num-lifts toplevels stxs)) ; sets up top-level and syntax-object array (define-form-struct prefix (num-lifts toplevels stxs)) ; sets up top-level and syntax-object array
@ -21,43 +28,46 @@
(define-form-struct module-variable (modidx sym pos phase)) ; direct access to exported id (define-form-struct module-variable (modidx sym pos phase)) ; direct access to exported id
;; In stxs of prefix: ;; In stxs of prefix:
(define-form-struct stx (encoded)) ; todo: decode syntax objects (define-form-struct stx (encoded))
(define-form-struct mod (name self-modidx prefix provides requires body syntax-body max-let-depth)) (define-form-struct form ())
(define-form-struct (expr form) ())
(define-form-struct lam (name flags num-params rest? closure-map max-let-depth body)) ; `lambda' (define-form-struct (mod form) (name self-modidx prefix provides requires body syntax-body max-let-depth))
(define-form-struct closure (code gen-id)) ; a static closure (nothing to close over)
(define-form-struct case-lam (name clauses)) ; each clause is an lam
(define-form-struct let-one (rhs body)) ; pushes one value onto stack (define-form-struct (lam expr) (name flags num-params rest? closure-map max-let-depth body)) ; `lambda'
(define-form-struct let-void (count boxes? body)) ; create new stack slots (define-form-struct (closure expr) (code gen-id)) ; a static closure (nothing to close over)
(define-form-struct install-value (count pos boxes? rhs body)) ; set existing stack slot(s) (define-form-struct (case-lam expr) (name clauses)) ; each clause is an lam
(define-form-struct let-rec (procs body)) ; put `letrec'-bound closures into existing stack slots
(define-form-struct boxenv (pos body)) ; box existing stack element
(define-form-struct localref (unbox? offset clear?)) ; access local via stack (define-form-struct (let-one expr) (rhs body)) ; pushes one value onto stack
(define-form-struct (let-void expr) (count boxes? body)) ; create new stack slots
(define-form-struct (install-value expr) (count pos boxes? rhs body)) ; set existing stack slot(s)
(define-form-struct (let-rec expr) (procs body)) ; put `letrec'-bound closures into existing stack slots
(define-form-struct (boxenv expr) (pos body)) ; box existing stack element
(define-form-struct toplevel (depth pos const? ready?)) ; access binding via prefix array (which is on stack) (define-form-struct (localref expr) (unbox? pos clear?)) ; access local via stack
(define-form-struct topsyntax (depth pos midpt)) ; access syntax object via prefix array (which is on stack)
(define-form-struct application (rator rands)) ; function call (define-form-struct (toplevel expr) (depth pos const? ready?)) ; access binding via prefix array (which is on stack)
(define-form-struct branch (test then else)) ; `if' (define-form-struct (topsyntax expr) (depth pos midpt)) ; access syntax object via prefix array (which is on stack)
(define-form-struct with-cont-mark (key val body)) ; `with-continuation-mark'
(define-form-struct beg0 (seq)) ; `begin0' (define-form-struct (application expr) (rator rands)) ; function call
(define-form-struct sequence (forms)) ; `begin' (define-form-struct (branch expr) (test then else)) ; `if'
(define-form-struct splice (forms)) ; top-level `begin' (define-form-struct (with-cont-mark expr) (key val body)) ; `with-continuation-mark'
(define-form-struct varref (toplevel)) ; `#%variable-reference' (define-form-struct (beg0 expr) (seq)) ; `begin0'
(define-form-struct assign (id rhs undef-ok?)) ; top-level or module-level set! (define-form-struct (seq form) (forms)) ; `begin'
(define-form-struct apply-values (proc args-expr)) ; `(call-with-values (lambda () ,args-expr) ,proc) (define-form-struct (splice form) (forms)) ; top-level `begin'
(define-form-struct primitive (id)) ; direct preference to a kernel primitive (define-form-struct (varref expr) (toplevel)) ; `#%variable-reference'
(define-form-struct (assign expr) (id rhs undef-ok?)) ; top-level or module-level set!
(define-form-struct (apply-values expr) (proc args-expr)) ; `(call-with-values (lambda () ,args-expr) ,proc)
(define-form-struct (primval expr) (id)) ; direct preference to a kernel primitive
;; Definitions (top level or within module): ;; Definitions (top level or within module):
(define-form-struct def-values (ids rhs)) (define-form-struct (def-values form) (ids rhs))
(define-form-struct def-syntaxes (ids rhs prefix max-let-depth)) (define-form-struct (def-syntaxes form) (ids rhs prefix max-let-depth))
(define-form-struct def-for-syntax (ids rhs prefix max-let-depth)) (define-form-struct (def-for-syntax form) (ids rhs prefix max-let-depth))
;; Top-level `require' ;; Top-level `require'
(define-form-struct req (reqs dummy)) (define-form-struct (req form) (reqs dummy))
;; A static closure can refer directly to itself, creating a cycle ;; A static closure can refer directly to itself, creating a cycle
(define-struct indirect ([v #:mutable]) #:prefab) (define-struct indirect ([v #:mutable]) #:prefab)
@ -145,7 +155,7 @@
(make-with-cont-mark key val body)])) (make-with-cont-mark key val body)]))
(define (read-sequence v) (define (read-sequence v)
(make-sequence v)) (make-seq v))
(define (read-define-values v) (define (read-define-values v)
(make-def-values (make-def-values
@ -173,7 +183,7 @@
(define (read-begin0 v) (define (read-begin0 v)
(match v (match v
[(struct sequence (exprs)) [(struct seq (exprs))
(make-beg0 exprs)])) (make-beg0 exprs)]))
(define (read-boxenv v) (define (read-boxenv v)
@ -429,9 +439,12 @@
;; Synatx unmarshaling ;; Synatx unmarshaling
(define-form-struct wrapped (datum wraps certs)) (define-form-struct wrapped (datum wraps certs))
(define-form-struct lexical-rename (alist))
(define-form-struct phase-shift (amt src dest)) (define-form-struct wrap ())
(define-form-struct module-rename (phase kind set-id unmarshals renames mark-renames plus-kern?)) (define-form-struct (lexical-rename wrap) (alist))
(define-form-struct (phase-shift wrap) (amt src dest))
(define-form-struct (module-rename wrap) (phase kind set-id unmarshals renames mark-renames plus-kern?))
(define-form-struct all-from-module (path phase src-phase exceptions prefix)) (define-form-struct all-from-module (path phase src-phase exceptions prefix))
(define-form-struct module-binding (path mod-phase import-phase id nominal-path nominal-phase nominal-id)) (define-form-struct module-binding (path mod-phase import-phase id nominal-path nominal-phase nominal-id))
@ -696,7 +709,7 @@
[read-accept-quasiquote #t]) [read-accept-quasiquote #t])
(read (open-input-bytes s))))] (read (open-input-bytes s))))]
[(reference) [(reference)
(make-primitive (read-compact-number cp))] (make-primval (read-compact-number cp))]
[(small-list small-proper-list) [(small-list small-proper-list)
(let* ([l (- ch cpt-start)] (let* ([l (- ch cpt-start)]
[ppr (eq? cpt-tag 'small-proper-list)]) [ppr (eq? cpt-tag 'small-proper-list)])

View File

@ -486,29 +486,33 @@
(define-syntax defstruct (define-syntax defstruct
(syntax-rules () (syntax-rules ()
[(_ name fields #:mutable #:inspector #f desc ...) [(_ name fields #:mutable #:inspector #f desc ...)
(**defstruct name fields #f #t desc ...)] (**defstruct name fields #f #t #f desc ...)]
[(_ name fields #:mutable #:transparent desc ...) [(_ name fields #:mutable #:transparent desc ...)
(**defstruct name fields #f #t desc ...)] (**defstruct name fields #f #t #f desc ...)]
[(_ name fields #:mutable #:prefab desc ...)
(**defstruct name fields #f #t #t desc ...)]
[(_ name fields #:mutable desc ...) [(_ name fields #:mutable desc ...)
(**defstruct name fields #f #f desc ...)] (**defstruct name fields #f #f #f desc ...)]
[(_ name fields #:inspector #f desc ...) [(_ name fields #:inspector #f desc ...)
(**defstruct name fields #t #t desc ...)] (**defstruct name fields #t #t #f desc ...)]
[(_ name fields #:transparent desc ...) [(_ name fields #:transparent desc ...)
(**defstruct name fields #t #t desc ...)] (**defstruct name fields #t #t #f desc ...)]
[(_ name fields #:prefab desc ...)
(**defstruct name fields #t #t #t desc ...)]
[(_ name fields desc ...) [(_ name fields desc ...)
(**defstruct name fields #t #f desc ...)])) (**defstruct name fields #t #f #f desc ...)]))
(define-syntax-rule (**defstruct name ([field field-contract] ...) immutable? (define-syntax-rule (**defstruct name ([field field-contract] ...) immutable?
transparent? desc ...) transparent? prefab? desc ...)
(with-togetherable-scheme-variables (with-togetherable-scheme-variables
() ()
() ()
(*defstruct (quote-syntax/loc name) 'name (*defstruct (quote-syntax/loc name) 'name
'([field field-contract] ...) '([field field-contract] ...)
(list (lambda () (schemeblock0 field-contract)) ...) (list (lambda () (schemeblock0 field-contract)) ...)
immutable? transparent? (lambda () (list desc ...))))) immutable? transparent? prefab? (lambda () (list desc ...)))))
(define (*defstruct stx-id name fields field-contracts immutable? transparent? (define (*defstruct stx-id name fields field-contracts immutable? transparent? prefab?
content-thunk) content-thunk)
(define (field-name f) ((if (pair? (car f)) caar car) f)) (define (field-name f) ((if (pair? (car f)) caar car) f))
(define (field-view f) (define (field-view f)
@ -634,7 +638,9 @@
(list flow-spacer flow-spacer (list flow-spacer flow-spacer
(to-flow (make-element (to-flow (make-element
#f #f
(list (to-element '#:transparent) (list (if prefab?
(to-element '#:prefab)
(to-element '#:transparent))
(schemeparenfont ")")))) (schemeparenfont ")"))))
'cont 'cont
'cont))] 'cont))]
@ -652,7 +658,9 @@
(list flow-spacer flow-spacer (list flow-spacer flow-spacer
(to-flow (make-element (to-flow (make-element
#f #f
(list (to-element '#:transparent) (list (if prefab?
(to-element '#:prefab)
(to-element '#:transparent))
(schemeparenfont ")")))) (schemeparenfont ")"))))
'cont 'cont
'cont))] 'cont))]

View File

@ -1,7 +1,9 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual @(require scribble/manual
"common.ss" "common.ss"
(for-label scheme/base)) (for-label scheme/base
compiler/decompile
(only-in compiler/zo-parse compilation-top?)))
@title[#:tag "decompile"]{Decompiling Bytecode} @title[#:tag "decompile"]{Decompiling Bytecode}
@ -84,3 +86,18 @@ Many forms in the decompiled code, such as @scheme[module],
syntax objects to a readable form.} syntax objects to a readable form.}
] ]
@; ------------------------------------------------------------
@section{Scheme API for Decompiling}
@defmodule[compiler/decompile]
@defproc[(decompile [top compilation-top?]) any/c]{
Consumes the result of parsing bytecode and returns an S-expression
(as described above) that represents the compiled code.}
@; ------------------------------------------------------------
@include-section["zo-parse.scrbl"]

View File

@ -0,0 +1,448 @@
#lang scribble/doc
@(require scribble/manual
(for-label scheme/base
compiler/zo-parse))
@(define-syntax-rule (defstruct+ id fields . rest)
(defstruct id fields #:transparent . rest))
@title{Scheme API for Parsing Bytecode}
@defmodule[compiler/zo-parse]
@defproc[(zo-parse [in input-port?]) compilation-top?]{
Parses a port (typically the result of opening a @filepath{.zo} file)
containing byte. The parsed bytecode is returned in a
@scheme[compilation-top] structure.
Beware that the structure types used to represent the bytecode are
subject to frequent changes across PLT Scheme versons.}
@; --------------------------------------------------
@section{Prefix}
@defstruct+[compilation-top ([max-let-depth exact-nonnegative-integer?]
[prefix prefix?]
[code (or/c form? any/c)])]{
Wraps compiled code. The @scheme[max-let-depth] field indicates the
maximum stack depth that @scheme[code] creates (not counting the
@scheme[prefix] array). The @scheme[prefix] field contains global
variable, cross-module variable, and syntax-object literal
mappings. The @scheme[code] field contains executable code; it is
normally a @scheme[form], but a literal value is represented as
itself.}
@defstruct+[prefix ([num-lifts exact-nonnegative-integer?]
[toplevels (listof (or/c #f symbol? global-bucket? module-variable?))]
[stxs (listof stx?)])]{
Represents a closure ``prefix'' that is pushed onto the stack before
evaluating a top-level sequence. The prefix is an array, where buckets
holding the values for @scheme[toplevels] are first, then a bucket for
another array if @scheme[stxs] is non-empty, then @scheme[num-lifts]
extra buckets for lifted local procedures.
In @scheme[toplevels]:
@itemize[
@item{@scheme[#f] indicates a dummy variable that is used to access
the enclosing module/namespace at run time}
@item{a symbol is a reference to a variable defined in the enclosing
module}
@item{a @scheme[global-bucket] is a top-level variable, and it
appears only outside of modules}
@item{a @scheme[module-variable] indicates a variable imported from
another module}
]
The variable buckets and syntax objects recorded by a prefix are
accessed by @scheme[toplevel] and @scheme[topsyntax] expression forms.}
@defstruct+[global-bucket ([name symbol?])]{
Represents a top-level variable, and used only in a @scheme[prefix].}
@defstruct+[module-variable ([modidx module-path-index?]
[sym symbol?]
[pos exact-integer?]
[phase (or/c 0 1)])]{
Represents a top-level variable, and used only in a @scheme[prefix].
The @scheme[pos] may record the variable's offset within its module,
or it can be @scheme[-1] if the variable is always accessed by name.
The @scheme[phase] indicates the phase level of the definition within
it module.}
@defstruct+[stx ([encoded wrapped?])]{
Wraps a syntax object in a @scheme[prefix].}
@; --------------------------------------------------
@section{Forms}
@defstruct+[form ()]{
A supertype for all forms that can appear in compiled code, except for
literals that are represented as themselves.}
@defstruct+[(def-values form) ([ids (listof toplevel?)]
[rhs (or/c expr? seq? indirect? any/c)])]{
Represents a @scheme[define-values] form.
After @scheme[rhs] is evaluated, the stack is restored to its depth
from before evaluating @scheme[rhs].}
@deftogether[(
@defstruct+[(def-syntaxes form) ([ids (listof toplevel?)]
[rhs (or/c expr? seq? indirect? any/c)]
[prefix prefix?]
[max-let-depth nonnegative-exact-integer?])]
@defstruct+[(def-for-syntax form) ([ids (listof toplevel?)]
[rhs (or/c expr? seq? indirect? any/c)]
[prefix prefix?]
[max-let-depth nonnegative-exact-integer?])]
)]{
Represents a @scheme[define-syntaxes] or
@scheme[define-values-for-syntax] form. The @scheme[rhs] expression
has its own @scheme[prefix], which is pushed before evaluating
@scheme[rhs]; the stack is restored after obtaining the result
values.}
@defstruct+[(req form) ([reqs (listof module-path?)]
[dummy toplevel?])]{
Represents a top-level @scheme[require] form (but not one in a
@scheme[module] form). The @scheme[dummy] variable is used to access
to the top-level namespace.}
@defstruct+[(mod form) ([name symbol?]
[self-modidx module-path-index?]
[prefix prefix?]
[provides (listof symbol?)]
[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?))]
[max-let-depth exact-nonnegative-integer?])]{
Represents a @scheme[module] declaration. The @scheme[body] forms use
@scheme[prefix], rather than any prefix in place for the module
declaration itself (and each @scheme[syntax-body] has its own
prefix). The @scheme[body] field contains the module's run-time code,
and @scheme[syntax-body] contains the module's compile-time code. The
@scheme[max-let-depth] field indicates the maximum stack depth created
by @scheme[body] forms (not counting the @scheme[prefix] array).}
@defstruct+[(seq form) ([forms (listof (or/c form? any/c))])]{
Represents a @scheme[begin] form, either as an expression or at the
top level (though the latter is more commonly a @scheme[splice] form).
When a @scheme[seq] appears in an expression position, its
@scheme[forms] are expressions.
After each form in @scheme[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 @scheme[begin] form where each evaluation is
wrapped with a continuation prompt.
After each form in @scheme[forms] is evaluated, the stack is restored
to its depth from before evaluating the form.}
@; --------------------------------------------------
@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 except for
@scheme[seq] (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 exact-integer?]
[num-params exact-nonnegative-integer?]
[rest? boolean?]
[closure-map (vectorof exact-nonnegative-integer?)]
[max-let-depth exact-nonnegative-integer?]
[body (or/c expr? seq? indirect? any/c)])]{
Represents a @scheme[lambda] form. The @scheme[name] field is a name
for debugging purposes. The @scheme[num-params] field indicates the
number of argumets accepted by the procedure, not counting a rest
argument; the @scheme[rest?] field indicates whether extra arguments
are accepted and collected into a ``rest'' variable. The
@scheme[closure-map] field is a vector of stack positions that are
captured when evaluating the @scheme[lambda] form to create a closure.
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 @scheme[body] is
run, the first value on the stack is the first value captured by the
@scheme[closure-map] array, and so on.
The @scheme[max-let-depth] field indicates the maximum stack depth
created by @scheme[body] (not including arguments and closure-captured
values pushed onto the stack). The @scheme[body] field is the
expression for the closure's body.}
@defstruct+[(closure expr) ([code lam?] [gen-id symbol?])]{
A @scheme[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 @scheme[code] field can
refer back to the same @scheme[closure] through an @scheme[indirect]
for a recursive constant procedure; the @scheme[gen-id] is different
for each such constant.}
@defstruct[indirect ([v closure?]) #:mutable #:prefab]{
An indirection used in expression positions to form cycles.}
@defstruct+[(case-lam expr) ([name (or/c symbol? vector?)]
[clauses (listof lam?)])]{
Represents a @scheme[case-lambda] form as a combination of
@scheme[lambda] forms that are tried (in order) based on the number of
arguments given.}
@defstruct+[(let-one expr) ([rhs (or/c expr? seq? indirect? any/c)]
[body (or/c expr? seq? indirect? any/c)])]{
Pushes an uninitialized slot onto the stack, evaluates @scheme[rhs]
and puts its value into the slot, and then runs @scheme[body].
After @scheme[rhs] is evaluated, the stack is restored to its depth
from before evaluating @scheme[rhs]. Note that the new slot is created
before evaluating @scheme[rhs].}
@defstruct+[(let-void expr) ([count nonnegative-exact-integer?]
[boxes? boolean?]
[body (or/c expr? seq? indirect? any/c)])]{
Pushes @scheme[count] uninitialized slots onto the stack and then runs
@scheme[body]. If @scheme[boxes?] is @scheme[#t], then the slots are
filled with boxes that contain @|undefined-const|.}
@defstruct+[(install-value expr) ([count nonnegative-exact-integer?]
[pos nonnegative-exact-integer?]
[boxes? boolean?]
[rhs (or/c expr? seq? indirect? any/c)]
[body (or/c expr? seq? indirect? any/c)])]{
Runs @scheme[rhs] to obtain @scheme[count] results, and installs them
into existing slots on the stack in order, skipping the first
@scheme[pos] stack positions. If @scheme[boxes?] is @scheme[#t], then
the values are put into existing boxes in the stack slots.
After @scheme[rhs] is evaluated, the stack is restored to its depth
from before evaluating @scheme[rhs].}
@defstruct+[(let-rec expr) ([procs (listof lam?)]
[body (or/c expr? seq? indirect? any/c)])]{
Represents a @scheme[letrec] form with @scheme[lambda] bindings. It
allocates a closure shell for each @scheme[lambda] form in
@scheme[procs], pushes them onto the stack in reverse order, fills out
each shell's closure using the created shells, and then evaluates
@scheme[body].}
@defstruct+[(boxenv expr) ([pos nonnegative-exact-integer?]
[body (or/c expr? seq? indirect? any/c)])]{
Sets the stack slot @scheme[pos] elements deep into the stack to a new
box containing the slot's old value. This form appears when a
@scheme[lambda] argument is mutated using @scheme[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 nonnegative-exact-integer?]
[clear? boolean?])]{
Represents a local-variable reference; access the value in the stack
slot skipping the first @scheme[pos] slots. If @scheme[unbox?] is
@scheme[#t], the stack slot contains a box, and a value is extracted
from the box. If @scheme[clear?] is @scheme[#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).}
@defstruct+[(toplevel expr) ([depth nonnegative-exact-integer?]
[pos nonnegative-exact-integer?]
[const? boolean?]
[ready? boolean?])]{
Represents a reference to a top-level or imported variable via the
@scheme[prefix] array. The @scheme[depth] field indicates the number
of stack slots to skip to reach the prefix array, and @scheme[pos] is
the offset into the array. If @scheme[const?] is @scheme[#t], then the
variable will definitely have a value and the value stays constant. If
@scheme[ready?] is @scheme[#t], then the variable will definitely have
a value (but the value might change in the future).}
@defstruct+[(topsyntax expr) ([depth nonnegative-exact-integer?]
[pos nonnegative-exact-integer?]
[midpt nonnegative-exact-integer?])]{
Represents a reference to a quoted syntax object via the
@scheme[prefix] array. The @scheme[depth] field indicates the number
of stack slots to skip to reach the prefix array, and @scheme[pos] is
the offset into the array. The @scheme[midpt] value is used internally
for lazy calculation of syntax information.}
@defstruct+[(application expr) ([rator (or/c expr? seq? indirect? any/c)]
[rands (listof (or/c expr? seq? indirect? any/c))])]{
Represents a function call. The @scheme[rator] field is the expression
for the function, and @scheme[rands] are the argument
expressions. Before any of the expressions are evaluated,
@scheme[(length rands)] uninitialized stack slots are created (to be
used as temporary space).}
@defstruct+[(branch expr) ([test (or/c expr? seq? indirect? any/c)]
[then (or/c expr? seq? indirect? any/c)]
[else (or/c expr? seq? indirect? any/c)])]{
Represents an @scheme[if] form.
After @scheme[test] is evaluated, the stack is restored to its depth
from before evaluating @scheme[test].}
@defstruct+[(with-cont-mark expr) ([key (or/c expr? seq? indirect? any/c)]
[val (or/c expr? seq? indirect? any/c)]
[body (or/c expr? seq? indirect? any/c)])]{
Represents a @scheme[with-continuation-mark] expression.
After each of @scheme[key] and @scheme[val] is evaluated, the stack is
restored to its depth from before evaluating @scheme[key] or
@scheme[val].}
@defstruct+[(beg0 expr) ([seq (listof (or/c expr? seq? indirect? any/c))])]{
Represents a @scheme[begin0] expression.
After each expression in @scheme[seq] is evaluated, the stack is
restored to its depth from before evaluating the expression.}
@defstruct+[(varref expr) ([toplevel toplevel?])]{
Represents a @scheme[#%variable-reference] form.}
@defstruct+[(assign expr) ([id toplevel?]
[rhs (or/c expr? seq? indirect? any/c)]
[undef-ok? boolean?])]{
Represents a @scheme[set!] expression that assigns to a top-level or
module-level variable. (Assignments to local variables are converted
to @scheme[install-value] expression.)
After @scheme[rhs] is evaluated, the stack is restored to its depth
from before evaluating @scheme[rhs].}
@defstruct+[(apply-values expr) ([proc (or/c expr? seq? indirect? any/c)]
[args-expr (or/c expr? seq? indirect? any/c)])]{
Represents @scheme[(call-with-values (lambda () args-expr) proc)],
which is handled specially by the run-time system.}
@defstruct+[(primval expr) ([id symbol?])]{
Represents a direct reference to a variable imported from the run-time
kernel.}
@; --------------------------------------------------
@section{Syntax Objects}
@defstruct+[wrapped ([datum any/c]
[wraps (listof wrap?)]
[certs list?])]{
Represents a syntax object, where @scheme[wraps] contain the lexical
information and @scheme[certs] is certificate information. When the
@scheme[datum] part it itself compound, its pieces are wrapped, too.}
@defstruct+[wrap ()]{
A supertype for lexical information elements.}
@defstruct+[(lexical-rename wrap) ([alist (listof (cons/c identifier? identifier?))])]{
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 ([path module-path-index?]
[phase (or/c exact-integer? #f)]
[src-phase (or/c exact-integer? #f)]
[exceptions (listof symbol?)]
[prefix symbol?])]{
Represents a set of simple imports from one module within a
@scheme[module-rename].}
@defstruct+[module-binding ([path module-path-index?]
[mod-phase (or/c exact-integer? #f)]
[import-phase (or/c exact-integer? #f)]
[id symbol?]
[nominal-path module-path-index?]
[nominal-phase (or/c exact-integer? #f)]
[nominal-id (or/c exact-integer? #f)])]{
Represents a single identifier import (i.e., the general case) within
a @scheme[module-rename].}

View File

@ -3301,19 +3301,19 @@ static Scheme_Object *make_struct_type(int argc, Scheme_Object **argv)
Scheme_Object *parent = argv[1]; Scheme_Object *parent = argv[1];
if (!SCHEME_FALSEP(parent) && !((Scheme_Struct_Type *)parent)->prefab_key) { if (!SCHEME_FALSEP(parent) && !((Scheme_Struct_Type *)parent)->prefab_key) {
bad = ("make-struct-type: generative supertype disallowed" bad = ("make-struct-type: generative supertype disallowed"
" for non-generative structure type with name: "); " for non-generative structure type with name: %S");
} else if (!SCHEME_NULLP(props)) { } else if (!SCHEME_NULLP(props)) {
bad = ("make-struct-type: properties disallowed" bad = ("make-struct-type: properties disallowed"
" for non-generative structure type with name: "); " for non-generative structure type with name: %S");
} else if (proc_attr) { } else if (proc_attr) {
bad = ("make-struct-type: procedure specification disallowed" bad = ("make-struct-type: procedure specification disallowed"
" for non-generative structure type with name: "); " for non-generative structure type with name: %S");
} else if (guard) { } else if (guard) {
bad = ("make-struct-type: guard disallowed" bad = ("make-struct-type: guard disallowed"
" for non-generative structure type with name: "); " for non-generative structure type with name: %S");
} }
if (bad) { if (bad) {
scheme_raise_exn(MZEXN_FAIL_CONTRACT, bad, inspector); scheme_raise_exn(MZEXN_FAIL_CONTRACT, bad, argv[0]);
} }
} }