/// <summary> /// Produces a choice pattern for <c>expr1 op expr2</c> or <c>expr2 op expr1</c>. /// </summary> public static Expression CommutativeOperator(Expression expr1, BinaryOperatorType op, Expression expr2) { return new Choice { new BinaryOperatorExpression(expr1, op, expr2), new BinaryOperatorExpression(expr2.Clone(), op, expr1.Clone()) }; }
public BinaryExpression(LexicalInfo lexicalInfoProvider, BinaryOperatorType operator_, Expression left, Expression right) : base(lexicalInfoProvider) { this.Operator = operator_; this.Left = left; this.Right = right; }
void VBNetTestBinaryOperatorExpressionTest(string program, BinaryOperatorType op) { BinaryOperatorExpression boe = ParseUtil.ParseExpression<BinaryOperatorExpression>(program); Assert.AreEqual(op, boe.Op); Assert.IsTrue(boe.Left is SimpleNameExpression); Assert.IsTrue(boe.Right is SimpleNameExpression); }
/// <summary> /// Get negation of the condition operator /// </summary> /// <returns> /// negation of the specified condition operator, or BinaryOperatorType.Any if it's not a condition operator /// </returns> public static BinaryOperatorType NegateConditionOperator(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.ConditionalOr: return BinaryOperatorType.ConditionalAnd; case BinaryOperatorType.ConditionalAnd: return BinaryOperatorType.ConditionalOr; } return BinaryOperatorType.Any; }
public BinaryOperatorResolveResult(IType resultType, ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs) : base(resultType) { if (lhs == null) throw new ArgumentNullException("lhs"); if (rhs == null) throw new ArgumentNullException("rhs"); this.Left = lhs; this.Operator = op; this.Right = rhs; }
public static BinaryOperatorNode Create(BinaryOperatorType type, SubExpressionNode left, SubExpressionNode right, Token token, int tokenIndex) { switch (type) { case BinaryOperatorType.Ampersand: return new AmpersandBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.AmpersandEqual: return new AmpersandEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.Caret: return new CaretBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.CaretEqual: return new CaretEqualBinaryOperaratorNode(left, right, token, tokenIndex); case BinaryOperatorType.Divide: return new DivideBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.DivideEqual: return new DivideEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.Minus: return new MinusBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.MinusEqual: return new MinusEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.Mod: return new ModBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.ModEqual: return new ModEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.Pipe: return new PipeBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.PipeEqual: return new PipeEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.Plus: return new PlusBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.PlusEqual: return new PlusEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.ShiftLeft: return new ShiftLeftBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.ShiftLeftEqual: return new ShiftLeftEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.ShiftRight: return new ShiftRightBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.ShiftRightEqual: return new ShiftRightEqualBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.Star: return new StarBinaryOperatorNode(left, right, token, tokenIndex); case BinaryOperatorType.StarEqual: return new StarEqualBinaryOperatorNode(left, right, token, tokenIndex); default: throw new InternalCompilerException("Unknown BinaryOperatorType."); } }
/// <summary> /// Get negation of the specified relational operator /// </summary> /// <returns> /// negation of the specified relational operator, or BinaryOperatorType.Any if it's not a relational operator /// </returns> public static BinaryOperatorType NegateRelationalOperator (BinaryOperatorType op) { switch (op) { case BinaryOperatorType.GreaterThan: return BinaryOperatorType.LessThanOrEqual; case BinaryOperatorType.GreaterThanOrEqual: return BinaryOperatorType.LessThan; case BinaryOperatorType.Equality: return BinaryOperatorType.InEquality; case BinaryOperatorType.InEquality: return BinaryOperatorType.Equality; case BinaryOperatorType.LessThan: return BinaryOperatorType.GreaterThanOrEqual; case BinaryOperatorType.LessThanOrEqual: return BinaryOperatorType.GreaterThan; } return BinaryOperatorType.Any; }
private static string Process(BinaryOperatorType binaryOperatorType) { switch (binaryOperatorType) { case BinaryOperatorType.Equal: return " = "; case BinaryOperatorType.NotEqual: return " != "; case BinaryOperatorType.Greater: return " > "; case BinaryOperatorType.GreaterOrEqual: return " >= "; case BinaryOperatorType.Less: return " < "; case BinaryOperatorType.LessOrEqual: return " <= "; case BinaryOperatorType.Like: return " LIKE "; case BinaryOperatorType.Minus: return " - "; case BinaryOperatorType.Plus: return " + "; case BinaryOperatorType.Multiply: return " * "; case BinaryOperatorType.Divide: return " / "; default: throw new NotSupportedException("Не поддерживаем BinaryOperatorType отличный от 'Equal', 'NotEqual', 'Greater', 'GreaterOrEqual', 'Less', 'LessOrEqual', 'Like', 'Minus', 'Plus', 'Multiply', 'Divide'. Переданное значение BinaryOperatorType: '{0}'".FillWith(binaryOperatorType)); } }
void SameOperatorPrecedenceTest(string firstOperator, BinaryOperatorType firstOperatorType, string secondOperator, BinaryOperatorType secondOperatorType, bool vb) { string program = "a " + secondOperator + " b " + firstOperator + " c"; BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program); Assert.AreEqual(firstOperatorType, boe.Operator); Assert.IsTrue(boe.Right is IdentifierExpression); boe = (BinaryOperatorExpression)boe.Left; Assert.AreEqual(secondOperatorType, boe.Operator); Assert.IsTrue(boe.Left is IdentifierExpression); Assert.IsTrue(boe.Right is IdentifierExpression); program = "a " + firstOperator + " b " + secondOperator + " c"; boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program); Assert.AreEqual(secondOperatorType, boe.Operator); Assert.IsTrue(boe.Right is IdentifierExpression); boe = (BinaryOperatorExpression)boe.Left; Assert.AreEqual(firstOperatorType, boe.Operator); Assert.IsTrue(boe.Left is IdentifierExpression); Assert.IsTrue(boe.Right is IdentifierExpression); }
public BinaryOperator(IElementCreationContext context, BinaryOperatorType defaultOperatorType) : base(context, context.Owner.GetFloatType()) { var services = new [] { new BinaryOperatorService(BinaryOperatorType.Addition, "+", (a, b) => a + b), new BinaryOperatorService(BinaryOperatorType.Subtraction, "-", (a, b) => a - b), new BinaryOperatorService(BinaryOperatorType.Multiplication, "*", (a, b) => a * b), new BinaryOperatorService(BinaryOperatorType.Division, "/", (a, b) => a / b), new BinaryOperatorService(BinaryOperatorType.ShiftLeft, "<<", (a, b) => a << b), new BinaryOperatorService(BinaryOperatorType.ShiftRight, ">>", (a, b) => a >> b), new BinaryOperatorService(BinaryOperatorType.BitwiseAnd, "&", (a , b) => a & b), new BinaryOperatorService(BinaryOperatorType.BitwiseOr, "|", (a , b) => a | b), new BinaryOperatorService(BinaryOperatorType.Modulus, "%", (a , b) => a % b), }; foreach (var service in services) { AddAction(new ElementAction(service.Text, () => OperatorType = service.Type)); } _services = services.ToDictionary(s => s.Type, s => s); ParameterA = context.Owner.CreateParameter("a", context.Owner.GetFloatType()); ParameterB = context.Owner.CreateParameter("b", context.Owner.GetFloatType()); Parameters.Add(ParameterA); Parameters.Add(ParameterB); Service = _services[BinaryOperatorType.Addition]; OperatorType = defaultOperatorType; if (!string.IsNullOrWhiteSpace(context.Data)) { var data = JsonConvert.DeserializeObject<BinaryOperatorData>(context.Data); OperatorType = data.OperatorType; } }
void OperatorPrecedenceTest(string strongOperator, BinaryOperatorType strongOperatorType, string weakOperator, BinaryOperatorType weakOperatorType, bool vb) { string program = "a " + weakOperator + " b " + strongOperator + " c"; BinaryOperatorExpression boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program); Assert.AreEqual(weakOperatorType, boe.Operator); Assert.IsTrue(boe.Left is IdentifierExpression); boe = (BinaryOperatorExpression)boe.Right; Assert.AreEqual(strongOperatorType, boe.Operator); Assert.IsTrue(boe.Left is IdentifierExpression); Assert.IsTrue(boe.Right is IdentifierExpression); program = "a " + strongOperator + " b " + weakOperator + " c"; boe = ParseUtilCSharp.ParseExpression<BinaryOperatorExpression>(program); Assert.AreEqual(weakOperatorType, boe.Operator); Assert.IsTrue(boe.Right is IdentifierExpression); boe = (BinaryOperatorExpression)boe.Left; Assert.AreEqual(strongOperatorType, boe.Operator); Assert.IsTrue(boe.Left is IdentifierExpression); Assert.IsTrue(boe.Right is IdentifierExpression); }
public static string GetBinaryOperatorMethodName(BinaryOperatorType operatorType) { switch (operatorType) { case BinaryOperatorType.Any: return(null); case BinaryOperatorType.BitwiseAnd: return("op_BitwiseAnd"); case BinaryOperatorType.BitwiseOr: return("op_BitwiseOr"); case BinaryOperatorType.ConditionalAnd: return("op_LogicalAnd"); case BinaryOperatorType.ConditionalOr: return("op_LogicalOr"); case BinaryOperatorType.ExclusiveOr: return("op_ExclusiveOr"); case BinaryOperatorType.GreaterThan: return("op_GreaterThan"); case BinaryOperatorType.GreaterThanOrEqual: return("op_GreaterThanOrEqual"); case BinaryOperatorType.Equality: return("op_Equality"); case BinaryOperatorType.InEquality: return("op_Inequality"); case BinaryOperatorType.LessThan: return("op_LessThan"); case BinaryOperatorType.LessThanOrEqual: return("op_LessThanOrEqual"); case BinaryOperatorType.Add: return("op_Addition"); case BinaryOperatorType.Subtract: return("op_Subtraction"); case BinaryOperatorType.Multiply: return("op_Multiply"); case BinaryOperatorType.Divide: return("op_Division"); case BinaryOperatorType.Modulus: return("op_Modulus"); case BinaryOperatorType.ShiftLeft: return("LeftShift"); case BinaryOperatorType.ShiftRight: return("RightShift"); case BinaryOperatorType.NullCoalescing: return(null); default: throw new ArgumentOutOfRangeException("operatorType", operatorType, null); } }
public BinaryOperatorExpression(Expression left, BinaryOperatorType type, Expression right) { AddChild(left, LeftExpressionRole); AddChild(right, RightExpressionRole); Operator = type; }
public BinaryOperatorExpression(Expression left, BinaryOperatorType op, Expression right) { this.Left = left; this.Operator = op; this.Right = right; }
static LiteralExpression GetFoldedIntegerLiteral(BinaryOperatorType @operator, ulong lhs, ulong rhs) { ulong result; switch (@operator) { //arithmetic case BinaryOperatorType.Addition: result = lhs + rhs; break; case BinaryOperatorType.Subtraction: result = lhs - rhs; break; case BinaryOperatorType.Multiply: result = lhs * rhs; break; case BinaryOperatorType.Division: result = lhs / rhs; break; case BinaryOperatorType.Modulus: result = lhs % rhs; break; case BinaryOperatorType.Exponentiation: result = (ulong)Math.Pow(lhs, rhs); break; //bitwise case BinaryOperatorType.BitwiseOr: result = lhs | rhs; break; case BinaryOperatorType.BitwiseAnd: result = lhs & rhs; break; case BinaryOperatorType.ExclusiveOr: result = lhs ^ rhs; break; case BinaryOperatorType.ShiftLeft: result = lhs << (int)rhs; break; case BinaryOperatorType.ShiftRight: result = lhs >> (int)rhs; break; //comparison case BinaryOperatorType.LessThan: return(new BoolLiteralExpression(lhs < rhs)); case BinaryOperatorType.LessThanOrEqual: return(new BoolLiteralExpression(lhs <= rhs)); case BinaryOperatorType.GreaterThan: return(new BoolLiteralExpression(lhs > rhs)); case BinaryOperatorType.GreaterThanOrEqual: return(new BoolLiteralExpression(lhs >= rhs)); case BinaryOperatorType.Equality: return(new BoolLiteralExpression(lhs == rhs)); case BinaryOperatorType.Inequality: return(new BoolLiteralExpression(lhs != rhs)); default: return(null); //not supported } return(new IntegerLiteralExpression((long)result)); }
ResolveResult BinaryOperatorResolveResult(IType resultType, ResolveResult lhs, BinaryOperatorType op, ResolveResult rhs) { return new OperatorResolveResult(resultType, BinaryOperatorExpression.GetLinqNodeType(op, this.CheckForOverflow), lhs, rhs); }
BinaryOperatorType GetRelatedBinaryOperatorForInPlaceOperator(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.InPlaceAddition: return BinaryOperatorType.Addition; case BinaryOperatorType.InPlaceSubtraction: return BinaryOperatorType.Subtraction; case BinaryOperatorType.InPlaceMultiply: return BinaryOperatorType.Multiply; case BinaryOperatorType.InPlaceDivision: return BinaryOperatorType.Division; case BinaryOperatorType.InPlaceModulus: return BinaryOperatorType.Modulus; case BinaryOperatorType.InPlaceBitwiseAnd: return BinaryOperatorType.BitwiseAnd; case BinaryOperatorType.InPlaceBitwiseOr: return BinaryOperatorType.BitwiseOr; case BinaryOperatorType.InPlaceExclusiveOr: return BinaryOperatorType.ExclusiveOr; case BinaryOperatorType.InPlaceShiftLeft: return BinaryOperatorType.ShiftLeft; case BinaryOperatorType.InPlaceShiftRight: return BinaryOperatorType.ShiftRight; } throw new ArgumentException("op"); }
public CriteriaOperatorPropertyValueFetcher Register(BinaryOperatorType operatorType, Func <ConstantValue, object> calculationFunction) { CalculationFunctionsRepository[operatorType] = calculationFunction; return(this); }
/// <summary> /// Optimize the <c>for item in range()</c> construct /// </summary> /// <param name="node">the for statement to check</param> private void CheckForItemInRangeLoop(ForStatement node) { MethodInvocationExpression mi = node.Iterator as MethodInvocationExpression; if (null == mi) { return; } if (!IsRangeInvocation(mi)) { return; } DeclarationCollection declarations = node.Declarations; if (declarations.Count != 1) { return; } ExpressionCollection args = mi.Arguments; Block body = new Block(node.LexicalInfo); Expression min; Expression max; Expression step; IntegerLiteralExpression mini; IntegerLiteralExpression maxi; IntegerLiteralExpression stepi; if (args.Count == 1) { mini = CodeBuilder.CreateIntegerLiteral(0); min = mini; max = args[0]; maxi = max as IntegerLiteralExpression; stepi = CodeBuilder.CreateIntegerLiteral(1); step = stepi; } else if (args.Count == 2) { min = args[0]; mini = min as IntegerLiteralExpression; max = args[1]; maxi = max as IntegerLiteralExpression; stepi = CodeBuilder.CreateIntegerLiteral(1); step = stepi; } else { min = args[0]; mini = min as IntegerLiteralExpression; max = args[1]; maxi = max as IntegerLiteralExpression; step = args[2]; stepi = step as IntegerLiteralExpression; } InternalLocal numVar = CodeBuilder.DeclareTempLocal( _currentMethod, TypeSystemServices.IntType); Expression numRef = CodeBuilder.CreateReference(numVar); // __num = <min> body.Add( CodeBuilder.CreateAssignment( numRef, min)); Expression endRef; if (null != maxi) { endRef = max; } else { InternalLocal endVar = CodeBuilder.DeclareTempLocal( _currentMethod, TypeSystemServices.IntType); endRef = CodeBuilder.CreateReference(endVar); // __end = <end> body.Add( CodeBuilder.CreateAssignment( endRef, max)); } if (args.Count == 1) { if (null != maxi) { if (maxi.Value < 0) { // raise ArgumentOutOfRangeException("max") (if <max> < 0) Statement statement = CodeBuilder.RaiseException( body.LexicalInfo, TypeSystemServices.Map(System_ArgumentOutOfRangeException_ctor), CodeBuilder.CreateStringLiteral("max")); body.Add(statement); } } else { IfStatement ifStatement = new IfStatement(body.LexicalInfo); ifStatement.TrueBlock = new Block(); // raise ArgumentOutOfRangeException("max") if __end < 0 Statement statement = CodeBuilder.RaiseException( body.LexicalInfo, TypeSystemServices.Map(System_ArgumentOutOfRangeException_ctor), CodeBuilder.CreateStringLiteral("max")); ifStatement.Condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.LessThan, endRef, CodeBuilder.CreateIntegerLiteral(0)); ifStatement.TrueBlock.Add(statement); body.Add(ifStatement); } } Expression stepRef; switch (args.Count) { case 1: stepRef = CodeBuilder.CreateIntegerLiteral(1); break; case 2: if (null != mini && null != maxi) { if (maxi.Value < mini.Value) { // __step = -1 stepRef = CodeBuilder.CreateIntegerLiteral(-1); } else { // __step = 1 stepRef = CodeBuilder.CreateIntegerLiteral(1); } } else { InternalLocal stepVar = CodeBuilder.DeclareTempLocal( _currentMethod, TypeSystemServices.IntType); stepRef = CodeBuilder.CreateReference(stepVar); // __step = 1 body.Add( CodeBuilder.CreateAssignment( stepRef, CodeBuilder.CreateIntegerLiteral(1))); // __step = -1 if __end < __num IfStatement ifStatement = new IfStatement(node.LexicalInfo); ifStatement.Condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.LessThan, endRef, numRef); ifStatement.TrueBlock = new Block(); ifStatement.TrueBlock.Add( CodeBuilder.CreateAssignment( stepRef, CodeBuilder.CreateIntegerLiteral(-1))); body.Add(ifStatement); } break; default: if (null != stepi) { stepRef = step; } else { InternalLocal stepVar = CodeBuilder.DeclareTempLocal( _currentMethod, TypeSystemServices.IntType); stepRef = CodeBuilder.CreateReference(stepVar); // __step = <step> body.Add( CodeBuilder.CreateAssignment( stepRef, step)); } break; } if (args.Count == 3) { Expression condition = null; bool run = false; if (null != stepi) { if (stepi.Value < 0) { if (null != maxi && null != mini) { run = maxi.Value > mini.Value; } else { condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.GreaterThan, endRef, numRef); } } else { if (null != maxi && null != mini) { run = maxi.Value < mini.Value; } else { condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.LessThan, endRef, numRef); } } } else { if (null != maxi && null != mini) { if (maxi.Value < mini.Value) { condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.GreaterThan, stepRef, CodeBuilder.CreateIntegerLiteral(0)); } else { condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.LessThan, stepRef, CodeBuilder.CreateIntegerLiteral(0)); } } else { condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.Or, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.And, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.LessThan, stepRef, CodeBuilder.CreateIntegerLiteral(0)), CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.GreaterThan, endRef, numRef)), CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.And, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.GreaterThan, stepRef, CodeBuilder.CreateIntegerLiteral(0)), CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, BinaryOperatorType.LessThan, endRef, numRef))); } } // raise ArgumentOutOfRangeException("step") if (__step < 0 and __end > __begin) or (__step > 0 and __end < __begin) Statement statement = CodeBuilder.RaiseException( body.LexicalInfo, TypeSystemServices.Map(System_ArgumentOutOfRangeException_ctor), CodeBuilder.CreateStringLiteral("step")); if (condition != null) { IfStatement ifStatement = new IfStatement(body.LexicalInfo); ifStatement.TrueBlock = new Block(); ifStatement.Condition = condition; ifStatement.TrueBlock.Add(statement); body.Add(ifStatement); } else if (run) { body.Add(statement); } // __end = __num + __step * cast(int, Math.Ceiling((__end - __num)/cast(double, __step))) if (null != stepi && null != maxi && null != mini) { int stepVal = (int)stepi.Value; int maxVal = (int)maxi.Value; int minVal = (int)mini.Value; endRef = CodeBuilder.CreateIntegerLiteral( minVal + stepVal * (int)System.Math.Ceiling((maxVal - minVal) / ((double)stepVal))); } else { Expression endBak = endRef; if (null != maxi) { InternalLocal endVar = CodeBuilder.DeclareTempLocal( _currentMethod, TypeSystemServices.IntType); endRef = CodeBuilder.CreateReference(endVar); } body.Add( CodeBuilder.CreateAssignment( endRef, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.IntType, BinaryOperatorType.Addition, numRef, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.IntType, BinaryOperatorType.Multiply, stepRef, CodeBuilder.CreateCast( TypeSystemServices.IntType, CodeBuilder.CreateMethodInvocation( TypeSystemServices.Map(System_Math_Ceiling), CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.DoubleType, BinaryOperatorType.Division, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.IntType, BinaryOperatorType.Subtraction, endBak, numRef), CodeBuilder.CreateCast( TypeSystemServices.DoubleType, stepRef)))))))); } } // while __num != __end: WhileStatement ws = new WhileStatement(node.LexicalInfo); BinaryOperatorType op = BinaryOperatorType.Inequality; if (stepRef.NodeType == NodeType.IntegerLiteralExpression) { if (((IntegerLiteralExpression)stepRef).Value > 0) { op = BinaryOperatorType.LessThan; } else { op = BinaryOperatorType.GreaterThan; } } ws.Condition = CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.BoolType, op, numRef, endRef); ws.Condition.LexicalInfo = node.LexicalInfo; // item = __num ws.Block.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference((InternalLocal)declarations[0].Entity), numRef)); Block rawBlock = new Block(); rawBlock["checked"] = false; // __num += __step rawBlock.Add( CodeBuilder.CreateAssignment( numRef, CodeBuilder.CreateBoundBinaryExpression( TypeSystemServices.IntType, BinaryOperatorType.Addition, numRef, stepRef))); ws.Block.Add(rawBlock as Statement); // <block> ws.Block.Add(node.Block); ws.OrBlock = node.OrBlock; ws.ThenBlock = node.ThenBlock; body.Add(ws); ReplaceCurrentNode(body); }
bool IsShiftOrHigher(BinaryOperatorType t) { return(IsAdditivOrHigher(t) || t == BinaryOperatorType.ShiftLeft || t == BinaryOperatorType.ShiftRight); }
bool IsAdditivOrHigher(BinaryOperatorType t) { return(IsMultiplicativ(t) || t == BinaryOperatorType.Add || t == BinaryOperatorType.Subtract); }
bool IsMultiplicativ(BinaryOperatorType t) { return(t == BinaryOperatorType.Divide || t == BinaryOperatorType.Multiply || t == BinaryOperatorType.Modulus); }
public FindBinaryOperatorNavigator(IMethod op, BinaryOperatorType operatorType) { this.op = op; this.operatorType = operatorType; }
SearchScope FindBinaryOperator(IMethod op, BinaryOperatorType operatorType) { return(FindOperator(op, m => new FindBinaryOperatorNavigator(m, operatorType))); }
private Expression CreateSideEffectAwareSlicingOperation(LexicalInfo lexicalInfo, BinaryOperatorType binaryOperator, SlicingExpression lvalue, Expression rvalue, InternalLocal returnValue) { MethodInvocationExpression eval = CodeBuilder.CreateEvalInvocation(lexicalInfo); if (HasSideEffect(lvalue.Target)) { InternalLocal temp = AddInitializedTempLocal(eval, lvalue.Target); lvalue.Target = CodeBuilder.CreateReference(temp); } foreach (Slice slice in lvalue.Indices) { Expression index = slice.Begin; if (HasSideEffect(index)) { InternalLocal temp = AddInitializedTempLocal(eval, index); slice.Begin = CodeBuilder.CreateReference(temp); } } BinaryExpression addition = CodeBuilder.CreateBoundBinaryExpression( GetExpressionType(lvalue), binaryOperator, CloneOrAssignToTemp(returnValue, lvalue), rvalue); Expression expansion = CodeBuilder.CreateAssignment( lvalue.CloneNode(), addition); // Resolve operator overloads if any BindArithmeticOperator(addition); if (eval.Arguments.Count > 0 || null != returnValue) { eval.Arguments.Add(expansion); if (null != returnValue) { eval.Arguments.Add(CodeBuilder.CreateReference(returnValue)); } BindExpressionType(eval, GetExpressionType(lvalue)); expansion = eval; } return expansion; }
public BinaryOperator(BinaryOperatorType type, IVisitable left, IVisitable right) { this.left = left; this.right = right; Type = type; }
public BinaryExpression CreateBoundBinaryExpression(IType expressionType, BinaryOperatorType op, Expression lhs, Expression rhs) { return new BinaryExpression(op, lhs, rhs) { ExpressionType = expressionType, IsSynthetic = true }; }
/// <summary> /// 그리트 뷰에 필터 조건을 적용한다. /// </summary> /// <param name="gv"></param> /// <param name="value"></param> /// <param name="columnName"></param> /// <param name="GOType"></param> /// <param name="OType"></param> public static void GridView_FilterApply(GridView gv, object value, string columnName, GroupOperatorType GOType = GroupOperatorType.And, BinaryOperatorType OType = BinaryOperatorType.Equal) { if (value == null) { //gvBooks.Columns[columnName].FilterInfo. return; } if (OType == BinaryOperatorType.Like) { value = "%" + value + "%"; } CriteriaOperator binaryFilter = new GroupOperator(GroupOperatorType.And, new BinaryOperator(columnName, value, OType)); //string filterDisplayText = String.Format("{0} = {1} ", columnName, value); //ColumnFilterInfo dateFilter = new ColumnFilterInfo(binaryFilter.ToString(), filterDisplayText); ColumnFilterInfo dateFilter = new ColumnFilterInfo(binaryFilter); gv.Columns[columnName].FilterInfo = dateFilter; }
/// <summary> /// Handle the following enum operators: /// E operator +(E x, U y); /// E operator +(U x, E y); /// E operator –(E x, U y); /// E operator &(E x, E y); /// E operator |(E x, E y); /// E operator ^(E x, E y); /// </summary> ResolveResult HandleEnumOperator(bool isNullable, IType enumType, BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs) { // evaluate as (E)((U)x op (U)y) if (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && !isNullable) { IType elementType = GetEnumUnderlyingType(enumType); lhs = ResolveCast(elementType, lhs); if (lhs.IsError) return lhs; rhs = ResolveCast(elementType, rhs); if (rhs.IsError) return rhs; return CheckErrorAndResolveCast(enumType, ResolveBinaryOperator(op, lhs, rhs)); } IType resultType = MakeNullable(enumType, isNullable); return BinaryOperatorResolveResult(resultType, lhs, op, rhs); }
bool IsShiftOrHigher (BinaryOperatorType t) { return IsAdditivOrHigher(t) || t == BinaryOperatorType.ShiftLeft || t == BinaryOperatorType.ShiftRight; }
/// <summary> /// Returns true if <paramref name="operatorType"/> is bitwise and, bitwise or, or exclusive or. /// </summary> public static bool IsBitwise(this BinaryOperatorType operatorType) { return(operatorType == BinaryOperatorType.BitwiseAnd || operatorType == BinaryOperatorType.BitwiseOr || operatorType == BinaryOperatorType.ExclusiveOr); }
public static string GetOperatorSymbol(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.BitwiseAnd: return("&"); case BinaryOperatorType.BitwiseOr: return("|"); case BinaryOperatorType.ConditionalAnd: return("&&"); case BinaryOperatorType.ConditionalOr: return("||"); case BinaryOperatorType.ExclusiveOr: return("^"); case BinaryOperatorType.GreaterThan: return(">"); case BinaryOperatorType.GreaterThanOrEqual: return(">="); case BinaryOperatorType.Equality: return("=="); case BinaryOperatorType.InEquality: return("!="); case BinaryOperatorType.LessThan: return("<"); case BinaryOperatorType.LessThanOrEqual: return("<="); case BinaryOperatorType.Add: return("+"); case BinaryOperatorType.Subtract: return("-"); case BinaryOperatorType.Multiply: return("*"); case BinaryOperatorType.Divide: return("/"); case BinaryOperatorType.Modulus: return("%"); case BinaryOperatorType.ShiftLeft: return("<<"); case BinaryOperatorType.ShiftRight: return(">>"); case BinaryOperatorType.NullCoalescing: return("??"); default: throw new NotSupportedException("Invalid value for BinaryOperatorType"); } }
Expression ConvertBinaryOperator(InvocationExpression invocation, BinaryOperatorType op, bool? isChecked = null) { if (invocation.Arguments.Count < 2) return NotSupported(invocation); Expression left = Convert(invocation.Arguments.ElementAt(0)); if (left == null) return null; Expression right = Convert(invocation.Arguments.ElementAt(1)); if (right == null) return null; BinaryOperatorExpression boe = new BinaryOperatorExpression(left, op, right); if (isChecked != null) boe.AddAnnotation(isChecked.Value ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation); switch (invocation.Arguments.Count) { case 2: return boe; case 3: Match m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(2)); if (m.Success) return boe.WithAnnotation(m.Get<AstNode>("method").Single().Annotation<MethodReference>()); else return null; case 4: if (!trueOrFalse.IsMatch(invocation.Arguments.ElementAt(2))) return null; m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(3)); if (m.Success) return boe.WithAnnotation(m.Get<AstNode>("method").Single().Annotation<MethodReference>()); else return null; default: return NotSupported(invocation); } }
public static string ToCpp(this BinaryOperatorType op) { switch (op) { case BinaryOperatorType.BitwiseAnd: return("&"); case BinaryOperatorType.BitwiseOr: return("|"); case BinaryOperatorType.ConditionalAnd: return("&&"); case BinaryOperatorType.ConditionalOr: return("||"); case BinaryOperatorType.ExclusiveOr: return("^"); case BinaryOperatorType.GreaterThan: return(">"); case BinaryOperatorType.GreaterThanOrEqual: return(">="); case BinaryOperatorType.Equality: return("=="); case BinaryOperatorType.InEquality: return("!="); case BinaryOperatorType.LessThan: return("<"); case BinaryOperatorType.LessThanOrEqual: return("<="); case BinaryOperatorType.Add: return("+"); case BinaryOperatorType.Subtract: return("-"); case BinaryOperatorType.Multiply: return("*"); case BinaryOperatorType.Divide: return("/"); case BinaryOperatorType.Modulus: return("%"); case BinaryOperatorType.ShiftLeft: return("<<"); case BinaryOperatorType.ShiftRight: return(">>"); case BinaryOperatorType.Any: case BinaryOperatorType.NullCoalescing: default: return(string.Format("({0})", op)); } }
static int GetOperatorPrecedence(Dictionary<BinaryOperatorType, int> dict, BinaryOperatorType op) { int p; dict.TryGetValue(op, out p); return p; }
public BinaryOperatorExpression(Expression left, BinaryOperatorType op, Expression right) { }
public JassBinaryExpressionSyntax(BinaryOperatorType @operator, IExpressionSyntax left, IExpressionSyntax right) { Operator = @operator; Left = left; Right = right; }
public static TokenRole GetOperatorRole(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.BitwiseAnd: return(BitwiseAndRole); case BinaryOperatorType.BitwiseOr: return(BitwiseOrRole); case BinaryOperatorType.ConditionalAnd: return(ConditionalAndRole); case BinaryOperatorType.ConditionalOr: return(ConditionalOrRole); case BinaryOperatorType.ExclusiveOr: return(ExclusiveOrRole); case BinaryOperatorType.GreaterThan: return(GreaterThanRole); case BinaryOperatorType.GreaterThanOrEqual: return(GreaterThanOrEqualRole); case BinaryOperatorType.Equality: return(EqualityRole); case BinaryOperatorType.InEquality: return(InEqualityRole); case BinaryOperatorType.LessThan: return(LessThanRole); case BinaryOperatorType.LessThanOrEqual: return(LessThanOrEqualRole); case BinaryOperatorType.Add: return(AddRole); case BinaryOperatorType.Subtract: return(SubtractRole); case BinaryOperatorType.Multiply: return(MultiplyRole); case BinaryOperatorType.Divide: return(DivideRole); case BinaryOperatorType.Modulus: return(ModulusRole); case BinaryOperatorType.ShiftLeft: return(ShiftLeftRole); case BinaryOperatorType.ShiftRight: return(ShiftRightRole); case BinaryOperatorType.NullCoalescing: return(NullCoalescingRole); case BinaryOperatorType.Range: return(RangeRole); default: throw new NotSupportedException("Invalid value for BinaryOperatorType"); } }
/// <summary> /// 그리트 뷰에 필터 Between 조건을 적용한다. /// </summary> /// <param name="gv"></param> /// <param name="value"></param> /// <param name="columnName"></param> /// <param name="GOType"></param> /// <param name="OType1"></param> /// <param name="OType2"></param> public static void GridView_FilterApply(GridView gv, object value_from, object value_to, string columnName, GroupOperatorType GOType = GroupOperatorType.And, BinaryOperatorType OType1 = BinaryOperatorType.GreaterOrEqual, BinaryOperatorType OType2 = BinaryOperatorType.LessOrEqual) { if (value_from == null || value_to == null) { //gvBooks.Columns[columnName].FilterInfo. return; } CriteriaOperator binaryFilter = new GroupOperator(GroupOperatorType.And, new BinaryOperator(columnName, value_from, OType1), new BinaryOperator(columnName, value_to, OType2)); //string filterDisplayText = String.Format("{0} = {1} ", columnName, value); //ColumnFilterInfo dateFilter = new ColumnFilterInfo(binaryFilter.ToString(), filterDisplayText); ColumnFilterInfo dateFilter = new ColumnFilterInfo(binaryFilter); gv.Columns[columnName].FilterInfo = dateFilter; }
SearchScope FindBinaryOperator(IMethod op, BinaryOperatorType operatorType) { return FindOperator(op, m => new FindBinaryOperatorNavigator(m, operatorType)); }
public static ExpressionType GetLinqNodeType(BinaryOperatorType op, bool checkForOverflow) { switch (op) { case BinaryOperatorType.BitwiseAnd: return(ExpressionType.And); case BinaryOperatorType.BitwiseOr: return(ExpressionType.Or); case BinaryOperatorType.ConditionalAnd: return(ExpressionType.AndAlso); case BinaryOperatorType.ConditionalOr: return(ExpressionType.OrElse); case BinaryOperatorType.ExclusiveOr: return(ExpressionType.ExclusiveOr); case BinaryOperatorType.GreaterThan: return(ExpressionType.GreaterThan); case BinaryOperatorType.GreaterThanOrEqual: return(ExpressionType.GreaterThanOrEqual); case BinaryOperatorType.Equality: return(ExpressionType.Equal); case BinaryOperatorType.InEquality: return(ExpressionType.NotEqual); case BinaryOperatorType.LessThan: return(ExpressionType.LessThan); case BinaryOperatorType.LessThanOrEqual: return(ExpressionType.LessThanOrEqual); case BinaryOperatorType.Add: return(checkForOverflow ? ExpressionType.AddChecked : ExpressionType.Add); case BinaryOperatorType.Subtract: return(checkForOverflow ? ExpressionType.SubtractChecked : ExpressionType.Subtract); case BinaryOperatorType.Multiply: return(checkForOverflow ? ExpressionType.MultiplyChecked : ExpressionType.Multiply); case BinaryOperatorType.Divide: return(ExpressionType.Divide); case BinaryOperatorType.Modulus: return(ExpressionType.Modulo); case BinaryOperatorType.ShiftLeft: return(ExpressionType.LeftShift); case BinaryOperatorType.ShiftRight: return(ExpressionType.RightShift); case BinaryOperatorType.NullCoalescing: return(ExpressionType.Coalesce); case BinaryOperatorType.Range: return(ExpressionType.Extension); default: throw new NotSupportedException("Invalid value for BinaryOperatorType"); } }
public CaseLabel(BinaryOperatorType binaryOperatorType, Expression label) {}
public BinaryExpression(BinaryOperatorType operator_, Expression left, Expression right) : this(LexicalInfo.Empty, operator_, left, right) { }
public static int ComparePrecedenceCSharp(BinaryOperatorType op1, BinaryOperatorType op2) { int p1 = GetOperatorPrecedence(csharpDict, op1); int p2 = GetOperatorPrecedence(csharpDict, op2); return p1.CompareTo(p2); }
public BinaryOperatorExpression(Expression left, BinaryOperatorType op, Expression right) { this.left = left; this.op = op; this.right = right; }
Expression ConvertBinaryOperator(InvocationExpression invocation, BinaryOperatorType op, bool?isChecked = null) { if (invocation.Arguments.Count < 2) { return(NotSupported(invocation)); } Expression left = Convert(invocation.Arguments.ElementAt(0)); if (left == null) { return(null); } Expression right = Convert(invocation.Arguments.ElementAt(1)); if (right == null) { return(null); } BinaryOperatorExpression boe = new BinaryOperatorExpression(left, op, right); if (isChecked != null) { boe.AddAnnotation(isChecked.Value ? AddCheckedBlocks.CheckedAnnotation : AddCheckedBlocks.UncheckedAnnotation); } switch (invocation.Arguments.Count) { case 2: return(boe); case 3: Match m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(2)); if (m.Success) { return(boe.WithAnnotation(m.Get <AstNode>("method").Single().Annotation <IMethod>())); } else { return(null); } case 4: if (!trueOrFalse.IsMatch(invocation.Arguments.ElementAt(2))) { return(null); } m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(3)); if (m.Success) { return(boe.WithAnnotation(m.Get <AstNode>("method").Single().Annotation <IMethod>())); } else { return(null); } default: return(NotSupported(invocation)); } }
static string GetBinaryOperatorText(BinaryOperatorType op) { return BooPrinterVisitor.GetBinaryOperatorText(op); }
static bool IsBitwiseOperator(BinaryOperatorType op) { return(op == BinaryOperatorType.BitwiseAnd || op == BinaryOperatorType.BitwiseOr || op == BinaryOperatorType.ExclusiveOr); }
private BinaryOperatorType GetCorrespondingHasValueOperator(BinaryOperatorType op) { if (BinaryOperatorType.Equality == op || BinaryOperatorType.Inequality == op) return op; //when there is at least one non-value operand then any other comparison //than equality/inequality is undefined/false (as in C#) return BinaryOperatorType.BitwiseAnd; }
/// <summary> /// Just calls the BinaryOperatorExpression constructor, /// but being an extension method; this allows for a nicer /// infix syntax in some cases. /// </summary> public static BinaryOperatorExpression Operator(this Expression left, BinaryOperatorType op, Expression right) { return(new BinaryOperatorExpression(left, op, right)); }
public static string GetBinaryOperator(BinaryOperatorType binaryOperatorType) { string str; switch (binaryOperatorType) { case BinaryOperatorType.BitwiseAnd: { str = "&"; break; } case BinaryOperatorType.BitwiseOr: { str = "|"; break; } case BinaryOperatorType.LogicalAnd: { str = "and"; break; } case BinaryOperatorType.LogicalOr: { str = "or"; break; } case BinaryOperatorType.ExclusiveOr: { str = "^"; break; } case BinaryOperatorType.GreaterThan: { str = ">"; break; } case BinaryOperatorType.GreaterThanOrEqual: { str = ">="; break; } case BinaryOperatorType.Equality: case BinaryOperatorType.Power: { str = "=="; break; } case BinaryOperatorType.InEquality: { str = "!="; break; } case BinaryOperatorType.LessThan: { str = "<"; break; } case BinaryOperatorType.LessThanOrEqual: { str = "<="; break; } case BinaryOperatorType.Add: { str = "+"; break; } case BinaryOperatorType.Subtract: { str = "-"; break; } case BinaryOperatorType.Multiply: { str = "*"; break; } case BinaryOperatorType.Divide: case BinaryOperatorType.DivideInteger: { str = "/"; break; } case BinaryOperatorType.Modulus: { str = "%"; break; } case BinaryOperatorType.Concat: { str = "+"; break; } case BinaryOperatorType.ShiftLeft: { str = "<<"; break; } case BinaryOperatorType.ShiftRight: { str = ">>"; break; } case BinaryOperatorType.ReferenceEquality: { str = "is"; break; } default: { goto case BinaryOperatorType.Power; } } return str; }
public override string FormatBinary(BinaryOperatorType operatorType, string leftOperand, string rightOperand) { return(operatorType == BinaryOperatorType.Like ? string.Format(CultureInfo.InvariantCulture, "{0} ilike {1}", leftOperand, rightOperand) : base.FormatBinary(operatorType, leftOperand, rightOperand)); }
static string GetOverloadableOperatorName(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.Add: return "op_Addition"; case BinaryOperatorType.Subtract: return "op_Subtraction"; case BinaryOperatorType.Multiply: return "op_Multiply"; case BinaryOperatorType.Divide: return "op_Division"; case BinaryOperatorType.Modulus: return "op_Modulus"; case BinaryOperatorType.BitwiseAnd: return "op_BitwiseAnd"; case BinaryOperatorType.BitwiseOr: return "op_BitwiseOr"; case BinaryOperatorType.ExclusiveOr: return "op_ExclusiveOr"; case BinaryOperatorType.ShiftLeft: return "op_LeftShift"; case BinaryOperatorType.ShiftRight: return "op_RightShift"; case BinaryOperatorType.Equality: return "op_Equality"; case BinaryOperatorType.InEquality: return "op_Inequality"; case BinaryOperatorType.GreaterThan: return "op_GreaterThan"; case BinaryOperatorType.LessThan: return "op_LessThan"; case BinaryOperatorType.GreaterThanOrEqual: return "op_GreaterThanOrEqual"; case BinaryOperatorType.LessThanOrEqual: return "op_LessThanOrEqual"; default: return null; } }
B.BinaryOperatorType ConvertOperator(BinaryOperatorType op) { switch (op) { case BinaryOperatorType.Add: return(B.BinaryOperatorType.Addition); case BinaryOperatorType.BitwiseAnd: return(B.BinaryOperatorType.BitwiseAnd); case BinaryOperatorType.BitwiseOr: return(B.BinaryOperatorType.BitwiseOr); case BinaryOperatorType.Concat: return(B.BinaryOperatorType.Addition); case BinaryOperatorType.Divide: return(B.BinaryOperatorType.Division); case BinaryOperatorType.DivideInteger: return(B.BinaryOperatorType.Division); case BinaryOperatorType.Equality: return(B.BinaryOperatorType.Equality); case BinaryOperatorType.ExclusiveOr: return(B.BinaryOperatorType.ExclusiveOr); case BinaryOperatorType.GreaterThan: return(B.BinaryOperatorType.GreaterThan); case BinaryOperatorType.GreaterThanOrEqual: return(B.BinaryOperatorType.GreaterThanOrEqual); case BinaryOperatorType.InEquality: return(B.BinaryOperatorType.Inequality); case BinaryOperatorType.LessThan: return(B.BinaryOperatorType.LessThan); case BinaryOperatorType.LessThanOrEqual: return(B.BinaryOperatorType.LessThanOrEqual); case BinaryOperatorType.Like: return(B.BinaryOperatorType.Match); case BinaryOperatorType.LogicalAnd: return(B.BinaryOperatorType.And); case BinaryOperatorType.LogicalOr: return(B.BinaryOperatorType.Or); case BinaryOperatorType.Modulus: return(B.BinaryOperatorType.Modulus); case BinaryOperatorType.Multiply: return(B.BinaryOperatorType.Multiply); case BinaryOperatorType.NullCoalescing: return(B.BinaryOperatorType.Or); case BinaryOperatorType.Power: return(B.BinaryOperatorType.Exponentiation); case BinaryOperatorType.ReferenceEquality: return(B.BinaryOperatorType.ReferenceEquality); case BinaryOperatorType.ReferenceInequality: return(B.BinaryOperatorType.ReferenceInequality); case BinaryOperatorType.ShiftLeft: return(B.BinaryOperatorType.ShiftLeft); case BinaryOperatorType.ShiftRight: return(B.BinaryOperatorType.ShiftRight); case BinaryOperatorType.Subtract: return(B.BinaryOperatorType.Subtraction); default: return(B.BinaryOperatorType.None); } }
/// <summary> /// Handle the case where an enum value is compared with another enum value /// bool operator op(E x, E y); /// </summary> ResolveResult HandleEnumComparison(BinaryOperatorType op, IType enumType, bool isNullable, ResolveResult lhs, ResolveResult rhs) { // evaluate as ((U)x op (U)y) IType elementType = GetEnumUnderlyingType(enumType); if (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && !isNullable) { lhs = ResolveCast(elementType, lhs); if (lhs.IsError) return lhs; rhs = ResolveCast(elementType, rhs); if (rhs.IsError) return rhs; return ResolveBinaryOperator(op, lhs, rhs); } IType resultType = compilation.FindType(KnownTypeCode.Boolean); return BinaryOperatorResolveResult(resultType, lhs, op, rhs); }
/// <summary> /// Returns the existing expression plus the specified integer value. /// The old <paramref name="expr"/> object is not modified, but might be a subobject on the new expression /// (and thus its parent property is modified). /// </summary> public static Expression AddInteger(Expression expr, int value) { PrimitiveExpression pe = expr as PrimitiveExpression; if (pe != null && pe.Value is int) { int newVal = (int)pe.Value + value; return(new PrimitiveExpression(newVal, newVal.ToString(System.Globalization.NumberFormatInfo.InvariantInfo))); } BinaryOperatorExpression boe = expr as BinaryOperatorExpression; if (boe != null && boe.Op == BinaryOperatorType.Add) { // clone boe: boe = new BinaryOperatorExpression(boe.Left, boe.Op, boe.Right); boe.Right = AddInteger(boe.Right, value); if (boe.Right is PrimitiveExpression && ((PrimitiveExpression)boe.Right).Value is int) { int newVal = (int)((PrimitiveExpression)boe.Right).Value; if (newVal == 0) { return(boe.Left); } else if (newVal < 0) { ((PrimitiveExpression)boe.Right).Value = -newVal; boe.Op = BinaryOperatorType.Subtract; } } return(boe); } if (boe != null && boe.Op == BinaryOperatorType.Subtract) { pe = boe.Right as PrimitiveExpression; if (pe != null && pe.Value is int) { int newVal = (int)pe.Value - value; if (newVal == 0) { return(boe.Left); } // clone boe: boe = new BinaryOperatorExpression(boe.Left, boe.Op, boe.Right); if (newVal < 0) { newVal = -newVal; boe.Op = BinaryOperatorType.Add; } boe.Right = new PrimitiveExpression(newVal, newVal.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)); return(boe); } } BinaryOperatorType opType = BinaryOperatorType.Add; if (value < 0) { value = -value; opType = BinaryOperatorType.Subtract; } return(new BinaryOperatorExpression(expr, opType, new PrimitiveExpression(value, value.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)))); }
public ResolveResult ResolveBinaryOperator(BinaryOperatorType op, ResolveResult lhs, ResolveResult rhs) { if (SpecialType.Dynamic.Equals(lhs.Type) || SpecialType.Dynamic.Equals(rhs.Type)) { lhs = Convert(lhs, SpecialType.Dynamic); rhs = Convert(rhs, SpecialType.Dynamic); return BinaryOperatorResolveResult(SpecialType.Dynamic, lhs, op, rhs); } // C# 4.0 spec: §7.3.4 Binary operator overload resolution string overloadableOperatorName = GetOverloadableOperatorName(op); if (overloadableOperatorName == null) { // Handle logical and/or exactly as bitwise and/or: // - If the user overloads a bitwise operator, that implicitly creates the corresponding logical operator. // - If both inputs are compile-time constants, it doesn't matter that we don't short-circuit. // - If inputs aren't compile-time constants, we don't evaluate anything, so again it doesn't matter that we don't short-circuit if (op == BinaryOperatorType.ConditionalAnd) { overloadableOperatorName = GetOverloadableOperatorName(BinaryOperatorType.BitwiseAnd); } else if (op == BinaryOperatorType.ConditionalOr) { overloadableOperatorName = GetOverloadableOperatorName(BinaryOperatorType.BitwiseOr); } else if (op == BinaryOperatorType.NullCoalescing) { // null coalescing operator is not overloadable and needs to be handled separately return ResolveNullCoalescingOperator(lhs, rhs); } else { throw new ArgumentException("Invalid value for BinaryOperatorType", "op"); } } // If the type is nullable, get the underlying type: bool isNullable = NullableType.IsNullable(lhs.Type) || NullableType.IsNullable(rhs.Type); IType lhsType = NullableType.GetUnderlyingType(lhs.Type); IType rhsType = NullableType.GetUnderlyingType(rhs.Type); // the operator is overloadable: OverloadResolution userDefinedOperatorOR = new OverloadResolution(compilation, new[] { lhs, rhs }, conversions: conversions); HashSet<IParameterizedMember> userOperatorCandidates = new HashSet<IParameterizedMember>(); userOperatorCandidates.UnionWith(GetUserDefinedOperatorCandidates(lhsType, overloadableOperatorName)); userOperatorCandidates.UnionWith(GetUserDefinedOperatorCandidates(rhsType, overloadableOperatorName)); foreach (var candidate in userOperatorCandidates) { userDefinedOperatorOR.AddCandidate(candidate); } if (userDefinedOperatorOR.FoundApplicableCandidate) { return CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR); } if (SpecialType.NullType.Equals(lhsType) && rhsType.IsReferenceType == false || lhsType.IsReferenceType == false && SpecialType.NullType.Equals(rhsType)) { isNullable = true; } if (op == BinaryOperatorType.ShiftLeft || op == BinaryOperatorType.ShiftRight) { // special case: the shift operators allow "var x = null << null", producing int?. if (SpecialType.NullType.Equals(lhsType) && SpecialType.NullType.Equals(rhsType)) isNullable = true; // for shift operators, do unary promotion independently on both arguments lhs = UnaryNumericPromotion(UnaryOperatorType.Plus, ref lhsType, isNullable, lhs); rhs = UnaryNumericPromotion(UnaryOperatorType.Plus, ref rhsType, isNullable, rhs); } else { bool allowNullableConstants = op == BinaryOperatorType.Equality || op == BinaryOperatorType.InEquality; if (!BinaryNumericPromotion(isNullable, ref lhs, ref rhs, allowNullableConstants)) return new ErrorResolveResult(lhs.Type); } // re-read underlying types after numeric promotion lhsType = NullableType.GetUnderlyingType(lhs.Type); rhsType = NullableType.GetUnderlyingType(rhs.Type); IEnumerable<CSharpOperators.OperatorMethod> methodGroup; CSharpOperators operators = CSharpOperators.Get(compilation); switch (op) { case BinaryOperatorType.Multiply: methodGroup = operators.MultiplicationOperators; break; case BinaryOperatorType.Divide: methodGroup = operators.DivisionOperators; break; case BinaryOperatorType.Modulus: methodGroup = operators.RemainderOperators; break; case BinaryOperatorType.Add: methodGroup = operators.AdditionOperators; { if (lhsType.Kind == TypeKind.Enum) { // E operator +(E x, U y); IType underlyingType = MakeNullable(GetEnumUnderlyingType(lhsType), isNullable); if (TryConvert(ref rhs, underlyingType)) { return HandleEnumOperator(isNullable, lhsType, op, lhs, rhs); } } if (rhsType.Kind == TypeKind.Enum) { // E operator +(U x, E y); IType underlyingType = MakeNullable(GetEnumUnderlyingType(rhsType), isNullable); if (TryConvert(ref lhs, underlyingType)) { return HandleEnumOperator(isNullable, rhsType, op, lhs, rhs); } } if (lhsType.Kind == TypeKind.Delegate && TryConvert(ref rhs, lhsType)) { return BinaryOperatorResolveResult(lhsType, lhs, op, rhs); } else if (rhsType.Kind == TypeKind.Delegate && TryConvert(ref lhs, rhsType)) { return BinaryOperatorResolveResult(rhsType, lhs, op, rhs); } if (lhsType is PointerType) { methodGroup = new [] { PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.Int32), PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.UInt32), PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.Int64), PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.UInt64) }; } else if (rhsType is PointerType) { methodGroup = new [] { PointerArithmeticOperator(rhsType, KnownTypeCode.Int32, rhsType), PointerArithmeticOperator(rhsType, KnownTypeCode.UInt32, rhsType), PointerArithmeticOperator(rhsType, KnownTypeCode.Int64, rhsType), PointerArithmeticOperator(rhsType, KnownTypeCode.UInt64, rhsType) }; } if (SpecialType.NullType.Equals(lhsType) && SpecialType.NullType.Equals(rhsType)) return new ErrorResolveResult(SpecialType.NullType); } break; case BinaryOperatorType.Subtract: methodGroup = operators.SubtractionOperators; { if (lhsType.Kind == TypeKind.Enum) { // E operator –(E x, U y); IType underlyingType = MakeNullable(GetEnumUnderlyingType(lhsType), isNullable); if (TryConvert(ref rhs, underlyingType)) { return HandleEnumOperator(isNullable, lhsType, op, lhs, rhs); } // U operator –(E x, E y); if (TryConvert(ref rhs, lhs.Type)) { return HandleEnumSubtraction(isNullable, lhsType, lhs, rhs); } } if (rhsType.Kind == TypeKind.Enum) { // U operator –(E x, E y); if (TryConvert(ref lhs, rhs.Type)) { return HandleEnumSubtraction(isNullable, rhsType, lhs, rhs); } } if (lhsType.Kind == TypeKind.Delegate && TryConvert(ref rhs, lhsType)) { return BinaryOperatorResolveResult(lhsType, lhs, op, rhs); } else if (rhsType.Kind == TypeKind.Delegate && TryConvert(ref lhs, rhsType)) { return BinaryOperatorResolveResult(rhsType, lhs, op, rhs); } if (lhsType is PointerType) { if (rhsType is PointerType) { IType int64 = compilation.FindType(KnownTypeCode.Int64); if (lhsType.Equals(rhsType)) { return BinaryOperatorResolveResult(int64, lhs, op, rhs); } else { return new ErrorResolveResult(int64); } } methodGroup = new [] { PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.Int32), PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.UInt32), PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.Int64), PointerArithmeticOperator(lhsType, lhsType, KnownTypeCode.UInt64) }; } if (SpecialType.NullType.Equals(lhsType) && SpecialType.NullType.Equals(rhsType)) return new ErrorResolveResult(SpecialType.NullType); } break; case BinaryOperatorType.ShiftLeft: methodGroup = operators.ShiftLeftOperators; break; case BinaryOperatorType.ShiftRight: methodGroup = operators.ShiftRightOperators; break; case BinaryOperatorType.Equality: case BinaryOperatorType.InEquality: case BinaryOperatorType.LessThan: case BinaryOperatorType.GreaterThan: case BinaryOperatorType.LessThanOrEqual: case BinaryOperatorType.GreaterThanOrEqual: { if (lhsType.Kind == TypeKind.Enum && TryConvert(ref rhs, lhs.Type)) { // bool operator op(E x, E y); return HandleEnumComparison(op, lhsType, isNullable, lhs, rhs); } else if (rhsType.Kind == TypeKind.Enum && TryConvert(ref lhs, rhs.Type)) { // bool operator op(E x, E y); return HandleEnumComparison(op, rhsType, isNullable, lhs, rhs); } else if (lhsType is PointerType && rhsType is PointerType) { return BinaryOperatorResolveResult(compilation.FindType(KnownTypeCode.Boolean), lhs, op, rhs); } switch (op) { case BinaryOperatorType.Equality: methodGroup = operators.EqualityOperators; break; case BinaryOperatorType.InEquality: methodGroup = operators.InequalityOperators; break; case BinaryOperatorType.LessThan: methodGroup = operators.LessThanOperators; break; case BinaryOperatorType.GreaterThan: methodGroup = operators.GreaterThanOperators; break; case BinaryOperatorType.LessThanOrEqual: methodGroup = operators.LessThanOrEqualOperators; break; case BinaryOperatorType.GreaterThanOrEqual: methodGroup = operators.GreaterThanOrEqualOperators; break; default: throw new InvalidOperationException(); } } break; case BinaryOperatorType.BitwiseAnd: case BinaryOperatorType.BitwiseOr: case BinaryOperatorType.ExclusiveOr: { if (lhsType.Kind == TypeKind.Enum && TryConvert(ref rhs, lhs.Type)) { // bool operator op(E x, E y); return HandleEnumOperator(isNullable, lhsType, op, lhs, rhs); } else if (rhsType.Kind == TypeKind.Enum && TryConvert(ref lhs, rhs.Type)) { // bool operator op(E x, E y); return HandleEnumOperator(isNullable, rhsType, op, lhs, rhs); } switch (op) { case BinaryOperatorType.BitwiseAnd: methodGroup = operators.BitwiseAndOperators; break; case BinaryOperatorType.BitwiseOr: methodGroup = operators.BitwiseOrOperators; break; case BinaryOperatorType.ExclusiveOr: methodGroup = operators.BitwiseXorOperators; break; default: throw new InvalidOperationException(); } } break; case BinaryOperatorType.ConditionalAnd: methodGroup = operators.LogicalAndOperators; break; case BinaryOperatorType.ConditionalOr: methodGroup = operators.LogicalOrOperators; break; default: throw new InvalidOperationException(); } OverloadResolution builtinOperatorOR = new OverloadResolution(compilation, new[] { lhs, rhs }, conversions: conversions); foreach (var candidate in methodGroup) { builtinOperatorOR.AddCandidate(candidate); } CSharpOperators.BinaryOperatorMethod m = (CSharpOperators.BinaryOperatorMethod)builtinOperatorOR.BestCandidate; IType resultType = m.ReturnType; if (builtinOperatorOR.BestCandidateErrors != OverloadResolutionErrors.None) { // If there are any user-defined operators, prefer those over the built-in operators. // It'll be a more informative error. if (userDefinedOperatorOR.BestCandidate != null) return CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR); else return new ErrorResolveResult(resultType); } else if (lhs.IsCompileTimeConstant && rhs.IsCompileTimeConstant && m.CanEvaluateAtCompileTime) { object val; try { val = m.Invoke(this, lhs.ConstantValue, rhs.ConstantValue); } catch (ArithmeticException) { return new ErrorResolveResult(resultType); } return new ConstantResolveResult(resultType, val); } else { lhs = Convert(lhs, m.Parameters[0].Type, builtinOperatorOR.ArgumentConversions[0]); rhs = Convert(rhs, m.Parameters[1].Type, builtinOperatorOR.ArgumentConversions[1]); return BinaryOperatorResolveResult(resultType, lhs, op, rhs); } }
/// <summary> /// Returns true, if the specified operator is a relational operator /// </summary> public static bool IsRelationalOperator(BinaryOperatorType op) { return(NegateRelationalOperator(op) != BinaryOperatorType.Any); }