import org.armedbear.lisp.*; public class TestDebugger4 { static Interpreter interp = Interpreter.createInstance(); public static void main(String[] args) { installDebuggerHook(); interp.eval("(defparameter *x* 1)"); interp.eval("(defun f ()" + " (progv '(*x*) '(2)" // + " (let ((*x* 2))" //also has same problem as progv + " (error \"test\")))"); //with this line enabled, the program prints the incorrect value 2 not 1. // interp.eval("(compile 'f)"); //the PROGV used for interpreted lisp is in SpecialOperators.java //but that code is not used for compiled lisp. Maybe the code generated //by compiler-pass2.lisp is used instead. //The former has a finally clause that is important. //My hypothesis is that the latter does not have the equivalent code in a //finally clause try { interp.eval("(f)"); } catch (Exception expected) {} p(interp.eval("*x*").javaInstance()); //correct: 1, incorrect: 2 } //copied from LispModule /* disable the debugger. raise a RuntimeException instead */ static void installDebuggerHook() { Symbol.DEBUGGER_HOOK .setSymbolValue(new Function() { public LispObject execute(LispObject c, LispObject h) { throw translateCondition(c);}}); } private static RuntimeException translateCondition(LispObject c) { return new RuntimeException(c.princToString()); } static void p(Object o) {System.out.println(o);} }