Пример #1
0
        protected override ICode VisitDoLoop(StmtDoLoop s)
        {
            var                body   = (Stmt)this.Visit(s.Body);
            StmtIf             lastIf = null;
            IEnumerable <Stmt> preIf  = null;

            if (body.StmtType == Stmt.NodeType.Block)
            {
                var sBlock = (StmtBlock)body;
                if (sBlock.Statements.Any())
                {
                    var sLast = sBlock.Statements.Last();
                    if (sLast.StmtType == Stmt.NodeType.If)
                    {
                        lastIf = (StmtIf)sLast;
                        preIf  = sBlock.Statements.Take(sBlock.Statements.Count() - 1).ToArray();
                    }
                }
            }
            else if (body.StmtType == Stmt.NodeType.If)
            {
                lastIf = (StmtIf)body;
                preIf  = Enumerable.Empty <Stmt>();
            }
            if (lastIf != null)
            {
                Stmt   afterLoop = null;
                StmtIf newIf     = null;
                // See if final 'if' condition is same as the 'do' condition.
                // TODO: This may lead to a non-terminating situation...
                if (lastIf.Condition.DoesEqual(s.While))
                {
                    afterLoop = lastIf.Else;
                    newIf     = new StmtIf(s.Ctx, lastIf.Condition, lastIf.Then, null);
                }
                else if (lastIf.Condition.DoesEqualNot(s.While))
                {
                    afterLoop = lastIf.Then;
                    newIf     = new StmtIf(s.Ctx, lastIf.Condition, null, lastIf.Else);
                }
                if (afterLoop != null)
                {
                    var loopBody = new StmtBlock(s.Ctx, preIf.Concat(newIf));
                    var loop     = new StmtDoLoop(s.Ctx, loopBody, s.While);
                    var ret      = new StmtBlock(s.Ctx, loop, afterLoop);
                    return(ret);
                }
            }
            if (body != s.Body)
            {
                return(new StmtDoLoop(s.Ctx, body, s.While));
            }
            else
            {
                return(s);
            }
        }
Пример #2
0
 protected override ICode VisitDoLoop(StmtDoLoop s)
 {
     this.NewLine();
     this.js.Append("do {");
     this.indent++;
     this.Visit(s.Body);
     this.indent--;
     this.NewLine();
     this.js.Append("} while (");
     this.Visit(s.While);
     this.js.Append(");");
     return(s);
 }
Пример #3
0
        protected virtual ICode VisitDoLoop(StmtDoLoop s)
        {
            this.ThrowOnNoOverride();
            var body   = this.Visit(s.Body);
            var @while = this.Visit(s.While);

            if (body != s.Body || @while != s.While)
            {
                return(new StmtDoLoop(s.Ctx, (Stmt)body, (Expr)@while));
            }
            else
            {
                return(s);
            }
        }
Пример #4
0
        protected override ICode VisitDoLoop(StmtDoLoop s)
        {
            var ctx    = s.Ctx;
            var body   = (Stmt)this.Visit(s.Body);
            var @while = (Expr)this.Visit(s.While); // This order matters - body must be visited before while

            GetVarsVisitor.GetAll(@while);
            this.AddKnownTrue(ctx.ExprGen.Not(@while));
            if (body != s.Body || @while != s.While)
            {
                return(new StmtDoLoop(ctx, body, @while));
            }
            else
            {
                return(s);
            }
        }
Пример #5
0
        protected override ICode VisitDoLoop(StmtDoLoop s)
        {
            var ctx    = s.Ctx;
            var body   = (Stmt)this.Visit(s.Body);
            var @while = (Expr)this.Visit(s.While);

            var conditionVars = VisitorFindVars.V(@while);
            var needAssigning = conditionVars.Except(this.stack.SelectMany(x => x), (IEqualityComparer <ExprVar>) this.phiComparer).ToArray();

            if (needAssigning.Any())
            {
                var replacements = needAssigning.Select(x => {
                    var newExpr = ctx.Local(x.Type);
                    var phi     = new ExprVarPhi(ctx)
                    {
                        Exprs = new[] { x, newExpr }
                    };
                    return(new { orgExpr = x, newExpr, phi });
                }).ToArray();
                foreach (var replace in replacements)
                {
                    this.stack.Peek().Add(replace.newExpr);
                    this.stack.Peek().Add(replace.phi);
                    @while = (Expr)VisitorReplace.V(@while, replace.orgExpr, replace.phi);
                }
                var assignmentStmts = replacements
                                      .Select(x => new StmtAssignment(ctx, x.newExpr, new ExprDefaultValue(ctx, x.newExpr.Type)))
                                      .ToArray();
                body = new StmtBlock(ctx, assignmentStmts.Concat(body));
            }

            if (body != s.Body || @while != s.While)
            {
                return(new StmtDoLoop(ctx, body, @while));
            }
            else
            {
                return(s);
            }
        }
        protected override ICode VisitDoLoop(StmtDoLoop s)
        {
            var body = (Stmt)this.Visit(s.Body);

            if (body == null)
            {
                // Loop has no body
                return(null);
            }
            if (s.While.IsLiteralBoolean(false))
            {
                // Will never loop
                return(body);
            }
            if (body != s.Body)
            {
                return(new StmtDoLoop(s.Ctx, body, s.While));
            }
            else
            {
                return(s);
            }
        }
 protected override ICode VisitDoLoop(StmtDoLoop s)
 {
     return(this.Isolate(() => base.VisitDoLoop(s)));
 }
Пример #8
0
        protected override ICode VisitContinuation(StmtContinuation s)
        {
            // TODO: Why is this de-recursing blocks in continuations? Why doesn't it just derecurse itself (if possible)???
            if (s.To.StmtType != Stmt.NodeType.Block)
            {
                return(base.VisitContinuation(s));
            }
            if (!this.seen.Add(s.To))
            {
                return(base.VisitContinuation(s));
            }
            var block = (StmtBlock)s.To;

            foreach (var stmt in block.Statements)
            {
                if (stmt.StmtType == Stmt.NodeType.Continuation)
                {
                    // Continuation not inside 'if'
                    var sCont = (StmtContinuation)stmt;
                    if (sCont.To == block)
                    {
                        // Recursive, so derecurse with no condition on loop
                        var body        = new StmtBlock(s.Ctx, block.Statements.TakeWhile(x => x != stmt).ToArray());
                        var replaceWith = new StmtDoLoop(s.Ctx, body, new ExprLiteral(s.Ctx, true, s.Ctx.Boolean));
                        this.replaces.Add(s.To, replaceWith);
                        return(base.VisitContinuation(s));
                    }
                }
                if (stmt.StmtType == Stmt.NodeType.If)
                {
                    // Continuation only statement within 'if' with only a 'then' clause
                    var sIf = (StmtIf)stmt;
                    if (sIf.Else == null && sIf.Then.StmtType == Stmt.NodeType.Continuation)
                    {
                        var sThen = (StmtContinuation)sIf.Then;
                        if (sThen.To == block)
                        {
                            // Recursive, so derecurse
                            var condition = sIf.Condition;
                            var bodyStmts = block.Statements.TakeWhile(x => x != stmt).ToArray();
                            var bodyLast  = bodyStmts.LastOrDefault();
                            var body      = new StmtBlock(s.Ctx, bodyStmts);
                            var loop      = new StmtDoLoop(s.Ctx, body, condition);
                            var afterLoop = block.Statements.SkipWhile(x => x != stmt).Skip(1).ToArray();
                            if (VisitorFindContinuations.Get(new StmtBlock(s.Ctx, afterLoop)).Any(x => x.To == block))
                            {
                                // Cannot de-recurse yet, must wait for continuations to be merged
                                return(base.VisitContinuation(s));
                            }
                            Stmt replaceWith;
                            if (afterLoop.Any())
                            {
                                var loopAndAfter = new[] { loop }.Concat(afterLoop).ToArray();
                                replaceWith = new StmtBlock(s.Ctx, loopAndAfter);
                            }
                            else
                            {
                                replaceWith = loop;
                            }
                            this.replaces.Add(s.To, replaceWith);
                            return(base.VisitContinuation(s));
                        }
                    }
                }
                if (VisitorFindContinuations.Any(stmt))
                {
                    // Another continuation present, cannot derecurse
                    break;
                }
            }
            return(base.VisitContinuation(s));
        }