From: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - 2008-08-04 19:32:59
|
On Mon, Aug 4, 2008 at 12:27 PM, Ville Voutilainen <vil...@gm...> wrote: >> If you're not afraid to code to the internals of ABCL (they're not >> that fast moving), I have a function called "safeFuncall" which >> catches any uncaught conditions and raises them as Java exceptions of >> type "ConditionThrowable". > > Sounds interesting. Is this code in ABCL cvs or just something > external you implemented? > >> Exactly. Want to have the code? Or maybe I should suggest adding this >> code to the LispObject implementation? > > Yes, if you can post the code I'd be interested in looking at it and probably > using it, too. The idea of adding it to LispObject sounds good too, since > some people use LispObject for invoking lisp code. I am personally more > inclined to use Interpreter, since I deal with code that has quite a bit > of macros. Anyway, having LispObject throw java-exceptions on uncaught > conditions is IMHO very useful. I wouldn't modify Interpreter to do the > same, though. > The code is below, I find it a bit of a mess now that I look at it again, but the general concept should be clear. HTH, Erik. /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package extendedlisp; import org.armedbear.lisp.*; import org.armedbear.lisp.Package; import java.lang.Runnable; /** * * @author Erik */ public class ExtendedLisp extends Lisp { final static Symbol _HANDLER_CLUSTERS_ = PACKAGE_SYS.intern("*HANDLER-CLUSTERS*"); final static Symbol ERROR = PACKAGE_CL.intern("ERROR"); public static class IgnoreHandler extends Function { final Symbol tag; public IgnoreHandler(Symbol aTag) { super(); tag = aTag; } @Override public LispObject execute(LispObject arg) throws ConditionThrowable { throw new Go(tag); } } public static class ConverterHandler extends Function { public ConverterHandler() { }; @Override public LispObject execute(LispObject arg) throws ConditionThrowable { throw LispErrorMap.getError(arg); } } public static LispObject createHandlers() throws ConditionThrowable { return NIL; } public static LispObject addToHandlers(LispObject cluster, Symbol type, LispObject handler) throws ConditionThrowable { return new Cons( new Cons(type, handler), cluster); } public static void bindHandlers(LispObject cluster) throws ConditionThrowable { LispObject cval = _HANDLER_CLUSTERS_.symbolValue(); if (cval == null) cval = NIL; LispThread.currentThread().bindSpecial(_HANDLER_CLUSTERS_, new Cons(cluster, cval)); } public static void unbindHandlers() throws ConditionThrowable { LispThread.currentThread().rebindSpecial(_HANDLER_CLUSTERS_, _HANDLER_CLUSTERS_.symbolValue().cdr()); } public static LispObject funcall_without_errors(LispObject fun, LispObject[] args, LispThread thread) throws ConditionThrowable { bindHandlers(addToHandlers(createHandlers(), ERROR, new IgnoreHandler(T))); // we don't care about the symbol here try { return funcall(fun, args, thread); } catch (ConditionThrowable ct) { return null; } finally { unbindHandlers(); } } public static LispObject funcall_with_conversion(LispObject fun, LispObject[] args, LispThread thread) throws ConditionThrowable { bindHandlers(addToHandlers(createHandlers(), ERROR, new ConverterHandler())); try { return funcall(fun, args, thread); } finally { unbindHandlers(); } } public static void ignoreErrors(Runnable R) throws ConditionThrowable { bindHandlers(addToHandlers(createHandlers(), ERROR, new IgnoreHandler(T))); try { R.run(); } finally { unbindHandlers(); } } } |