/// <summary> /// Function call context (with closures) /// </summary> /// <param name="name2ndx">Value name -> index</param> /// <param name="values">Values array</param> /// <param name="callerCtx">Calling context</param> /// <param name="args">Arguments array</param> /// <param name="declCtx">Context in which function is declared (for closures)</param> /// <param name="valuesNdx">Descriptor of function context values: /// -(k+1) = value from caller context; /// 0 = local value (from current context); /// +(k+1) = value from declaration context (closures emulation). /// </param> public AsyncExprCtx(IDictionary <string, int> name2ndx, IList values, IList args, AsyncExprCtx callerCtx, AsyncExprCtx declCtx, IList <int> valuesNdx) { this.name2ndx = name2ndx; int n = values.Count; ctxValues = new CtxValue[n]; for (int i = 0; i < valuesNdx.Count; i++) { int j = valuesNdx[i]; if (j < 0) { ctxValues[i] = new CtxValue(args[~j], callerCtx); } else if (j > 0) { ctxValues[i] = new CtxValue(declCtx, j - 1); } else { ctxValues[i] = new CtxValue(values[i]); } } parent = callerCtx; }
/// <summary> /// Function call context /// </summary> public AsyncExprCtx(Generator.Ctx funcCtx, AsyncExprCtx callerCtx, IList args, int nArgs) { if (funcCtx.parent != null) { Trace.Assert(funcCtx.parent.name2ndx == callerCtx.name2ndx); } else { Trace.Assert(funcCtx.values.Count == nArgs); } this.name2ndx = funcCtx.name2ndx; var values = funcCtx.values; int n = values.Count; ctxValues = new CtxValue[n]; //int nArgs = args.Count; for (int i = 0; i < nArgs; i++) { ctxValues[i] = new CtxValue(args[i], callerCtx); } for (int i = nArgs; i < n; i++) { ctxValues[i] = new CtxValue(values[i]); } parent = callerCtx; }
/// <summary> /// New independent context /// </summary> /// <param name="name2ndx">names index</param> /// <param name="values">values list</param> protected AsyncExprCtx(IDictionary <string, int> name2ndx, IList values) { this.name2ndx = name2ndx; int n = values.Count; ctxValues = new CtxValue[n]; for (int i = 0; i < n; i++) { ctxValues[i] = new CtxValue(values[i]); } }
/// <summary> /// Context for next loop iteration /// </summary> /// <param name="prevIterationContext"></param> /// <param name="nextIterationValues"></param> /// <param name="ndxOfValsToCalc"></param> public AsyncExprCtx(AsyncExprCtx prevIterationContext, IList nextIterationValues, IEnumerable <int> ndxOfValsToCalc) { int n = nextIterationValues.Count; name2ndx = prevIterationContext.name2ndx; parent = prevIterationContext.parent; Trace.Assert(parent != null); ctxValues = new CtxValue[n]; for (int i = 0; i < n; i++) { ctxValues[i] = prevIterationContext.ctxValues[i]; } foreach (int i in ndxOfValsToCalc) { if (i < 0) { ctxValues[~i] = new CtxValue(nextIterationValues[~i], prevIterationContext); } else { ctxValues[i] = new CtxValue(nextIterationValues[i]); } } }