(C context, Object frm)
| 6783 | |
| 6784 | static class Parser implements IParser{ |
| 6785 | public Expr parse(C context, Object frm) { |
| 6786 | ISeq form = (ISeq) frm; |
| 6787 | //(letfns* [var (fn [args] body) ...] body...) |
| 6788 | if(!(RT.second(form) instanceof IPersistentVector)) |
| 6789 | throw new IllegalArgumentException("Bad binding form, expected vector"); |
| 6790 | |
| 6791 | IPersistentVector bindings = (IPersistentVector) RT.second(form); |
| 6792 | if((bindings.count() % 2) != 0) |
| 6793 | throw new IllegalArgumentException("Bad binding form, expected matched symbol expression pairs"); |
| 6794 | |
| 6795 | ISeq body = RT.next(RT.next(form)); |
| 6796 | |
| 6797 | if(context == C.EVAL) |
| 6798 | return analyze(context, RT.list(RT.list(FNONCE, PersistentVector.EMPTY, form))); |
| 6799 | |
| 6800 | IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.deref(), |
| 6801 | NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.deref()); |
| 6802 | |
| 6803 | try |
| 6804 | { |
| 6805 | Var.pushThreadBindings(dynamicBindings); |
| 6806 | |
| 6807 | //pre-seed env (like Lisp labels) |
| 6808 | PersistentVector lbs = PersistentVector.EMPTY; |
| 6809 | for(int i = 0; i < bindings.count(); i += 2) |
| 6810 | { |
| 6811 | if(!(bindings.nth(i) instanceof Symbol)) |
| 6812 | throw new IllegalArgumentException( |
| 6813 | "Bad binding form, expected symbol, got: " + bindings.nth(i)); |
| 6814 | Symbol sym = (Symbol) bindings.nth(i); |
| 6815 | if(sym.getNamespace() != null) |
| 6816 | throw Util.runtimeException("Can't let qualified name: " + sym); |
| 6817 | LocalBinding lb = registerLocal(sym, tagOf(sym), null,false); |
| 6818 | lb.canBeCleared = false; |
| 6819 | lbs = lbs.cons(lb); |
| 6820 | } |
| 6821 | PersistentVector bindingInits = PersistentVector.EMPTY; |
| 6822 | for(int i = 0; i < bindings.count(); i += 2) |
| 6823 | { |
| 6824 | Symbol sym = (Symbol) bindings.nth(i); |
| 6825 | Expr init = analyze(C.EXPRESSION, bindings.nth(i + 1), sym.name); |
| 6826 | LocalBinding lb = (LocalBinding) lbs.nth(i / 2); |
| 6827 | lb.init = init; |
| 6828 | BindingInit bi = new BindingInit(lb, init); |
| 6829 | bindingInits = bindingInits.cons(bi); |
| 6830 | } |
| 6831 | return new LetFnExpr(bindingInits, (new BodyExpr.Parser()).parse(context, body)); |
| 6832 | } |
| 6833 | finally |
| 6834 | { |
| 6835 | Var.popThreadBindings(); |
| 6836 | } |
| 6837 | } |
| 6838 | } |
| 6839 | |
| 6840 | public Object eval() { |
nothing calls this directly
no test coverage detected