racket/pkgs/racket-doc/syntax/scribblings/parse/state.scrbl

96 lines
3.6 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#lang scribble/doc
@(require scribble/manual
scribble/struct
scribble/decode
scribble/eval
"../common.rkt"
"parse-common.rkt")
@(define the-eval (make-sp-eval))
@title[#:tag "state"]{Unwindable State}
@declare-exporting[syntax/parse]
@deftogether[[
@defproc[(syntax-parse-state-ref [key any/c]
[default default/c (lambda () (error ....))])
any/c]
@defproc[(syntax-parse-state-set! [key any/c] [value any/c]) void?]
@defproc[(syntax-parse-state-update! [key any/c]
[update (-> any/c any/c)]
[default default/c (lambda () (error ....))])
void?]
@defproc[(syntax-parse-state-cons! [key any/c]
[value any/c]
[default default/c null])
void?]
]]{
Get or update the current @racket[syntax-parse] state. Updates to the
state are unwound when @racket[syntax-parse] backtracks. Keys are
compared using @racket[eq?].
The state can be updated only within @racket[~do] patterns (or
@racket[#:do] blocks). In addition, @racket[syntax-parse]
automatically adds identifiers that match literals (from
@racket[~literal] patterns and literals declared with
@racket[#:literals], but not from @racket[~datum] or
@racket[#:datum-literals]) under the key @racket['literals].
@examples[#:eval the-eval
(define-syntax-class cond-clause
#:literals (=> else)
(pattern [test:expr => ~! answer:expr ...])
(pattern [else answer:expr ...])
(pattern [test:expr answer:expr ...]))
(syntax-parse #'(cond [A => B] [else C])
[(_ c:cond-clause ...) (syntax-parse-state-ref 'literals null)])
]
@history[#:added "6.11.0.4"]
}
@defproc[(syntax-parse-track-literals [stx syntax?] [#:introduce? introduce? any/c #t]) syntax?]{
Add a @racket['disappeared-use] @tech[#:doc refman]{syntax property} to
@racket[stx] containing the information stored in the current
@racket[syntax-parse] state under the key @racket['literals]. If
@racket[stx] already has a @racket['disappeared-use] property, the
added information is @racket[cons]ed onto the propertys current value.
Due to the way @racket[syntax-parse] automatically adds identifiers that match
literals to the state under the key @racket['literals], as described in the
documentation for @racket[syntax-parse-state-ref],
@racket[syntax-parse-track-literals] can be used to automatically add any
identifiers used as literals to the @racket['disappeared-use] property.
If @racket[syntax-parse-track-literals] is called within the dynamic
extent of a @tech[#:doc refman]{syntax transformer} (see
@racket[syntax-transforming?]), @racket[introduce?] is not @racket[#f], and the
value in the current @racket[syntax-parse] state under the key
@racket['literals] is a list, then @racket[syntax-local-introduce] is applied to
any identifiers in the list before they are added to @racket[stx]s
@racket['disappeared-use] property.
Most of the time, it is unnecessary to call this function directly. Instead, the
@racket[#:track-literals] option should be provided to @racket[syntax-parse],
which will automatically call @racket[syntax-parse-track-literals] on
syntax-valued results.
@examples[#:eval the-eval
(define-syntax-class cond-clause
#:literals (=> else)
(pattern [test:expr => ~! answer:expr ...])
(pattern [else answer:expr ...])
(pattern [test:expr answer:expr ...]))
(syntax-property
(syntax-parse #'(cond [A => B] [else C])
[(_ c:cond-clause ...) (syntax-parse-track-literals #'#f)])
'disappeared-use)
]
@history[#:added "6.90.0.29"]}
@(close-eval the-eval)