~ chicken-core (chicken-5) cc95833b8521a08486d1f704e43a50dc03da070a


commit cc95833b8521a08486d1f704e43a50dc03da070a
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Wed Aug 17 15:06:10 2011 +0200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Wed Aug 17 15:06:10 2011 +0200

    handle forall in special cases for types.db

diff --git a/scrutinizer.scm b/scrutinizer.scm
index ee4add57..2b5a9222 100755
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -84,13 +84,19 @@
 ; specialization specifiers:
 ;
 ;   SPECIALIZATION = ((MVAL ... [#!rest MVAL]) [RESULTS] TEMPLATE)
-;   MVAL = VAL | (not VAL) | (or VAL ...) | (and VAL ...)
+;   MVAL = VAL 
+;        | (not MVAL)
+;        | (or MVAL ...)
+;        | (and MVAL ...)
+;        | (forall (VAR1 ...) MVAL)
 ;   TEMPLATE = #(INDEX)
 ;            | #(INDEX ...)
 ;            | #(SYMBOL)
 ;            | INTEGER | SYMBOL | STRING
 ;            | (quote CONSTANT)
 ;            | (TEMPLATE . TEMPLATE)
+;
+;   - complex procedure types can currently not be matched
 
 
 (define-constant +fragment-max-length+ 6)
@@ -106,7 +112,6 @@
 	(aliased '())
 	(noreturn #f)
 	(dropped-branches 0)
-	(typecases 0)
 	(safe-calls 0))
 
     (define (constant-result lit)
@@ -361,7 +366,7 @@
       (define (optargs a)
 	(memq a '(#!rest #!optional)))
       (let loop ((args1 args1) (args2 args2) (opt1 #f) (opt2 #f))
-	(d "  args ~a ~a ~a ~a" args1 args2 opt1 opt2)
+	(dd "  args ~a ~a ~a ~a" args1 args2 opt1 opt2)
 	(cond ((null? args1) 
 	       (or opt2
 		   (null? args2)
@@ -895,10 +900,10 @@
 		  (let ((ts (walk (first subs) e loc #f #f flow ctags)))
 		    ;; first exp is always a variable so ts must be of length 1
 		    (let loop ((types params) (subs (cdr subs)))
-		      (cond ((null? types) (bomb "no more clauses in `compiler-typecase'" types))
+		      (cond ((null? types)
+			     (bomb "no clause applies in `compiler-typecase'" params (car ts)))
 			    ((match-specialization (list (car types)) ts '() #f)
 			     ;; drops exp
-			     (set! typecases (add1 typecases))
 			     (copy-node! (car subs) n)
 			     (walk n e loc dest tail flow ctags))
 			    (else
@@ -923,8 +928,6 @@
 	(debugging 'x "safe calls" safe-calls)) ;XXX
       (when (positive? dropped-branches)
 	(debugging 'x "dropped branches" dropped-branches)) ;XXX
-      (when (positive? typecases)
-	(debugging 'x "expanded typecases" typecases)) ;XXX
       rn)))
 
 
@@ -1321,20 +1324,27 @@
        (lambda (e)
 	 (let* ((name (car e))
 		(old (variable-mark name '##compiler#type))
-		(new (cadr e))
-		(specs (and (pair? (cddr e)) (cddr e))))
-	   (when (pair? new)
-	     (case (car new)
-	       ((procedure!)
-		(mark-variable name '##compiler#enforce #t)
-		(set-car! new 'procedure))
-	       ((procedure!? procedure?!)
-		(mark-variable name '##compiler#enforce #t)
-		(mark-variable name '##compiler#predicate (cadr new))
-		(set! new (cons 'procedure (cddr new))))
-	       ((procedure?)
-		(mark-variable name '##compiler#predicate (cadr new))
-		(set! new (cons 'procedure (cddr new))))))
+		(specs (and (pair? (cddr e)) (cddr e)))
+		(new
+		 (let adjust ((new (cadr e)))
+		   (if (pair? new)
+		       (case (car new)
+			 ((procedure!)
+			  (mark-variable name '##compiler#enforce #t)
+			  `(procedure ,@(cdr new)))
+			 ((procedure!? procedure?!)
+			  (mark-variable name '##compiler#enforce #t)
+			  (mark-variable name '##compiler#predicate (cadr new))
+			  `(procedure ,@(cddr new)))
+			 ((procedure?)
+			  (mark-variable name '##compiler#predicate (cadr new))
+			  `(procedure ,@(cddr new)))
+			 ((forall)
+			  `(forall ,(cadr new) ,(adjust (caddr new))))
+			 (else new))
+		       new))))
+	   ;; validation is needed, even though .types-files can be considered
+	   ;; correct, because type variables have to be renamed:
 	   (let-values (((t _) (validate-type new name)))
 	     (unless t
 	       (warning "invalid type specification" name new))
@@ -1382,6 +1392,13 @@
 (define (match-specialization typelist atypes typeenv exact)
   ;; - does not accept complex procedure types in typelist!
   ;; - "exact" means: "or"-type in atypes is not allowed (used for predicates)
+  ;;
+  ;;XXX It is not entirely clear to me whether we can simply use the "match"
+  ;;    above instead of having a second matcher. The only difference
+  ;;    seems to be the specialization-types allow "not" and disallow
+  ;;    complex procedure types (the latter would be handled by the
+  ;;    full matcher). And what about "exact"?
+  ;;
   (define (match st t)
     (cond ((eq? st t))
 	  ((and (symbol? st) (assq st typeenv)) => 
@@ -1412,10 +1429,10 @@
 	   ((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))
 	  ((and (pair? t) (eq? 'forall (car t)))
 	   (match st (third t))) ; assumes typeenv has already been extracted
+	  ((and (pair? t) (eq? 'procedure (car t)))
+	   (match st 'procedure))
 	  ((pair? st)
 	   (case (car st)
 	     ((forall)
@@ -1437,8 +1454,8 @@
 		   (eq? 'pair (car t))
 		   (match (second st) (second t))
 		   (match (third st) (third t))))
-	     ((procedure) 		;XXX
-	      (match 'procedure t))
+	     ((procedure) 		
+	      (bomb "match-specialization: can not match complex procedure type" st))
 	     (else (equal? st t))))
 	  ((eq? st '*))
 	  ;; "list" different from "number": a pair is not necessarily a list:
diff --git a/types.db b/types.db
index 33a2ee8e..a92f4323 100644
--- a/types.db
+++ b/types.db
@@ -62,12 +62,21 @@
 (pair? (procedure? pair pair? (*) boolean))
 
 (cons (procedure cons (* *) pair))
+;* (cons (forall (a b) (procedure cons (a b) (pair a b))))
+
 (##sys#cons (procedure ##sys#cons (* *) pair))
+;* (##sys#cons (forall (a b) (procedure ##sys#cons (a b) (pair a b))))
 
 (car (procedure! car (pair) *) ((pair) (##core#inline "C_u_i_car" #(1))))
+;* (car (forall (a) (procedure! car ((pair a *)) a) ((pair) (##core#inline "C_u_i_car" #(1))))
 (cdr (procedure! cdr (pair) *) ((pair) (##core#inline "C_u_i_cdr" #(1))))
+;* (cdr (forall (a) (procedure! cdr ((pair * a)) a) ((pair) (##core#inline "C_u_i_cdr" #(1))))
 
 (caar (procedure! caar (pair) *))
+;* (caar (forall (a) (procedure! caar ((pair (pair a *) *)) a))
+
+;*XXX ...
+
 (cadr (procedure! cadr (pair) *))
 (cdar (procedure! cdar (pair) *))
 (cddr (procedure! cddr (pair) *))
@@ -497,12 +506,18 @@
 (values (procedure values (#!rest values) . *))
 (##sys#values (procedure ##sys#values (#!rest values) . *))
 
-(call-with-values (procedure! call-with-values ((procedure () . *) procedure) . *)
+(call-with-values (procedure! call-with-values ((procedure () . *) procedure) . *))
+
+;XXX match-specialization can't handle complex procedure types yet
+#;(call-with-values (procedure! call-with-values ((procedure () . *) procedure) . *)
   (((procedure () *) *) (let ((#(tmp1) #(1)))
 			  (let ((#(tmp2) #(2)))
 			    (#(tmp2) (#(tmp1)))))))
 
 (##sys#call-with-values
+ (procedure! ##sys#call-with-values ((procedure () . *) procedure) . *))
+
+#;(##sys#call-with-values
  (procedure! ##sys#call-with-values ((procedure () . *) procedure) . *)
  (((procedure () *) *) (let ((#(tmp1) #(1)))
 			 (let ((#(tmp2) #(2)))
Trap