~ 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