Added and documented ~as-rest
This commit is contained in:
parent
de64530806
commit
365fed9872
1
main.rkt
1
main.rkt
|
@ -34,6 +34,7 @@
|
|||
~try-before
|
||||
~try-after
|
||||
~lift-rest
|
||||
~as-rest
|
||||
~mixin
|
||||
~post-check
|
||||
~post-fail
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
try-order-point<
|
||||
try-order-point>
|
||||
~lift-rest
|
||||
~as-rest
|
||||
~omitable-lifted-rest ;; Private
|
||||
(expander-out eh-mixin)) ;; Private
|
||||
|
||||
|
@ -293,6 +294,23 @@
|
|||
{~do 'expanded-pats}
|
||||
{~bind [clause-present #t]}}]))))
|
||||
|
||||
(define-eh-mixin-expander ~as-rest
|
||||
(λ (stx)
|
||||
(syntax-case stx ()
|
||||
[(_ pat ...)
|
||||
(let ()
|
||||
(define/with-syntax clause-present (get-new-clause!))
|
||||
(define/with-syntax clause-seq (get-new-clause!))
|
||||
(define/with-syntax (expanded-pat ...)
|
||||
;; let the ~post, ~global etc. within pat … be recognized
|
||||
(stx-map expand-all-eh-mixin-expanders #'(pat ...)))
|
||||
(lift-rest! '~lift-rest
|
||||
#'clause-present
|
||||
#'({~parse (expanded-pat ...)
|
||||
#'(clause-seq (... ...))}))
|
||||
#'{~seq clause-seq (... ...)
|
||||
{~bind [clause-present #t]}})])))
|
||||
|
||||
(define-eh-mixin-expander ~lift-rest
|
||||
(λ (stx)
|
||||
(syntax-case stx ()
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
@defform[#:kind "eh-mixin expander"
|
||||
{~lift-rest pat}]{
|
||||
|
||||
Lifts @racket[pat] out of the current mixin, so that it is used as a pattern to
|
||||
match the tail of the improper list being matched. It is subject to the
|
||||
following restrictions:
|
||||
|
@ -65,3 +64,26 @@
|
|||
@item{Post and global operations can be used within the @racket[pat]. This
|
||||
combination of features is not thoroughly tested, however. Please report any
|
||||
issues you run into.}]}
|
||||
|
||||
@defform[#:kind "eh-mixin expander"
|
||||
{~as-rest pat ...}]{
|
||||
|
||||
Like @racket[~seq], but the @racket[pat]s are injected as part of the same
|
||||
@racket[~or] as @racket[~lift-rest]. This means that syntax/parse will not
|
||||
throw an error for the following code:
|
||||
|
||||
@examples[#:eval (make-evaluator)
|
||||
(eval:no-prompt
|
||||
(define p2
|
||||
(syntax-parser
|
||||
[(~no-order {~once name:id}
|
||||
{~once message:str}
|
||||
(~once (~or {~as-rest val:nat}
|
||||
{~seq {~lift-rest val:nat}})))
|
||||
(syntax->datum
|
||||
#'(#:name name #:messsage message #:val val))])))
|
||||
(code:line (p2 #'(x 123 "msg")) (code:comment "matched by ~as-rest"))
|
||||
(code:line (p2 #'(x "msg" 123)) (code:comment "matched by ~as-rest"))
|
||||
(code:line (p2 #'(x "msg" . 456)) (code:comment "matched by ~lift-rest"))
|
||||
(eval:alts (code:line (p2 #'(x "msg" 123 . 456)) (code:comment "can't have both"))
|
||||
(eval:error (p2 #'(x "msg" 123 . 456))))]}
|
Loading…
Reference in New Issue
Block a user