Support prefab struct literals in quasipatterns.
Fixes PR 10050. svn: r17495
This commit is contained in:
parent
3006abec4b
commit
ac9d2d8d9e
|
@ -8,7 +8,8 @@
|
||||||
"reorder.ss"
|
"reorder.ss"
|
||||||
scheme/struct-info
|
scheme/struct-info
|
||||||
scheme/stxparam
|
scheme/stxparam
|
||||||
scheme/nest)
|
scheme/nest
|
||||||
|
unstable/syntax)
|
||||||
|
|
||||||
(provide compile*)
|
(provide compile*)
|
||||||
|
|
||||||
|
@ -43,8 +44,8 @@
|
||||||
esc)])
|
esc)])
|
||||||
#`[(#,predicate-stx #,x) rhs]))
|
#`[(#,predicate-stx #,x) rhs]))
|
||||||
(define (compile-con-pat accs pred pat-acc)
|
(define (compile-con-pat accs pred pat-acc)
|
||||||
(with-syntax ([(tmps ...) (generate-temporaries accs)])
|
(with-syntax* ([(tmps ...) (generate-temporaries accs)]
|
||||||
(with-syntax ([(accs ...) accs]
|
[(accs ...) accs]
|
||||||
[pred pred]
|
[pred pred]
|
||||||
[body (compile*
|
[body (compile*
|
||||||
(append (syntax->list #'(tmps ...)) xs)
|
(append (syntax->list #'(tmps ...)) xs)
|
||||||
|
@ -56,7 +57,7 @@
|
||||||
(Row-vars-seen row)))
|
(Row-vars-seen row)))
|
||||||
rows)
|
rows)
|
||||||
esc)])
|
esc)])
|
||||||
#`[(pred #,x) (let ([tmps (accs #,x)] ...) body)])))
|
#`[(pred #,x) (let ([tmps (accs #,x)] ...) body)]))
|
||||||
(cond
|
(cond
|
||||||
[(eq? 'box k)
|
[(eq? 'box k)
|
||||||
(compile-con-pat (list #'unbox) #'box? (compose list Box-p))]
|
(compile-con-pat (list #'unbox) #'box? (compose list Box-p))]
|
||||||
|
@ -116,7 +117,22 @@
|
||||||
[accs (Struct-accessors s)]
|
[accs (Struct-accessors s)]
|
||||||
[pred (Struct-pred s)])
|
[pred (Struct-pred s)])
|
||||||
(compile-con-pat accs pred Struct-ps))]
|
(compile-con-pat accs pred Struct-ps))]
|
||||||
[else (error 'compile "bad key: ~a" k)]))
|
;; it's a prefab struct
|
||||||
|
[(list? k)
|
||||||
|
(let* ([s (Row-first-pat (car rows))]
|
||||||
|
[key (PrefabStruct-key s)]
|
||||||
|
[pats (PrefabStruct-ps s)])
|
||||||
|
(with-syntax*
|
||||||
|
([struct-type-id (syntax-local-lift-expression #`(prefab-key->struct-type '#,key #,(length pats)))]
|
||||||
|
[(_ _ _ acc-proc _ _ _ _) (syntax-local-lift-values-expression 8 #`(struct-type-info struct-type-id))])
|
||||||
|
(compile-con-pat
|
||||||
|
(for/list ([p pats]
|
||||||
|
[i (in-naturals)])
|
||||||
|
#`(make-struct-field-accessor acc-proc #,i)
|
||||||
|
#;#`(lambda (val) (acc-proc val #,i)))
|
||||||
|
#`(struct-type-make-predicate struct-type-id)
|
||||||
|
PrefabStruct-ps)))]
|
||||||
|
[else (error 'match-compile "bad key: ~a" k)]))
|
||||||
|
|
||||||
|
|
||||||
;; produces the syntax for a let clause
|
;; produces the syntax for a let clause
|
||||||
|
|
|
@ -57,6 +57,16 @@
|
||||||
(pq #'rest)
|
(pq #'rest)
|
||||||
#f))]
|
#f))]
|
||||||
[(a . b) (make-Pair (pq #'a) (pq #'b))]
|
[(a . b) (make-Pair (pq #'a) (pq #'b))]
|
||||||
|
;; prefab structs
|
||||||
|
[struct
|
||||||
|
(prefab-struct-key (syntax-e #'struct))
|
||||||
|
(let ([key (prefab-struct-key (syntax-e #'struct))]
|
||||||
|
[pats (cdr (vector->list (struct->vector (syntax-e #'struct))))])
|
||||||
|
(make-And (list (make-Pred #`(struct-type-make-predicate (prefab-key->struct-type '#,key #,(length pats))))
|
||||||
|
(make-App #'struct->vector
|
||||||
|
(make-Vector (cons (make-Dummy #f) (map pq pats))))))
|
||||||
|
#;
|
||||||
|
(make-PrefabStruct key (map pq pats)))]
|
||||||
;; the hard cases
|
;; the hard cases
|
||||||
[#(p ...)
|
[#(p ...)
|
||||||
(ormap (lambda (p)
|
(ormap (lambda (p)
|
||||||
|
|
|
@ -59,6 +59,10 @@
|
||||||
;; ps is a listof patterns
|
;; ps is a listof patterns
|
||||||
(define-struct (Struct CPat) (id pred super accessors ps) #:transparent)
|
(define-struct (Struct CPat) (id pred super accessors ps) #:transparent)
|
||||||
|
|
||||||
|
;; ps is a listof patterns
|
||||||
|
;; key is a prefab struct key
|
||||||
|
(define-struct (PrefabStruct CPat) (key pred accessors ps) #:transparent)
|
||||||
|
|
||||||
;; both fields are lists of pats
|
;; both fields are lists of pats
|
||||||
(define-struct (HashTable CPat) (key-pats val-pats) #:transparent)
|
(define-struct (HashTable CPat) (key-pats val-pats) #:transparent)
|
||||||
|
|
||||||
|
@ -105,6 +109,7 @@
|
||||||
;; the result is #f if p is not a constructor pattern
|
;; the result is #f if p is not a constructor pattern
|
||||||
(define (pat-key p)
|
(define (pat-key p)
|
||||||
(cond [(Struct? p) (get-key (Struct-id p))]
|
(cond [(Struct? p) (get-key (Struct-id p))]
|
||||||
|
[(PrefabStruct? p) (list (PrefabStruct-key p))]
|
||||||
[(Box? p) 'box]
|
[(Box? p) 'box]
|
||||||
[(Vector? p) 'vector]
|
[(Vector? p) 'vector]
|
||||||
[(Pair? p) 'pair]
|
[(Pair? p) 'pair]
|
||||||
|
@ -167,6 +172,8 @@
|
||||||
(merge (map bound-vars (Vector-ps p)))]
|
(merge (map bound-vars (Vector-ps p)))]
|
||||||
[(Struct? p)
|
[(Struct? p)
|
||||||
(merge (map bound-vars (Struct-ps p)))]
|
(merge (map bound-vars (Struct-ps p)))]
|
||||||
|
[(PrefabStruct? p)
|
||||||
|
(merge (map bound-vars (PrefabStruct-ps p)))]
|
||||||
[(App? p)
|
[(App? p)
|
||||||
(bound-vars (App-p p))]
|
(bound-vars (App-p p))]
|
||||||
[(Not? p) null]
|
[(Not? p) null]
|
||||||
|
|
|
@ -608,4 +608,22 @@
|
||||||
(match `(begin 1 2 3)
|
(match `(begin 1 2 3)
|
||||||
[`(begin ,es ... ,en)
|
[`(begin ,es ... ,en)
|
||||||
(list es en)]))
|
(list es en)]))
|
||||||
|
|
||||||
|
(comp '(a b c)
|
||||||
|
(let ()
|
||||||
|
|
||||||
|
(define-struct foo (a b c) #:prefab)
|
||||||
|
(match (make-foo 'a 'b 'c)
|
||||||
|
[`#s(foo ,x ,y ,z)
|
||||||
|
(list x y z)])))
|
||||||
|
(comp '(a b c)
|
||||||
|
(let ()
|
||||||
|
|
||||||
|
(define-struct foo (a b c) #:prefab)
|
||||||
|
(define-struct (bar foo) (d) #:prefab)
|
||||||
|
(match (make-bar 'a 'b 'c 1)
|
||||||
|
[`#s((bar foo 3) ,x ,y ,z ,w)
|
||||||
|
(list x y z)])
|
||||||
))
|
))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user