document compiler/zo-parse and compiler/decompile
svn: r12947
This commit is contained in:
parent
0cd2537a82
commit
7aec6b8761
|
@ -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))
|
||||||
|
|
|
@ -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)])
|
||||||
|
|
|
@ -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))]
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
448
collects/scribblings/mzc/zo-parse.scrbl
Normal file
448
collects/scribblings/mzc/zo-parse.scrbl
Normal 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].}
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user