[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Toplevel question



>Hello,
>
>I am developing a mathematical software that is based on a
>read-eval-print-loop. Naturaly, I would like to use MCL's own loop
>since it manages a lot of things automaticaly.
>
>The problem is that I need to have my own error handler active.
>The following almost works
>
>(%set-toplevel
>  (function
>    (lambda ()
>      (handler-bind ((error (function my-own-error-handler)))
>        (let ((*break-on-warnings* nil))
>          (loop
>            (toplevel-loop)))))))
>
>(toplevel)
>
>But things like meta-g in the listener behave strangely so
>there's something I not doing quite correctly.

This is a bug in ed-grab-last-input. I'll send a patch to anyone who
asks. This patch will be part of patch 2 for MCL 2.0, unless Mark
has already frozen the patch. Ask for "toplevel-meta-g-patch".

There are a couple of problems with your code.

1) Many of the conditions that MCL signals are of type SIMPLE-ERROR,
   not ERROR, so you may want to handle SIMPLE-ERROR in your HANDLER-BIND.
   Out of memory and stack overflow conditions are not instances of
   SIMPLE-ERROR. If you want to handle them, too, you'll need to
   handle SERIOUS-CONDITION.

2) MCL's TOPLEVEL-LOOP contains a catch that catches the tag to which
   (TOPLEVEL) throws. Then it returns. Since you are calling TOPLEVEL-LOOP
   in a loop, (TOPLEVEL) will no longer really get you to toplevel.
   Hence, once you install your toplevel function with %SET-TOPLEVEL,
   you will never be able to change it (%SET-TOPLEVEL will change the
   variable that stores the toplevel function, but you'll never be able
   to throw to the kernel in the place where it funcalls that function).
   One solution is to not call TOPLEVEL-LOOP in a loop (though I have
   made a patch to get rid of this problem by making TOPLEVEL-LOOP
   throw rather than just returning):

(%set-toplevel
  (function
    (lambda ()
      (handler-bind ((simple-error (function my-own-error-handler)))
        (let ((*break-on-warnings* nil))
          (toplevel-loop))))))