1 ;;;; Inspector for sb-aclrepl
3 ;;;; The documentation, which may or may not apply in its entirety at
4 ;;;; any given time, for this functionality is on the ACL website:
5 ;;;; <http://www.franz.com/support/documentation/6.2/doc/inspector.htm>.
7 ;;;; A summary of inspector navigation is contained in the below *INSPECT-HELP*
10 (cl:in-package #:sb-aclrepl)
12 (eval-when (:compile-toplevel :load-toplevel :execute)
13 (defconstant +default-inspect-length+ 10))
16 ;; stack of parents of inspected object
18 ;; a stack of indices of parent object components
21 ;; FIXME - raw mode isn't currently used in object display
22 (defparameter *current-inspect* nil
24 (defparameter *inspect-raw* nil
25 "Raw mode for object display.")
26 (defparameter *inspect-length* +default-inspect-length+
27 "maximum number of components to print")
28 (defparameter *inspect-skip* 0
29 "number of initial components to skip when displaying an object")
31 (defvar *inspect-help*
32 ":istep takes between 0 to 3 arguments.
34 :i redisplay current object
35 :i = redisplay current object
36 :i nil redisplay current object
37 :i ? display this help
38 :i * inspect the current * value
39 :i + <form> inspect the (eval form)
40 :i <index> inspect the numbered component of object
41 :i <name> inspect the named component of object
42 :i <form> evaluation and inspect form
45 :i < inspect previous parent component
46 :i > inspect next parent component
47 :i set <index> <form> set indexed component to evalated form
48 i set <name> <form> set named component to evalated form
49 :i print <max> set the maximum number of components to print
50 :i skip <n> skip a number of components when printing
51 :i tree print inspect stack
54 ;;; When *INSPECT-UNBOUND-OBJECT-MARKER* occurs in a parts list, it
55 ;;; indicates that that a slot is unbound.
56 (eval-when (:compile-toplevel :load-toplevel :execute)
57 (defvar *inspect-unbound-object-marker* (gensym "INSPECT-UNBOUND-OBJECT-")))
60 ;; Setup binding for multithreading
61 (let ((*current-inspect* nil)
63 (*inspect-length* +default-inspect-length+)
66 (defun inspector (object input-stream output-stream)
67 (declare (ignore input-stream))
68 (setq object (eval object))
69 (setq *current-inspect* (make-inspect))
70 (new-break :inspect *current-inspect*)
72 (setf (inspect-object-stack *current-inspect*) (list object))
73 (setf (inspect-select-stack *current-inspect*)
74 (list (format nil "(inspect ~S)" object)))
75 (redisplay output-stream))
77 (setq sb-impl::*inspect-fun* #'inspector)
79 (defun istep (args stream)
80 (unless *current-inspect*
81 (setq *current-inspect* (make-inspect)))
84 (when (first args) (read-from-string (first args)))
87 (defun istep-dispatch (args option-string option stream)
89 ((or (string= "=" option-string) (zerop (length args)))
90 (istep-cmd-redisplay stream))
91 ((or (string= "-" option-string) (string= "^" option-string))
92 (istep-cmd-parent stream))
93 ((string= "*" option-string)
94 (istep-cmd-inspect-* stream))
95 ((string= "+" option-string)
96 (istep-cmd-inspect-new-form (read-from-string (second args)) stream))
97 ((or (string= "<" option-string)
98 (string= ">" option-string))
99 (istep-cmd-select-parent-component option-string stream))
100 ((string-equal "set" option-string)
101 (istep-cmd-set (second args) (third args) stream))
102 ((string-equal "raw" option-string)
103 (istep-cmd-set-raw (second args) stream))
104 ((string-equal "q" option-string)
106 ((string-equal "?" option-string)
107 (istep-cmd-help stream))
108 ((string-equal "skip" option-string)
109 (istep-cmd-skip (second args) stream))
110 ((string-equal "tree" option-string)
111 (istep-cmd-tree stream))
112 ((string-equal "print" option-string)
113 (istep-cmd-print (second args) stream))
114 ((or (symbolp option)
116 (istep-cmd-select-component option stream))
118 (istep-cmd-set-stack option stream))))
120 (defun set-current-inspect (inspect)
121 (setq *current-inspect* inspect))
123 (defun reset-stack ()
124 (setf (inspect-object-stack *current-inspect*) nil)
125 (setf (inspect-select-stack *current-inspect*) nil))
127 (defun output-inspect-note (stream note &rest args)
128 (apply #'format stream note args)
129 (princ #\Newline stream))
132 (inspect-object-stack *current-inspect*))
134 (defun redisplay (stream)
135 (display-current stream))
138 ;;; istep command processing
141 (defun istep-cmd-redisplay (stream)
144 (defun istep-cmd-parent (stream)
146 ((> (length (inspect-object-stack *current-inspect*)) 1)
147 (setf (inspect-object-stack *current-inspect*)
148 (cdr (inspect-object-stack *current-inspect*)))
149 (setf (inspect-select-stack *current-inspect*)
150 (cdr (inspect-select-stack *current-inspect*)))
153 (output-inspect-note stream "Object has no parent"))
155 (no-object-msg stream))))
157 (defun istep-cmd-inspect-* (stream)
159 (setf (inspect-object-stack *current-inspect*) (list *))
160 (setf (inspect-select-stack *current-inspect*) (list "(inspect *)"))
161 (set-break-inspect *current-inspect*)
164 (defun istep-cmd-inspect-new-form (form stream)
165 (inspector (eval form) nil stream))
167 (defun istep-cmd-select-parent-component (option stream)
169 (if (eql (length (stack)) 1)
170 (output-inspect-note stream "Object does not have a parent")
171 (let ((parent (second (stack)))
172 (id (car (inspect-select-stack *current-inspect*))))
173 (multiple-value-bind (position parts)
174 (find-part-id parent id)
175 (let ((new-position (if (string= ">" option)
178 (if (< -1 new-position (parts-count parts))
179 (let* ((value (element-at parts new-position)))
180 (setf (car (inspect-object-stack *current-inspect*))
182 (setf (car (inspect-select-stack *current-inspect*))
183 (id-at parts new-position))
185 (output-inspect-note stream
186 "Parent has no selectable component indexed by ~d"
188 (no-object-msg stream)))
190 (defun istep-cmd-set-raw (option-string stream)
191 (when (inspect-object-stack *current-inspect*)
193 ((null option-string)
194 (setq *inspect-raw* t))
195 ((eq (read-from-string option-string) t)
196 (setq *inspect-raw* t))
197 ((eq (read-from-string option-string) nil)
198 (setq *inspect-raw* nil)))
201 (defun istep-cmd-reset ()
203 (set-break-inspect *current-inspect*))
205 (defun istep-cmd-help (stream)
206 (format stream *inspect-help*))
208 (defun istep-cmd-skip (option-string stream)
210 (let ((len (read-from-string option-string)))
211 (if (and (integerp len) (>= len 0))
212 (let ((*inspect-skip* len))
214 (output-inspect-note stream "Skip length invalid")))
215 (output-inspect-note stream "Skip length missing")))
217 (defun istep-cmd-print (option-string stream)
219 (let ((len (read-from-string option-string)))
220 (if (and (integerp len) (plusp len))
221 (setq *inspect-length* len)
222 (output-inspect-note stream "Cannot set print limit to ~A~%" len)))
223 (output-inspect-note stream "Print length missing")))
225 (defun select-description (select)
228 (format nil "which is componenent number ~d of" select))
230 (format nil "which is the ~a component of" select))
232 (format nil "which was selected by ~A" select))
234 (write-to-string select))))
236 (defun istep-cmd-tree (stream)
237 (let ((stack (inspect-object-stack *current-inspect*)))
240 (output-inspect-note stream "The current object is:")
241 (dotimes (i (length stack))
244 (inspected-description (nth i stack))
246 (nth i (inspect-select-stack *current-inspect*))))))
247 (no-object-msg stream))))
249 (defun istep-cmd-set (id-string value-string stream)
251 (let ((id (when id-string (read-from-string id-string))))
252 (multiple-value-bind (position parts)
253 (find-part-id (car (stack)) id)
257 (let ((new-value (eval (read-from-string value-string))))
258 (let ((result (set-component-value (car (stack))
265 (output-inspect-note stream result))
267 (redisplay stream))))))
270 "Object has no selectable component named by ~A" id))
271 (output-inspect-note stream
272 "Object has no selectable components"))))
273 (no-object-msg stream)))
275 (defun istep-cmd-select-component (id stream)
277 (multiple-value-bind (position parts)
278 (find-part-id (car (stack)) id)
281 (let* ((value (element-at parts position)))
282 (cond ((eq value *inspect-unbound-object-marker*)
283 (output-inspect-note stream "That slot is unbound"))
285 (push value (inspect-object-stack *current-inspect*))
286 (push id (inspect-select-stack *current-inspect*))
287 (redisplay stream)))))
289 (output-inspect-note stream "Object does not contain any subobjects"))
294 stream "Object has no selectable component named ~A"
298 stream "Object has no selectable component indexed by ~d"
301 stream "Enter a valid index (~:[0-~W~;0~])"
302 (= (parts-count parts) 1)
303 (1- (parts-count parts))))))))
304 (no-object-msg stream)))
306 (defun istep-cmd-set-stack (form stream)
308 (let ((object (eval form)))
309 (setf (inspect-object-stack *current-inspect*) (list object))
310 (setf (inspect-select-stack *current-inspect*)
311 (list (format nil ":i ~S" object))))
312 (set-break-inspect *current-inspect*)
316 ;;; aclrepl-specific inspection display
319 (defun no-object-msg (s)
320 (output-inspect-note s "No object is being inspected"))
322 (defun display-current (s)
324 (let ((inspected (car (stack))))
325 (setq cl:* inspected)
326 (display-inspect inspected s *inspect-length* *inspect-skip*))
329 ) ;; end binding for multithreading
332 (defun display-inspect (object stream &optional length skip)
333 (multiple-value-bind (elements labels count)
334 (inspected-elements object length skip)
335 (format stream "~&~A" (inspected-description object))
336 (unless (or (characterp object) (typep object 'fixnum))
337 (format stream " at #x~X" (sb-kernel:get-lisp-obj-address object)))
338 (princ #\newline stream)
341 (display-labeled-element (elt elements i) (elt labels i) stream))))
343 (defun array-label-p (label)
344 (and (stringp (cdr label)) (char= (char (cdr label) 0) #\[)))
346 (defun named-or-array-label-p (label)
349 (defun display-labeled-element (element label stream)
351 ((eq label :ellipses)
352 (format stream " ..."))
354 (format stream "tail-> ~A" (inspected-description element)))
355 ((named-or-array-label-p label)
357 (if (array-label-p label)
359 "~4,' D ~16,1,1,'-A> ~A")
361 (format nil "~A " (cdr label))
362 (inspected-description element)))
364 (format stream "~4,' D-> ~A" label (inspected-description element)))))
366 ;;; THE BEGINNINGS OF AN INSPECTOR API
367 ;;; which can be used to retrieve object descriptions as component values/labels and also
368 ;;; process print length and skip selectors
370 ;;; FUNCTIONS TO CONSIDER FOR EXPORT
374 ;;; INSPECTED-ELEMENTS
375 ;;; INSPECTED-DESCRIPTION
377 ;;; will also need hooks
378 ;;; *inspect-start-inspection*
379 ;;; (maybe. Would setup a window for a GUI inspector)
380 ;;; *inspect-prompt-fun*
381 ;;; *inspect-read-cmd*
383 ;;; and, either an *inspect-process-cmd*, or *inspect-display* hook
384 ;;; That'll depend if choose to have standardized inspector commands such that
385 ;;; (funcall *inspect-read-cmd*) will return a standard command that SBCL will
386 ;;; process and then call the *inspect-display* hook, or if the
387 ;;; *inspect-read-cmd* will return an impl-dependent cmd that sbcl will
388 ;;; send to the contributed inspector for processing and display.
390 (defun find-part-id (object id)
391 "COMPONENT-ID can be an integer or a name of a id.
392 Returns (VALUES POSITION PARTS).
393 POSITION is NIL if the id is invalid or not found."
394 (let* ((parts (inspected-parts object))
395 (name (when (symbolp id) (symbol-name id) id)))
398 (when (< -1 id (parts-count parts)) id)
399 (case (parts-seq-type parts)
401 (position name (the list (parts-components parts))
402 :key #'car :test #'string-equal))
404 (when (string-equal name "tail")
405 (1- (parts-count parts))))))
408 (defun element-at (parts position)
409 (let ((count (parts-count parts))
410 (components (parts-components parts)))
411 (when (< -1 position count)
412 (case (parts-seq-type parts)
414 (if (= position (1- count))
415 (cdr (last components))
416 (elt components position)))
418 (cdr (elt components position)))
420 (aref (the array components) position))
422 (elt components position))))))
424 (defun id-at (parts position)
425 (let ((count (parts-count parts)))
426 (when (< -1 position count)
427 (case (parts-seq-type parts)
429 (if (= position (1- count))
433 (array-index-string position parts))
435 (car (elt (parts-components parts) position)))
439 (defun inspected-elements (object &optional length (skip 0))
440 "Returns elements of an object that have been trimmed and labeled based on
441 length and skip. Returns (VALUES ELEMENTS LABELS ELEMENT-COUNT)
442 where ELEMENTS and LABELS are vectors containing ELEMENT-COUNT items.
443 LABELS may be a string, number, cons pair, :tail, or :ellipses.
444 This function may return an ELEMENT-COUNT of up to (+ 3 length) which would
445 include an :ellipses at the beginning, :ellipses at the end,
446 and the last element."
447 (let* ((parts (inspected-parts object))
448 (print-length (if length length (parts-count parts)))
449 (last-part (last-part parts))
450 (last-requested (last-requested parts print-length skip))
451 (element-count (compute-elements-count parts print-length skip))
452 (first-to (if (first-element-ellipses-p parts skip) 1 0))
453 (elements (when (plusp element-count) (make-array element-count)))
454 (labels (when (plusp element-count) (make-array element-count))))
455 ;; possible first ellipses
456 (when (first-element-ellipses-p parts skip)
457 (set-element-values elements labels 0 nil :ellipses))
460 ((> i (- last-requested skip)))
461 (set-element elements labels parts (+ i first-to) (+ i skip)))
462 ;; last parts value if needed
463 (when (< last-requested last-part)
464 (set-element elements labels parts (- element-count 1) last-part))
465 ;; ending ellipses or next to last parts value if needed
466 (when (< last-requested (1- last-part))
467 (if (= last-requested (- last-part 2))
468 (set-element elements labels parts (- element-count 2) (1- last-part))
469 (set-element-values elements labels (- element-count 2) nil :ellipses)))
470 (values elements labels element-count)))
472 (defun last-requested (parts print skip)
473 (min (1- (parts-count parts)) (+ skip print -1)))
475 (defun last-part (parts)
476 (1- (parts-count parts)))
478 (defun compute-elements-count (parts length skip)
479 "Compute the number of elements in parts given the print length and skip."
480 (let ((element-count (min length (max 0 (- (parts-count parts) skip)))))
481 (when (plusp skip) ; starting ellipses
482 (incf element-count))
483 (when (< (last-requested parts length skip)
484 (last-part parts)) ; last value
486 (when (< (last-requested parts length skip)
487 (1- (last-part parts))) ; ending ellipses
488 (incf element-count)))
491 (defun set-element (elements labels parts to-index from-index)
492 (set-element-values elements labels to-index (element-at parts from-index)
493 (label-at parts from-index)))
495 (defun set-element-values (elements labels index element label)
496 (setf (aref elements index) element)
497 (setf (aref labels index) label))
499 (defun first-element-ellipses-p (parts skip)
500 (and (parts-count parts) (plusp skip)))
502 (defun label-at (parts position)
503 "Helper function for inspected-elements. Conses the
504 position with the label if the label is a string."
505 (let ((id (id-at parts position)))
510 (defun array-index-string (index parts)
511 "Formats an array index in row major format."
512 (let ((rev-dimensions (parts-seq-hint parts)))
513 (if (null rev-dimensions)
516 (dolist (dim rev-dimensions)
517 (multiple-value-bind (q r) (floor index dim)
520 (format nil "[~W~{,~W~}]" (car list) (cdr list))))))
523 ;;; INSPECTED-DESCRIPTION
525 ;;; Accepts an object and returns
526 ;;; DESCRIPTION is a summary description of the destructured object,
527 ;;; e.g. "the object is a CONS".
529 (defgeneric inspected-description (object))
531 (defmethod inspected-description ((object symbol))
532 (format nil "the symbol ~A" object))
534 (defmethod inspected-description ((object structure-object))
535 (format nil "~W" (find-class (type-of object))))
537 (defmethod inspected-description ((object package))
538 (format nil "the ~A package" (package-name object)))
540 (defmethod inspected-description ((object standard-object))
541 (format nil "~W" (class-of object)))
543 (defmethod inspected-description ((object sb-kernel:funcallable-instance))
544 (format nil "a funcallable-instance of type ~S" (type-of object)))
546 (defmethod inspected-description ((object function))
547 (format nil "~S" object) nil)
549 (defmethod inspected-description ((object vector))
550 (declare (vector object))
551 (format nil "a ~:[~;displaced ~]vector (~W)"
552 (and (sb-kernel:array-header-p object)
553 (sb-kernel:%array-displaced-p object))
556 (defmethod inspected-description ((object simple-vector))
557 (declare (simple-vector object))
558 (format nil "a simple ~A vector (~D)"
559 (array-element-type object)
562 (defmethod inspected-description ((object array))
563 (declare (array object))
564 (format nil "~:[A displaced~;An~] array of ~A with dimensions ~W"
565 (and (sb-kernel:array-header-p object)
566 (sb-kernel:%array-displaced-p object))
567 (array-element-type object)
568 (array-dimensions object)))
570 (defun simple-cons-pair-p (object)
573 (defmethod inspected-description ((object cons))
574 (if (simple-cons-pair-p object)
576 (inspected-description-of-nontrivial-list object)))
578 (defun dotted-safe-length (object)
579 "Returns (VALUES LENGTH PROPER-P) where length is the number of cons cells"
580 (do ((length 0 (1+ length))
581 (lst object (cdr lst)))
585 (values length nil)))
586 ;; nothing to do in body
589 (defun inspected-description-of-nontrivial-list (object)
590 (multiple-value-bind (length proper-p) (dotted-safe-length object)
592 (format nil "a proper list with ~D element~:*~P" length)
593 (format nil "a dotted list with ~D element~:*~P + tail" length))))
595 (defmethod inspected-description ((object double-float))
596 (format nil "double-float ~W" object))
598 (defmethod inspected-description ((object single-float))
599 (format nil "single-float ~W" object))
601 (defmethod inspected-description ((object fixnum))
602 (format nil "fixnum ~W" object))
604 (defmethod inspected-description ((object complex))
605 (format nil "complex number ~W" object))
607 (defmethod inspected-description ((object simple-string))
608 (format nil "a simple-string (~W) ~W" (length object) object))
610 (defmethod inspected-description ((object bignum))
611 (format nil "bignum ~W" object))
613 (defmethod inspected-description ((object ratio))
614 (format nil "ratio ~W" object))
616 (defmethod inspected-description ((object character))
617 (format nil "character ~W char-code #x~X" object (char-code object)))
619 (defmethod inspected-description ((object t))
620 (format nil "a generic object ~W" object))
622 (defmethod inspected-description ((object (eql *inspect-unbound-object-marker*)))
628 ;;; Accepts the arguments OBJECT LENGTH SKIP and returns,
629 ;;; (LIST COMPONENTS SEQ-TYPE COUNT SEQ-HINT)
632 ;;; COMPONENTS are the component parts of OBJECT (whose
633 ;;; representation is determined by SEQ-TYPE). Except for the
634 ;;; SEQ-TYPE :named and :array, components is just the OBJECT itself
636 ;;; SEQ-TYPE determines what representation is used for components
638 ;;; If SEQ-TYPE is :named, then each element is (CONS NAME VALUE)
639 ;;; If SEQ-TYPE is :improper-list, then each element is just value,
640 ;;; but the last element must be retrieved by
641 ;;; (cdr (last components))
642 ;;; If SEQ-TYPE is :list, then each element is a value of an array
643 ;;; If SEQ-TYPE is :vector, then each element is a value of an vector
644 ;;; If SEQ-TYPE is :array, then each element is a value of an array
645 ;;; with rank >= 2. The
647 ;;; COUNT is the total number of components in the OBJECT
649 ;;; SEQ-HINT is a seq-type dependent hint. Used by SEQ-TYPE :array
650 ;;; to hold the reverse-dimensions of the orignal array.
652 (declaim (inline parts-components))
653 (defun parts-components (parts)
656 (declaim (inline parts-count))
657 (defun parts-count (parts)
660 (declaim (inline parts-seq-type))
661 (defun parts-seq-type (parts)
664 (declaim (inline parts-seq-hint))
665 (defun parts-seq-hint (parts)
668 (defgeneric inspected-parts (object)
671 (defmethod inspected-parts ((object symbol))
673 (list (cons "NAME" (symbol-name object))
674 (cons "PACKAGE" (symbol-package object))
675 (cons "VALUE" (if (boundp object)
676 (symbol-value object)
677 *inspect-unbound-object-marker*))
678 (cons "FUNCTION" (if (fboundp object)
679 (symbol-function object)
680 *inspect-unbound-object-marker*))
681 (cons "PLIST" (symbol-plist object)))))
682 (list components (length components) :named nil)))
684 (defun inspected-structure-parts (object)
685 (let ((components-list '())
686 (info (sb-kernel:layout-info (sb-kernel:layout-of object))))
687 (when (sb-kernel::defstruct-description-p info)
688 (dolist (dd-slot (sb-kernel:dd-slots info) (nreverse components-list))
689 (push (cons (sb-kernel:dsd-%name dd-slot)
690 (funcall (sb-kernel:dsd-accessor-name dd-slot) object))
693 (defmethod inspected-parts ((object structure-object))
694 (let ((components (inspected-structure-parts object)))
695 (list components (length components) :named nil)))
697 (defun inspected-standard-object-parts (object)
698 (let ((components nil)
699 (class-slots (sb-pcl::class-slots (class-of object))))
700 (dolist (class-slot class-slots components)
701 (let* ((slot-name (slot-value class-slot 'sb-pcl::name))
702 (slot-value (if (slot-boundp object slot-name)
703 (slot-value object slot-name)
704 *inspect-unbound-object-marker*)))
705 (push (cons (symbol-name slot-name) slot-value) components)))))
708 (defmethod inspected-parts ((object standard-object))
709 (let ((components (inspected-standard-object-parts object)))
710 (list components (length components) :named nil)))
712 (defmethod inspected-parts ((object sb-kernel:funcallable-instance))
713 (let ((components (inspected-structure-parts object)))
714 (list components (length components) :named nil)))
716 (defmethod inspected-parts ((object function))
717 (let* ((type (sb-kernel:widetag-of object))
718 (object (if (= type sb-vm:closure-header-widetag)
719 (sb-kernel:%closure-fun object)
721 (components (list (cons "arglist"
722 (sb-kernel:%simple-fun-arglist object)))))
723 (list components (length components) :named nil)))
725 (defmethod inspected-parts ((object vector))
726 (list object (length object) :vector nil))
728 (defmethod inspected-parts ((object array))
729 (let ((size (array-total-size object)))
730 (list (make-array size :displaced-to object)
733 (reverse (array-dimensions object)))))
735 (defmethod inspected-parts ((object cons))
736 (if (simple-cons-pair-p object)
737 (inspected-parts-of-simple-cons object)
738 (inspected-parts-of-nontrivial-list object)))
740 (defun inspected-parts-of-simple-cons (object)
741 (let ((components (list (cons "car" (car object))
742 (cons "cdr" (cdr object)))))
743 (list components 2 :named nil)))
745 (defun inspected-parts-of-nontrivial-list (object)
746 (multiple-value-bind (count proper-p) (dotted-safe-length object)
748 (list object count :list nil)
749 ;; count tail element
750 (list object (1+ count) :improper-list nil))))
752 (defmethod inspected-parts ((object complex))
753 (let ((components (list (cons "real" (realpart object))
754 (cons "imag" (imagpart object)))))
755 (list components (length components) :named nil)))
757 (defmethod inspected-parts ((object ratio))
758 (let ((components (list (cons "numerator" (numerator object))
759 (cons "denominator" (denominator object)))))
760 (list components (length components) :named nil)))
762 (defmethod inspected-parts ((object t))
763 (list nil 0 nil nil))
766 ;; FIXME - implement setting of component values
768 (defgeneric set-component-value (object component-id value element))
770 (defmethod set-component-value ((object cons) id value element)
771 (format nil "Cons object does not support setting of component ~A" id))
773 (defmethod set-component-value ((object array) id value element)
774 (format nil "Array object does not support setting of component ~A" id))
776 (defmethod set-component-value ((object symbol) id value element)
777 (format nil "Symbol object does not support setting of component ~A" id))
779 (defmethod set-component-value ((object structure-object) id value element)
780 (format nil "Structure object does not support setting of component ~A" id))
782 (defmethod set-component-value ((object standard-object) id value element)
783 (format nil "Standard object does not support setting of component ~A" id))
785 (defmethod set-component-value ((object t) id value element)
786 (format nil "Object does not support setting of component ~A" id))