Exemplo n.º 1
0
        /// <summary>
        /// Splits a <see cref="WhileStatement"/> 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(WhileStatement statement, List <Statement> collected, List <List <Statement> > fragments)
        {
            if (!statement.All().OfType <AwaitExpression>().Any())
            {
                throw new Exception($"Cannot process a while statement without await calls in the body");
            }

            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.Body, 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, true));
            }
            // Jump to self, not next at the end of the loop
            else
            {
                trueStatements[trueStatements.Count - 1] = new CaseGotoStatement(selflabel, false);
            }

            ifs.TrueStatement  = ToBlockStatement(trueStatements);
            ifs.FalseStatement = new CaseGotoStatement(fragments.Count, true);

            return(extras + 1);
        }