public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context) { int n = _bindingInits.count(); List <ParameterExpression> parms = new List <ParameterExpression>(n); List <Expression> forms = new List <Expression>(n); /// First, set up the environment. for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); ParameterExpression parmExpr = Expression.Parameter(typeof(IFn), bi.Binding.Name); bi.Binding.ParamExpression = parmExpr; parms.Add(parmExpr); } // Then initialize for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); ParameterExpression parmExpr = (ParameterExpression)bi.Binding.ParamExpression; forms.Add(Expression.Assign(parmExpr, bi.Init.GenCode(RHC.Expression, objx, context))); } // The work forms.Add(_body.GenCode(rhc, objx, context)); return(Expression.Block(parms, forms)); }
void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed) { List <LocalBuilder> locals = new List <LocalBuilder>(); for (int i = 0; i < _bindingInits.count(); i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); Type primType = Compiler.MaybePrimitiveType(bi.Init); if (primType != null) { LocalBuilder local = ilg.DeclareLocal(primType); locals.Add(local); GenContext.SetLocalName(local, bi.Binding.Name); bi.Binding.LocalVar = local; ((MaybePrimitiveExpr)bi.Init).EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Stloc, local); } else { LocalBuilder local = ilg.DeclareLocal(typeof(Object)); locals.Add(local); GenContext.SetLocalName(local, bi.Binding.Name); bi.Binding.LocalVar = local; bi.Init.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Stloc, local); } } Label loopLabel = ilg.DefineLabel(); ilg.MarkLabel(loopLabel); try { if (_isLoop) { Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel)); } if (emitUnboxed) { ((MaybePrimitiveExpr)_body).EmitUnboxed(rhc, objx, ilg); } else { _body.Emit(rhc, objx, ilg); } } finally { if (_isLoop) { Var.popThreadBindings(); } } }
private Expression GenCode(RHC rhc, ObjExpr objx, GenContext context, bool genUnboxed) { LabelTarget loopLabel = Expression.Label(); List <ParameterExpression> parms = new List <ParameterExpression>(); List <Expression> forms = new List <Expression>(); for (int i = 0; i < _bindingInits.count(); i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); Type primType = Compiler.MaybePrimitiveType(bi.Init); ParameterExpression parmExpr; Expression initExpr; if (primType != null) { parmExpr = Expression.Parameter(primType, bi.Binding.Name); initExpr = ((MaybePrimitiveExpr)bi.Init).GenCodeUnboxed(RHC.Expression, objx, context); } else { parmExpr = Expression.Parameter(typeof(object), bi.Binding.Name); initExpr = Compiler.MaybeBox(bi.Init.GenCode(RHC.Expression, objx, context)); } bi.Binding.ParamExpression = parmExpr; parms.Add(parmExpr); forms.Add(Expression.Assign(parmExpr, initExpr)); } forms.Add(Expression.Label(loopLabel)); try { if (_isLoop) { Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel)); } Expression form = genUnboxed ? ((MaybePrimitiveExpr)_body).GenCodeUnboxed(rhc, objx, context) : _body.GenCode(rhc, objx, context); forms.Add(form); } finally { if (_isLoop) { Var.popThreadBindings(); } } Expression block = Expression.Block(parms, forms); return(block); }
public override Expression GenDlr(GenContext context) { LabelTarget loopLabel = Expression.Label(); List <ParameterExpression> parms = new List <ParameterExpression>(); List <Expression> forms = new List <Expression>(); for (int i = 0; i < _bindingInits.count(); i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); Type primType = Compiler.MaybePrimitiveType(bi.Init); ParameterExpression parmExpr = Expression.Parameter(primType ?? typeof(object), bi.Binding.Name); bi.Binding.ParamExpression = parmExpr; parms.Add(parmExpr); //forms.Add(Expression.Assign(parmExpr, Compiler.MaybeBox(bi.Init.GenDlr(context)))); Expression initExpr = primType != null ? ((MaybePrimitiveExpr)bi.Init).GenDlrUnboxed(context) : Compiler.MaybeBox(bi.Init.GenDlr(context)); forms.Add(Expression.Assign(parmExpr, initExpr)); } forms.Add(Expression.Label(loopLabel)); try { if (_isLoop) { Var.pushThreadBindings(PersistentHashMap.create(Compiler.LOOP_LABEL, loopLabel)); } forms.Add(_body.GenDlr(context)); } finally { if (_isLoop) { Var.popThreadBindings(); } } Expression block = Expression.Block(parms, forms); return(block); }
public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg) { int n = _bindingInits.count(); // Define our locals for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); LocalBuilder local = ilg.DeclareLocal(typeof(IFn)); bi.Binding.LocalVar = local; ilg.Emit(OpCodes.Ldnull); ilg.Emit(OpCodes.Stloc, local); } // Then initialize IPersistentSet lbset = PersistentHashSet.EMPTY; for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); lbset = (IPersistentSet)lbset.cons(bi.Binding); bi.Init.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Stloc, bi.Binding.LocalVar); } for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); ObjExpr fe = (ObjExpr)bi.Init; ilg.Emit(OpCodes.Ldloc, bi.Binding.LocalVar); fe.EmitLetFnInits(ilg, bi.Binding.LocalVar, objx, lbset); } _body.Emit(rhc, objx, ilg); }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // form => (letfn* [var1 (fn [args] body) ... ] body ... ) IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) throw new ParseException("Bad binding form, expected vector"); if ((bindings.count() % 2) != 0) throw new ParseException("Bad binding form, expected matched symbol/expression pairs."); ISeq body = RT.next(RT.next(form)); if (pcon.Rhc == RHC.Eval) return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "letfn__" + RT.nextID()); IPersistentMap dynamicBindings = RT.map( Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(), Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref()); try { Var.pushThreadBindings(dynamicBindings); // pre-seed env (like Lisp labels) IPersistentVector lbs = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i)); Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) throw new ParseException("Can't let qualified name: " + sym); LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null, typeof(Object), false); // b.CanBeCleared = false; lbs = lbs.cons(b); } IPersistentVector bindingInits = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { Symbol sym = (Symbol)bindings.nth(i); Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression),bindings.nth(i + 1),sym.Name); LocalBinding b = (LocalBinding)lbs.nth(i / 2); b.Init = init; BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); } return new LetFnExpr(bindingInits,new BodyExpr.Parser().Parse(pcon, body)); } finally { Var.popThreadBindings(); } }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // form => (letfn* [var1 (fn [args] body) ... ] body ... ) if (!(RT.second(form) is IPersistentVector bindings)) { throw new ParseException("Bad binding form, expected vector"); } if ((bindings.count() % 2) != 0) { throw new ParseException("Bad binding form, expected matched symbol/expression pairs."); } ISeq body = RT.next(RT.next(form)); if (pcon.Rhc == RHC.Eval) { return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "letfn__" + RT.nextID())); } IPersistentMap dynamicBindings = RT.map( Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(), Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref()); try { Var.pushThreadBindings(dynamicBindings); // pre-seed env (like Lisp labels) IPersistentVector lbs = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) { throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i)); } Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) { throw new ParseException("Can't let qualified name: " + sym); } LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null, typeof(Object), false); // b.CanBeCleared = false; lbs = lbs.cons(b); } IPersistentVector bindingInits = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { Symbol sym = (Symbol)bindings.nth(i); Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression), bindings.nth(i + 1), sym.Name); LocalBinding b = (LocalBinding)lbs.nth(i / 2); b.Init = init; BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); } return(new LetFnExpr(bindingInits, new BodyExpr.Parser().Parse(pcon, body))); } finally { Var.popThreadBindings(); } }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // form => (let [var1 val1 var2 val2 ... ] body ... ) // or (loop [var1 val1 var2 val2 ... ] body ... ) bool isLoop = RT.first(form).Equals(Compiler.LoopSym); IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) throw new ParseException("Bad binding form, expected vector"); if ((bindings.count() % 2) != 0) throw new ParseException("Bad binding form, expected matched symbol/value pairs."); ISeq body = RT.next(RT.next(form)); if (pcon.Rhc == RHC.Eval || (pcon.Rhc == RHC.Expression && isLoop)) return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "let__" + RT.nextID()); ObjMethod method = (ObjMethod)Compiler.MethodVar.deref(); IPersistentMap backupMethodLocals = method.Locals; IPersistentMap backupMethodIndexLocals = method.IndexLocals; IPersistentVector recurMismatches = PersistentVector.EMPTY; for (int i = 0; i < bindings.count() / 2; i++) { recurMismatches = recurMismatches.cons(false); } // may repeat once for each binding with a mismatch, return breaks while (true) { IPersistentMap dynamicBindings = RT.map( Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(), Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref()); method.Locals = backupMethodLocals; method.IndexLocals = backupMethodIndexLocals; if (isLoop) dynamicBindings = dynamicBindings.assoc(Compiler.LoopLocalsVar, null); try { Var.pushThreadBindings(dynamicBindings); IPersistentVector bindingInits = PersistentVector.EMPTY; IPersistentVector loopLocals = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i)); Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) throw new ParseException("Can't let qualified name: " + sym); Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), bindings.nth(i + 1), sym.Name); if (isLoop) { if (recurMismatches != null && RT.booleanCast(recurMismatches.nth(i / 2)) ) { HostArg ha = new HostArg(HostArg.ParameterType.Standard, init, null); List<HostArg> has = new List<HostArg>(1); has.Add(ha); init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "box", null, has, false); if (RT.booleanCast(RT.WarnOnReflectionVar.deref())) RT.errPrintWriter().WriteLine("Auto-boxing loop arg: " + sym); } else if (Compiler.MaybePrimitiveType(init) == typeof(int)) { List<HostArg> args = new List<HostArg>(); args.Add(new HostArg(HostArg.ParameterType.Standard, init, null)); init = new StaticMethodExpr("", null, null, typeof(RT), "longCast", null, args, false); } else if (Compiler.MaybePrimitiveType(init) == typeof(float)) { List<HostArg> args = new List<HostArg>(); args.Add(new HostArg(HostArg.ParameterType.Standard, init, null)); init = new StaticMethodExpr("", null, null, typeof(RT), "doubleCast", null, args, false); } } // Sequential enhancement of env (like Lisp let*) LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init, false); BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); if (isLoop) loopLocals = loopLocals.cons(b); } if (isLoop) Compiler.LoopLocalsVar.set(loopLocals); Expr bodyExpr; bool moreMismatches = false; try { if (isLoop) { // stuff with clear paths, Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, null)); } bodyExpr = new BodyExpr.Parser().Parse(isLoop ? pcon.SetRhc(RHC.Return) : pcon, body); } finally { if (isLoop) { Var.popThreadBindings(); for (int i = 0; i < loopLocals.count(); i++) { LocalBinding lb = (LocalBinding)loopLocals.nth(i); if (lb.RecurMismatch) { recurMismatches = (IPersistentVector)recurMismatches.assoc(i, true); moreMismatches = true; } } } } if (!moreMismatches) return new LetExpr(bindingInits, bodyExpr, isLoop); } finally { Var.popThreadBindings(); } } }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // form => (let [var1 val1 var2 val2 ... ] body ... ) // or (loop [var1 val1 var2 val2 ... ] body ... ) bool isLoop = RT.first(form).Equals(Compiler.LoopSym); if (!(RT.second(form) is IPersistentVector bindings)) { throw new ParseException("Bad binding form, expected vector"); } if ((bindings.count() % 2) != 0) { throw new ParseException("Bad binding form, expected matched symbol/value pairs."); } ISeq body = RT.next(RT.next(form)); if (pcon.Rhc == RHC.Eval || (pcon.Rhc == RHC.Expression && isLoop)) { return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "let__" + RT.nextID())); } ObjMethod method = (ObjMethod)Compiler.MethodVar.deref(); IPersistentMap backupMethodLocals = method.Locals; IPersistentMap backupMethodIndexLocals = method.IndexLocals; IPersistentVector recurMismatches = PersistentVector.EMPTY; for (int i = 0; i < bindings.count() / 2; i++) { recurMismatches = recurMismatches.cons(false); } // may repeat once for each binding with a mismatch, return breaks while (true) { IPersistentMap dynamicBindings = RT.map( Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(), Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref()); method.SetLocals(backupMethodLocals, backupMethodIndexLocals); if (isLoop) { dynamicBindings = dynamicBindings.assoc(Compiler.LoopLocalsVar, null); } try { Var.pushThreadBindings(dynamicBindings); IPersistentVector bindingInits = PersistentVector.EMPTY; IPersistentVector loopLocals = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) { throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i)); } Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) { throw new ParseException("Can't let qualified name: " + sym); } Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), bindings.nth(i + 1), sym.Name); if (isLoop) { if (recurMismatches != null && RT.booleanCast(recurMismatches.nth(i / 2))) { HostArg ha = new HostArg(HostArg.ParameterType.Standard, init, null); List <HostArg> has = new List <HostArg>(1) { ha }; init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "box", null, has, false); if (RT.booleanCast(RT.WarnOnReflectionVar.deref())) { RT.errPrintWriter().WriteLine("Auto-boxing loop arg: " + sym); } } else if (Compiler.MaybePrimitiveType(init) == typeof(int)) { List <HostArg> args = new List <HostArg> { new HostArg(HostArg.ParameterType.Standard, init, null) }; init = new StaticMethodExpr("", null, null, typeof(RT), "longCast", null, args, false); } else if (Compiler.MaybePrimitiveType(init) == typeof(float)) { List <HostArg> args = new List <HostArg> { new HostArg(HostArg.ParameterType.Standard, init, null) }; init = new StaticMethodExpr("", null, null, typeof(RT), "doubleCast", null, args, false); } } // Sequential enhancement of env (like Lisp let*) LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init, typeof(Object), false); BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); if (isLoop) { loopLocals = loopLocals.cons(b); } } if (isLoop) { Compiler.LoopLocalsVar.set(loopLocals); } Expr bodyExpr; bool moreMismatches = false; try { if (isLoop) { object methodReturnContext = pcon.Rhc == RHC.Return ? Compiler.MethodReturnContextVar.deref() : null; // stuff with clear paths, Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, null, Compiler.MethodReturnContextVar, methodReturnContext)); } bodyExpr = new BodyExpr.Parser().Parse(isLoop ? pcon.SetRhc(RHC.Return) : pcon, body); } finally { if (isLoop) { Var.popThreadBindings(); for (int i = 0; i < loopLocals.count(); i++) { LocalBinding lb = (LocalBinding)loopLocals.nth(i); if (lb.RecurMismatch) { recurMismatches = (IPersistentVector)recurMismatches.assoc(i, true); moreMismatches = true; } } } } if (!moreMismatches) { return(new LetExpr(bindingInits, bodyExpr, isLoop)); } } finally { Var.popThreadBindings(); } } }
public Expr Parse(object frm) { ISeq form = (ISeq)frm; // form => (letfn* [var1 (fn [args] body) ... ] body ... ) IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) { throw new ArgumentException("Bad binding form, expected vector"); } if ((bindings.count() % 2) != 0) { throw new ArgumentException("Bad binding form, expected matched symbol/value pairs."); } ISeq body = RT.next(RT.next(form)); // TODO: This is one place where context makes a difference. Need to figure this out. // if (ctxt == C.EVAL) // return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form))); IPersistentMap dynamicBindings = RT.map( Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(), Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref()); try { Var.pushThreadBindings(dynamicBindings); // pre-seed env (like Lisp labels) IPersistentVector lbs = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) { throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i)); } Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) { throw new Exception("Can't let qualified name: " + sym); } LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null); lbs = lbs.cons(b); } IPersistentVector bindingInits = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { Symbol sym = (Symbol)bindings.nth(i); Expr init = Compiler.GenerateAST(bindings.nth(i + 1), sym.Name); // Sequential enhancement of env (like Lisp let*) LocalBinding b = (LocalBinding)lbs.nth(i / 2); b.Init = init; BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); } return(new LetFnExpr(bindingInits, new BodyExpr.Parser().Parse(body))); } finally { Var.popThreadBindings(); } }
public Expr Parse(object frm, bool isRecurContext) { ISeq form = (ISeq)frm; // form => (letfn* [var1 (fn [args] body) ... ] body ... ) IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) throw new ArgumentException("Bad binding form, expected vector"); if ((bindings.count() % 2) != 0) throw new ArgumentException("Bad binding form, expected matched symbol/value pairs."); ISeq body = RT.next(RT.next(form)); IPersistentMap dynamicBindings = RT.map( Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(), Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref()); try { Var.pushThreadBindings(dynamicBindings); // pre-seed env (like Lisp labels) IPersistentVector lbs = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i)); Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) throw new Exception("Can't let qualified name: " + sym); LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null); lbs = lbs.cons(b); } IPersistentVector bindingInits = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { Symbol sym = (Symbol)bindings.nth(i); Expr init = Compiler.GenerateAST(bindings.nth(i + 1),sym.Name,false); // Sequential enhancement of env (like Lisp let*) LocalBinding b = (LocalBinding)lbs.nth(i / 2); b.Init = init; BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); } return new LetFnExpr(bindingInits,new BodyExpr.Parser().Parse(body,isRecurContext)); } finally { Var.popThreadBindings(); } }
public Expr Parse(object frm) { ISeq form = (ISeq) frm; // form => (let [var1 val1 var2 val2 ... ] body ... ) // or (loop [var1 val1 var2 val2 ... ] body ... ) bool isLoop = RT.first(form).Equals(Compiler.LOOP); IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) throw new ArgumentException("Bad binding form, expected vector"); if ((bindings.count() % 2) != 0) throw new ArgumentException("Bad binding form, expected matched symbol/value pairs."); ISeq body = RT.next(RT.next(form)); // TODO: This is one place where context makes a difference. Need to figure this out. // Second test clause added in Rev 1216. // if (ctxt == C.EVAL || (context == c.EXPRESSION && isLoop)) // return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form))); // As of Rev 1216, I tried tjos out. // However, it goes into an infinite loop. Still need to figure this out. //if (isLoop) // Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form))); IPersistentMap dynamicBindings = RT.map( Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(), Compiler.NEXT_LOCAL_NUM,Compiler.NEXT_LOCAL_NUM.deref()); if (isLoop) dynamicBindings = dynamicBindings.assoc(Compiler.LOOP_LOCALS, null); try { Var.pushThreadBindings(dynamicBindings); IPersistentVector bindingInits = PersistentVector.EMPTY; IPersistentVector loopLocals = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i)); Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) throw new Exception("Can't let qualified name: " + sym); Expr init = Compiler.GenerateAST(bindings.nth(i + 1)); // Sequential enhancement of env (like Lisp let*) LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init); BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); if (isLoop) loopLocals = loopLocals.cons(b); } if (isLoop) Compiler.LOOP_LOCALS.set(loopLocals); return new LetExpr(bindingInits, new BodyExpr.Parser().Parse(body), isLoop); } finally { Var.popThreadBindings(); } }
public Expr Parse(object frm, bool isRecurContext) { ISeq form = (ISeq) frm; // form => (let [var1 val1 var2 val2 ... ] body ... ) // or (loop [var1 val1 var2 val2 ... ] body ... ) bool isLoop = RT.first(form).Equals(Compiler.LOOP); IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) throw new ArgumentException("Bad binding form, expected vector"); if ((bindings.count() % 2) != 0) throw new ArgumentException("Bad binding form, expected matched symbol/value pairs."); ISeq body = RT.next(RT.next(form)); IPersistentMap dynamicBindings = RT.map( Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(), Compiler.NEXT_LOCAL_NUM,Compiler.NEXT_LOCAL_NUM.deref()); if (isLoop) dynamicBindings = dynamicBindings.assoc(Compiler.LOOP_LOCALS, null); try { Var.pushThreadBindings(dynamicBindings); IPersistentVector bindingInits = PersistentVector.EMPTY; IPersistentVector loopLocals = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i)); Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) throw new Exception("Can't let qualified name: " + sym); Expr init = Compiler.GenerateAST(bindings.nth(i + 1),false); // Sequential enhancement of env (like Lisp let*) LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init); BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); if (isLoop) loopLocals = loopLocals.cons(b); } if (isLoop) Compiler.LOOP_LOCALS.set(loopLocals); return new LetExpr(bindingInits, new BodyExpr.Parser().Parse(body,isLoop || isRecurContext), isLoop); } finally { Var.popThreadBindings(); } }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // form => (let [var1 val1 var2 val2 ... ] body ... ) // or (loop [var1 val1 var2 val2 ... ] body ... ) bool isLoop = RT.first(form).Equals(Compiler.LOOP); IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) throw new ArgumentException("Bad binding form, expected vector"); if ((bindings.count() % 2) != 0) throw new ArgumentException("Bad binding form, expected matched symbol/value pairs."); ISeq body = RT.next(RT.next(form)); if (pcon.Rhc == RHC.Eval || (pcon.Rhc == RHC.Expression && isLoop)) return Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)),"let__"+RT.nextID()); ObjMethod method = (ObjMethod)Compiler.METHOD.deref(); IPersistentMap backupMethodLocals = method.Locals; IPersistentMap backupMethodIndexLocals = method.IndexLocals; IPersistentVector recurMismatches = null; // we might repeat once if a loop with a recurMismatch, return breaks while (true) { IPersistentMap dynamicBindings = RT.map( Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(), Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref()); if (isLoop) dynamicBindings = dynamicBindings.assoc(Compiler.LOOP_LOCALS, null); try { Var.pushThreadBindings(dynamicBindings); IPersistentVector bindingInits = PersistentVector.EMPTY; IPersistentVector loopLocals = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i)); Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) throw new Exception("Can't let qualified name: " + sym); Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), bindings.nth(i + 1), sym.Name); //if (isLoop) //{ // if (recurMismatches != null && ((LocalBinding)recurMismatches.nth(i / 2)).RecurMistmatch) // { // HostArg ha = new HostArg(HostArg.ParameterType.Standard,init,null); // List<HostArg> has = new List<HostArg>(1); // has.Add(ha); // init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "box", has); // if (RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) // RT.errPrintWriter().WriteLine("Auto-boxing loop arg: " + sym); // } // else if (Compiler.MaybePrimitiveType(init) == typeof(int)) // { // HostArg ha = new HostArg(HostArg.ParameterType.Standard, init, null); // List<HostArg> has = new List<HostArg>(1); // has.Add(ha); // init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "longCast", has); // } // else if (Compiler.MaybePrimitiveType(init) == typeof(float)) // { // HostArg ha = new HostArg(HostArg.ParameterType.Standard, init, null); // List<HostArg> has = new List<HostArg>(1); // has.Add(ha); // init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "doubleCast", has); // } //} // Sequential enhancement of env (like Lisp let*) LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init, false); BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); if (isLoop) loopLocals = loopLocals.cons(b); } if (isLoop) Compiler.LOOP_LOCALS.set(loopLocals); Expr bodyExpr; try { if (isLoop) { // stuff with clear paths } bodyExpr = new BodyExpr.Parser().Parse(isLoop ? pcon.SetRhc(RHC.Return) : pcon, body); } finally { if (isLoop) { // stuff with clear paths recurMismatches = null; for (int i = 0; i < loopLocals.count(); i++) { LocalBinding lb = (LocalBinding)loopLocals.nth(i); if (lb.RecurMistmatch) recurMismatches = loopLocals; } } } if (recurMismatches == null) return new LetExpr(bindingInits, bodyExpr, isLoop); } finally { Var.popThreadBindings(); } } }
public Expr Parse(object frm) { ISeq form = (ISeq)frm; // form => (let [var1 val1 var2 val2 ... ] body ... ) // or (loop [var1 val1 var2 val2 ... ] body ... ) bool isLoop = RT.first(form).Equals(Compiler.LOOP); IPersistentVector bindings = RT.second(form) as IPersistentVector; if (bindings == null) { throw new ArgumentException("Bad binding form, expected vector"); } if ((bindings.count() % 2) != 0) { throw new ArgumentException("Bad binding form, expected matched symbol/value pairs."); } ISeq body = RT.next(RT.next(form)); // TODO: This is one place where context makes a difference. Need to figure this out. // Second test clause added in Rev 1216. // if (ctxt == C.EVAL || (context == c.EXPRESSION && isLoop)) // return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form))); // As of Rev 1216, I tried tjos out. // However, it goes into an infinite loop. Still need to figure this out. //if (isLoop) // Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form))); IPersistentMap dynamicBindings = RT.map( Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(), Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref()); if (isLoop) { dynamicBindings = dynamicBindings.assoc(Compiler.LOOP_LOCALS, null); } try { Var.pushThreadBindings(dynamicBindings); IPersistentVector bindingInits = PersistentVector.EMPTY; IPersistentVector loopLocals = PersistentVector.EMPTY; for (int i = 0; i < bindings.count(); i += 2) { if (!(bindings.nth(i) is Symbol)) { throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i)); } Symbol sym = (Symbol)bindings.nth(i); if (sym.Namespace != null) { throw new Exception("Can't let qualified name: " + sym); } Expr init = Compiler.GenerateAST(bindings.nth(i + 1)); // Sequential enhancement of env (like Lisp let*) LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init); BindingInit bi = new BindingInit(b, init); bindingInits = bindingInits.cons(bi); if (isLoop) { loopLocals = loopLocals.cons(b); } } if (isLoop) { Compiler.LOOP_LOCALS.set(loopLocals); } return(new LetExpr(bindingInits, new BodyExpr.Parser().Parse(body), isLoop)); } finally { Var.popThreadBindings(); } }