CMUCL source file info and ilisp's compile-defun-lisp

Bob Rogers <[email protected]>
Newsgroups gmane.lisp.ilisp.devel
Message-ID <[email protected]>
   The good news is that I have finally managed to scratch a long-
standing itch of mine that may be of interest to others.  The patch to
ilisp 5.12.0 below makes CMUCL remember source file names for functions
that are defined or modified interactively via ilisp, and extracts them
again when needed.  This prevents the "creeping M-. blackout" that
otherwise tends to develop during long sessions.  Fortunately, the
changes are modest, and work through existing CMUCL compiler
functionality, so although I've only tested this in version 18d, it
probably works in earlier versions as well.  The key is that
c::compile-from-stream allows us to pass an additional "source info"
structure that describes where the stream data came from.

   Now for the not-so-good news:

   1.  This c::source-info hackery strikes me as fairly arcane; though
it looks as if this could indeed be how it was meant to be done, I am
not fully convinced.  The data structures involved seem unnecessarily
convoluted, probably because they were designed to handle cases I don't
know about, but perhaps because I've misunderstood them.  Likely both,
in fact.  Does anyone on the CMUCL team know of a better way, or have
any hints in that direction?

   2.  Using c::compile-from-stream generates the standard CMU
"Converted SOURCE-FILE./Compiling DEFUN SOURCE-FILE: " spew by default,
which is somewhat obnoxious when compiling a single definition.  So I've
turned it off by specifying ":print nil", which results in absolute
silence (except for errors or warnings), which some may feel is going
too far in the other direction.  That's what the ilisp-hi.el tweak is
for; it provides a default "we're done" message if the compiler doesn't
say anything.  It might be a good idea to extend the protocol in order
to pass a *compile-print* value from emacs; this could then be a user
option, perhaps depending on definition vs. region, etc.

					-- Bob Rogers
					   http://rgrjr.dyndns.org/

------------------------------------------------------------------------
rgr> foreach file (ilisp-hi.el cmulisp.lisp cl-ilisp.lisp)
foreach? diff -u $file:r.orig.$file:e $file
foreach? end
--- ilisp-hi.orig.el	Sun Jun  2 18:34:11 2002
+++ ilisp-hi.el	Fri Aug 23 21:27:11 2002
@@ -195,10 +195,13 @@
 	    (insert form)
 	    (compile-defun-lisp)))
       ;; Display the value returned by the compilation. -fmw
+      ;; [and fake it if the compiler was silent.  -- rgr, 23-Aug-02.]
       (let* ((thing (car (cdr (cdr form))))
 	     (result (compile-region-lisp start end (or switch 'result)
 					  (format "Compiling %s" thing))))
-	(lisp-display-output result)))))
+	(lisp-display-output (if (equal result "")
+				 (format "Compiled %s" thing)
+				 result))))))
 
 ;;;%%%And-go
 (defun compile-region-and-go-lisp (start end)
--- cmulisp.orig.lisp	Thu May 23 10:58:34 2002
+++ cmulisp.lisp	Fri Aug 23 21:52:27 2002
@@ -209,17 +209,25 @@
 function was defined in.  If it was not defined in some file, nil is
 returned."
   (flet ((frob (code)
-	       (let ((info (the-function-if-defined ((#:%code-debug-info
-                                                      :kernel)
-                                                     (#:code-debug-info
-                                                      :kernel))
-                                                    code)))
-		 (when info
-		       (let ((sources (c::debug-info-source info)))
-			 (when sources
-			       (let ((source (car sources)))
-				 (when (eq (c::debug-source-from source) :file)
-				       (c::debug-source-name source)))))))))
+	   ;; extract a source file from a code object.
+	   (let ((info (the-function-if-defined ((#:%code-debug-info
+						  :kernel)
+						 (#:code-debug-info
+						  :kernel))
+						code)))
+	     (dolist (source (and info (c::debug-info-source info)))
+	       (case (c::debug-source-from source)
+		 (:file
+		   (when (c::debug-source-name source)
+		     (return (c::debug-source-name source))))
+		 ;; this accesses the c::source-info data installed by the
+		 ;; ilisp-compile fn.
+		 (:stream
+		   (let ((dsi (c::debug-source-info source)))
+		     (when dsi
+		       (let ((file-info (first (c::source-info-files dsi))))
+			 (when file-info
+			   (return (c::file-info-name file-info))))))))))))
 	(typecase function
 		  (symbol (fun-defined-from-pathname (fdefinition function)))
                   (#.(the-symbol-if-defined ((#:byte-closure :kernel) ()))
--- cl-ilisp.orig.lisp	Sun Jun  2 18:34:11 2002
+++ cl-ilisp.lisp	Fri Aug 23 21:31:19 2002
@@ -350,7 +350,7 @@
   ;; NOTE: Rich Mallory proposed a variation of the next piece of
   ;; code. for the time being we stick to the following simpler code.
   ;; Marco Antoniotti: Jan 2 1995.
-  #-lucid
+  #-(or lucid cmu)
   (ilisp-eval
    (format nil "(funcall (compile nil '(lambda () ~A)))"
 	   form)
@@ -365,9 +365,25 @@
  				 (merge-pathnames filename)))
  	(lcl:*redefinition-action* nil))
     (with-input-from-string (s form)
-			    (lucid::compile-in-core-from-stream s)
-			    (values)))
-  )
+      (lucid::compile-in-core-from-stream s)
+      (values)))
+  ;; Without this variant, CMUCL loses the source file information.  Tested in
+  ;; cmucl 18d, but it is likely to work in much older versions as well.
+  #+cmu
+  (let ((*package* (ilisp-find-package package))
+ 	(source-info
+	  (c::make-file-source-info (c::verify-source-files filename))))
+    (with-input-from-string (s form)
+      (c::compile-from-stream s :source-info source-info
+			      ;; this shuts of the "Converted foo/Compiling foo"
+			      ;; messages, which are a bit much for a single
+			      ;; defun, though may be desirable for a region.
+			      :print nil
+			      ;; [if we don't shut this off too, the default of
+			      ;; :maybe gets turned into t for top-level forms.
+			      ;; -- rgr, 23-Aug-02.]
+			      :byte-compile nil)
+      (values))))
 
 ;;;
 (defun ilisp-describe (sexp package)
rgr> 


-------------------------------------------------------
This sf.net email is sponsored by: OSDN - Tired of that same old
cell phone?  Get a new here for FREE!
https://www.inphonic.com/r.asp?r=sourceforge1&refcode1=vs3390
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.