try "phase-collapsing" instead of "phaseless"

This commit is contained in:
Matthew Flatt 2013-02-26 18:36:06 -07:00
parent 2e652fc2b3
commit 2646ff6895
12 changed files with 131 additions and 130 deletions

View File

@ -1091,7 +1091,7 @@
[l (cons lang-info l)] ; lang-info
[l (cons (map convert-module post-submodules) l)]
[l (cons (map convert-module pre-submodules) l)]
[l (cons (if (memq 'phaseless flags) #t #f) l)]
[l (cons (if (memq 'phase-collapsing flags) #t #f) l)]
[l (cons self-modidx l)]
[l (cons srcname l)]
[l (cons (if (pair? name) (car name) name) l)]

View File

@ -251,7 +251,7 @@
(define (read-module v)
(match v
[`(,submod-path
,name ,srcname ,self-modidx ,phaseless?
,name ,srcname ,self-modidx ,phase-collapsing?
,pre-submods ,post-submods
,lang-info ,functional? ,et-functional?
,rename ,max-let-depth ,dummy
@ -337,7 +337,7 @@
dummy
lang-info
rename
(if phaseless? '(phaseless) '())
(if phase-collapsing? '(phase-collapsing) '())
(map read-module pre-submods)
(map read-module post-submods))]))]))
(define (read-module-wrap v)

View File

@ -139,7 +139,7 @@
[dummy toplevel?]
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
[internal-context (or/c #f #t stx? (vectorof stx?))]
[flags (listof (or/c 'phaseless))]
[flags (listof (or/c 'phase-collapsing))]
[pre-submodules (listof mod?)]
[post-submodules (listof mod?)]))

View File

@ -205,7 +205,7 @@ binding, constructor, etc.}
[dummy toplevel?]
[lang-info (or/c #f (vector/c module-path? symbol? any/c))]
[internal-context (or/c #f #t stx? (vectorof stx?))]
[flags (listof (or/c 'phaseless))]
[flags (listof (or/c 'phase-collapsing))]
[pre-submodules (listof mod?)]
[post-submodules (listof mod?)])]{
Represents a @racket[module] declaration.
@ -248,8 +248,8 @@ binding, constructor, etc.}
syntax-object value embeds an arbitrary lexical context.
The @racket[flags] field records certain properties of the module.
The @racket['phaseless] flag indicates that the module body is
evaluated once and the results shared across all phases; such a
The @racket['phase-collapsing] flag indicates that the module body is
evaluated once and the results shared across instances for all phases; such a
module contains only definitions of functions, structure types, and
structure type properties.

View File

@ -599,33 +599,33 @@ top-level variables in higher @tech{phases}, while module
top-levels are in corresponding higher @tech{phase}s.
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@subsection[#:tag "phaseless-modules"]{Phaseless Modules}
@subsection[#:tag "phase-collapsing-modules"]{Phase-Collapsing Modules}
Module declarations that fit a highly constrained form create
@deftech{phaseless} modules. A @tech{phaseless} module's
@deftech{phase-collapsing} modules. A @tech{phase-collapsing} module's
instantiations across all phases and @tech{module registries} share
the variables produced by the first instantiation of the module.
The intent of a @tech{phaseless} module is to support values that are
The intent of a @tech{phase-collapsing} module is to support values that are
recognizable after @tech{phase} crossings. For example, when a macro
transformer running in phase 1 raises a syntax error as represented by
a @racket[exn:fail:syntax] instance, the instance is recognizable by a
phase-0 exception handler wrapping a call to @racket[eval] or
@racket[expand] that triggered the syntax error, because the
@racket[exn:fail:syntax] structure type is defined by a
@tech{phaseless} module.
@tech{phase-collapsing} module.
A @tech{phaseless} module imports only other @tech{phaseless} modules,
A @tech{phase-collapsing} module imports only other @tech{phase-collapsing} modules,
and it contains only definitions that bind variables to functions,
structure types and related functions, or structure-type properties
and related functions. A @tech{phaseless} module never includes syntax
and related functions. A @tech{phase-collapsing} module never includes syntax
literals (via @racket[quote-syntax]) or variable references (via
@racket[#%variable-reference]). See @secref["phaseless-grammar"] for
the syntactic specification of a @tech{phaseless} module
@racket[#%variable-reference]). See @secref["phase-collapsing-grammar"] for
the syntactic specification of a @tech{phase-collapsing} module
declaration.
A documented module should be assumed non-@tech{phaseless} unless it
is specified as @tech{phaseless} (such as
A documented module should be assumed non-@tech{phase-collapsing} unless it
is specified as @tech{phase-collapsing} (such as
@racketmodname[racket/kernel]).
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -647,7 +647,7 @@ redeclared, each redeclaration of the module is immediately
If the current @tech{inspector} does not manage a module's declaration
inspector (see @secref["modprotect"]), then the module cannot be
redeclared. Similarly, a @tech{phaseless} module cannot be redeclared.
redeclared. Similarly, a @tech{phase-collapsing} module cannot be redeclared.
Even if redeclrection succeeds, instantiation of a module that is
previously instantiated may fail if instantiation for the
redeclaration attempts to modify variables that are constant (see

View File

@ -10,7 +10,7 @@
@title{Kernel Forms and Functions}
@defmodule*[(racket/kernel)]{The @racketmodname[racket/kernel] library
is a @tech{phaseless} module that provides a minimal set of syntactic
is a @tech{phase-collapsing} module that provides a minimal set of syntactic
forms and functions.}
``Minimal'' means that @racketmodname[racket/kernel] includes only

View File

@ -989,9 +989,9 @@ information. Inferred and property-assigned names are also available
to syntax transformers, via @racket[syntax-local-name].
@;----------------------------------------
@section[#:tag "phaseless-grammar"]{Phaseless Module Declarations}
@section[#:tag "phase-collapsing-grammar"]{Phase-Collapsing Module Declarations}
A module is @tech{phaseless} only if it fits the following grammar,
A module is @tech{phase-collapsing} only if it fits the following grammar,
which uses non-terminals from @secref["fully-expanded"], only if
it includes no uses of @racket[quote-syntax] or @racket[#%variable-reference],
and only if no module-level binding is @racket[set!]ed.
@ -1003,16 +1003,17 @@ and only if no module-level binding is @racket[set!]ed.
set! quote-syntax quote with-continuation-mark
#%plain-app
cons list make-struct-type make-struct-type-property)
[phaseless-module (module id module-path
(#%plain-module-begin
phaseless-form ...))]
[phaseless-form (begin phaseless-form ...)
[phase-collapse-module (module id module-path
(#%plain-module-begin
phase-collapse-form ...))]
[phase-collapse-form (begin phase-collapse-form ...)
(#%provide raw-provide-spec ...)
submodule-form
(define-values (id ...) phaseless-expr)
(define-values (id ...)
phase-collapse-expr)
(#%require raw-require-spec ...)]
[phaseless-expr id
(@#,racket[quote] phaseless-datum)
[phase-collapse-expr id
(@#,racket[quote] phase-collapse-datum)
(#%plain-lambda formals expr ...+)
(case-lambda (formals expr ...+) ...)
(#%plain-app cons expr ...+)
@ -1020,15 +1021,15 @@ and only if no module-level binding is @racket[set!]ed.
(#%plain-app make-struct-type expr ...+)
(#%plain-app make-struct-type-property
expr ...+)]
[phaseless-datum number
[phase-collapse-datum number
boolean
identifier
string
bytes]
]
This grammar applies after @tech{expansion}, but because a @tech{phaseless}
module imports only from other phaseless modules, the only relevant
This grammar applies after @tech{expansion}, but because a @tech{phase-collapsing}
module imports only from other phase-collapsing modules, the only relevant
expansion steps are the implicit introduction of
@racket[#%plain-module-begin], implicit introduction of @racket[#%plain-app],
and implicit introduction and/or expansion of @racket[#%datum].

View File

@ -0,0 +1,96 @@
#lang racket/base
(require compiler/zo-parse)
(define (check-phase-collapsing is? form)
(parameterize ([current-namespace (make-base-namespace)])
(define o (open-output-bytes))
(write (compile `(module m racket/kernel ,form)) o)
(close-output-port o)
(define i (open-input-bytes (get-output-bytes o)))
(define e (zo-parse i))
(unless (equal? is? (and (memq 'phase-collapsing (mod-flags (compilation-top-code e))) #t))
(error 'phase-collapsing "failed: ~s ~s" is? form))))
(check-phase-collapsing #t '(define-values (x) 5))
(check-phase-collapsing #t '(define-values (x) '5))
(check-phase-collapsing #t '(define-values (x) (#%datum . 5)))
(check-phase-collapsing #t '(define-values (x) #t))
(check-phase-collapsing #t '(define-values (x) 'x))
(check-phase-collapsing #t '(define-values (x) "x"))
(check-phase-collapsing #t '(define-values (x) #"x"))
(check-phase-collapsing #t '(define-values (x) cons))
(check-phase-collapsing #t '(define-values (x) (cons 1 2)))
(check-phase-collapsing #t '(define-values (x) (list 1 2)))
(check-phase-collapsing #t '(define-values (x) (cons 1 '())))
(check-phase-collapsing #t '(#%require racket/private/stx))
(check-phase-collapsing #t '(define-values (x) (lambda (x) x)))
(check-phase-collapsing #t '(define-values (x) (case-lambda [(x) x] [y y])))
(check-phase-collapsing #t '(define-values (struct: ? -ref) (make-struct-type-property 'p)))
(check-phase-collapsing #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's #f 0 0)))
(check-phase-collapsing #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 0 0)))
(check-phase-collapsing #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 1 0 #f (list (cons prop:procedure 0)))))
(check-phase-collapsing #t '(begin
(define-values (x) 5)
(define-values (y) 6)))
(check-phase-collapsing #f '(define-values (x) #(x)))
(check-phase-collapsing #f '(define-values (x) '(x)))
(check-phase-collapsing #f '(define-values (x) (lambda () (set! x 8))))
(check-phase-collapsing #f '(define-values (x) (quote-syntax x)))
(check-phase-collapsing #f '(define-values (x) (lambda () (quote-syntax x))))
(check-phase-collapsing #f '(define-values (x) (#%variable-reference)))
(check-phase-collapsing #f '(define-values (x) (lambda () (#%variable-reference))))
(check-phase-collapsing #f '(define-values (x) (lambda () (if #f (#%variable-reference) 10))))
(check-phase-collapsing #f '(define-values (x) (#%variable-reference x)))
(check-phase-collapsing #f '(#%require racket/base))
(check-phase-collapsing #t '(module* sub #f (vector 1 2 3)))
(check-phase-collapsing #t '(module* sub #f (#%variable-reference)))
(check-phase-collapsing #t '(module* sub racket/base (#%variable-reference)))
(check-phase-collapsing #t '(module sub racket/base (#%variable-reference)))
;; Check phase crossing via an exception:
(parameterize ([current-namespace (make-base-namespace)])
(eval `(module m racket/kernel
(#%provide s? make-s)
(define-values (struct:s make-s s? s-ref s-set!) (make-struct-type 's #f 0 0))))
(eval '(require 'm))
(define s? (eval 's?))
(eval '(require (for-syntax racket/base 'm)))
(eval '(define-syntax (m stx) (raise (make-s))))
(with-handlers ([s? void])
(eval '(m)))
(define (check-exn)
(with-handlers ([s? void])
(eval '(module n racket/base
(require (for-syntax racket/base 'm))
(begin-for-syntax
(raise (make-s)))))))
(check-exn)
(define (check-attach namespace-attach-module)
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) ''m ns)
(parameterize ([current-namespace ns])
(check-exn)))
(check-attach namespace-attach-module)
(check-attach namespace-attach-module-declaration))
;; Check disallowing redeclaration:
(parameterize ([current-namespace (make-base-namespace)])
(parameterize ([compile-enforce-module-constants #f])
(eval `(module m racket/kernel
(#%provide x)
(define-values (x) 5)))
(compile `(module m racket/kernel
(#%provide x)
(define-values (x) 6)))
(unless (void?
(with-handlers ([exn:fail? void])
(eval `(module m racket/kernel
(#%provide x)
(define-values (x) 6)))
'ok))
(error 'phase-collapsing "redeclaration should have been disallowed"))))
(displayln "All tests passed.")

View File

@ -1,96 +0,0 @@
#lang racket/base
(require compiler/zo-parse)
(define (check-phaseless is? form)
(parameterize ([current-namespace (make-base-namespace)])
(define o (open-output-bytes))
(write (compile `(module m racket/kernel ,form)) o)
(close-output-port o)
(define i (open-input-bytes (get-output-bytes o)))
(define e (zo-parse i))
(unless (equal? is? (and (memq 'phaseless (mod-flags (compilation-top-code e))) #t))
(error 'phaseless "failed: ~s ~s" is? form))))
(check-phaseless #t '(define-values (x) 5))
(check-phaseless #t '(define-values (x) '5))
(check-phaseless #t '(define-values (x) (#%datum . 5)))
(check-phaseless #t '(define-values (x) #t))
(check-phaseless #t '(define-values (x) 'x))
(check-phaseless #t '(define-values (x) "x"))
(check-phaseless #t '(define-values (x) #"x"))
(check-phaseless #t '(define-values (x) cons))
(check-phaseless #t '(define-values (x) (cons 1 2)))
(check-phaseless #t '(define-values (x) (list 1 2)))
(check-phaseless #t '(define-values (x) (cons 1 '())))
(check-phaseless #t '(#%require racket/private/stx))
(check-phaseless #t '(define-values (x) (lambda (x) x)))
(check-phaseless #t '(define-values (x) (case-lambda [(x) x] [y y])))
(check-phaseless #t '(define-values (struct: ? -ref) (make-struct-type-property 'p)))
(check-phaseless #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's #f 0 0)))
(check-phaseless #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 0 0)))
(check-phaseless #t '(define-values (struct: make- ? -ref -set!) (make-struct-type 's struct:exn 1 0 #f (list (cons prop:procedure 0)))))
(check-phaseless #t '(begin
(define-values (x) 5)
(define-values (y) 6)))
(check-phaseless #f '(define-values (x) #(x)))
(check-phaseless #f '(define-values (x) '(x)))
(check-phaseless #f '(define-values (x) (lambda () (set! x 8))))
(check-phaseless #f '(define-values (x) (quote-syntax x)))
(check-phaseless #f '(define-values (x) (lambda () (quote-syntax x))))
(check-phaseless #f '(define-values (x) (#%variable-reference)))
(check-phaseless #f '(define-values (x) (lambda () (#%variable-reference))))
(check-phaseless #f '(define-values (x) (lambda () (if #f (#%variable-reference) 10))))
(check-phaseless #f '(define-values (x) (#%variable-reference x)))
(check-phaseless #f '(#%require racket/base))
(check-phaseless #t '(module* sub #f (vector 1 2 3)))
(check-phaseless #t '(module* sub #f (#%variable-reference)))
(check-phaseless #t '(module* sub racket/base (#%variable-reference)))
(check-phaseless #t '(module sub racket/base (#%variable-reference)))
;; Check phase crossing via an exception:
(parameterize ([current-namespace (make-base-namespace)])
(eval `(module m racket/kernel
(#%provide s? make-s)
(define-values (struct:s make-s s? s-ref s-set!) (make-struct-type 's #f 0 0))))
(eval '(require 'm))
(define s? (eval 's?))
(eval '(require (for-syntax racket/base 'm)))
(eval '(define-syntax (m stx) (raise (make-s))))
(with-handlers ([s? void])
(eval '(m)))
(define (check-exn)
(with-handlers ([s? void])
(eval '(module n racket/base
(require (for-syntax racket/base 'm))
(begin-for-syntax
(raise (make-s)))))))
(check-exn)
(define (check-attach namespace-attach-module)
(define ns (make-base-namespace))
(namespace-attach-module (current-namespace) ''m ns)
(parameterize ([current-namespace ns])
(check-exn)))
(check-attach namespace-attach-module)
(check-attach namespace-attach-module-declaration))
;; Check disallowing redeclaration:
(parameterize ([current-namespace (make-base-namespace)])
(parameterize ([compile-enforce-module-constants #f])
(eval `(module m racket/kernel
(#%provide x)
(define-values (x) 5)))
(compile `(module m racket/kernel
(#%provide x)
(define-values (x) 6)))
(unless (void?
(with-handlers ([exn:fail? void])
(eval `(module m racket/kernel
(#%provide x)
(define-values (x) 6)))
'ok))
(error 'phaseless "redeclaration should have been disallowed"))))
(displayln "All tests passed.")

View File

@ -1,5 +1,5 @@
Version 5.3.3.6
Added "phaseless" module inference and instantiation
Added "phase-collapse" module inference and instantiation
compiler/zo-structs: added flags field to mod
Version 5.3.3.4

View File

@ -6380,7 +6380,7 @@ static Scheme_Object *do_module_execute(Scheme_Object *data, Scheme_Env *genv,
if (old_m && old_m->phaseless) {
scheme_contract_error("module->namespace",
"cannot redeclare phaseless module",
"cannot redeclare phase-collapsing module",
"module name", 1, m->modname,
NULL);
return NULL;

View File

@ -5216,7 +5216,7 @@ module_optimize(Scheme_Object *data, Optimize_Info *info, int context)
scheme_log(info->logger,
SCHEME_LOG_DEBUG,
0,
"compilation of phaseless module: %D",
"compilation of phase-collapsing module: %D",
m->modname);
}