X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fdescribe.lisp;h=67e45b5474efe8da655a83e73e31f78ac2e01c4a;hb=e9c546b14771ebe96447c3920a75e9e580f9075f;hp=17aba7615a829339c35b0d78c36167ae27723f4a;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/describe.lisp b/src/code/describe.lisp index 17aba76..67e45b5 100644 --- a/src/code/describe.lisp +++ b/src/code/describe.lisp @@ -95,7 +95,7 @@ count (zerop count)) (let ((n 0)) (declare (type index n)) - (dohash (k v x) + (dohash ((k v) x :locked t) (unless (zerop n) (write-char #\space s)) (incf n) @@ -161,12 +161,14 @@ ;; any nondefault options. (format-universal-time nil (sb-c::debug-source-compiled source) :style :abbreviated)) - (let ((name (sb-c::debug-source-name source))) - (ecase (sb-c::debug-source-from source) - (:file - (format s "~&~A~@:_ Created: " (namestring name)) - (format-universal-time s (sb-c::debug-source-created source))) - (:lisp (format s "~&~S" name))))))))) + (let ((name (sb-c::debug-source-namestring source))) + (cond (name + (format s "~&~A~@:_ Created: " name) + (format-universal-time s (sb-c::debug-source-created source))) + ((sb-di:debug-source-form source) + (format s "~& ~S" (sb-di:debug-source-form source))) + (t (bug "Don't know how to use a DEBUG-SOURCE without ~ + a namestring or a form."))))))))) ;;; Describe a compiled function. The closure case calls us to print ;;; the guts. @@ -191,9 +193,17 @@ (%describe-fun-name name s (%simple-fun-type x)))) (%describe-compiled-from (sb-kernel:fun-code-header x) s)) +(defun %describe-fun (x s &optional (kind :function) (name nil)) + (etypecase x + #+sb-eval + (sb-eval:interpreted-function + (%describe-interpreted-fun x s kind name)) + (function + (%describe-compiled-fun x s kind name)))) + ;;; Describe a function object. KIND and NAME provide some information ;;; about where the function came from. -(defun %describe-fun (x s &optional (kind :function) (name nil)) +(defun %describe-compiled-fun (x s &optional (kind :function) (name nil)) (declare (type function x)) (declare (type stream s)) (declare (type (member :macro :function) kind)) @@ -206,15 +216,14 @@ (format s "~S is a function." x)))) (format s "~@:_~@" 'function-lambda-expression - (%fun-name x)) + (nth-value 2 (function-lambda-expression x))) (case (widetag-of x) (#.sb-vm:closure-header-widetag (%describe-fun-compiled (%closure-fun x) s kind name) - (format s "~@:_Its closure environment is:") - (pprint-logical-block (s nil) - (pprint-indent :current 8) - (dotimes (i (- (get-closure-length x) (1- sb-vm:closure-info-offset))) - (format s "~@:_~S: ~S" i (%closure-index-ref x i))))) + (format s "~&Its closure environment is:") + (loop for value in (%closure-values x) + for i = 0 then (1+ i) + do (format s "~& ~S: ~S" i value))) (#.sb-vm:simple-fun-header-widetag (%describe-fun-compiled x s kind name)) (#.sb-vm:funcallable-instance-header-widetag @@ -226,6 +235,46 @@ (format s "~@:_It is an unknown type of function.")))) (terpri s)) +;; Describe an interpreted function. +#+sb-eval +(defun %describe-interpreted-fun (x s &optional (kind :function) (name nil)) + (declare (type sb-eval:interpreted-function x)) + (declare (type stream s)) + (declare (type (member :macro :function) kind)) + (fresh-line s) + (pprint-logical-block (s nil) + (ecase kind + (:macro (format s "Macro-function: ~S" x)) + (:function (if name + (format s "Function: ~S" x) + (format s "~S is a function." x)))) + (format s "~@:_~@" + 'function-lambda-expression + (nth-value 2 (function-lambda-expression x))) + (format s "~&It is an interpreted function.~%") + (let ((args (sb-eval:interpreted-function-lambda-list x))) + (cond ((not args) + (write-string "There are no arguments." s)) + (t + (format s "~&~@(The ~@[~A's ~]arguments are:~@:_~)" kind) + (write-string " " s) + (let ((*print-pretty* t) + (*print-escape* t) + (*print-base* 10) + (*print-radix* nil)) + (pprint-logical-block (s nil) + (pprint-indent :current 2) + (format s "~A" args))))) + (format s "~&It was defined as: ") + (let ((*print-pretty* t) + (*print-escape* t) + (*print-base* 10) + (*print-radix* nil)) + (pprint-logical-block (s nil) + (pprint-indent :current 2) + (format s "~A" (function-lambda-expression x)))))) + (terpri s)) + (defmethod describe-object ((x function) s) (%describe-fun x s :function)) @@ -301,15 +350,22 @@ ((fboundp x) (describe-symbol-fdefinition (fdefinition x) s :name x))) + ;; Describe deftype lambda-list and doc + (when (info :type :expander x) + (format s "~&DEFTYPE lambda-list: ~A" (info :type :lambda-list x)) + (%describe-doc x s 'type "Type")) + ;; Print other documentation. (%describe-doc x s 'structure "Structure") - (%describe-doc x s 'type "Type") (%describe-doc x s 'setf "Setf macro") (dolist (assoc (info :random-documentation :stuff x)) - (format s - "~&~@" - (car assoc) - (cdr assoc))) + (let ((type (car assoc))) + (format s + "~&~@" + (case type + ((optimize) "optimize quality") + (t (car assoc))) + (cdr assoc)))) ;; Mention the associated type information, if any. ;;