syntax/parse: add expr/c to main module
Merge to release branch
(cherry picked from commit 0aecbf97ff
)
This commit is contained in:
parent
fe3ee8cbc5
commit
4fbf087e17
|
@ -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)])])
|
||||||
|
|
|
@ -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)))])
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user