summaryrefslogtreecommitdiff
path: root/Lib/chicken/tinyclos-multi-generic.patch
blob: 2a85f1a63878b79cc10435c319ea5269f9fb90b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# This patch is against chicken 1.92, but it should work just fine
# with older versions of chicken.  It adds support for mulit-argument
# generics, that is, generics now correctly handle adding methods
# with different lengths of specializer lists

# Comments, bugs, suggestions send to chicken-users@nongnu.org

# Patch written by John Lenz <lenz@cs.wisc.edu>

--- tinyclos.scm.old	2005-04-04 23:35:10.000000000 -0500
+++ tinyclos.scm	2005-04-05 14:03:26.740306763 -0500
@@ -868,13 +868,24 @@
     (##tinyclos#slot-set!
      generic
      'methods
-     (cons method
-	   (filter-in
-	    (lambda (m) 
-	      (let ([ms1 (method-specializers m)]
-		    [ms2 (method-specializers method)] )
-		(not (every2 (lambda (x y) (eq? x y)) ms1 ms2) ) ) )
-	    (##tinyclos#slot-ref generic 'methods))))
+       (let filter-in-method ([methods (##tinyclos#slot-ref generic 'methods)])
+         (if (null? methods)
+           (list method)
+           (let ([l1 (length (method-specializers method))]
+		 [l2 (length (method-specializers (##sys#slot methods 0)))])
+             (cond ((> l1 l2)
+                    (cons (##sys#slot methods 0) (filter-in-method (##sys#slot methods 1))))
+                   ((< l1 l2)
+                    (cons method methods))
+                   (else
+                     (let check-method ([ms1 (method-specializers method)]
+                                        [ms2 (method-specializers (##sys#slot methods 0))])
+                       (cond ((and (null? ms1) (null? ms2))
+                              (cons method (##sys#slot methods 1))) ;; skip the method already in the generic
+                             ((eq? (##sys#slot ms1 0) (##sys#slot ms2 0))
+                              (check-method (##sys#slot ms1 1) (##sys#slot ms2 1)))
+                             (else
+                               (cons (##sys#slot methods 0) (filter-in-method (##sys#slot methods 1))))))))))))
     (if (memq generic generic-invocation-generics)
 	(set! method-cache-tag (vector))
 	(%entity-cache-set! generic #f) )
@@ -946,9 +957,13 @@
       (lambda (args)
 	(let ([applicable
 	       (filter-in (lambda (method)
-			    (every2 applicable?
-				   (method-specializers method)
-				   args))
+                            (let check-applicable ([list1 (method-specializers method)]
+                                                   [list2 args])
+                              (cond ((null? list1) #t)
+                                    ((null? list2) #f)
+                                    (else
+                                      (and (applicable? (##sys#slot list1 0) (##sys#slot list2 0))
+                                           (check-applicable (##sys#slot list1 1) (##sys#slot list2 1)))))))
 			  (generic-methods generic) ) ] )
 	  (if (or (null? applicable) (null? (##sys#slot applicable 1))) 
 	      applicable
@@ -975,8 +990,10 @@
 	   [else
 	    (cond ((and (null? specls1) (null? specls2))
 		   (##sys#error "two methods are equally specific" generic))
-		  ((or (null? specls1) (null? specls2))
-		   (##sys#error "two methods have different number of specializers" generic))
+		  ;((or (null? specls1) (null? specls2))
+		  ; (##sys#error "two methods have different number of specializers" generic))
+                  ((null? specls1) #f)
+                  ((null? specls2) #t)
 		  ((null? args)
 		   (##sys#error "fewer arguments than specializers" generic))
 		  (else
@@ -1235,7 +1252,7 @@
 (define <tcp-listener> (make-primitive-class "tcp-listener" <structure>))
 (define <c++-object> (make <class> 'name "c++-object" 'direct-supers (list <object>) 'direct-slots '(this)))
 
-(set! method-caching-enabled #t)
+;(set! method-caching-enabled #t)
 
 
 ;;; Utilities: