From 7aec6b876181bea97b43f16fbe2c237f946d06b3 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 28 Dec 2008 18:57:13 +0000 Subject: [PATCH] document compiler/zo-parse and compiler/decompile svn: r12947 --- collects/compiler/decompile.ss | 10 +- collects/compiler/zo-parse.ss | 83 +++-- collects/scribble/private/manual-proc.ss | 30 +- collects/scribblings/mzc/decompile.scrbl | 19 +- collects/scribblings/mzc/zo-parse.scrbl | 448 +++++++++++++++++++++++ src/mzscheme/src/struct.c | 10 +- 6 files changed, 543 insertions(+), 57 deletions(-) create mode 100644 collects/scribblings/mzc/zo-parse.scrbl diff --git a/collects/compiler/decompile.ss b/collects/compiler/decompile.ss index c78d310a40..cef5601613 100644 --- a/collects/compiler/decompile.ss +++ b/collects/compiler/decompile.ss @@ -23,7 +23,7 @@ (close-output-port out) in)))]) (let ([n (match v - [(struct compilation-top (_ prefix (struct primitive (n)))) n] + [(struct compilation-top (_ prefix (struct primval (n)))) n] [else #f])]) (hash-set! table n (car b))))) table)) @@ -77,7 +77,7 @@ lift-ids) (map (lambda (stx id) `(define ,id ,(if stx - `(#%decode-syntax ,stx #;(stx-encoded stx)) + `(#%decode-syntax ,(stx-encoded stx)) #f))) stxs stx-ids)))] [else (error 'decompile-prefix "huh?: ~e" a-prefix)])) @@ -126,7 +126,7 @@ `(let () ,@defns ,(decompile-expr rhs globs '(#%globals) closed))))] - [(struct sequence (forms)) + [(struct seq (forms)) `(begin ,@(map (lambda (form) (decompile-form form globs stack closed)) forms))] @@ -179,7 +179,7 @@ `(#%checked ,id)))] [(struct topsyntax (depth pos midpt)) (list-ref/protect globs (+ midpt pos) 'topsyntax)] - [(struct primitive (id)) + [(struct primval (id)) (hash-ref primitive-table id)] [(struct assign (id rhs undef-ok?)) `(set! ,(decompile-expr id globs stack closed) @@ -249,7 +249,7 @@ [(struct apply-values (proc args-expr)) `(#%apply-values ,(decompile-expr proc globs stack closed) ,(decompile-expr args-expr globs stack closed))] - [(struct sequence (exprs)) + [(struct seq (exprs)) `(begin ,@(for/list ([expr (in-list exprs)]) (decompile-expr expr globs stack closed)))] [(struct beg0 (exprs)) diff --git a/collects/compiler/zo-parse.ss b/collects/compiler/zo-parse.ss index 00c1a5dbb2..6e4abbc12c 100644 --- a/collects/compiler/zo-parse.ss +++ b/collects/compiler/zo-parse.ss @@ -7,11 +7,18 @@ ;; ---------------------------------------- ;; 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 - (define-struct id (field-id ...) #:transparent) + (define-struct id+par (field-id ...) #:transparent) (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 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 ;; 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 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 (mod form) (name self-modidx prefix provides requires body syntax-body max-let-depth)) -(define-form-struct let-one (rhs body)) ; pushes one value onto stack -(define-form-struct let-void (count boxes? body)) ; create new stack slots -(define-form-struct install-value (count pos boxes? rhs body)) ; set existing stack slot(s) -(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 (lam expr) (name flags num-params rest? closure-map max-let-depth body)) ; `lambda' +(define-form-struct (closure expr) (code gen-id)) ; a static closure (nothing to close over) +(define-form-struct (case-lam expr) (name clauses)) ; each clause is an lam -(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 topsyntax (depth pos midpt)) ; access syntax object via prefix array (which is on stack) +(define-form-struct (localref expr) (unbox? pos clear?)) ; access local via stack -(define-form-struct application (rator rands)) ; function call -(define-form-struct branch (test then else)) ; `if' -(define-form-struct with-cont-mark (key val body)) ; `with-continuation-mark' -(define-form-struct beg0 (seq)) ; `begin0' -(define-form-struct sequence (forms)) ; `begin' -(define-form-struct splice (forms)) ; top-level `begin' -(define-form-struct varref (toplevel)) ; `#%variable-reference' -(define-form-struct assign (id rhs undef-ok?)) ; top-level or module-level set! -(define-form-struct apply-values (proc args-expr)) ; `(call-with-values (lambda () ,args-expr) ,proc) -(define-form-struct primitive (id)) ; direct preference to a kernel primitive +(define-form-struct (toplevel expr) (depth pos const? ready?)) ; access binding via prefix array (which is on stack) +(define-form-struct (topsyntax expr) (depth pos midpt)) ; access syntax object via prefix array (which is on stack) + +(define-form-struct (application expr) (rator rands)) ; function call +(define-form-struct (branch expr) (test then else)) ; `if' +(define-form-struct (with-cont-mark expr) (key val body)) ; `with-continuation-mark' +(define-form-struct (beg0 expr) (seq)) ; `begin0' +(define-form-struct (seq form) (forms)) ; `begin' +(define-form-struct (splice form) (forms)) ; top-level `begin' +(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): -(define-form-struct def-values (ids rhs)) -(define-form-struct def-syntaxes (ids rhs prefix max-let-depth)) -(define-form-struct def-for-syntax (ids rhs prefix max-let-depth)) +(define-form-struct (def-values form) (ids rhs)) +(define-form-struct (def-syntaxes form) (ids rhs prefix max-let-depth)) +(define-form-struct (def-for-syntax form) (ids rhs prefix max-let-depth)) ;; 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 (define-struct indirect ([v #:mutable]) #:prefab) @@ -145,7 +155,7 @@ (make-with-cont-mark key val body)])) (define (read-sequence v) - (make-sequence v)) + (make-seq v)) (define (read-define-values v) (make-def-values @@ -173,7 +183,7 @@ (define (read-begin0 v) (match v - [(struct sequence (exprs)) + [(struct seq (exprs)) (make-beg0 exprs)])) (define (read-boxenv v) @@ -429,9 +439,12 @@ ;; Synatx unmarshaling (define-form-struct wrapped (datum wraps certs)) -(define-form-struct lexical-rename (alist)) -(define-form-struct phase-shift (amt src dest)) -(define-form-struct module-rename (phase kind set-id unmarshals renames mark-renames plus-kern?)) + +(define-form-struct wrap ()) +(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 module-binding (path mod-phase import-phase id nominal-path nominal-phase nominal-id)) @@ -696,7 +709,7 @@ [read-accept-quasiquote #t]) (read (open-input-bytes s))))] [(reference) - (make-primitive (read-compact-number cp))] + (make-primval (read-compact-number cp))] [(small-list small-proper-list) (let* ([l (- ch cpt-start)] [ppr (eq? cpt-tag 'small-proper-list)]) diff --git a/collects/scribble/private/manual-proc.ss b/collects/scribble/private/manual-proc.ss index 1cbaeaedf0..110aa0fc30 100644 --- a/collects/scribble/private/manual-proc.ss +++ b/collects/scribble/private/manual-proc.ss @@ -486,29 +486,33 @@ (define-syntax defstruct (syntax-rules () [(_ name fields #:mutable #:inspector #f desc ...) - (**defstruct name fields #f #t desc ...)] + (**defstruct name fields #f #t #f 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 ...) - (**defstruct name fields #f #f desc ...)] + (**defstruct name fields #f #f #f desc ...)] [(_ name fields #:inspector #f desc ...) - (**defstruct name fields #t #t desc ...)] + (**defstruct name fields #t #t #f 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 ...) - (**defstruct name fields #t #f desc ...)])) + (**defstruct name fields #t #f #f desc ...)])) (define-syntax-rule (**defstruct name ([field field-contract] ...) immutable? - transparent? desc ...) + transparent? prefab? desc ...) (with-togetherable-scheme-variables () () (*defstruct (quote-syntax/loc name) 'name '([field 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) (define (field-name f) ((if (pair? (car f)) caar car) f)) (define (field-view f) @@ -634,7 +638,9 @@ (list flow-spacer flow-spacer (to-flow (make-element #f - (list (to-element '#:transparent) + (list (if prefab? + (to-element '#:prefab) + (to-element '#:transparent)) (schemeparenfont ")")))) 'cont 'cont))] @@ -652,7 +658,9 @@ (list flow-spacer flow-spacer (to-flow (make-element #f - (list (to-element '#:transparent) + (list (if prefab? + (to-element '#:prefab) + (to-element '#:transparent)) (schemeparenfont ")")))) 'cont 'cont))] diff --git a/collects/scribblings/mzc/decompile.scrbl b/collects/scribblings/mzc/decompile.scrbl index 31d3803295..f0283401f4 100644 --- a/collects/scribblings/mzc/decompile.scrbl +++ b/collects/scribblings/mzc/decompile.scrbl @@ -1,7 +1,9 @@ #lang scribble/doc @(require scribble/manual "common.ss" - (for-label scheme/base)) + (for-label scheme/base + compiler/decompile + (only-in compiler/zo-parse compilation-top?))) @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.} ] + +@; ------------------------------------------------------------ + +@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"] diff --git a/collects/scribblings/mzc/zo-parse.scrbl b/collects/scribblings/mzc/zo-parse.scrbl new file mode 100644 index 0000000000..1e65548b57 --- /dev/null +++ b/collects/scribblings/mzc/zo-parse.scrbl @@ -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].} diff --git a/src/mzscheme/src/struct.c b/src/mzscheme/src/struct.c index 6434106e2b..9d2a188980 100644 --- a/src/mzscheme/src/struct.c +++ b/src/mzscheme/src/struct.c @@ -3301,19 +3301,19 @@ static Scheme_Object *make_struct_type(int argc, Scheme_Object **argv) Scheme_Object *parent = argv[1]; if (!SCHEME_FALSEP(parent) && !((Scheme_Struct_Type *)parent)->prefab_key) { 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)) { 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) { 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) { bad = ("make-struct-type: guard disallowed" - " for non-generative structure type with name: "); + " for non-generative structure type with name: %S"); } if (bad) { - scheme_raise_exn(MZEXN_FAIL_CONTRACT, bad, inspector); + scheme_raise_exn(MZEXN_FAIL_CONTRACT, bad, argv[0]); } }