On a little more thought, I had a look at the “Common Lisp condition system” and it isn’t terribly complicated. All a condition is, is a type of the error (a symbol), a string describing the error, and optionally the offending object.
uLisp already has those concepts, you would just need to pack them in a list. This could then be used by (handler-bind)
.
Then instead of using the MUFFLEERRORS flag to tell you if you’re inside an (ignore-errors)
or not, you just don’t do anything with the error. If it bubbles up to the top level REPL, it, wasn’t handled, so then print it.
Instead of printing an error, error() and error2() would stuff the details in a global variable and longjmp out. (handler-bind)
would make a setjmp trap like (unwind-protect)
and (ignore-errors)
, and if it gets longjmp’ed into it checks the global variable containing the appropriate handler, calling it if it matches or longjmp’ing out if none match. If you longjmp yourself back into the REPL, then print the error, clear it, and then REPL again.
I do notice that the “condition” is a CLOS object, but since uLisp doesn’t have CLOS my best suggestion is to make (handler-bind)
work like (case)
where you can have multiple condition types match one handler at once. (You could probably even use fn_case() to do the matching for you, calling it like fn_case(cons(error_type, cases), env)
)