Allow dotted list syntax for match expanders, e.g. (match v [(some-match-expander a b c . d) (displayln (list a b c d))])
This commit is contained in:
parent
9f2db6a915
commit
bcbedc56a3
|
@ -646,6 +646,30 @@ expander and @racket[len] always returns @racket[0].
|
|||
(len nil)
|
||||
(len (cons 1 nil))
|
||||
(len (cons 1 (cons 2 nil)))]
|
||||
|
||||
Match expanders accept any syntax pair whose first element is an
|
||||
@racket[identifier?] bound to the expander. The following example
|
||||
shows a match expander which can be called with an improper syntax
|
||||
list of the form @racket[(expander a b . rest)].
|
||||
@examples[#:label #f
|
||||
#:eval match-eval
|
||||
(eval:no-prompt
|
||||
(define-match-expander my-vector
|
||||
(λ (stx)
|
||||
(syntax-case stx ()
|
||||
[(_ pat ...)
|
||||
#'(vector pat ...)]
|
||||
[(_ pat ... . rest-pat)
|
||||
#'(app vector->list (list-rest pat ... rest-pat))]))))
|
||||
(match #(1 2 3 4 5)
|
||||
[(my-vector a b . rest)
|
||||
(list->vector (append rest (list a b)))])]
|
||||
|
||||
@history[
|
||||
#:changed "6.9.0.2"
|
||||
@elem{Match expanders now allowed any syntax pair whose first element is an
|
||||
@racket[identifier?] bound to the expander. The example above did not work
|
||||
with previous versions.}]
|
||||
}
|
||||
|
||||
@defthing[prop:match-expander struct-type-property?]{
|
||||
|
|
|
@ -158,6 +158,25 @@
|
|||
(check = 7 (match (list (make-point 2 3))
|
||||
[(list (Point (app add1 x) (app add1 y))) (+ x y)]))
|
||||
))
|
||||
|
||||
(test-case "Expander which accepts a dotted list syntax"
|
||||
(let ()
|
||||
(define-match-expander bar
|
||||
(lambda (stx)
|
||||
(syntax-case stx ()
|
||||
[(_ a b . c)
|
||||
#'(and (app sub1 c) (app a b))]))
|
||||
+)
|
||||
;; check that it works as a pattern
|
||||
(check = 3 (match 4 [(bar add1 5 . x) x]))
|
||||
;; check that sub-patterns still work on the dotted argument
|
||||
(check = 3 (match 4 [(bar add1 5 . (? number? y)) y]))
|
||||
(check = 3 (match 4 [(bar add1 5 ? number? y) y]))
|
||||
;; check that it works inside other patterns, e.g. a list
|
||||
(check-equal? '(4 6 8) (match '(5 7 9)
|
||||
[(list (bar add1 number? . x) ...) x]))
|
||||
;; check that it works as an expression
|
||||
(check = 12 (apply bar '(3 4 5))))) ; bar works like +
|
||||
))
|
||||
|
||||
(define simple-tests
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
regexp pregexp list-rest list-no-order hash-table
|
||||
quasiquote mcons list* mlist)
|
||||
(lambda (x y) (eq? (syntax-e x) (syntax-e y)))
|
||||
[(expander args ...)
|
||||
[(expander . args)
|
||||
(and (identifier? #'expander)
|
||||
(syntax-local-value/record #'expander match-expander?))
|
||||
(match-expander-transform
|
||||
|
|
Loading…
Reference in New Issue
Block a user