~ chicken-core (chicken-5) a84501c6e9236ada00545869204f3dcd3a1b7511
commit a84501c6e9236ada00545869204f3dcd3a1b7511 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Fri Aug 12 12:12:43 2011 +0200 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Fri Aug 12 12:12:43 2011 +0200 handle complex types in specialization-match diff --git a/scrutinizer.scm b/scrutinizer.scm index e5460cdd..17da5a18 100755 --- a/scrutinizer.scm +++ b/scrutinizer.scm @@ -1203,48 +1203,92 @@ (print "; END OF FILE")))) (define (match-specialization typelist atypes exact) - ;; - does not accept complex procedure or list/vector/pair types in typelist! - ;; - "exact" means: "or"-type in atypes is not allowed + ;; - does not accept complex procedure types in typelist! + ;; - "exact" means: "or"-type in atypes is not allowed (used for predicates) (define (match st t) (cond ((eq? st t)) - ((and (pair? t) (memq (car t) '(vector list))) - (match st (car t))) ;XXX hack, insufficient - ((and (pair? t) (eq? 'pair (car t))) - (match st 'pair)) ;XXX same here + ((memq st '(vector list)) + (match (list st '*) t)) + ((memq t '(vector list)) + (match st (list t '*))) + ((eq? 'pair st) + (match '(pair * *) t)) + ((eq? 'pair t) + (match st '(pair * *))) + ((and (pair? t) (eq? 'or (car t))) + ((if exact every any) (cut match st <>) (cdr t))) + ((and (pair? t) (eq? 'and (car t))) + (every (cut match st <>) (cdr t))) + ((and (pair? t) (eq? 'procedure (car t))) + (match st 'procedure)) ((pair? st) (case (car st) ((not) (matchnot (cadr st) t)) ((or) (any (cut match <> t) (cdr st))) ((and) (every (cut match <> t) (cdr st))) - ((procedure) (bomb "match-specialization: invalid complex procedure type" st)) + ((list) + (or (eq? 'null t) + (and (pair? t) + (eq? 'list (car t)) + (match (second st) (second t))))) + ((vector) + (and (pair? t) + (eq? 'vector (car t)) + (match (second st) (second t)))) + ((pair) + (and (pair? t) + (eq? 'pair (car t)) + (match (second st) (second t)) + (match (third st) (third t)))) + ((procedure) ;XXX + (match 'procedure t)) (else (equal? st t)))) ((eq? st '*)) ;; "list" different from "number": a pair is not necessarily a list: - ((eq? st 'list) (eq? t 'list)) ((eq? st 'number) (match '(or fixnum float) t)) - ((pair? t) - (case (car t) - ((or) ((if exact every any) (cut match st <>) (cdr t))) - ((and) (every (cut match st <>) (cdr t))) - ((procedure) (match st 'procedure)) - ;; (not ...) should not occur - (else (equal? st t)))) (else (equal? st t)))) (define (matchnot st t) (cond ((eq? st t) #f) - ((and (pair? t) (memq (car t) '(vector list))) - (match st (car t))) ;XXX hack, insufficient - ((and (pair? t) (eq? 'pair (car t))) - (match st 'pair)) ;XXX same here - ((eq? 'list t) (matchnot st '(or null pair))) + ((memq st '(vector list)) + (matchnot (list st '*) t)) + ((memq t '(vector list)) + (matchnot st (list t '*))) + ((eq? 'pair st) + (matchnot '(pair * *) t)) + ((eq? 'pair t) + (matchnot st '(pair * *))) + ((and (pair? t) (eq? 'or (car t))) + (every (cut matchnot st <>) (cdr t))) + ((and (pair? t) (eq? 'and (car t))) + (any (cut matchnot st <>) (cdr t))) ;XXX test for "exact" here, too? + ((eq? 'number st) (not (match '(or fixnum float) t))) ((eq? 'number t) (matchnot st '(or fixnum float))) ((eq? '* t) #f) - ((eq? 'list st) (not (match '(or null pair) t))) - ((eq? 'number st) (not (match '(or fixnum float) t))) - ((pair? t) - (case (car t) - ((or) (every (cut matchnot st <>) (cdr t))) - ((and) (any (cut matchnot st <>) (cdr t))) ;XXX test for "exact" here, too? + ((eq? 'null st) + (or (not (pair? t)) + (not (eq? 'list (car t))))) + ((pair? st) + (case (car st) + ;;XXX "and" not handled here + ((or) (every (cut matchnot <> t) (cdr t))) + ((list) + (and (not (eq? 'null t)) + (or (not (pair? t)) + (and (eq? 'list (car t)) + (matchnot (second st) (second t))) + (matchnot `(pair ,(second st) *) t)))) ;XXX too conservative? + ((vector) + (or (not (pair? t)) + (not (eq? 'vector (car t))) + (matchnot (second st) (second t)))) + ((pair) + (or (not (pair? t)) + (case (car t) + ((list) (matchnot (second st) (second t))) + ((pair) + (and (matchnot (second st) (second t)) + (matchnot (third st) (third t)))) + (else #f)))) (else (not (match st t))))) (else (not (match st t))))) (let loop ((tl typelist) (atypes atypes))Trap