public override void Visit(ConditionalNode node) { Contracts.AssertValue(node); if (TryShowValue(node)) { return; } Precedence prec0 = GetPrec(node.Cond); Precedence prec1 = GetPrec(node.Left); Precedence prec2 = GetPrec(node.Right); bool parens0 = NeedParensLeft(prec0, Precedence.Conditional); if (parens0) { _wrt.Write('('); } node.Cond.Accept(this); if (parens0) { _wrt.Write(')'); } _wrt.Write(" ? "); node.Left.Accept(this); _wrt.Write(" : "); node.Right.Accept(this); ShowType(node); }
// Parses the next (maximal) expression with precedence >= precMin. private ExprNode ParseExpr(Precedence precMin) { // ParseOperand may accept PrefixUnary and higher, so ParseExpr should never be called // with precMin > Precedence.PrefixUnary - it will not correctly handle those cases. Contracts.Assert(Precedence.None <= precMin); Contracts.Assert(precMin <= Precedence.PrefixUnary); // Get the left operand. ExprNode node = ParsePrimary(); // Process operators and right operands as long as the precedence bound is satisfied. for (; ;) { Contracts.AssertValue(node); switch (TidCur) { case TokKind.Car: Contracts.Assert(precMin <= Precedence.Power); // Note that the right operand can include unary operators. node = new BinaryOpNode(TokMove(), BinaryOp.Power, node, ParseExpr(Precedence.PrefixUnary)); break; case TokKind.Mul: if (precMin > Precedence.Mul) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.Mul, node, ParseExpr(Precedence.Mul + 1)); break; case TokKind.Div: if (precMin > Precedence.Mul) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.Div, node, ParseExpr(Precedence.Mul + 1)); break; case TokKind.Per: if (precMin > Precedence.Mul) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.Mod, node, ParseExpr(Precedence.Mul + 1)); break; case TokKind.Sub: if (precMin > Precedence.Add) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.Sub, node, ParseExpr(Precedence.Add + 1)); break; case TokKind.Add: if (precMin > Precedence.Add) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.Add, node, ParseExpr(Precedence.Add + 1)); break; case TokKind.AmpAmp: case TokKind.And: if (precMin > Precedence.And) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.And, node, ParseExpr(Precedence.And + 1)); break; case TokKind.BarBar: case TokKind.Or: if (precMin > Precedence.Or) { return(node); } node = new BinaryOpNode(TokMove(), BinaryOp.Or, node, ParseExpr(Precedence.Or + 1)); break; case TokKind.QueQue: if (precMin > Precedence.Coalesce) { return(node); } // Note that the associativity is different than other binary operators (right instead of left), // so the recursive call accepts Precedence.Coal. node = new BinaryOpNode(TokMove(), BinaryOp.Coalesce, node, ParseExpr(Precedence.Coalesce)); break; case TokKind.Que: if (precMin > Precedence.Conditional) { return(node); } node = new ConditionalNode(TokMove(), node, ParseExpr(), TokEat(TokKind.Colon), ParseExpr()); break; // Comparison operators // expr = ... = expr // expr <> ... <> expr case TokKind.Equ: case TokKind.EquEqu: if (precMin > Precedence.Compare) { return(node); } node = ParseCompareExpr(node, CompareOp.Equal, TokKind.Equ, TokKind.EquEqu); break; case TokKind.LssGrt: case TokKind.BngEqu: if (precMin > Precedence.Compare) { return(node); } node = ParseCompareExpr(node, CompareOp.NotEqual, TokKind.LssGrt, TokKind.BngEqu); break; // expr < expr // expr <= expr case TokKind.Lss: case TokKind.LssEqu: if (precMin > Precedence.Compare) { return(node); } node = ParseCompareExpr(node, CompareOp.IncrChain, TokKind.LssEqu, TokKind.Lss); break; // expr > expr // expr >= expr case TokKind.Grt: case TokKind.GrtEqu: if (precMin > Precedence.Compare) { return(node); } node = ParseCompareExpr(node, CompareOp.DecrChain, TokKind.GrtEqu, TokKind.Grt); break; case TokKind.True: case TokKind.False: case TokKind.IntLit: case TokKind.FltLit: case TokKind.DblLit: case TokKind.CharLit: case TokKind.StrLit: PostError(TokCur, "Operator expected"); node = new BinaryOpNode(TokCur, BinaryOp.Error, node, ParseExpr(Precedence.Error)); break; default: return(node); } } }
public override void PostVisit(ConditionalNode node) { Contracts.Assert(false); }
public override bool PreVisit(ConditionalNode node) { Visit(node); return(false); }
public abstract void Visit(ConditionalNode node);
public virtual bool PreVisit(ConditionalNode node) { return(true); }