From: Herbert Kay
Subject: ilisp bug fixes for akcl
Date: 
Message-ID: <1328@tokio.cs.utexas.edu>
Mike Christiansen has mentioned to me that he has gotten a bunch of 
requests for my ilisp fixes for the akcl dialect.  So, without
further ado, here are the fixes

>In article <·····················@euphoria.ssc.gov> you write:
>>I am having problems getting ilisp to works with akcl. (ilisp is 
>>gnu's interactive lisp interface for several CL implementations
>>includeing kcl/akcl). Has anyone been able to make this work?.
>>
>>thanks.
>>
>>--
>>
>>Mike Christiansen
>>Superconducting Super Collider Laboratory
>>Dallas, TX.
>>········@carob.ssc.gov

I had the same problem.  Here is my copy of the fix that I sent to the ilisp 
people.  It involves changing a variable and a function definition in the
file ilisp-src.el.  Even with these fixes, there still seem to be some bugs,
but at least it turns over.  

			Good luck,

			  - Bert Kay
			    ····@cs.utexas.edu

-----------------------------

	I am running gnuemacs version 18.54.17, ilisp version 4.10, and akcl 
        version 1.473.

	1) The akcl dialect definition should change the comint-prompt-regexp
	   to "^>+".  Ilisp version 4.10 had this prompt default to the kcl
	   prompt which is "^>+ ".

	2) In ilisp-src.el, the function edit-definitions-lisp has a bug
	   such that when the 'source' local variable is not set, its value
	   is set to nil rather than "nil".  This causes lisp-last-line
	   to bomb.  Here is my version of edit-definitions-lisp :

(defun edit-definitions-lisp (symbol type &optional stay search locator)
  "Find the source files for the TYPE definitions of SYMBOL.  If STAY,
use the same window.  If SEARCH, do not look for symbol in inferior
LISP.  The definition will be searched for through the inferior LISP
and if not found it will be searched for in the current tags file and
if not found in the files in lisp-edit-files set up by
\(\\[lisp-directory]) or the buffers in one of lisp-source-modes if
lisp-edit-files is T.  If lisp-edit-files is nil, no search will be
done if not found through the inferior LISP.  TYPES are from
ilisp-source-types which is an alist of symbol strings or list
strings.  With a negative prefix, look for the current symbol as the
first type in ilisp-source-types."
  (interactive 
   (let* ((types (ilisp-value 'ilisp-source-types t))
	  (default (if types (car (car types))))
	  (function (lisp-function-name))
	  (symbol (lisp-buffer-symbol function)))
     (if (lisp-minus-prefix)
	 (list function default)
	 (list (ilisp-read-symbol 
		(format "Edit Definition [%s]: " symbol)
		function
		nil
		t)
	       (if types 
		   (ilisp-completing-read
		    (format "Type [%s]: " default)
		    types default))))))
  (let* ((name (lisp-buffer-symbol symbol))
	 (symbol-name (lisp-symbol-name symbol))
	 (command (ilisp-value 'ilisp-find-source-command t))
	 (source
	  (if (and command (not search))
	      (ilisp-send
	       (format command symbol-name
		       (lisp-symbol-package symbol)
		       type)
	       (concat "Finding " type " " name " definitions")
	       'source)
	      ;; Added next line because the string "nil" rather than the 
	      ;; atom nil is needed here so that lisp-last-line works OK.
	      ;; BKay 23Mar91
	      (format "nil")))
	 (result (lisp-last-line source))
	 (case-fold-search t)
	 (source-ok (not (or (ilisp-value 'comint-errorp t)
			     (string-match "nil" (car result)))))
	 (tagged nil))
    (unwind-protect
	 (if (and tags-file-name (not source-ok))
	     (progn (setq lisp-using-tags t)
		    (find-tag symbol-name nil stay)
		    (setq tagged t)))
      (if (not tagged)
	  (progn
	    (setq lisp-last-definition (cons symbol type)
		  lisp-last-file nil
		  lisp-last-locator (or locator (ilisp-value 'ilisp-locator)))
	    (insert "OK to here")
	    (lisp-setup-edit-definitions
	     (format "%s %s definitions:" type name)
	     (if source-ok (cdr result) lisp-edit-files))
	    (next-definition-lisp nil t))))))
From: Jeff Dalton
Subject: Re: ilisp bug fixes for akcl
Date: 
Message-ID: <4494@skye.ed.ac.uk>
In article <····@tokio.cs.utexas.edu> ····@cs.utexas.edu (Herbert Kay) writes:
>Mike Christiansen has mentioned to me that he has gotten a bunch of 
>requests for my ilisp fixes for the akcl dialect.  So, without
>further ado, here are the fixes

>I had the same problem.  Here is my copy of the fix that I sent to the ilisp 
>people.  It involves changing a variable and a function definition in the
>file ilisp-src.el.  Even with these fixes, there still seem to be some bugs,
>but at least it turns over.  

I use ILISP 4.0 and 4.10 with AKCL 1-505 without too many problems.
I hadn't encountered the bugs your change fixes, but I have fixed
some other things and noted a few things I haven't fixed.

The things I've noted and not fixed may not actually be ILISP problems
and if they are ILISP problems may not be specific to KCL.  They are:

  * In at least 4.0, typing "]" after a string (that ends in ")
    inserts a "]" rather than the required number of ")"s.

  * The normal indentation rules are not followed inside a backquote.

  * The "Started initializing ILISP" message stays after
    initialization has completed, rather than going away or being
    replaced with something that says "done".  At least one person
    here is sufficiently confused / annoyed by this that they have
    decided ILISP is unreliable / poorly written and so don't use it.
    (Strange, perhaps, but true.)

  * In ILISP 4.10, I get two prompts at the beginning before all
    is initialized.  (This is not just KCL.)

In my .emacs I have:

---------------------------.emacs-------------------------------------
;;; Lisp-mode-hook starts with no value, but maybe in a future 
;;; release ...

(if (not (boundp 'lisp-mode-hook))
    (setq lisp-mode-hook '()))


;;; Ilisp setup (Ilisp 4.0)

(setq load-path (cons "/usr/bute/local/lib/emacs/ilisp" load-path))

(autoload 'run-ilisp "ilisp" "Select a new inferior LISP." t)
(autoload 'clisp     "ilisp" "Inferior generic Common LISP." t)
(autoload 'allegro   "ilisp" "Inferior Allegro Common LISP." t)
(autoload 'lucid     "ilisp" "Inferior Lucid Common LISP." t)
(autoload 'kcl       "ilisp" "Inferior Kyoto Common LISP." t)
(autoload 'scheme    "ilisp" "Inferior generic Scheme." t)
(autoload 'oaklisp   "ilisp" "Inferior Oaklisp Scheme." t)

(setq lisp-mode-hook
      (append lisp-mode-hook
	      '((lambda () (require 'ilisp)))))

;;; N.B. Site-hook shouldn't be modified in an individual .emacs,
;;; but since there isn't any site-wide modification and since these
;;; settings are appropriate for the entire site ...

(setq ilisp-site-hook
      '(lambda ()

         (add-hook 'kcl-hook
	   '(lambda ()
	      (ilisp-load-init 'kcl "kcl.lisp")
	      (setq comint-fix-error ":q"
		    comint-continue ":r")
	      (setq comint-prompt-status
	            (function
		     (lambda (old line)
		       (comint-prompt-status old
					     line
					     'kcl-check-prompt))))
	      (setq ilisp-program "kcl"
	            ilisp-binary-extension "o")))

	 ))

;;; kcl-check-prompt doesn't after the first break because the
;;; number of ">" characters doesn't increase.

(defun kcl-check-prompt (old new)
  "Compare the break level printed at the beginning of the prompt."
  (let* ((was-in-break (and old (string-match ">+" old)))
 	 (old-level (if was-in-break
 			(- (match-end 0) (match-beginning 0))
 			0))
 	 (is-in-break (string-match ">+" new))
 	 (new-level (if is-in-break
 			(- (match-end 0) (match-beginning 0))
 			0)))
    (<= new-level old-level)))

----------------------------------------------------------------------

Then I define an ILISP-COMPILE that works in KCL in a file "kcl.lisp".
Note that this file is mentioned in a call to ilisp-load-init in my
.emacs file.

-------------------------kcl.lisp-------------------------------------
;;;
;;; KCL initializations
;;; Author: Jeff Dalton, ········@ed.ac.uk
;;;

(in-package :user)

;;; Alternative ILISP-COMPILE
;;;
;;; It appears that what ILISP-COMPILE is supposed to do is to evaluate
;;; the form but compile any FUNCTION-expressions in it.  This normally
;;; happens by using EVALHOOK to evaluate the form with a hook function
;;; that calls COMPILE.  That doesn't work as intended for COMPILE-DEFUN-
;;; LISP in KCL, because DEFUN is treated as a special form, and the hook
;;; function never gets a chance to do anything.
;;;
;;; It might also be argued that there's an easier way to do more or
;;; less the right thing without using EVALHOOK, namely to do what we
;;; do here.

(defun ilisp-compile (form package filename)
  "Compile FORM in PACKAGE recording FILENAME as the source file."
  (ilisp-eval
    (format nil "(lisp:funcall (lisp:compile nil '(lisp:lambda () ~A)))"
	    form)
    package
    filename))


;;; N.B. We're supposed to have code here that makes sure all the
;;; functions we define are compiled, but we don't.  A call to COMPILE
;;; takes too long in KCL.

----------------------------------------------------------------------

Finally, I make some changes in clisp.lisp.  This description is
for ILISP 4.0.  First, I do somethings to make KCL's COMPILE-FILE
do something LOAD will be happy with.

At the very beginning, before the (in-package 'user), I put:

------------------------------
;;; The PCL package won't be there soon enough at load time
;;; in AKCL unless we put the IN-PACKAGE at the top-level.  [jwd]

#+kcl (in-package :pcl)
------------------------------

I put the definition of handler-case inside an EVAL-WHEN:

------------------------------
(eval-when (eval compile)
  (unless (macro-function 'handler-case)
    (defmacro handler-case (expression &rest handlers)
      "Evaluate EXPRESSION using HANDLERS to handle errors."
      handlers
      #+allegro `(excl::handler-case ,expression ,@handlers)
      #+lucid `(lucid::handler-case ,expression ,@handlers)
      #-(or allegro lucid) expression)))
------------------------------

The most important change is to fix escape-tab.  In ilisp-matching-
symbols, you will see some code like this:

       (if external-p
	   (do-external-symbols (symbol *package*)
	     (check-symbol symbol symbol-string))
	 (progn
	   ;; KCL does not go over used symbols.
	   #+(or kcl ibcl)
	   (dolist (used-package (package-use-list *package*))
	     (do-external-symbols (symbol used-package)
	       (check-symbol symbol symbol-string)))
	   #-(or kcl ibcl)
	   (do-symbols (symbol *package*)
	     (check-symbol symbol symbol-string))))

The #-(or kcl ibcl) is wrong.  Take it out.  If you leave it in,
completion will find only symbols that are external in some used
package.  If you defind a function FOO of your own, completion
won't find it.  That is, the correct code looks like this:

       (if external-p
	   (do-external-symbols (symbol *package*)
	     (check-symbol symbol symbol-string))
	 (progn
	   ;; KCL does not go over used symbols.
	   #+(or kcl ibcl)
	   (dolist (used-package (package-use-list *package*))
	     (do-external-symbols (symbol used-package)
	       (check-symbol symbol symbol-string)))
	   ;; Need this for all dialects, not: #-(or kcl ibcl)
	   (do-symbols (symbol *package*)
	     (check-symbol symbol symbol-string))))

-- Jeff

Jeff Dalton,                      JANET: ········@uk.ac.ed             
AI Applications Institute,        ARPA:  ·················@nsfnet-relay.ac.uk
Edinburgh University.             UUCP:  ...!ukc!ed.ac.uk!J.Dalton