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; } }
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; }
public static Stmt Ceiling(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.ceil", arg), arg); return new StmtReturn(ctx, e); }