/// <summary> /// Execute each expression. /// </summary> /// <returns></returns> public object VisitForEach(ForEachExpr expr) { expr.DoContinueRunning = true; expr.DoBreakLoop = false; expr.DoContinueLoop = false; // for(user in users) // Push scope for var name var source = expr.SourceExpr.Evaluate(this) as LObject; // Check : 1. null object? if (source == LObjects.Null) return LObjects.Null; IEnumerator enumerator = null; if (source.Type == LTypes.Array) enumerator = ((IList)source.GetValue()).GetEnumerator(); else if (source.Type == LTypes.Map) enumerator = ((IDictionary)source.GetValue()).GetEnumerator(); else if (source.Type == LTypes.Table) enumerator = ((IList) source.GetValue()).GetEnumerator(); expr.DoContinueRunning = enumerator.MoveNext(); while (expr.DoContinueRunning) { // Set the next value of "x" in for(x in y). var current = enumerator.Current is LObject ? enumerator.Current : LangTypeHelper.ConvertToLangClass(enumerator.Current); this.Ctx.Memory.SetValue(expr.VarName, current); if (expr.Statements != null && expr.Statements.Count > 0) { foreach (var stmt in expr.Statements) { stmt.Evaluate(this); this.Ctx.Limits.CheckLoop(expr); // If Break statment executed. if (expr.DoBreakLoop) { expr.DoContinueRunning = false; break; } // Continue statement. else if (expr.DoContinueLoop) break; } } else break; // Break loop here. if (expr.DoContinueRunning == false) break; // Increment. expr.DoContinueRunning = enumerator.MoveNext(); } return LObjects.Null; }
/// <summary> /// Creates a unary expression with symbol scope, context, script refernce set. /// </summary> /// <param name="varname"></param> /// <param name="sourceExpr"></param> /// <returns></returns> public static Expr ForEach(string varname, Expr sourceExpr, TokenData token) { var exp = new ForEachExpr(); exp.VarName = varname; exp.SourceExpr = sourceExpr; SetupContext(exp, token); return exp; }
/// <summary> /// Visits the for each statement tree. /// </summary> /// <param name="forExpr"></param> public object VisitForEach(ForEachExpr expr) { _callBackOnNodeStart(expr); expr.Condition.Visit(this); foreach (var stmt in expr.Statements) { stmt.Visit(this); } return null; }