summaryrefslogtreecommitdiff
path: root/module/oop
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2014-12-18 12:51:11 +0100
committerAndy Wingo <wingo@pobox.com>2015-01-23 16:15:59 +0100
commitc0a56ec78ddf9df65f591104a1d7bbcada099477 (patch)
treeb005238856dbb5a7951075246bd90daf9073fc04 /module/oop
parent667937533225956b6048b75f4a3c03cdd61584f3 (diff)
downloadguile-c0a56ec78ddf9df65f591104a1d7bbcada099477.tar.gz
%compute-applicable-methods in Scheme
* libguile/goops.c: Move %compute-applicable-methods to Scheme. (scm_sys_goops_loaded): No need to initialize var_compute_applicable_methods. * libguile/goops.h (scm_sys_compute_applicable_methods): Remove. This was internal so it shouldn't cause a problem. * module/oop/goops.scm (%sort-applicable-methods): (%compute-applicable-methods): New definitions.
Diffstat (limited to 'module/oop')
-rw-r--r--module/oop/goops.scm31
1 files changed, 29 insertions, 2 deletions
diff --git a/module/oop/goops.scm b/module/oop/goops.scm
index 95be42ac4..a0c6119dc 100644
--- a/module/oop/goops.scm
+++ b/module/oop/goops.scm
@@ -508,6 +508,34 @@
;;; {Methods}
;;;
+(define (%sort-applicable-methods methods types)
+ (sort methods (lambda (a b) (%method-more-specific? a b types))))
+
+(define (%compute-applicable-methods gf args)
+ (define (method-applicable? m types)
+ (let lp ((specs (method-specializers m)) (types types))
+ (cond
+ ((null? specs) (null? types))
+ ((not (pair? specs)) #t)
+ ((null? types) #f)
+ (else
+ (and (memq (car specs) (class-precedence-list (car types)))
+ (lp (cdr specs) (cdr types)))))))
+ (let ((n (length args))
+ (types (map class-of args)))
+ (let lp ((methods (generic-function-methods gf))
+ (applicable '()))
+ (if (null? methods)
+ (and (not (null? applicable))
+ (%sort-applicable-methods applicable types))
+ (let ((m (car methods)))
+ (lp (cdr methods)
+ (if (method-applicable? m types)
+ (cons m applicable)
+ applicable)))))))
+
+(define compute-applicable-methods %compute-applicable-methods)
+
(define (toplevel-define! name val)
(module-define! (current-module) name val))
@@ -1664,8 +1692,7 @@
(set! compute-applicable-methods %%compute-applicable-methods)
(define-method (sort-applicable-methods (gf <generic>) methods args)
- (let ((targs (map class-of args)))
- (sort methods (lambda (m1 m2) (method-more-specific? m1 m2 targs)))))
+ (%sort-applicable-methods methods (map class-of args)))
(define-method (method-more-specific? (m1 <method>) (m2 <method>) targs)
(%method-more-specific? m1 m2 targs))