X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/bf090e021a5c20da452a4841cdfb8eb78e29544e..23e44cba8fe33e8cdde22d1ae14d78d992b9f8bb:/src/utilities.lisp diff --git a/src/utilities.lisp b/src/utilities.lisp index 5c061bb..98d314a 100644 --- a/src/utilities.lisp +++ b/src/utilities.lisp @@ -313,6 +313,9 @@ except where overridden by INITARGS." (apply #'copy-instance-using-class (class-of object) object initargs)) +(export '(generic-function-methods method-specializers + eql-specializer eql-specializer-object)) + ;;;-------------------------------------------------------------------------- ;;; List utilities. @@ -378,7 +381,7 @@ the input LISTS in the sense that if A precedes B in some input list then A will also precede B in the output list. If the lists aren't consistent (e.g., some list contains A followed by B, and another contains B followed - by A) then an error of type INCONSISTENT-MERGE-ERROR is signalled. + by A) then an error of type `inconsistent-merge-error' is signalled. Item equality is determined by TEST. @@ -618,7 +621,7 @@ (defun symbolicate (&rest symbols) "Return a symbol named after the concatenation of the names of the SYMBOLS. - The symbol is interned in the current *PACKAGE*. Trad." + The symbol is interned in the current `*package*'. Trad." (intern (apply #'concatenate 'string (mapcar #'symbol-name symbols)))) ;;;-------------------------------------------------------------------------- @@ -629,7 +632,7 @@ ((object stream &rest args) &body body) "Print helper for usually-unreadable objects. - If *PRINT-ESCAPE* is set then print OBJECT unreadably using BODY. + If `*print-escape*' is set then print OBJECT unreadably using BODY. Otherwise just print using BODY." (with-gensyms (print) `(flet ((,print () ,@body)) @@ -691,6 +694,38 @@ ,(loopguts indexvar t nil)))))))))) ;;;-------------------------------------------------------------------------- +;;; Structure accessor hacks. + +(export 'define-access-wrapper) +(defmacro define-access-wrapper (from to &key read-only) + "Make (FROM THING) work like (TO THING). + + If not READ-ONLY, then also make (setf (FROM THING) VALUE) work like + (setf (TO THING) VALUE). + + This is mostly useful for structure slot accessors where the slot has to + be given an unpleasant name to avoid it being an external symbol." + `(progn + (declaim (inline ,from ,@(and (not read-only) `((setf ,from))))) + (defun ,from (object) + (,to object)) + ,@(and (not read-only) + `((defun (setf ,from) (value object) + (setf (,to object) value)))))) + +(export 'define-on-demand-slot) +(defmacro define-on-demand-slot (class slot (instance) &body body) + "Defines a slot which computes its initial value on demand. + + Sets up the named SLOT of CLASS to establish its value as the implicit + progn BODY, by defining an appropriate method on `slot-unbound'." + (with-gensyms (classvar slotvar) + `(defmethod slot-unbound + (,classvar (,instance ,class) (,slotvar (eql ',slot))) + (declare (ignore ,classvar)) + (setf (slot-value ,instance ',slot) (progn ,@body))))) + +;;;-------------------------------------------------------------------------- ;;; CLOS hacking. (export 'default-slot)