syntax/parse: add expr/c to main module

Merge to release branch
(cherry picked from commit 0aecbf97ff)
This commit is contained in:
Ryan Culpepper 2011-07-08 03:38:33 -06:00 committed by Eli Barzilay
parent fe3ee8cbc5
commit 4fbf087e17
6 changed files with 81 additions and 71 deletions

View File

@ -3,11 +3,13 @@
"parse/private/sc.rkt" "parse/private/sc.rkt"
"parse/private/litconv.rkt" "parse/private/litconv.rkt"
"parse/private/lib.rkt" "parse/private/lib.rkt"
"parse/experimental/provide.rkt") "parse/experimental/provide.rkt"
"parse/experimental/contract.rkt")
(provide (except-out (all-from-out "parse/private/sc.rkt") (provide (except-out (all-from-out "parse/private/sc.rkt")
syntax-parser/template parser/rhs) syntax-parser/template parser/rhs)
(all-from-out "parse/private/litconv.rkt") (all-from-out "parse/private/litconv.rkt")
(except-out (all-from-out "parse/private/lib.rkt") (except-out (all-from-out "parse/private/lib.rkt")
static)) static)
expr/c)
(provide-syntax-class/contract (provide-syntax-class/contract
[static (syntax-class/c [(-> any/c any/c) (or/c string? symbol? #f)])]) [static (syntax-class/c [(-> any/c any/c) (or/c string? symbol? #f)])])

View File

@ -29,7 +29,7 @@
(#:positive (or/c syntax? string? module-path-index? (#:positive (or/c syntax? string? module-path-index?
'from-macro 'use-site 'unknown) 'from-macro 'use-site 'unknown)
#:negative (or/c syntax? string? module-path-index? #:negative (or/c syntax? string? module-path-index?
'from-macro 'same-as-use-site 'unknown) 'from-macro 'use-site 'unknown)
#:name (or/c identifier? string? symbol? #f) #:name (or/c identifier? string? symbol? #f)
#:macro (or/c identifier? string? symbol? #f) #:macro (or/c identifier? string? symbol? #f)
#:context (or/c syntax? #f)))]) #:context (or/c syntax? #f)))])

View File

@ -6,10 +6,7 @@
"parse-common.rkt" "parse-common.rkt"
(for-label racket/class)) (for-label racket/class))
@title[#:tag "exprc"]{Experimental: Contracts on macro sub-expressions} @title[#:tag "exprc"]{Contracts on macro sub-expressions}
@emph{This section involves facilities that are experimental and
subject to change.}
Just as procedures often expect certain kinds of values as arguments, Just as procedures often expect certain kinds of values as arguments,
macros often have expectations about the expressions they are macros often have expectations about the expressions they are

View File

@ -13,23 +13,8 @@ The following facilities are experimental.
@defmodule[syntax/parse/experimental/contract] @defmodule[syntax/parse/experimental/contract]
Macros can apply contracts to their sub-expressions using the This module is deprecated; it reprovides @racket[expr/c] for backward
@racket[expr/c] syntax class. compatibility.
@defproc[(expr/c [contract-expr syntax?]
[#:positive pos-blame 'use-site]
[#:negative neg-blame 'from-macro]
[#:name expr-name #f]
[#:macro macro-name #f]
[#:context ctx #f])
(attributes c)]{
Accepts an expression (@racket[expr]) and computes an attribute
@racket[c] that represents the expression wrapped with the contract
represented by @racket[contract-expr].
See @secref{exprc} for an example.
}
@section{Contracts for syntax classes} @section{Contracts for syntax classes}

View File

@ -58,6 +58,77 @@ When used outside of the dynamic extent of a macro transformer (see
The attribute @var[value] contains the value the name is bound to. The attribute @var[value] contains the value the name is bound to.
} }
@defproc[(expr/c [contract-expr syntax?]
[#:positive pos-blame
(or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown)
'use-site]
[#:negative neg-blame
(or/c syntax? string? module-path-index? 'from-macro 'use-site 'unknown)
'from-macro]
[#:name expr-name (or/c identifier? string? symbol?) #f]
[#:macro macro-name (or/c identifier? string? symbol?) #f]
[#:context ctx (or/c syntax? #f) #, @elem{determined automatically}])
(attributes c)]{
Accepts an expression (@racket[expr]) and computes an attribute
@racket[c] that represents the expression wrapped with the contract
represented by @racket[contract-expr].
The contract's positive blame represents the obligations of the
expression being wrapped. The negative blame represents the
obligations of the macro imposing the contract---the ultimate user
of @racket[expr/c]. By default, the positive blame is taken as
the module currently being expanded, and the negative blame is
inferred from the definition site of the macro (itself inferred from
the @racket[context] argument), but both blame locations can be
overridden.
The @racket[pos-blame] and @racket[neg-blame] arguments are turned
into blame locations as follows:
@itemize[
@item{If the argument is a string, it is used directly as the blame
label.}
@item{If the argument is syntax, its source location is used
to produce the blame label.}
@item{If the argument is a module path index, its resolved module path
is used.}
@item{If the argument is @racket['from-macro], the macro is inferred
from either the @racket[macro-name] argument (if @racket[macro-name]
is an identifier) or the @racket[context] argument, and the module
where it is @emph{defined} is used as the blame location. If
neither an identifier @racket[macro-name] nor a @racket[context]
argument is given, the location is @racket["unknown"].}
@item{If the argument is @racket['use-site], the module being
expanded is used.}
@item{If the argument is @racket['unknown], the blame label is
@racket["unknown"].}
]
The @racket[macro-name] argument is used to determine the macro's
binding, if it is an identifier. If @racket[expr-name] is given,
@racket[macro-name] is also included in the contract error message. If
@racket[macro-name] is omitted or @racket[#f], but @racket[context] is
a syntax object, then @racket[macro-name] is determined from
@racket[context].
If @racket[expr-name] is not @racket[#f], it is used in the contract's
error message to describe the expression the contract is applied to.
The @racket[context] argument is used, when necessary, to infer the
macro name for the negative blame party and the contract error
message. The @racket[context] should be either an identifier or a
syntax pair with an identifer in operator position; in either case,
that identifier is taken as the macro ultimately requesting the
contract wrapping.
See @secref{exprc} for an example.
@bold{Important:} Make sure when using @racket[expr/c] to use the
@racket[c] attribute. The @racket[expr/c] syntax class does not change how
pattern variables are bound; it only computes an attribute that
represents the checked expression.
}
@section{Literal sets} @section{Literal sets}

View File

@ -1,6 +1,6 @@
#lang scribble/manual #lang scribble/manual
@(require scribble/struct scribble/decode scribble/eval "utils.rkt" @(require scribble/struct scribble/decode scribble/eval "utils.rkt"
(for-label racket/base racket/contract unstable/wrapc racket/syntax)) (for-label racket/base racket/contract unstable/wrapc racket/syntax syntax/parse))
@(define the-eval (make-base-eval)) @(define the-eval (make-base-eval))
@(the-eval '(require racket/contract (for-syntax racket/base unstable/wrapc))) @(the-eval '(require racket/contract (for-syntax racket/base unstable/wrapc)))
@ -35,52 +35,7 @@ Returns a syntax object representing an expression that applies the
contract represented by @racket[contract-expr] to the value produced contract represented by @racket[contract-expr] to the value produced
by @racket[expr]. by @racket[expr].
The contract's positive blame represents the obligations of the The other arguments have the same meaning as for @racket[expr/c].
expression being wrapped. The negative blame represents the
obligations of the macro imposing the contract---the ultimate caller
of @racket[wrap-expr/c]. By default, the positive blame is taken as
the module currently being expanded, and the negative blame is
inferred from the definition site of the macro (itself inferred from
the @racket[context] argument). But both blame locations can be
overridden.
Positive and negative blame locations are determined from
@racket[pos-blame] and @racket[neg-blame], respectively, as follows:
@itemize[
@item{If the argument is a string, it is used directly as the blame
label.}
@item{If the argument is syntax, its source location is used
to produce the blame label.}
@item{If the argument is a module path index, its resolved module path
is used.}
@item{If the argument is @racket['from-macro], the macro is inferred
from either the @racket[macro-name] argument (if @racket[macro-name]
is an identifier) or the @racket[context] argument, and the module
where it is @emph{defined} is used as the negative blame location. If
neither an identifier @racket[macro-name] nor a @racket[context]
argument is given, the location is @racket["unknown"].}
@item{If the argument is @racket['use-site], the module being
expanded is used.}
@item{If the argument is @racket['unknown], the blame label is
@racket["unknown"].}
]
The @racket[macro-name] argument is used to determine the macro's
binding, if it is an identifier. If @racket[expr-name] is given,
@racket[macro-name] is also included in the contract error message. If
@racket[macro-name] is omitted or @racket[#f], but @racket[context] is
a syntax object, then @racket[macro-name] is determined from
@racket[context].
If @racket[expr-name] is not @racket[#f], it is used in the contract's
error message to describe the expression the contract is applied to.
The @racket[context] argument is used, when necessary, to infer the
macro name for the negative blame party and the contract error
message. The @racket[context] should be either an identifier or a
syntax pair with an identifer in operator position; in either case,
that identifier is taken as the macro ultimately requesting the
contract wrapping.
@examples[#:eval the-eval @examples[#:eval the-eval
(define-syntax (myparameterize1 stx) (define-syntax (myparameterize1 stx)