Added and documented ~as-rest

This commit is contained in:
Georges Dupéron 2016-09-28 23:22:12 +02:00
parent de64530806
commit 365fed9872
3 changed files with 42 additions and 1 deletions

View File

@ -34,6 +34,7 @@
~try-before ~try-before
~try-after ~try-after
~lift-rest ~lift-rest
~as-rest
~mixin ~mixin
~post-check ~post-check
~post-fail ~post-fail

View File

@ -43,6 +43,7 @@
try-order-point< try-order-point<
try-order-point> try-order-point>
~lift-rest ~lift-rest
~as-rest
~omitable-lifted-rest ;; Private ~omitable-lifted-rest ;; Private
(expander-out eh-mixin)) ;; Private (expander-out eh-mixin)) ;; Private
@ -293,6 +294,23 @@
{~do 'expanded-pats} {~do 'expanded-pats}
{~bind [clause-present #t]}}])))) {~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 (define-eh-mixin-expander ~lift-rest
(λ (stx) (λ (stx)
(syntax-case stx () (syntax-case stx ()

View File

@ -12,7 +12,6 @@
@defform[#:kind "eh-mixin expander" @defform[#:kind "eh-mixin expander"
{~lift-rest pat}]{ {~lift-rest pat}]{
Lifts @racket[pat] out of the current mixin, so that it is used as a pattern to 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 match the tail of the improper list being matched. It is subject to the
following restrictions: following restrictions:
@ -65,3 +64,26 @@
@item{Post and global operations can be used within the @racket[pat]. This @item{Post and global operations can be used within the @racket[pat]. This
combination of features is not thoroughly tested, however. Please report any combination of features is not thoroughly tested, however. Please report any
issues you run into.}]} 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))))]}