コード例 #1
0
        public void AcceptLoopBlock(LoopBlock stmt)
        {
            IfStatement cond = stmt.Body.AsSingleStatement() as IfStatement;

            if (cond == null)
            {
                return;
            }

            if (cond.Conditions.Count != 1 ||
                cond.Branches.Count != 2)
            {
                return;
            }

            IList <Statement> trueBranch = cond.Branches[0].AsStatementList();

            if (trueBranch.Count == 0 ||
                !trueBranch.Last().Equals(new ContinueLoopStatement()
            {
                Loop = stmt
            }))
            {
                return;
            }

            IList <Statement> falseBranch = cond.Branches[1].AsStatementList();

            if (falseBranch.Count == 0)
            {
                return;
            }

#if false
            BreakLoopStatement breaker = new BreakLoopStatement()
            {
                Loop = stmt
            };
            Statement trailer = cond.Branches[1].Clone;
            trailer.RemoveAll(breaker);
#endif

            Statement         trailer = cond.Branches[1].Clone;
            BreakLoopReplacer blr     = new BreakLoopReplacer(stmt);
            trailer.Accept(blr);

            if (trailer.NeedsLoopScope(stmt))
            {
                return;
            }
#if false
            CompoundStatement trailer = new CompoundStatement();
            trailer.Statements.AddRange(falseBranch.Take(falseBranch.Count - 1));
            if (trailer.NeedsLoopScope(stmt))
            {
                return;
            }

            BreakLoopStatement breaker = falseBranch.Last() as BreakLoopStatement;
            if (breaker == null)
            {
                return;
            }

            if (breaker.Loop.IsAncestor(stmt))
            {
                /* Consider the following situation:
                 *
                 * L1: loop
                 *   some outer loop work
                 *   L2: loop
                 *     if someCondition then
                 *       do something
                 *       continue L2
                 *     else
                 *       do something different
                 *       break L1
                 *     end if
                 *   end loop L2
                 * end loop L1
                 *
                 * As the inner break statement breaks the outer loop, this loop
                 * must be transformed into the following code:
                 *
                 * L1: loop
                 *   some outer loop work
                 *   while someCondition loop
                 *     do something
                 *   end while
                 *   do something different
                 *   break L1
                 * end loop
                 * */

                if (breaker.Loop != stmt)
                {
                    trailer.Statements.Add(breaker);
                }
            }
            else
            {
                return;
            }
#endif

            CompoundStatement newBody = new CompoundStatement();
            newBody.Statements.AddRange(trueBranch.Take(trueBranch.Count - 1));

            LoopBlock whileBlock = (LoopBlock)stmt.Clone;
            whileBlock.HeadCondition = cond.Conditions[0];
            whileBlock.Body          = newBody;
            whileBlock.Trailer       = trailer;

            Result = whileBlock;
        }
コード例 #2
0
        public void AcceptLoopBlock(LoopBlock stmt)
        {
            IfStatement cond = stmt.Body.AsSingleStatement() as IfStatement;
            if (cond == null)
                return;

            if (cond.Conditions.Count != 1 ||
                cond.Branches.Count != 2)
                return;

            IList<Statement> trueBranch = cond.Branches[0].AsStatementList();
            if (trueBranch.Count == 0 ||
                !trueBranch.Last().Equals(new ContinueLoopStatement() { Loop = stmt }))
                return;

            IList<Statement> falseBranch = cond.Branches[1].AsStatementList();
            if (falseBranch.Count == 0)
                return;

#if false
            BreakLoopStatement breaker = new BreakLoopStatement() { Loop = stmt };
            Statement trailer = cond.Branches[1].Clone;
            trailer.RemoveAll(breaker);
#endif

            Statement trailer = cond.Branches[1].Clone;
            BreakLoopReplacer blr = new BreakLoopReplacer(stmt);
            trailer.Accept(blr);

            if (trailer.NeedsLoopScope(stmt))
                return;
#if false
            CompoundStatement trailer = new CompoundStatement();
            trailer.Statements.AddRange(falseBranch.Take(falseBranch.Count - 1));
            if (trailer.NeedsLoopScope(stmt))
                return;

            BreakLoopStatement breaker = falseBranch.Last() as BreakLoopStatement;
            if (breaker == null)
                return;

            if (breaker.Loop.IsAncestor(stmt))
            {
                /* Consider the following situation:
                 * 
                 * L1: loop
                 *   some outer loop work
                 *   L2: loop
                 *     if someCondition then
                 *       do something
                 *       continue L2
                 *     else
                 *       do something different
                 *       break L1
                 *     end if
                 *   end loop L2
                 * end loop L1
                 * 
                 * As the inner break statement breaks the outer loop, this loop
                 * must be transformed into the following code:
                 * 
                 * L1: loop
                 *   some outer loop work
                 *   while someCondition loop
                 *     do something
                 *   end while
                 *   do something different
                 *   break L1
                 * end loop
                 * */

                if (breaker.Loop != stmt)
                {
                    trailer.Statements.Add(breaker);
                }
            }
            else
                return;
#endif

            CompoundStatement newBody = new CompoundStatement();
            newBody.Statements.AddRange(trueBranch.Take(trueBranch.Count - 1));

            LoopBlock whileBlock = (LoopBlock)stmt.Clone;
            whileBlock.HeadCondition = cond.Conditions[0];
            whileBlock.Body = newBody;
            whileBlock.Trailer = trailer;

            Result = whileBlock;
        }