/// <summary> /// Splits a <see cref="ForStatement"/> into a set of cases /// </summary> /// <returns>The number of new fragments.</returns> /// <param name="statement">The statement(s) to split.</param> /// <param name="collected">The currently collected statements.</param> /// <param name="fragments">The currently collected fragments.</param> private int SplitStatement(ForStatement statement, List <Statement> collected, List <List <Statement> > fragments) { if (!statement.All().OfType <AwaitExpression>().Any()) { try { statement.GetStaticForLoopValues(); // If this is a basic static loop, just treat it as a normal collected.Add(statement); return(0); } catch { throw new Exception($"Cannot process a non-static for loop without await calls in the body"); } } collected.Add( new ExpressionStatement( new AssignmentExpression( new IdentifierExpression(statement.LoopIndex), statement.Initializer))); EndFragment(collected, fragments, fragments.Count + 2, true); collected.Add(new ExpressionStatement(statement.Increment)); EndFragment(collected, fragments, fragments.Count + 1, true); var ifs = new IfElseStatement(statement.Condition, new EmptyStatement(), new EmptyStatement()); collected.Add(ifs); var selflabel = fragments.Count; EndFragment(collected, fragments, -1, true); var extras = SplitStatement(statement.LoopBody, collected, fragments); List <Statement> trueStatements; // Build the loop body into a list if (extras == 0) { trueStatements = new List <Statement>(collected); collected.Clear(); } else { trueStatements = fragments[selflabel + 1]; fragments.RemoveAt(selflabel + 1); extras--; } // TODO: Handle if we fall out of the loop if (!(trueStatements.Last() is CaseGotoStatement)) { trueStatements.Add(new CaseGotoStatement(selflabel - 1, true)); } // Jump to self, not next at the end of the loop else { trueStatements[trueStatements.Count - 1] = new CaseGotoStatement(selflabel - 1, false); } ifs.TrueStatement = ToBlockStatement(trueStatements); ifs.FalseStatement = new CaseGotoStatement(fragments.Count, true); return(extras + 3); }