commit 365fed987251528b61419c24047d13c49c9f7191
parent de645308068bf7d8724aeded7eee5746425a524f
Author: Georges Dupéron <georges.duperon@gmail.com>
Date: Wed, 28 Sep 2016 23:22:12 +0200
Added and documented ~as-rest
Diffstat:
3 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/main.rkt b/main.rkt
@@ -34,6 +34,7 @@
~try-before
~try-after
~lift-rest
+ ~as-rest
~mixin
~post-check
~post-fail
diff --git a/private/no-order.rkt b/private/no-order.rkt
@@ -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 ()
diff --git a/scribblings/rest.scrbl b/scribblings/rest.scrbl
@@ -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))))]}
+\ No newline at end of file