5 ;;; This init file was last tested with SBCL 0.6.13 and
8 ;;; This file is part of ILISP.
9 ;;; Please refer to the file COPYING for copyrights and licensing
11 ;;; Please refer to the file ACKNOWLEGDEMENTS for an (incomplete) list
12 ;;; of present and past contributors.
14 ;;; $Id: sbcl.lisp,v 1.2 2002-05-30 13:59:21 wbd Exp $
19 ;; ILISP-specifics for SBCL. Since version 0.7 introduced lots of changes,
20 ;; e.g.(bytecode-)interpreter goes away, and lots of other 'renaming'-changes,
21 ;; take care of that, by testing via the 'magic'-macros:
22 ;; THE-SYMBOL-IF-DEFINED, and THE-FUNCTION-IF-DEFINED.
26 ;; <1> - interpreter related changes (interpreter missing in sbcl-0.7.x)
27 ;; <2> - byte-compiler related changes (sbcl-0.7.x)
28 ;; <3> - renamings in sbcl-0.7.x., where in general this is accounted for
29 ;; using THE-SYMBOL-IF-DEFINED and THE-FUNCTION-IF-DEFINED macros.
30 ;; In general, the "new" symbol comes before the "old" symbol.
32 ;;;% CMU CL does not define defun as a macro
33 (defun ilisp-compile (form package filename)
34 "Compile FORM in PACKAGE recording FILENAME as the source file."
37 (format nil "(funcall (compile nil '(lambda () ~A)))" form)
40 ;;;% Stream settings, when running connected to pipes.
42 ;;; When SBCL is running as a piped process, it still manages to open
43 ;;; /dev/tty to use it for the *terminal-io* stream. This means that an
44 ;;; error will cause lisp to stop and wait for input from /dev/tty, which is
45 ;;; probably not available and certainly not what you were expecting.
47 ;;; We want it to use the same input that the user is typing at, ie,
50 (defvar *Fix-pipe-streams* T
51 "Set to Nil if you want them left alone. And tell me you don't get stuck.")
53 (when (and *Fix-pipe-streams*
54 (sb-impl::synonym-stream-p *terminal-io*)
55 (eq (sb-impl::synonym-stream-symbol *terminal-io*)
57 (setf *terminal-io* (make-two-way-stream sb-impl::*stdin* sb-impl::*stdout*))
58 ;; *query-io* and *debug-io* are synonym streams to this, so this fixes
62 ;;; Normally, errors which occur while in the debugger are just ignored, unless
63 ;;; the user issues the "flush" command, which toggles this behavior.
65 (setq sb-debug:*flush-debug-errors* nil) ; allow multiple error levels.
68 ;;;%% arglist/source-file utils.
70 (defun get-correct-fn-object (sym)
71 "Deduce how to get the \"right\" function object and return it."
72 (let ((fun (or (macro-function sym)
73 (and (fboundp sym) (symbol-function sym)))))
75 (if (and (= (the-function-if-defined ((#:widetag-of :sb-impl)
76 (#:get-type :sb-impl)) fun)
78 #.(the-symbol-if-defined
79 ((#:closure-header-widetag :sb-vm)
80 (#:closure-header-type :sb-vm) :eval-p t)))
81 (not (the-function-if-defined
82 ((#:interpreted-function-p :sb-eval) ()) fun)))
84 (the-function-if-defined ((#:%closure-fun :sb-impl)
85 (#:closure-function :sb-impl))
87 ;; else just return the old function-object
90 (error "Unknown function ~a. Check package." sym)
93 ;;; 2000-04-02: Martin Atzmueller
94 ;;; better (more bulletproof) arglist code adapted from cmulisp.lisp:
96 (defun extract-function-info-from-name (sym)
97 (let ((mf (macro-function sym)))
101 (values (symbol-function sym) :function)
104 (defun arglist (symbol package)
106 (let* ((package-name (if (packagep package)
107 (package-name package)
109 (x (ilisp-find-symbol symbol package-name)))
110 (flet ((massage-arglist (args)
112 (string (if (or (null args) (string= args "()"))
116 (let ((*print-pretty* t)
120 (format nil "~A" args))
124 (multiple-value-bind (func kind)
125 (extract-function-info-from-name x)
127 (case (the-function-if-defined ((#:widetag-of :sb-impl)
128 (#:get-type :sb-impl)) func)
130 ((#.(the-symbol-if-defined ((#:closure-header-widetag :sb-vm)
131 (#:closure-header-type :sb-vm)
133 #.(the-symbol-if-defined ((#:simple-fun-header-widetag :sb-vm)
134 (#:function-header-type :sb-vm)
136 #.(the-symbol-if-defined ((#:closure-fun-header-widetag
138 (#:closure-function-header-type
142 (the-function-if-defined ((#:%simple-fun-arglist :sb-impl)
143 (#:%function-arglist :sb-impl))
145 (#.(the-symbol-if-defined
146 ((#:funcallable-instance-header-widetag :sb-vm)
147 (#:funcallable-instance-header-type :sb-vm)
151 (#.(the-symbol-if-defined ((#:byte-function :sb-kernel) ()))
152 "Byte compiled function or macro, no arglist available.")
153 (#.(the-symbol-if-defined ((#:byte-closure :sb-kernel) ()))
154 "Byte compiled closure, no arglist available.")
155 ((or generic-function sb-pcl::generic-function)
156 (sb-pcl::generic-function-pretty-arglist func))
158 (#.(the-symbol-if-defined ((#:interpreted-function :sb-eval) ()))
159 (the-function-if-defined
160 ((#:interpreted-function-arglist :sb-eval) ()
161 :function-binding-p t)
162 (massage-arglist (funcall the-function func))))
163 (t (print 99 *trace-output*) "No arglist available.")
165 (t "No arglist available.")) ; case
166 "Unknown function - no arglist available." ; For the time
174 ;;; source-file symbol package type --
175 ;;; New version provided by Richard Harris <rharris@chestnut.com> with
176 ;;; suggestions by Larry Hunter <hunter@work.nlm.nih.gov>.
178 (defun source-file (symbol package type)
179 (declare (ignore type))
181 (let* ((x (ilisp-find-symbol symbol package))
182 (fun (get-correct-fn-object x)))
185 (not (the-function-if-defined
186 ((#:interpreted-function-p :sb-eval) ()) fun)))
187 ;; The hack above is necessary because CMUCL does not
188 ;; correctly record source file information when 'loading'
189 ;; a non compiled file.
190 ;; In this case we fall back on the TAGS machinery.
191 ;; (At least as I underestand the code).
192 ;; Marco Antoniotti 11/22/94.
193 (cond ((sb-pcl::generic-function-p fun)
194 (dolist (method (sb-pcl::generic-function-methods fun))
195 (print-simple-source-info
196 (or (sb-pcl::method-fast-function method)
197 (sb-pcl::method-function method))))
199 (t (print-simple-source-info fun)))))))
201 ;;; Patch suggested by Richard Harris <rharris@chestnut.com>
203 ;;; FUN-DEFINED-FROM-PATHNAME takes a symbol or function object. It
204 ;;; returns a pathname for the file the function was defined in. If it was
205 ;;; not defined in some file, then nil is returned.
207 ;;; FUN-DEFINED-FROM-PATHNAME is from hemlock/rompsite.lisp (cmucl17f),
208 ;;; with added read-time conditionalization to work in older versions
209 ;;; of cmucl. It may need a little bit more conditionalization for
210 ;;; some older versions of cmucl.
212 (defun fun-defined-from-pathname (function)
213 "Returns the file where FUNCTION is defined in (if the file can be found).
214 Takes a symbol or function and returns the pathname for the file the
215 function was defined in. If it was not defined in some file, nil is
218 (let ((info (sb-kernel:%code-debug-info code)))
220 (let ((sources (sb-c::debug-info-source info)))
222 (let ((source (car sources)))
223 (when (eq (sb-c::debug-source-from source) :file)
224 (sb-c::debug-source-name source)))))))))
226 (symbol (fun-defined-from-pathname (fdefinition function)))
228 (#.(the-symbol-if-defined ((#:byte-function :sb-kernel) ()))
229 "Byte compiled function or macro, no arglist available.")
230 (#.(the-symbol-if-defined ((#:byte-closure :sb-kernel) ()))
231 "Byte compiled closure, no arglist available.")
232 (#.(the-symbol-if-defined ((#:byte-closure :sb-kernel) ()))
233 (fun-defined-from-pathname
234 (the-function-if-defined ((#:byte-closure-function :sb-kernel) ()
235 :function-binding-p t)
236 (funcall the-function function))))
237 (#.(the-symbol-if-defined ((#:byte-function :sb-kernel) ()))
238 (the-function-if-defined ((#:byte-function-component :sb-c) ()
239 :function-binding-p t)
240 (frob (funcall the-function function))))
243 (frob (the-function-if-defined ((#:fun-code-header :sb-kernel)
244 (#:function-code-header :sb-kernel))
245 (the-function-if-defined
246 ((#:%simple-fun-self :sb-kernel)
247 (#:%function-self :sb-kernel))
252 ;;; print-simple-source-info --
253 ;;; Patches suggested by Larry Hunter <hunter@work.nlm.nih.gov> and
254 ;;; Richard Harris <rharris@chestnut.com>
257 (defun print-simple-source-info (fun)
258 (let ((path (fun-defined-from-pathname fun)))
259 (when (and path (probe-file path))
260 (print (namestring (truename path)))
264 (defun sbcl-trace (symbol package breakp)
265 "Trace SYMBOL in PACKAGE."
267 (let ((real-symbol (ilisp-find-symbol symbol package)))
268 (setq breakp (read-from-string breakp))
269 (when real-symbol (eval `(trace ,real-symbol :break ,breakp))))))
271 ;;; end of file -- sbcl.lisp --