commit c7c254969563d375c18e81745d45deb3c41fb91c
parent 76c9e89b20cdd0e88a5f69a3db04f974ee55a758
Author: Georges Dupéron <georges.duperon@gmail.com>
Date: Thu, 29 Sep 2016 16:28:18 +0200
Fixed ^ {once} for the match expander
Diffstat:
3 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/implementation.rkt b/implementation.rkt
@@ -264,10 +264,8 @@
(nt #'(base ^ from - ∞ . rest))]
[(:base {~^ power:nat} . rest)
#`(base ^ {power} . #,(nt #'rest))]
- [(:base {~^ once} . rest)
- #`(base ^ {once} . #,(nt #'rest))]
- [(:base . rest)
- #`(base ^ {once} . #,(nt #'rest))]))
+ [(:base {~optional {~^ once}} . rest)
+ #`(base ^ {once} . #,(nt #'rest))]))
(nt stx))
@@ -286,7 +284,7 @@
(define xl
(syntax-parser
#:context context
- #:literals (^ * + - ∞)
+ #:literals (^ * + - ∞ once)
[()
#'(list)]
[rest:not-stx-pair
@@ -335,8 +333,8 @@
#:when (regexp-match? #px"^\\.\\.[0-9]+$"
(symbol->string (syntax-e #'ellipsis)))
#`(list-rest-ish [] base ellipsis #,(xl #'rest))]
- [(:base {~^ once})
- #`(list-rest-ish [] base #|no ellipsis|# . #,(xl #'rest))]
+ [(:base {~^ once} . rest)
+ #`(list-rest-ish [] base #|no ellipsis|# #,(xl #'rest))]
[(:base {~^ power:nat})
#:with occurrences (gensym 'occurrences)
#`(list-rest-ish [(? (λ (_) (= (length occurrences) power)))]
diff --git a/scribblings/split-xlist.scrbl b/scribblings/split-xlist.scrbl
@@ -1,11 +1,15 @@
#lang scribble/manual
@require[phc-toolkit/scribblings/utils
+ scribble/examples
@for-label[xlist
typed/racket/base]]
@title{Splitting an xlist in its constituent sublists}
@(declare-exporting xlist)
+@(define make-eval (make-eval-factory '(xlist)
+ #:lang 'typed/racket))
+
@defform*[#:kind "match-expander"
#:literals (^ * + - ∞)
[(split-xlist pat τᵢ ...)
@@ -52,4 +56,13 @@
equivalent, the type of the sublist will be @racket[(xList type ^ _n)]}
@item{If the @racket[_repeat] for that element is @racket[_from - _to] or an
equivalent, the type of the sublist will be
- @racket[(xList type ^ _from - _to)]}]}
+ @racket[(xList type ^ _from - _to)]}
+ @item{The @racket[#:rest] or dotted rest is included as the last element of
+ the list matched against @racket[pat]. If the first form without a rest type
+ is used, the list matched against @racket[pat] still contains @racket['()] as
+ a last element:
+ @examples[#:eval (make-eval)
+ (match '(1 2 3)
+ [(split-xlist (list (list a) (list b c) (? null?))
+ Number¹ Number⃰)
+ (vector c b a)])]}]}
diff --git a/test/test-match.rkt b/test/test-match.rkt
@@ -198,3 +198,11 @@
(list n2 s n1)]
'((7 8 9) (d e f) (1 2 3)))
(void))
+
+(test-begin
+ "{once}, {1} and a simple pattern variable"
+ (check-match '(a a a a a a a a)
+ [(xlist a1 ^ {once} a2 ^ {1} a3 a4 ^ *)
+ (list a4 a3 a2 a1)]
+ '((a a a a a) a (a) a))
+ (void))