syntax/parse: scheme->racket, docs for literal phases

This commit is contained in:
Ryan Culpepper 2010-05-04 20:40:27 -06:00
parent 3816f9cf1a
commit 6d1b2af74d
2 changed files with 60 additions and 18 deletions

View File

@ -1,5 +1,5 @@
#lang scheme/base #lang racket/base
(require (for-template scheme/base)) (require (for-template racket/base))
(provide txlift (provide txlift
get-txlifts get-txlifts
get-txlifts-as-definitions get-txlifts-as-definitions

View File

@ -66,7 +66,7 @@ For example, here is is a module that defines
standard @scheme[let] form (including ``named @scheme[let]''): standard @scheme[let] form (including ``named @scheme[let]''):
@schemeblock[ @schemeblock[
(module example scheme/base (module example racket/base
(require (for-syntax scheme/base syntax/parse)) (require (for-syntax scheme/base syntax/parse))
(define-syntax (mylet stx) (define-syntax (mylet stx)
(syntax-parse stx (syntax-parse stx
@ -82,8 +82,8 @@ The macro is defined as a procedure that takes one argument,
@scheme[syntax-case], except that there is no literals list between @scheme[syntax-case], except that there is no literals list between
the syntax argument and the sequence of clauses. the syntax argument and the sequence of clauses.
@bold{Note: } Remember not to put a literals list between the syntax @bold{Note: } Remember not to put a @scheme[syntax-case] style
argument and the clauses! literals list between the syntax argument and the clauses!
The patterns contain identifiers consisting of two parts separated by The patterns contain identifiers consisting of two parts separated by
a colon character, such as @scheme[loop:id] or @scheme[e:expr]. These a colon character, such as @scheme[loop:id] or @scheme[e:expr]. These
@ -104,15 +104,15 @@ syntax classes (see @secref{lib} for a list). Programmers can also
define their own using @scheme[define-syntax-class]: define their own using @scheme[define-syntax-class]:
@schemeblock[ @schemeblock[
(module example-syntax scheme/base (module example-syntax racket/base
(require syntax/parse) (require syntax/parse)
(provide binding) (provide binding)
(define-syntax-class binding (define-syntax-class binding
#:attributes (x e) #:attributes (x e)
(pattern (x:id e:expr)))) (pattern (x:id e:expr))))
(module example scheme/base (module example racket/base
(require (for-syntax scheme/base (require (for-syntax racket/base
syntax/parse syntax/parse
'example-syntax)) 'example-syntax))
(define-syntax (mylet stx) (define-syntax (mylet stx)
@ -135,7 +135,7 @@ Alternatively, the syntax class could be made a local definition,
thus: thus:
@schemeblock[ @schemeblock[
(module example scheme/base (module example racket/base
(require (for-syntax scheme/base (require (for-syntax scheme/base
syntax/parse)) syntax/parse))
(define-syntax (mylet stx) (define-syntax (mylet stx)
@ -286,9 +286,12 @@ Two parsing forms are provided: @scheme[syntax-parse] and
(code:line #:conventions (convention-id ...)) (code:line #:conventions (convention-id ...))
(code:line #:local-conventions (convention-rule ...))] (code:line #:local-conventions (convention-rule ...))]
[literal literal-id [literal literal-id
(pattern-id literal-id)] (pattern-id literal-id)
(pattern-id literal-id #:phase phase-expr)]
[literal-set literal-set-id [literal-set literal-set-id
[literal-set-id #:at context-id]] (literal-set-id literal-set-option ...)]
[literal-set-option (code:line #:at context-id)
(code:line #:phase phase-expr)]
[clause (syntax-pattern pattern-directive ... expr ...+)]) [clause (syntax-pattern pattern-directive ... expr ...+)])
#:contracts ([stx-expr syntax?])]{ #:contracts ([stx-expr syntax?])]{
@ -320,12 +323,12 @@ failures; otherwise @scheme[stx-expr] is used.
@specsubform/subs[(code:line #:literals (literal ...)) @specsubform/subs[(code:line #:literals (literal ...))
([literal literal-id ([literal literal-id
[pattern-id literal-id]])]{ (pattern-id literal-id)
(pattern-id literal-id #:phase phase-expr)])]{
@margin-note{ @margin-note{
Unlike @scheme[syntax-case], @scheme[syntax-parse] requires all Unlike @scheme[syntax-case], @scheme[syntax-parse] requires all
literals to have a binding. To match identifiers by their symbolic literals to have a binding. To match identifiers by their symbolic
names, consider using the @scheme[~datum] pattern form instead. names, use the @scheme[~datum] pattern form instead.
} }
@; @;
The @scheme[#:literals] option specifies identifiers that should be The @scheme[#:literals] option specifies identifiers that should be
@ -335,16 +338,22 @@ within the pattern to signify the positions to be matched
(@scheme[pattern-id]), and the identifier expected to occur in those (@scheme[pattern-id]), and the identifier expected to occur in those
positions (@scheme[literal-id]). If the entry is a single identifier, positions (@scheme[literal-id]). If the entry is a single identifier,
that identifier is used for both purposes. that identifier is used for both purposes.
If the @scheme[#:phase] option is given, then the literal is compared
at phase @scheme[phase-expr]. Specifically, the binding of the
@scheme[literal-id] at phase @scheme[phase-expr] must match the
input's binding at phase @scheme[phase-expr].
} }
@specsubform/subs[(code:line #:literal-sets (literal-set ...)) @specsubform/subs[(code:line #:literal-sets (literal-set ...))
([literal-set literal-set-id ([literal-set literal-set-id
[literal-set-id #:at context-id]])]{ (literal-set-id literal-set-option ...)]
[literal-set-option (code:line #:at context-id)
(code:line #:phase phase-expr)])]{
Many literals can be declared at once via one or more @tech{literal Many literals can be declared at once via one or more @tech{literal
sets}, imported with the @scheme[#:literal-sets] option. The sets}, imported with the @scheme[#:literal-sets] option. See
literal-set definition determines the literal identifiers to recognize @tech{literal sets} for more information.
and the names used in the patterns to recognize those literals.
} }
@specsubform[(code:line #:conventions (conventions-id ...))]{ @specsubform[(code:line #:conventions (conventions-id ...))]{
@ -721,6 +730,39 @@ identifiers the literal matches.
[(define-values (x:id ...) e:expr) 'v] [(define-values (x:id ...) e:expr) 'v]
[(define-syntaxes (x:id ...) e:expr) 's]) [(define-syntaxes (x:id ...) e:expr) 's])
] ]
The literals in a literal set always refer to the phase-0 bindings of
the enclosing module. For example:
@myexamples[
(module common racket/base
(define x 'something)
(provide x))
(module lits racket/base
(require syntax/parse 'common)
(define-literal-set common-lits (x))
(provide common-lits))
]
In the literal set @scheme[common-lits], the literal @scheme[x] always
recognizes identifiers bound to the variable @scheme[x] defined in
module @schememodname['common].
When a literal set is used with the @scheme[#:phase phase-expr]
option, the literals' fixed bindings are compared against the binding of
the input literal at the specified phase. Continuing the example:
@myexamples[
(require syntax/parse 'lits (for-syntax 'common))
(syntax-parse #'x #:literal-sets ([common-lits #:phase 1])
[x 'yes]
[_ 'no])
]
The occurrence of @scheme[x] in the pattern matches any identifier
whose binding at phase 1 is the @scheme[x] from module
@schememodname['common].
} }
@defform/subs[(define-conventions name-id convention-rule ...) @defform/subs[(define-conventions name-id convention-rule ...)