From: Andrew Topp <talmakion@ya...> - 2004-03-07 13:22:08
This is pretty much what I was doing in Universal Corporation. I've only
just started rewriting the ECL plugin over the past couple of weeks, but
a laptop HD crash made me loose a fair chunk of work. So not much has
>>I have a follow-up question: is there a way of
>>determining if the parsing of the lisp code works ok?
>>Ideally I'd like to be able to call a function to tell
>>me if the interpreted lisp code contains errors and,
>>if so, what those errors are (but I'd like the
>>application to capture this information, without
>>requiring user interaction).
> Why don't you enclose your lisp code in some handler-bind or
> handler-case form? si_safe_eval(..) just outputs the symbol
> error if something bad happens. If you want something
> fancier, you can install some lisp function, or macro, that
> captures the error and outputs the useful information.
I was doing something in the style of the Python postmortem debugger. A
function defined in Lisp code (loaded from UC's initialization .lisp
file), which caught errors and saved as much state as it could, call
stack, any info that I could get (reading through ECL's own debugger is
where I learnt most of that), saving it to a special variable, and
returning an error status to the C++ caller.
This code has been ripped out, it wasn't as complete in the CVS as it
was for me, but a fair bit is still there in the UC CVS history.
> Sorry, I am taking a plane in 5 hours and cannot be more
> precise, but anybody with a knowledge of lisp will be able
> to help you.
That counts me out :).
>>I was guessing cl_safe_eval() supports this, but I
>>couldn't figure out how to make it do so.
This function just sets si::*ignore-errors* (which causes the ECL error
handler to not trigger on an error), sets up the frame stack (look at
the frs_push()) with a CATCHALL 'tag' so that any error will just drop
out into that function, and returns an error status if something bad
Think of this usage of frs_push() as something like a setjmp/longjmp
used in C for stack unwinding, except it should also handle resetting
the ECL state to something sane.
This function is a very simple C version of the error-catching I was
doing with native Lisp. From Lisp, you have access to a great deal more,
easily. It just sucks that I'm not that great at Lisp.
> My suggestion is that you implement a cleverer routine in lisp,
> which takes a form and produces a bytecodes object (for instance
> with (coerce form 'function)). Write also another routine that
> applies this function capturing errors. Give them meaninful
> names, and if you want (you do not really need it) compile them.
> Use cl_funcal(...) to invoke these cleverer functions.
I tried doing this myself, but my implementation was too kludgy. As I
mentioned, I'm going for a complete ground-up rewrite.
> Best regards,
> P.S.: I will be away in the Alps for a week. Probably without
> internet :-/
Have fun :)
(Goes for Michael too ;)