Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1.0.5.46: improve handling of non-standard subclasses of SB-MOP:SPECI…
…ALIZER ... define SPECIALIZER-CLASS-OR-NIL for use in RAISE-METATYPE, and adjust RAISE-METATYPE to handle NIL return values. ... add commentary around RAISE-METATYPE to explain what all the metatypes actually mean. ... EMIT-FETCH-WRAPPER was missing a CONDITION-INSTANCE case, and further drew fine distinctions where there were none... ... so delete BUILT-IN-OR-STRUCTURE-WRAPPER, and call WRAPPER-OF instead. (But leave in the GC safety bug reported sbcl-devel 2007-05-10.) ... one more fix to PARAMETER-SPECIALIZER-DECLARATION-IN-DEFMETHOD for CLASS-EQ specializers on built-in-classes.
- Loading branch information
Showing
9 changed files
with
162 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
;;;; miscellaneous side-effectful tests of the MOP | ||
|
||
;;;; This software is part of the SBCL system. See the README file for | ||
;;;; more information. | ||
;;;; | ||
;;;; While most of SBCL is derived from the CMU CL system, the test | ||
;;;; files (like this one) were written from scratch after the fork | ||
;;;; from CMU CL. | ||
;;;; | ||
;;;; This software is in the public domain and is provided with | ||
;;;; absolutely no warranty. See the COPYING and CREDITS files for | ||
;;;; more information. | ||
|
||
;;; a test of a non-standard specializer class. Some context: a | ||
;;; (mostly content-free) discussion on comp.lang.lisp around | ||
;;; 2007-05-08 about the merits of Lisp, wherein an F#/OCaml advocate | ||
;;; implies roughly "I've heard that CLOS is slower than pattern | ||
;;; matching" | ||
|
||
;;; This implements a generic function type which dispatches on | ||
;;; patterns in its methods. The implementation below is a simple | ||
;;; interpreter of patterns; compiling the patterns into a | ||
;;; discrimination net, or other optimized dispatch structure, would | ||
;;; be an interesting exercise for the reader. (As would fixing some | ||
;;; other marked issues). | ||
|
||
(defpackage "MOP-27" | ||
(:use "CL" "SB-MOP")) | ||
|
||
(in-package "MOP-27") | ||
|
||
(defclass pattern-specializer (specializer) | ||
((pattern :initarg pattern :reader pattern) | ||
(direct-methods :initform nil :reader specializer-direct-methods))) | ||
|
||
(defvar *pattern-specializer-table* (make-hash-table :test 'equal)) | ||
|
||
(defun ensure-pattern-specializer (pattern) | ||
(or (gethash pattern *pattern-specializer-table*) | ||
(setf (gethash pattern *pattern-specializer-table*) | ||
(make-instance 'pattern-specializer 'pattern pattern)))) | ||
|
||
;;; only one arg for now | ||
(defclass pattern-gf/1 (standard-generic-function) () | ||
(:metaclass funcallable-standard-class)) | ||
|
||
(defmethod compute-discriminating-function ((generic-function pattern-gf/1)) | ||
(lambda (arg) | ||
(let* ((methods (generic-function-methods generic-function)) | ||
(function (method-interpreting-function methods generic-function))) | ||
(set-funcallable-instance-function generic-function function) | ||
(funcall function arg)))) | ||
|
||
(defun method-interpreting-function (methods gf) | ||
(lambda (arg) | ||
(dolist (method methods (no-applicable-method gf (list arg))) | ||
(when (matchesp arg (pattern (car (method-specializers method)))) | ||
(return (funcall (method-function method) (list arg) nil)))))) | ||
|
||
(defun matchesp (arg pattern) | ||
(cond | ||
((null pattern) t) | ||
((atom pattern) (eql arg pattern)) | ||
(t (and (matchesp (car arg) (car pattern)) | ||
(matchesp (cdr arg) (cdr pattern)))))) | ||
|
||
|
||
;;; protocol functions. SPECIALIZER-DIRECT-METHODS is implemented by | ||
;;; a reader on the specializer. FIXME: implement | ||
;;; SPECIALIZER-DIRECT-GENERIC-FUNCTIONS. | ||
(defmethod add-direct-method ((specializer pattern-specializer) method) | ||
(pushnew method (slot-value specializer 'direct-methods))) | ||
(defmethod remove-direct-method ((specializer pattern-specializer) method) | ||
(setf (slot-value specializer 'direct-methods) | ||
(remove method (slot-value specializer 'direct-methods)))) | ||
|
||
(defgeneric simplify (x) | ||
(:generic-function-class pattern-gf/1)) | ||
;;; KLUDGE: order of definition matters, as we simply traverse | ||
;;; generic-function-methods until a pattern matches our argument. | ||
;;; Additionally, we're not doing anything interesting with regard to | ||
;;; destructuring the pattern for use in the method body; a real | ||
;;; implementation would make it more convenient. | ||
(let ((specializer (ensure-pattern-specializer 'nil))) | ||
(eval `(defmethod simplify ((x ,specializer)) x))) | ||
(let ((specializer (ensure-pattern-specializer '(* nil 0)))) | ||
(eval `(defmethod simplify ((x ,specializer)) 0))) | ||
(let ((specializer (ensure-pattern-specializer '(* 0 nil)))) | ||
(eval `(defmethod simplify ((x ,specializer)) 0))) | ||
|
||
(assert (eql (simplify '(* 0 3)) 0)) | ||
(assert (eql (simplify '(* (+ x y) 0)) 0)) | ||
(assert (equal (simplify '(+ x y)) '(+ x y))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters