(C context, Object frm)
| 2786 | static class Parser implements IParser{ |
| 2787 | |
| 2788 | public Expr parse(C context, Object frm) { |
| 2789 | ISeq form = (ISeq) frm; |
| 2790 | // if(context == C.EVAL || context == C.EXPRESSION) |
| 2791 | if(context != C.RETURN) |
| 2792 | return analyze(context, RT.list(RT.list(FNONCE, PersistentVector.EMPTY, form))); |
| 2793 | |
| 2794 | //(try try-expr* catch-expr* finally-expr?) |
| 2795 | //catch-expr: (catch class sym expr*) |
| 2796 | //finally-expr: (finally expr*) |
| 2797 | |
| 2798 | PersistentVector body = PersistentVector.EMPTY; |
| 2799 | PersistentVector catches = PersistentVector.EMPTY; |
| 2800 | Expr bodyExpr = null; |
| 2801 | Expr finallyExpr = null; |
| 2802 | boolean caught = false; |
| 2803 | |
| 2804 | int retLocal = getAndIncLocalNum(); |
| 2805 | int finallyLocal = getAndIncLocalNum(); |
| 2806 | for(ISeq fs = form.next(); fs != null; fs = fs.next()) |
| 2807 | { |
| 2808 | Object f = fs.first(); |
| 2809 | Object op = (f instanceof ISeq) ? ((ISeq) f).first() : null; |
| 2810 | if(!Util.equals(op, CATCH) && !Util.equals(op, FINALLY)) |
| 2811 | { |
| 2812 | if(caught) |
| 2813 | throw Util.runtimeException("Only catch or finally clause can follow catch in try expression"); |
| 2814 | body = body.cons(f); |
| 2815 | } |
| 2816 | else |
| 2817 | { |
| 2818 | if(bodyExpr == null) |
| 2819 | try { |
| 2820 | Var.pushThreadBindings(RT.map(NO_RECUR, true, METHOD_RETURN_CONTEXT, null)); |
| 2821 | bodyExpr = (new BodyExpr.Parser()).parse(context, RT.seq(body)); |
| 2822 | } finally { |
| 2823 | Var.popThreadBindings(); |
| 2824 | } |
| 2825 | |
| 2826 | if(Util.equals(op, CATCH)) |
| 2827 | { |
| 2828 | Class c = HostExpr.maybeClass(RT.second(f), false); |
| 2829 | if(c == null) |
| 2830 | throw new IllegalArgumentException("Unable to resolve classname: " + RT.second(f)); |
| 2831 | if(!(RT.third(f) instanceof Symbol)) |
| 2832 | throw new IllegalArgumentException( |
| 2833 | "Bad binding form, expected symbol, got: " + RT.third(f)); |
| 2834 | Symbol sym = (Symbol) RT.third(f); |
| 2835 | if(sym.getNamespace() != null) |
| 2836 | throw Util.runtimeException("Can't bind qualified name:" + sym); |
| 2837 | |
| 2838 | IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.deref(), |
| 2839 | NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.deref(), |
| 2840 | IN_CATCH_FINALLY, RT.T); |
| 2841 | try |
| 2842 | { |
| 2843 | Var.pushThreadBindings(dynamicBindings); |
| 2844 | LocalBinding lb = registerLocal(sym, |
| 2845 | (Symbol) (RT.second(f) instanceof Symbol ? RT.second(f) |
nothing calls this directly
no test coverage detected