public dynamic Visit(TernaryExpr expr) { var node = Visit((ExpressionBase)expr); node.Text = "Ternary"; return(node); }
public dynamic Visit(TernaryExpr expr) { var cond = _codeGen.Local(Visit((dynamic)expr.First)) as Operand; var first = _codeGen.Local(Visit((dynamic)expr.Second)) as Operand; var second = _codeGen.Local(Visit((dynamic)expr.Third)) as Operand; return(cond.Conditional(first, second)); }
public dynamic Visit(TernaryExpr expr) { Visit((ExpressionBase)expr); if (OptimizeMode.ExpressionSimplify) { var left = expr.First as LiteralExpr; if (left != null) { return(left.Value ? expr.Second : expr.Third); } } return(expr); }
public dynamic Visit(TernaryExpr expr) { if (expr.FirstType != SymbolType.Bool) { throw new ParseException("Тип условия должен быть bool", expr.Node); } if (expr.Third == null) { return(expr.SecondType); } if (expr.SecondType != expr.Third.GetExprType()) { throw new ParseException("Типы левой и правой части должны быть одинаковы", expr.Node); } return(expr.SecondType); }
/// <summary> /// Rule: Expr -> OrExpr (QUESTION Expr COLON Expr )? ; /// </summary> protected override object EvalExpr(ParseTree tree, params object[] paramlist) { if (GetNode(TokenType.QUESTION) == null) { return((ExpressionBase)GetNode(TokenType.OrExpr).Eval(tree)); } var ternaryExpr = new TernaryExpr { First = (ExpressionBase)GetNode(TokenType.OrExpr).Eval(tree), Second = (ExpressionBase)nodes.OfTokenType(TokenType.Expr).First().Eval(tree), Third = (ExpressionBase)nodes.OfTokenType(TokenType.Expr).Last().Eval(tree), Node = this }; return(ternaryExpr); }
private static bool ShallowEq(TernaryExpr expr1, TernaryExpr expr2) { return(expr1.Op == expr2.Op); }
public dynamic Visit(TernaryExpr expr) { Visit((ExpressionBase)expr); return(null); }
public virtual void Visit(TernaryExpr ternaryExpression) { VisitNullableExpression(ternaryExpression.E0); VisitNullableExpression(ternaryExpression.E1); VisitNullableExpression(ternaryExpression.E2); }
void RelationalExpression(out Expression e, bool allowSemi, bool allowLambda) { Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken x, firstOpTok = null; Expression e0, e1, acc = null; BinaryExpr.Opcode op; List<Expression> chain = null; List<BinaryExpr.Opcode> ops = null; List<Expression/*?*/> prefixLimits = null; Expression k; int kind = 0; // 0 ("uncommitted") indicates chain of ==, possibly with one != // 1 ("ascending") indicates chain of ==, <, <=, possibly with one != // 2 ("descending") indicates chain of ==, >, >=, possibly with one != // 3 ("illegal") indicates illegal chain // 4 ("disjoint") indicates chain of disjoint set operators bool hasSeenNeq = false; Term(out e0, allowSemi, allowLambda); e = e0; if (IsRelOp()) { RelOp(out x, out op, out k); firstOpTok = x; Term(out e1, allowSemi, allowLambda); if (k == null) { e = new BinaryExpr(x, op, e0, e1); if (op == BinaryExpr.Opcode.Disjoint) acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, e0, e1); // accumulate first two operands. } else { Contract.Assert(op == BinaryExpr.Opcode.Eq || op == BinaryExpr.Opcode.Neq); e = new TernaryExpr(x, op == BinaryExpr.Opcode.Eq ? TernaryExpr.Opcode.PrefixEqOp : TernaryExpr.Opcode.PrefixNeqOp, k, e0, e1); } while (IsRelOp()) { if (chain == null) { chain = new List<Expression>(); ops = new List<BinaryExpr.Opcode>(); prefixLimits = new List<Expression>(); chain.Add(e0); ops.Add(op); prefixLimits.Add(k); chain.Add(e1); switch (op) { case BinaryExpr.Opcode.Eq: kind = 0; break; case BinaryExpr.Opcode.Neq: kind = 0; hasSeenNeq = true; break; case BinaryExpr.Opcode.Lt: case BinaryExpr.Opcode.Le: kind = 1; break; case BinaryExpr.Opcode.Gt: case BinaryExpr.Opcode.Ge: kind = 2; break; case BinaryExpr.Opcode.Disjoint: kind = 4; break; default: kind = 3; break; } } e0 = e1; RelOp(out x, out op, out k); switch (op) { case BinaryExpr.Opcode.Eq: if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "chaining not allowed from the previous operator"); } break; case BinaryExpr.Opcode.Neq: if (hasSeenNeq) { SemErr(x, "a chain cannot have more than one != operator"); } if (kind != 0 && kind != 1 && kind != 2) { SemErr(x, "this operator cannot continue this chain"); } hasSeenNeq = true; break; case BinaryExpr.Opcode.Lt: case BinaryExpr.Opcode.Le: if (kind == 0) { kind = 1; } else if (kind != 1) { SemErr(x, "this operator chain cannot continue with an ascending operator"); } break; case BinaryExpr.Opcode.Gt: case BinaryExpr.Opcode.Ge: if (kind == 0) { kind = 2; } else if (kind != 2) { SemErr(x, "this operator chain cannot continue with a descending operator"); } break; case BinaryExpr.Opcode.Disjoint: if (kind != 4) { SemErr(x, "can only chain disjoint (!!) with itself."); kind = 3; } break; default: SemErr(x, "this operator cannot be part of a chain"); kind = 3; break; } Term(out e1, allowSemi, allowLambda); ops.Add(op); prefixLimits.Add(k); chain.Add(e1); if (k != null) { Contract.Assert(op == BinaryExpr.Opcode.Eq || op == BinaryExpr.Opcode.Neq); e = new TernaryExpr(x, op == BinaryExpr.Opcode.Eq ? TernaryExpr.Opcode.PrefixEqOp : TernaryExpr.Opcode.PrefixNeqOp, k, e0, e1); } else if (op == BinaryExpr.Opcode.Disjoint && acc != null) { // the second conjunct always holds for legal programs e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, acc, e1)); acc = new BinaryExpr(x, BinaryExpr.Opcode.Add, acc, e1); //e0 has already been added. } else { e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, e0, e1)); } } } if (chain != null) { e = new ChainingExpression(firstOpTok, chain, ops, prefixLimits, e); } }
public override Expression CloneExpr(Expression expr) { if (expr is ConcreteSyntaxExpression) { var e = (ConcreteSyntaxExpression)expr; // Note, the CoLemmaPostconditionSubstituter is an unusual cloner in that it operates on // resolved expressions. Hence, we bypass the syntactic parts here. return CloneExpr(e.Resolved); } else if (expr is FunctionCallExpr) { var e = (FunctionCallExpr)expr; if (friendlyCalls.Contains(e)) { return CloneCallAndAddK(e); } } else if (expr is BinaryExpr && isCoContext) { var e = (BinaryExpr)expr; if ((e.ResolvedOp == BinaryExpr.ResolvedOpcode.EqCommon || e.ResolvedOp == BinaryExpr.ResolvedOpcode.NeqCommon) && friendlyCalls.Contains(e)) { var op = e.ResolvedOp == BinaryExpr.ResolvedOpcode.EqCommon ? TernaryExpr.Opcode.PrefixEqOp : TernaryExpr.Opcode.PrefixNeqOp; var A = CloneExpr(e.E0); var B = CloneExpr(e.E1); var teq = new TernaryExpr(Tok(e.tok), op, k, A, B); var opString = op == TernaryExpr.Opcode.PrefixEqOp ? "==" : "!="; reporter.Info(MessageSource.Cloner, e.tok, opString + suffix); return teq; } } return base.CloneExpr(expr); }
protected abstract object MatchTernaryExpr(TernaryExpr ternaryExpr);
public virtual void Visit(TernaryExpr expr) { }