Пример #1
0
        public static Stmt Floor(Ctx ctx)
        {
            var arg = ctx.MethodParameter(0);
            var e   = new ExprTernary(ctx,
                                      new ExprJsResolvedMethod(ctx, ctx.Boolean, null, "Number.isFinite", arg),
                                      new ExprJsResolvedMethod(ctx, ctx.Double, null, "Math.floor", arg),
                                      arg);

            return(new StmtReturn(ctx, e));
        }
Пример #2
0
 protected override ICode VisitTernary(ExprTernary e)
 {
     this.js.Append("(");
     this.Visit(e.Condition);
     this.js.Append(" ? ");
     this.Visit(e.IfTrue);
     this.js.Append(" : ");
     this.Visit(e.IfFalse);
     this.js.Append(")");
     return(e);
 }
Пример #3
0
        protected virtual ICode VisitTernary(ExprTernary e)
        {
            this.ThrowOnNoOverride();
            var condition = (Expr)this.Visit(e.Condition);
            var ifTrue    = (Expr)this.Visit(e.IfTrue);
            var ifFalse   = (Expr)this.Visit(e.IfFalse);

            if (condition != e.Condition || ifTrue != e.IfTrue || ifFalse != e.IfFalse)
            {
                return(new ExprTernary(e.Ctx, condition, ifTrue, ifFalse));
            }
            else
            {
                return(e);
            }
        }
        protected override ICode VisitTernary(ExprTernary e)
        {
            var condition = (Expr)this.Visit(e.Condition);
            var ifTrue    = (Expr)this.Visit(e.IfTrue);
            var ifFalse   = (Expr)this.Visit(e.IfFalse);

            if (condition.IsLiteralBoolean(true))
            {
                return(ifTrue);
            }
            if (condition.IsLiteralBoolean(false))
            {
                return(ifFalse);
            }

            if (e.Type.IsBoolean())
            {
                if (ifTrue.IsLiteralBoolean(true))
                {
                    return(e.Ctx.ExprGen.Or(condition, ifFalse));
                }
                if (ifTrue.IsLiteralBoolean(false))
                {
                    return(e.Ctx.ExprGen.And(e.Ctx.ExprGen.NotAutoSimplify(condition), ifFalse));
                }
            }

            if (condition.ExprType == Expr.NodeType.Unary)
            {
                var cUn = (ExprUnary)condition;
                if (cUn.Op == UnaryOp.Not)
                {
                    // Remove 'not' from condition and swap ifTrue and ifFalse,
                    return(new ExprTernary(e.Ctx, cUn.Expr, ifFalse, ifTrue));
                }
            }

            if (condition != e.Condition || ifTrue != e.IfTrue || ifFalse != e.IfFalse)
            {
                return(new ExprTernary(e.Ctx, condition, ifTrue, ifFalse));
            }
            else
            {
                return(e);
            }
        }
        protected override ICode VisitIf(StmtIf s)
        {
            var then  = (Stmt)this.Visit(s.Then);
            var @else = (Stmt)this.Visit(s.Else);

            if (then == null && @else == null)
            {
                return(null);
            }
            // Remove 'if' if condition is just true or false
            if (s.Condition.ExprType == Expr.NodeType.Literal)
            {
                if (s.Condition.IsLiteralBoolean(true))
                {
                    return(then);
                }
                if (s.Condition.IsLiteralBoolean(false))
                {
                    return(@else);
                }
            }
            // If 'then' and 'else' are identical, then remove 'if'
            if (then.DoesEqual(@else))
            {
                return(then);
            }
            // If 'if' only has an 'else' case, not a 'then' case, then swap
            if (then == null)
            {
                return(new StmtIf(s.Ctx, s.Ctx.ExprGen.NotAutoSimplify(s.Condition), @else, null));
            }
            // If both 'if' parts only contain an assignment to the same (with phi clustering) target, then turn into ternary assignment
            if (then != null && @else != null && then.StmtType == Stmt.NodeType.Assignment && @else.StmtType == Stmt.NodeType.Assignment)
            {
                var thenAssign = (StmtAssignment)then;
                var elseAssign = (StmtAssignment)@else;
                if (this.AreClustered(thenAssign.Target, elseAssign.Target))
                {
                    this.replaceVars.Add(Tuple.Create(elseAssign.Target, thenAssign.Target));
                    var ternary = new ExprTernary(s.Ctx, s.Condition, thenAssign.Expr, elseAssign.Expr);
                    return(new StmtAssignment(s.Ctx, thenAssign.Target, ternary));
                }
            }
            // If 'if' contains only 'if' then combine condition with 'and'
            if (@else == null && then.StmtType == Stmt.NodeType.If)
            {
                var thenIf = (StmtIf)then;
                if (thenIf.Else == null)
                {
                    return(new StmtIf(s.Ctx, s.Ctx.ExprGen.And(s.Condition, thenIf.Condition), thenIf.Then, null));
                }
            }
            if (then != s.Then || @else != s.Else)
            {
                return(new StmtIf(s.Ctx, s.Condition, then, @else));
            }
            else
            {
                return(s);
            }
        }