From 365fed987251528b61419c24047d13c49c9f7191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Wed, 28 Sep 2016 23:22:12 +0200 Subject: [PATCH] Added and documented ~as-rest --- main.rkt | 1 + private/no-order.rkt | 18 ++++++++++++++++++ scribblings/rest.scrbl | 24 +++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/main.rkt b/main.rkt index eed1d92..000ded0 100644 --- 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 index 7cf2abb..8702a4a 100644 --- 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 index 15d5360..44d99cf 100644 --- 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