* Created a new class, FUNCALLABLE-STANDARD-CLASS.

* Create a new class STD-CLASS that sits between CLASS and the
  two children STANDARD-CLASS and FUNCALLABLE-STANDARD-CLASS.
* Generic functions are now of type FUNCALLABLE-STANDARD-OBJECT.
Based on a patch by A. Gavrilov.
This commit is contained in:
Juan Jose Garcia Ripoll 2009-11-08 00:58:36 +01:00
parent 35fd642cd6
commit ce91c03f9d
6 changed files with 79 additions and 142 deletions

View file

@ -41,7 +41,11 @@
;; itself as metaclass. MAKE-EMPTY-CLASS takes care of that.
;;
(let* ((standard-class (make-empty-standard-class 'STANDARD-CLASS nil))
(std-class (make-empty-standard-class 'STD-CLASS standard-class))
(standard-object (make-empty-standard-class 'STANDARD-OBJECT standard-class))
(funcallable-standard-class
(make-empty-standard-class 'FUNCALLABLE-STANDARD-CLASS
standard-class))
(the-class (make-empty-standard-class 'CLASS standard-class))
(the-t (make-empty-standard-class 'T the-class))
;; It does not matter that we pass NIL instead of a class object,
@ -52,7 +56,7 @@
collect (canonical-slot-to-direct-slot nil s)))
(hash-table (make-hash-table :size 24)))
;; 2) STANDARD-CLASS and CLASS are the only classes with slots. Create a
;; 2) STANDARD-CLASS and CLASS and others are classes with slots. Create a
;; hash table for them, so that SLOT-VALUE works. Notice that we
;; make a intentional mistake: CLASS and STANDARD-CLASS share the same
;; hashtable!!
@ -68,11 +72,22 @@
(setf (class-slots the-class) (copy-list class-slots)
(class-size the-class) (length class-slots)
(slot-table the-class) hash-table
(class-direct-slots the-class) class-slots
(class-slots standard-class) standard-slots
(class-direct-slots the-class) class-slots)
(setf (class-slots standard-class) standard-slots
(class-size standard-class) (length standard-slots)
(slot-table standard-class) hash-table
(class-direct-slots standard-class) (set-difference standard-slots class-slots))
(class-direct-slots standard-class)
(set-difference standard-slots class-slots))
(setf (class-slots funcallable-standard-class) standard-slots
(class-size funcallable-standard-class) (length standard-slots)
(slot-table funcallable-standard-class) hash-table
(class-direct-slots funcallable-standard-class)
(class-direct-slots standard-class))
(setf (class-slots std-class) standard-slots
(class-size std-class) (length standard-slots)
(slot-table std-class) hash-table
(class-direct-slots std-class)
(class-direct-slots standard-class))
;; 3) Fix the class hierarchy
(setf (class-direct-superclasses the-t) nil
@ -81,16 +96,22 @@
(class-direct-subclasses standard-object) (list the-class)
(class-direct-superclasses the-class) (list standard-object)
(class-direct-subclasses the-class) (list standard-class)
(class-direct-superclasses standard-class) (list the-class))
(class-direct-superclasses std-class) (list the-class)
(class-direct-superclasses standard-class) (list std-class)
(class-direct-superclasses funcallable-standard-class) (list std-class))
(si::instance-sig-set the-class)
(si::instance-sig-set std-class)
(si::instance-sig-set standard-class)
(si::instance-sig-set standard-object)
(si::instance-sig-set funcallable-standard-class)
(si::instance-sig-set the-t)
;; 4) Fix the class precedence list
(let ((cpl (list standard-class the-class standard-object the-t)))
(setf (class-precedence-list standard-class) cpl
(let ((cpl (list std-class the-class standard-object the-t)))
(setf (class-precedence-list std-class) cpl
(class-precedence-list standard-class) (list* standard-class cpl)
(class-precedence-list funcallable-standard-class) (list* funcallable-standard-class cpl)
(class-precedence-list the-class) (cdr cpl)
(class-precedence-list standard-object) (cddr cpl)
(class-precedence-list the-t) (cdddr cpl)))
@ -99,6 +120,8 @@
)
(defconstant +the-standard-class+ (find-class 'standard-class nil))
(defconstant +the-funcallable-standard-class+
(find-class 'funcallable-standard-class nil))
(defmethod class-prototype ((class class))
(unless (slot-boundp class 'prototype)
@ -114,8 +137,8 @@
(defun find-slot-definition (class slot-name)
(declare (si::c-local))
(if nil #+nil ; TODO: fix
(eq (si:instance-class class) +the-standard-class+)
(if (or (eq (si:instance-class class) +the-standard-class+)
(eq (si:instance-class class) +the-funcallable-standard-class+))
(gethash slot-name (slot-table class) nil)
(find slot-name (class-slots class) :key #'slot-definition-name)))

View file

@ -50,7 +50,7 @@
#'shared-initialize (list new-data added-slots))))
(apply #'shared-initialize new-data added-slots initargs)))
(defmethod change-class ((instance standard-object) (new-class standard-class)
(defmethod change-class ((instance standard-object) (new-class std-class)
&rest initargs)
(let* ((old-instance (si::copy-instance instance))
(new-size (class-size new-class))

View file

@ -43,7 +43,7 @@
x))))
(map-into direct-slots #'identity new-direct-slots)
(map-into effective-slots #'identity new-effective-slots)
(when (typep class 'standard-class)
(when (typep class 'std-class)
(std-create-slots-table class)))
(mapc #'convert-one-class (class-direct-subclasses class)))
@ -65,12 +65,12 @@
(make-instances-obsolete (find-class 't))
(convert-one-class (find-class 't)))
(defmethod reader-method-class ((class standard-class)
(defmethod reader-method-class ((class std-class)
(direct-slot direct-slot-definition)
&rest initargs)
(find-class 'standard-reader-method))
(defmethod writer-method-class ((class standard-class)
(defmethod writer-method-class ((class std-class)
(direct-slot direct-slot-definition)
&rest initargs)
(find-class 'standard-writer-method))

View file

@ -58,7 +58,7 @@
(si::inspect-indent)
(format t "It has no class slots.~%")))))
(defmethod select-clos-N ((instance standard-class))
(defun select-clos-N-inner-class (instance)
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS)))
(if local-slotds
@ -83,30 +83,11 @@
(si::inspect-indent)
(format t "It has no (local) slots.~%")))))
(defmethod select-clos-N ((instance std-class))
(select-clos-N-inner-class instance))
(defmethod select-clos-N ((instance t))
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS)))
(if local-slotds
(progn
(si::inspect-indent)
(format t "The (local) slots are:~%")
(incf si::*inspect-level*)
(dolist (slotd local-slotds)
(si::inspect-indent-1)
(format t "name : ~S" (clos::slot-definition-name slotd))
(if (slot-boundp instance (clos::slot-definition-name slotd))
(si::inspect-recursively "value:"
(slot-value instance (clos::slot-definition-name slotd))
; (slot-value instance (clos::slot-definition-name slotd))
)
(si::inspect-print "value: Unbound"
nil
; (slot-value instance (clos::slot-definition-name slotd))
)))
(decf si::*inspect-level*))
(progn
(si::inspect-indent)
(format t "It has no (local) slots.~%")))))
(select-clos-N-inner-class instance))
(defmethod select-clos-L ((instance standard-object))
(let* ((class (si:instance-class instance))
@ -130,7 +111,7 @@
(format t "It has no class slots.~%")))
(terpri)))
(defmethod select-clos-L ((instance standard-class))
(defun select-clos-L-inner-class (instance)
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS)))
(terpri)
@ -143,18 +124,11 @@
(format t "It has no (local) slots.~%")))
(terpri)))
(defmethod select-clos-L ((instance std-class))
(select-clos-L-inner-class instance))
(defmethod select-clos-L ((instance t))
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS)))
(terpri)
(if local-slotds
(progn
(format t "The names of the (local) slots are:~%")
(dolist (slotd local-slotds)
(format t " ~S~%" (clos::slot-definition-name slotd))))
(progn
(format t "It has no (local) slots.~%")))
(terpri)))
(select-clos-L-inner-class instance))
(defmethod select-clos-J ((instance standard-object))
(let* ((class (si:instance-class instance))
@ -185,7 +159,7 @@
(terpri)
(terpri)))))
(defmethod select-clos-J ((instance standard-class))
(defun select-clos-J-inner-class (instance)
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS))
(slotd (car (member (prog1
@ -215,35 +189,11 @@
(terpri)
(terpri)))))
(defmethod select-clos-J ((instance std-class))
(select-clos-J-inner-class instance))
(defmethod select-clos-J ((instance t))
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS))
(slotd (car (member (prog1
(read-preserving-whitespace *query-io*)
(si::inspect-read-line))
local-slotds
:key #'clos::slot-definition-name
:test #'eq))))
(if slotd
(progn
(incf si::*inspect-level*)
(si::inspect-indent-1)
(format t "name : ~S" (clos::slot-definition-name slotd))
(if (slot-boundp instance (clos::slot-definition-name slotd))
(si::inspect-recursively "value:"
(slot-value instance (clos::slot-definition-name slotd))
; (slot-value instance (clos::slot-definition-name slotd))
)
(si::inspect-print "value: Unbound"
nil
; (slot-value instance (clos::slot-definition-name slotd))
))
(decf si::*inspect-level*))
(progn
(terpri)
(format t "~S is not a slot of the instance." (slot-definition-name slotd))
(terpri)
(terpri)))))
(select-clos-J-inner-class instance))
(defun select-clos-? ()
(declare (si::c-local))
@ -262,8 +212,9 @@ q (or Q): quits the inspection.~%~
))
(defmethod inspect-obj ((instance standard-object))
(unless (eq (si:instance-class (si:instance-class instance))
(find-class 'STANDARD-CLASS))
(unless (let ((metaclass (si:instance-class (si:instance-class instance))))
(or (eq metaclass (find-class 'STANDARD-CLASS))
(eq metaclass (find-class 'FUNCALLABLE-STANDARD-CLASS))))
(terpri)
(format t "No applicable method CLOS::INSPECT-OBJ for an instance~%")
(format t "of class ~S" (si:instance-class instance))
@ -320,7 +271,7 @@ q (or Q): quits the inspection.~%~
(si::inspect-indent)))
(incf si::*inspect-level*))
(defmethod inspect-obj ((instance standard-class))
(defun inspect-obj-inner-class (instance)
(decf si::*inspect-level*)
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS)))
@ -371,56 +322,11 @@ q (or Q): quits the inspection.~%~
(si::inspect-indent)))
(incf si::*inspect-level*))
(defmethod inspect-obj ((instance std-class))
(inspect-obj-inner-class instance))
(defmethod inspect-obj ((instance t))
(decf si::*inspect-level*)
(let* ((class (si:instance-class instance))
(local-slotds (slot-value class 'CLOS::SLOTS)))
(declare (type class))
(loop
(format t "~S - clos object:" instance)
(incf si::*inspect-level*)
(si::inspect-indent)
(format t "- it is an instance of class named ~S,"
(class-name class))
(si::inspect-indent)
(format t "- it has ~A local slots: " (length local-slotds))
(force-output)
(case (do ((char (read-char *query-io*) (read-char *query-io*)))
((and (char/= char #\Space) (char/= #\Tab)) char))
((#\Newline #\Return)
(select-clos-N instance)
(return nil))
((#\n #\N)
(si::inspect-read-line)
(select-clos-N instance)
(return nil))
((#\s #\S)
(si::inspect-read-line)
(return nil))
((#\p #\P)
(si::inspect-read-line)
(si::select-P instance))
((#\a #\A)
(si::inspect-read-line)
(throw 'SI::ABORT-INSPECT nil))
((#\e #\E)
(si::select-E))
((#\q #\Q)
(si::inspect-read-line)
(throw 'SI::QUIT-INSPECT nil))
((#\l #\L)
(si::inspect-read-line)
(select-clos-L instance))
((#\j #\J)
(select-clos-J instance))
((#\?)
(si::inspect-read-line)
(select-clos-?))
(t
(si::inspect-read-line)))
(decf si::*inspect-level*)
(si::inspect-indent)))
(incf si::*inspect-level*))
(inspect-obj-inner-class instance))
;;; -------------------------------------------------------------------------
;;;

View file

@ -167,7 +167,7 @@
class)
(defmethod shared-initialize :after ((class standard-class) slot-names &rest initargs &key
(defmethod shared-initialize :after ((class std-class) slot-names &rest initargs &key
(optimize-slot-access (list *optimize-slot-access*))
sealedp)
(setf (slot-value class 'optimize-slot-access) (first optimize-slot-access)
@ -186,6 +186,7 @@
(list (find-class (typecase class
(STANDARD-CLASS 'STANDARD-OBJECT)
(STRUCTURE-CLASS 'STRUCTURE-OBJECT)
(FUNCALLABLE-STANDARD-CLASS 'FUNCALLABLE-STANDARD-OBJECT)
(otherwise (error "No :DIRECT-SUPERCLASS ~
argument was supplied for metaclass ~S." (class-of class))))))))
;; FIXME!!! Here should come the invocation of VALIDATE-SUPERCLASS!
@ -203,10 +204,12 @@ argument was supplied for metaclass ~S." (class-of class))))))))
(defun find-slot-definition (class slot-name)
(declare (si::c-local))
(if nil #+nil ; TODO: fix
(eq (si:instance-class class) +the-standard-class+)
(gethash slot-name (slot-table class) nil)
(find slot-name (class-slots class) :key #'slot-definition-name)))
(let (table)
(if (and (or (eq (si:instance-class class) +the-standard-class+)
(eq (si:instance-class class) +the-funcallable-standard-class+))
(not (eq (setf table (slot-table class)) 'SI::UNBOUND)))
(gethash slot-name table nil)
(find slot-name (class-slots class) :key #'slot-definition-name))))
(defmethod finalize-inheritance ((class class))
;; FINALIZE-INHERITANCE computes the guts of what defines a class: the
@ -301,7 +304,7 @@ because it contains a reference to the undefined class~% ~A"
(setf (gethash (slot-definition-name slotd) table) slotd))
(setf (slot-table class) table)))
(defmethod finalize-inheritance ((class standard-class))
(defmethod finalize-inheritance ((class std-class))
(call-next-method)
(std-create-slots-table class)
(std-class-generate-accessors class))
@ -496,7 +499,7 @@ because it contains a reference to the undefined class~% ~A"
(return)))))))))
slots))
(defmethod compute-slots :around ((class standard-class))
(defmethod compute-slots :around ((class std-class))
(std-class-compute-slots class (call-next-method)))
;;; ----------------------------------------------------------------------
@ -586,8 +589,6 @@ because it contains a reference to the undefined class~% ~A"
;; the instance.
;;
(dolist (slotd (class-direct-slots standard-class))
#+(or)
(print (slot-definition-name slotd))
(multiple-value-bind (reader writer)
(let ((name (slot-definition-name slotd))
(allocation (slot-definition-allocation slotd))
@ -723,7 +724,7 @@ because it contains a reference to the undefined class~% ~A"
;;; ----------------------------------------------------------------------
;;; Methods
(defmethod describe-object ((obj standard-class) (stream t))
(defmethod describe-object ((obj std-class) (stream t))
(let ((slotds (class-slots (si:instance-class obj))))
(format t "~%~A is an instance of class ~A"
obj (class-name (si:instance-class obj)))

View file

@ -11,15 +11,22 @@
(in-package "CLOS")
;;; ----------------------------------------------------------------------
;;; Funcallable object
;;; ----------------------------------------------------------------------
(defclass funcallable-standard-object (standard-object function) ())
;;; ----------------------------------------------------------------------
;;; Generic Functions
;;; ----------------------------------------------------------------------
(defclass generic-function (standard-object function) ())
(defclass generic-function (standard-object function) ()
(:metaclass 'funcallable-standard-class))
(defclass standard-generic-function (generic-function)
#.+standard-generic-function-slots+)
#.+standard-generic-function-slots+
(:metaclass 'funcallable-standard-class))
;;;----------------------------------------------------------------------
;;; Method