X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/be01e762d1fd40a88b26f4bdd40f8f9449d79e0a..981b6fb624186a54320cea34e53e16276aee2bdb:/src/class-finalize-impl.lisp diff --git a/src/class-finalize-impl.lisp b/src/class-finalize-impl.lisp index 25ce1c2..23d7107 100644 --- a/src/class-finalize-impl.lisp +++ b/src/class-finalize-impl.lisp @@ -276,6 +276,35 @@ (cdr class-precedence-list))))))))) ;;;-------------------------------------------------------------------------- +;;; Metaclasses. + +(defun maximum (items order what) + "Return a maximum item according to the non-strict partial ORDER." + (reduce (lambda (best this) + (cond ((funcall order best this) best) + ((funcall order this best) this) + (t (error "Unable to choose best ~A." what)))) + items)) + +(defmethod guess-metaclass ((class sod-class)) + "Default metaclass-guessing function for classes. + + Return the most specific metaclass of any of the CLASS's direct + superclasses." + + ;; During bootstrapping, our superclasses might not have their own + ;; metaclasses resolved yet. If we find this, then throw `bootstrapping' + ;; so that `shared-initialize' on `sod-class' can catch it (or as a shot + ;; across the bows of anyone else who calls us). + (maximum (mapcar (lambda (super) + (if (slot-boundp super 'metaclass) + (slot-value super 'metaclass) + (throw 'bootstrapping nil))) + (sod-class-direct-superclasses class)) + #'sod-subclass-p + (format nil "metaclass for `~A'" class))) + +;;;-------------------------------------------------------------------------- ;;; Sanity checking. (defmethod check-sod-class ((class sod-class)) @@ -352,6 +381,11 @@ ;; If this fails, mark the class as a loss. (setf (slot-value class 'state) :broken) + ;; Set up the metaclass if it's not been set already. This is delayed + ;; to give bootstrapping a chance to set up metaclass and superclass + ;; circularities. + (default-slot (class 'metaclass) (guess-metaclass class)) + ;; Finalize all of the superclasses. There's some special pleading ;; here to make bootstrapping work: we don't try to finalize the ;; metaclass if we're a root class (no direct superclasses -- because