syntax/parse: add docs for ~undo, #:undo
This commit is contained in:
parent
414fd515ab
commit
e0a8058db5
|
@ -34,7 +34,7 @@ means specifically @tech{@Spattern}.
|
|||
|
||||
@racketgrammar*[#:literals (_ ~var ~literal ~or ~alt ~or* ~and ~not ~rest ~datum
|
||||
~describe ~seq ~optional ~rep ~once ~between
|
||||
~! ~bind ~fail ~parse ~peek ~peek-not ~do ~post)
|
||||
~! ~bind ~fail ~parse ~peek ~peek-not ~do ~undo ~post)
|
||||
[S-pattern
|
||||
pvar-id
|
||||
pvar-id:syntax-class-id
|
||||
|
@ -98,7 +98,8 @@ means specifically @tech{@Spattern}.
|
|||
(~parse S-pattern stx-expr)
|
||||
(@#,ref[~and a] A-pattern ...+)
|
||||
(@#,ref[~post a] A-pattern)
|
||||
(~do defn-or-expr ...)]
|
||||
(~do defn-or-expr ...)
|
||||
(~undo defn-or-expr ...)]
|
||||
[proper-S-pattern
|
||||
#, @elem{a @svar{S-pattern} that is not a @svar{A-pattern}}]
|
||||
[proper-H-pattern
|
||||
|
@ -1095,6 +1096,36 @@ definition in a @racket[~do] block.
|
|||
]
|
||||
}
|
||||
|
||||
@specsubform[(@#,defhere[~undo] defn-or-expr ...)]{
|
||||
|
||||
Has no effect when initially matched, but if backtracking returns to a
|
||||
point @emph{before} the @racket[~undo] pattern, the
|
||||
@racket[defn-or-expr]s are executed. They are evaluated in the scope
|
||||
of all previous attribute bindings.
|
||||
|
||||
Use @racket[~do] paired with @racket[~undo] to perform side effects
|
||||
and then unwind them if the enclosing pattern is later discarded.
|
||||
|
||||
@examples[#:eval the-eval
|
||||
(define total 0)
|
||||
(define-syntax-class nat/add
|
||||
(pattern (~and n:nat
|
||||
(~do (printf "adding ~s\n" (syntax-e #'n))
|
||||
(set! total (+ total (syntax-e #'n))))
|
||||
(~undo (printf "subtracting ~s\n" (syntax-e #'n))
|
||||
(set! total (- total (syntax-e #'n)))))))
|
||||
|
||||
(syntax-parse #'(1 2 3)
|
||||
[(x:nat/add ...) 'ok])
|
||||
total
|
||||
(set! total 0)
|
||||
(syntax-parse #'(1 2 3 bad)
|
||||
[(x:nat/add ...) 'ok]
|
||||
[_ 'something-else])
|
||||
total
|
||||
]
|
||||
}
|
||||
|
||||
@specsubform[(@#,def[~post a] A-pattern)]{
|
||||
|
||||
Like the @Spattern version, @ref[~post s], but contains only
|
||||
|
|
|
@ -200,7 +200,8 @@ follows:
|
|||
(code:line #:fail-when condition-expr message-expr)
|
||||
(code:line #:fail-unless condition-expr message-expr)
|
||||
(code:line #:when condition-expr)
|
||||
(code:line #:do [def-or-expr ...])]
|
||||
(code:line #:do [def-or-expr ...])
|
||||
(code:line #:undo [def-or-expr ...])]
|
||||
|
||||
@specsubform[(code:line #:declare pvar-id stxclass maybe-role)
|
||||
#:grammar
|
||||
|
@ -325,7 +326,7 @@ backtracks. In other words, @racket[#:when] is like
|
|||
Equivalent to @racket[#:post (~fail #:unless condition-expr #f)].
|
||||
}
|
||||
|
||||
@specsubform[(code:line #:do [def-or-expr ...])]{
|
||||
@specsubform[(code:line #:do [defn-or-expr ...])]{
|
||||
|
||||
Takes a sequence of definitions and expressions, which may be
|
||||
intermixed, and evaluates them in the scope of all previous attribute
|
||||
|
@ -336,7 +337,17 @@ There is currently no way to bind attributes using a @racket[#:do]
|
|||
block. It is an error to shadow an attribute binding with a definition
|
||||
in a @racket[#:do] block.
|
||||
|
||||
Equivalent to @racket[#:and (~do def-or-expr ...)].
|
||||
Equivalent to @racket[#:and (~do defn-or-expr ...)].
|
||||
}
|
||||
|
||||
@specsubform[(code:line #:undo [defn-or-expr ...])]{
|
||||
|
||||
Has no effect when initially matched, but if backtracking returns to a
|
||||
point @emph{before} the @racket[#:undo] directive, the
|
||||
@racket[defn-or-expr]s are executed. See @racket[~undo] for an
|
||||
example.
|
||||
|
||||
Equivalent to @racket[#:and (~undo defn-or-expr ...)].
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user