Add mlist patterns, and handle ...
svn: r9774
This commit is contained in:
parent
ad4cd48f8b
commit
2bf93a2fa0
|
@ -307,6 +307,8 @@
|
||||||
[maxs (GSeq-maxs first)]
|
[maxs (GSeq-maxs first)]
|
||||||
[onces? (GSeq-onces? first)]
|
[onces? (GSeq-onces? first)]
|
||||||
[tail (GSeq-tail first)]
|
[tail (GSeq-tail first)]
|
||||||
|
[mutable? (GSeq-mutable? first)]
|
||||||
|
[make-Pair (if mutable? make-MPair make-Pair)]
|
||||||
[k (Row-rhs (car block))]
|
[k (Row-rhs (car block))]
|
||||||
[xvar (car (generate-temporaries (list #'x)))]
|
[xvar (car (generate-temporaries (list #'x)))]
|
||||||
[complete-heads-pattern
|
[complete-heads-pattern
|
||||||
|
|
|
@ -48,17 +48,19 @@
|
||||||
;; p : the repeated pattern
|
;; p : the repeated pattern
|
||||||
;; dd : the ... stx
|
;; dd : the ... stx
|
||||||
;; rest : the syntax for the rest
|
;; rest : the syntax for the rest
|
||||||
(define (dd-parse parse p dd rest)
|
(define (dd-parse parse p dd rest #:mutable [mutable? #f])
|
||||||
(let* ([count (ddk? dd)]
|
(let* ([count (ddk? dd)]
|
||||||
[min (and (number? count) count)])
|
[min (and (number? count) count)])
|
||||||
(make-GSeq (parameterize ([match-...-nesting (add1 (match-...-nesting))])
|
(make-GSeq
|
||||||
|
(parameterize ([match-...-nesting (add1 (match-...-nesting))])
|
||||||
(list (list (parse p))))
|
(list (list (parse p))))
|
||||||
(list min)
|
(list min)
|
||||||
;; no upper bound
|
;; no upper bound
|
||||||
(list #f)
|
(list #f)
|
||||||
;; patterns in p get bound to lists
|
;; patterns in p get bound to lists
|
||||||
(list #f)
|
(list #f)
|
||||||
(parse rest))))
|
(parse rest)
|
||||||
|
mutable?)))
|
||||||
|
|
||||||
;; stx : the syntax object for the whole pattern
|
;; stx : the syntax object for the whole pattern
|
||||||
;; cert : the certifier
|
;; cert : the certifier
|
||||||
|
@ -93,9 +95,11 @@
|
||||||
[(not (car acc)) (cdr acc)]
|
[(not (car acc)) (cdr acc)]
|
||||||
[else acc])])
|
[else acc])])
|
||||||
(make-Struct id pred (get-lineage (cert struct-name)) acc
|
(make-Struct id pred (get-lineage (cert struct-name)) acc
|
||||||
(if (eq? '_ (syntax-e pats))
|
(cond [(eq? '_ (syntax-e pats))
|
||||||
(map make-Dummy acc)
|
(map make-Dummy acc)]
|
||||||
(let* ([ps (syntax->list pats)])
|
[(syntax->list pats)
|
||||||
|
=>
|
||||||
|
(lambda (ps)
|
||||||
(unless (= (length ps) (length acc))
|
(unless (= (length ps) (length acc))
|
||||||
(raise-syntax-error
|
(raise-syntax-error
|
||||||
'match
|
'match
|
||||||
|
@ -104,7 +108,11 @@
|
||||||
(syntax->datum struct-name) (length acc)
|
(syntax->datum struct-name) (length acc)
|
||||||
(length ps))
|
(length ps))
|
||||||
stx pats))
|
stx pats))
|
||||||
(map parse ps))))))))
|
(map parse ps))]
|
||||||
|
[else (raise-syntax-error
|
||||||
|
'match
|
||||||
|
"improper syntax for struct pattern"
|
||||||
|
stx pats)]))))))
|
||||||
|
|
||||||
(define (trans-match pred transformer pat)
|
(define (trans-match pred transformer pat)
|
||||||
(make-And (list (make-Pred pred) (make-App transformer pat))))
|
(make-And (list (make-Pred pred) (make-App transformer pat))))
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
(GSeq-mins p1)
|
(GSeq-mins p1)
|
||||||
(GSeq-maxs p1)
|
(GSeq-maxs p1)
|
||||||
(GSeq-onces? p1)
|
(GSeq-onces? p1)
|
||||||
(append-pats (GSeq-tail p1) p2))]
|
(append-pats (GSeq-tail p1) p2)
|
||||||
|
(GSeq-mutable? p1))]
|
||||||
[(Null? p1) p2]
|
[(Null? p1) p2]
|
||||||
[else (error 'match "illegal input to append-pats")]))
|
[else (error 'match "illegal input to append-pats")]))
|
||||||
|
|
||||||
|
@ -55,7 +56,8 @@
|
||||||
(list #f)
|
(list #f)
|
||||||
;; patterns in p get bound to lists
|
;; patterns in p get bound to lists
|
||||||
(list #f)
|
(list #f)
|
||||||
(make-Null (make-Dummy #f))))]
|
(make-Null (make-Dummy #f))
|
||||||
|
#f))]
|
||||||
[(a . b) (make-Pair (pq #'a) (pq #'b))]
|
[(a . b) (make-Pair (pq #'a) (pq #'b))]
|
||||||
;; the hard cases
|
;; the hard cases
|
||||||
[#(p ...)
|
[#(p ...)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
(define (parse stx) (parse/cert stx cert))
|
(define (parse stx) (parse/cert stx cert))
|
||||||
(syntax-case* stx (not var struct box cons list vector ? and or quote app
|
(syntax-case* stx (not var struct box cons list vector ? and or quote app
|
||||||
regexp pregexp list-rest list-no-order hash-table
|
regexp pregexp list-rest list-no-order hash-table
|
||||||
quasiquote mcons list*)
|
quasiquote mcons list* mlist)
|
||||||
(lambda (x y) (eq? (syntax-e x) (syntax-e y)))
|
(lambda (x y) (eq? (syntax-e x) (syntax-e y)))
|
||||||
[(expander args ...)
|
[(expander args ...)
|
||||||
(and (identifier? #'expander)
|
(and (identifier? #'expander)
|
||||||
|
@ -104,7 +104,8 @@
|
||||||
(cons max (map (lambda _ 1) ps))
|
(cons max (map (lambda _ 1) ps))
|
||||||
;; vars in lp are lists, vars elsewhere are not
|
;; vars in lp are lists, vars elsewhere are not
|
||||||
(cons #f (map (lambda _ #t) ps))
|
(cons #f (map (lambda _ #t) ps))
|
||||||
(make-Null (make-Dummy #f))))]
|
(make-Null (make-Dummy #f))
|
||||||
|
#f))]
|
||||||
[(list-no-order p ...)
|
[(list-no-order p ...)
|
||||||
(ormap ddk? (syntax->list #'(p ...)))
|
(ormap ddk? (syntax->list #'(p ...)))
|
||||||
(raise-syntax-error
|
(raise-syntax-error
|
||||||
|
@ -118,16 +119,26 @@
|
||||||
(map (lambda _ 1) ps)
|
(map (lambda _ 1) ps)
|
||||||
;; all of these patterns get bound to only one thing
|
;; all of these patterns get bound to only one thing
|
||||||
(map (lambda _ #t) ps)
|
(map (lambda _ #t) ps)
|
||||||
(make-Null (make-Dummy #f))))]
|
(make-Null (make-Dummy #f))
|
||||||
|
#f))]
|
||||||
[(list) (make-Null (make-Dummy stx))]
|
[(list) (make-Null (make-Dummy stx))]
|
||||||
|
[(mlist) (make-Null (make-Dummy stx))]
|
||||||
[(list ..)
|
[(list ..)
|
||||||
(ddk? #'..)
|
(ddk? #'..)
|
||||||
(raise-syntax-error 'match "incorrect use of ... in pattern" stx #'..)]
|
(raise-syntax-error 'match "incorrect use of ... in pattern" stx #'..)]
|
||||||
|
[(mlist ..)
|
||||||
|
(ddk? #'..)
|
||||||
|
(raise-syntax-error 'match "incorrect use of ... in pattern" stx #'..)]
|
||||||
[(list p .. . rest)
|
[(list p .. . rest)
|
||||||
(ddk? #'..)
|
(ddk? #'..)
|
||||||
(dd-parse parse #'p #'.. (syntax/loc stx (list . rest)))]
|
(dd-parse parse #'p #'.. (syntax/loc stx (list . rest)))]
|
||||||
|
[(mlist p .. . rest)
|
||||||
|
(ddk? #'..)
|
||||||
|
(dd-parse parse #'p #'.. (syntax/loc stx (list . rest)) #:mutable #t)]
|
||||||
[(list e es ...)
|
[(list e es ...)
|
||||||
(make-Pair (parse #'e) (parse (syntax/loc stx (list es ...))))]
|
(make-Pair (parse #'e) (parse (syntax/loc stx (list es ...))))]
|
||||||
|
[(mlist e es ...)
|
||||||
|
(make-MPair (parse #'e) (parse (syntax/loc stx (mlist es ...))))]
|
||||||
[(list* . rest)
|
[(list* . rest)
|
||||||
(parse (syntax/loc stx (list-rest . rest)))]
|
(parse (syntax/loc stx (list-rest . rest)))]
|
||||||
[(list-rest e)
|
[(list-rest e)
|
||||||
|
|
|
@ -84,7 +84,8 @@
|
||||||
;; onces? : listof boolean -- is this pattern being bound only once (take the
|
;; onces? : listof boolean -- is this pattern being bound only once (take the
|
||||||
;; car of the variables)
|
;; car of the variables)
|
||||||
;; tail : pattern
|
;; tail : pattern
|
||||||
(define-struct (GSeq Pat) (headss mins maxs onces? tail) #:transparent)
|
;; mutable? : is this for mutable lists?
|
||||||
|
(define-struct (GSeq Pat) (headss mins maxs onces? tail mutable?) #:transparent)
|
||||||
|
|
||||||
;; match with equal?
|
;; match with equal?
|
||||||
;; v is a quotable scheme value
|
;; v is a quotable scheme value
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#lang scheme/base
|
#lang scheme/base
|
||||||
|
|
||||||
(require scheme/match
|
(require scheme/match
|
||||||
|
scheme/mpair
|
||||||
(for-syntax scheme/base)
|
(for-syntax scheme/base)
|
||||||
(prefix-in m: mzlib/match))
|
(prefix-in m: mzlib/match)
|
||||||
|
(only-in srfi/13 string-contains))
|
||||||
(require (planet "test-compat2.ss" ("schematics" "schemeunit.plt" 2 10)))
|
(require (planet "test-compat2.ss" ("schematics" "schemeunit.plt" 2 10)))
|
||||||
|
|
||||||
|
|
||||||
|
@ -516,6 +518,16 @@
|
||||||
[(mcons a b) (+ a b)]
|
[(mcons a b) (+ a b)]
|
||||||
[_ 'no]))
|
[_ 'no]))
|
||||||
|
|
||||||
|
(comp 3
|
||||||
|
(match (mlist 1 2)
|
||||||
|
[(mlist a b) (+ a b)]
|
||||||
|
[_ 'no]))
|
||||||
|
|
||||||
|
(comp 3
|
||||||
|
(match (mlist 1 2)
|
||||||
|
[(mlist a ...) (apply + a)]
|
||||||
|
[_ 'no]))
|
||||||
|
|
||||||
(comp 1
|
(comp 1
|
||||||
(match (box 'x) ('#&x 1) (else #f)))
|
(match (box 'x) ('#&x 1) (else #f)))
|
||||||
|
|
||||||
|
@ -528,6 +540,16 @@
|
||||||
(match 1)
|
(match 1)
|
||||||
'no))
|
'no))
|
||||||
|
|
||||||
|
(comp 'yes
|
||||||
|
(with-handlers ([exn:fail:syntax? (lambda _ 'yes)]
|
||||||
|
[values (lambda _ 'no)])
|
||||||
|
(expand #'(let ()
|
||||||
|
(define-struct foo (bar))
|
||||||
|
(define the-bar (match (make-foo 42)
|
||||||
|
[(struct foo bar) ;; note the bad syntax
|
||||||
|
bar]))
|
||||||
|
0))))
|
||||||
|
|
||||||
;; raises error
|
;; raises error
|
||||||
(comp 'yes (with-handlers ([exn:fail:syntax? (lambda _ 'yes)])
|
(comp 'yes (with-handlers ([exn:fail:syntax? (lambda _ 'yes)])
|
||||||
(expand (quote-syntax (match '(1 x 2 y 3 z)
|
(expand (quote-syntax (match '(1 x 2 y 3 z)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user