private static IExpression InvertBinaryOperation(IBinaryOperation binOp) { Contract.Requires(binOp != null); Contract.Ensures(Contract.Result<IExpression>() != null); BinaryOperation/*?*/ result = null; if (binOp is IEquality && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float32 && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float64) result = new NotEquality(); else if (binOp is INotEquality && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float32 && binOp.LeftOperand.Type.TypeCode != PrimitiveTypeCode.Float64) result = new Equality(); else if (binOp is ILessThan) result = new GreaterThanOrEqual() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((ILessThan)binOp).IsUnsignedOrUnordered, binOp) }; else if (binOp is ILessThanOrEqual) result = new GreaterThan() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((ILessThanOrEqual)binOp).IsUnsignedOrUnordered, binOp) }; else if (binOp is IGreaterThan) result = new LessThanOrEqual() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((IGreaterThan)binOp).IsUnsignedOrUnordered, binOp) }; else if (binOp is IGreaterThanOrEqual) result = new LessThan() { IsUnsignedOrUnordered = KeepUnsignedButInvertUnordered(((IGreaterThanOrEqual)binOp).IsUnsignedOrUnordered, binOp) }; if (result != null) { result.LeftOperand = binOp.LeftOperand; result.RightOperand = binOp.RightOperand; result.Type = binOp.Type; result.Locations.AddRange(binOp.Locations); return result; } LogicalNot logicalNot = new LogicalNot(); logicalNot.Operand = binOp; logicalNot.Type = binOp.Type; logicalNot.Locations.AddRange(binOp.Locations); return logicalNot; }
public override IExpression Rewrite(IGreaterThan greaterThan) { // Catch use of the x > null idiom used by Roslyn as generated // code for x != null statements. if (ExpressionHelper.IsNullLiteral(greaterThan.RightOperand)) { var c = new NotEquality { LeftOperand = greaterThan.LeftOperand, RightOperand = greaterThan.RightOperand, Type = greaterThan.Type }; return(c); } return(base.Rewrite(greaterThan)); }
public override IExpression VisitBinaryExpression(BinaryExpressionSyntax node) { var o = this.semanticModel.GetTypeInfo(node); var t = this.mapper.Map(o.Type); if (node.Kind == SyntaxKind.AssignExpression) { this.lhs = true; } var left = this.Visit(node.Left); this.lhs = false; var right = this.Visit(node.Right); BinaryOperation op = null; var locs = Helper.SourceLocation(this.tree, node); switch (node.Kind) { case SyntaxKind.AddAssignExpression: { var a = new Assignment() { Locations = locs, Source = new Addition() { LeftOperand = left, RightOperand = right, }, Target = Helper.MakeTargetExpression(left), Type = t, }; return(a); } case SyntaxKind.AddExpression: op = new Addition(); break; case SyntaxKind.AssignExpression: { var mc = left as MethodCall; if (mc != null) { // then this is really o.P = e for some property P // and the property access has been translated into a call // to set_P. mc.Arguments = new List <IExpression> { right, }; return(mc); } var be = left as BoundExpression; if (be != null) { var a = new Assignment() { Locations = locs, Source = right, Target = new TargetExpression() { Definition = be.Definition, Instance = be.Instance, Type = be.Type, }, Type = t, }; return(a); } var arrayIndexer = left as ArrayIndexer; if (arrayIndexer != null) { var a = new Assignment() { Locations = locs, Source = right, Target = new TargetExpression() { Definition = arrayIndexer, Instance = arrayIndexer.IndexedObject, Type = right.Type, }, Type = t, }; return(a); } var addressDereference = left as AddressDereference; if (addressDereference != null) { var a = new Assignment() { Locations = locs, Source = right, Target = new TargetExpression() { Definition = addressDereference, Instance = null, Type = t, }, Type = t, }; return(a); } throw new InvalidDataException("VisitBinaryExpression: Can't figure out lhs in assignment" + left.Type.ToString()); } case SyntaxKind.BitwiseAndExpression: op = new BitwiseAnd(); break; case SyntaxKind.BitwiseOrExpression: op = new BitwiseOr(); break; case SyntaxKind.DivideExpression: op = new Division(); break; case SyntaxKind.EqualsExpression: op = new Equality(); break; case SyntaxKind.ExclusiveOrExpression: op = new ExclusiveOr(); break; case SyntaxKind.GreaterThanExpression: op = new GreaterThan(); break; case SyntaxKind.GreaterThanOrEqualExpression: op = new GreaterThanOrEqual(); break; case SyntaxKind.LeftShiftExpression: op = new LeftShift(); break; case SyntaxKind.LessThanExpression: op = new LessThan(); break; case SyntaxKind.LessThanOrEqualExpression: op = new LessThanOrEqual(); break; case SyntaxKind.LogicalAndExpression: return(new Conditional() { Condition = left, Locations = locs, ResultIfTrue = right, ResultIfFalse = new CompileTimeConstant() { Type = t, Value = false }, Type = t, }); case SyntaxKind.LogicalOrExpression: return(new Conditional() { Condition = left, Locations = Helper.SourceLocation(this.tree, node), ResultIfTrue = new CompileTimeConstant() { Type = t, Value = true }, ResultIfFalse = right, Type = t, }); case SyntaxKind.ModuloExpression: op = new Modulus(); break; case SyntaxKind.MultiplyExpression: op = new Multiplication(); break; case SyntaxKind.NotEqualsExpression: op = new NotEquality(); break; case SyntaxKind.RightShiftExpression: op = new RightShift(); break; case SyntaxKind.SubtractAssignExpression: { var a = new Assignment() { Locations = locs, Source = new Subtraction() { LeftOperand = left, RightOperand = right, }, Target = Helper.MakeTargetExpression(left), Type = t, }; return(a); } case SyntaxKind.MultiplyAssignExpression: { var a = new Assignment() { Locations = locs, Source = new Multiplication() { LeftOperand = left, RightOperand = right, }, Target = Helper.MakeTargetExpression(left), Type = t, }; return(a); } case SyntaxKind.DivideAssignExpression: { var a = new Assignment() { Locations = locs, Source = new Division() { LeftOperand = left, RightOperand = right, }, Target = Helper.MakeTargetExpression(left), Type = t, }; return(a); } case SyntaxKind.ModuloAssignExpression: { var a = new Assignment() { Locations = locs, Source = new Modulus() { LeftOperand = left, RightOperand = right, }, Target = Helper.MakeTargetExpression(left), Type = t, }; return(a); } case SyntaxKind.SubtractExpression: op = new Subtraction(); break; default: throw new InvalidDataException("VisitBinaryExpression: unknown node = " + node.Kind); } op.Locations = locs; op.LeftOperand = left; op.RightOperand = right; op.Type = t; return(op); }
public static IExpression Normalize(IExpression expression) { LogicalNot /*?*/ logicalNot = expression as LogicalNot; if (logicalNot != null) { IExpression operand = logicalNot.Operand; #region LogicalNot: ! LogicalNot /*?*/ operandAsLogicalNot = operand as LogicalNot; if (operandAsLogicalNot != null) { return(Normalize(operandAsLogicalNot.Operand)); } #endregion #region BinaryOperations: ==, !=, <, <=, >, >= BinaryOperation /*?*/ binOp = operand as BinaryOperation; if (binOp != null) { BinaryOperation /*?*/ result = null; if (binOp is IEquality) { result = new NotEquality(); } else if (binOp is INotEquality) { result = new Equality(); } else if (binOp is ILessThan) { result = new GreaterThanOrEqual(); } else if (binOp is ILessThanOrEqual) { result = new GreaterThan(); } else if (binOp is IGreaterThan) { result = new LessThanOrEqual(); } else if (binOp is IGreaterThanOrEqual) { result = new LessThan(); } if (result != null) { result.LeftOperand = Normalize(binOp.LeftOperand); result.RightOperand = Normalize(binOp.RightOperand); return(result); } } #endregion #region Conditionals: &&, || Conditional /*?*/ conditional = operand as Conditional; if (conditional != null) { if (ExpressionHelper.IsIntegralNonzero(conditional.ResultIfTrue) || ExpressionHelper.IsIntegralZero(conditional.ResultIfFalse)) { Conditional result = new Conditional(); LogicalNot not; //invert condition not = new LogicalNot(); not.Operand = conditional.Condition; result.Condition = Normalize(not); //invert false branch and switch with true branch not = new LogicalNot(); not.Operand = conditional.ResultIfFalse; result.ResultIfTrue = Normalize(not); //invert true branch and switch with false branch not = new LogicalNot(); not.Operand = conditional.ResultIfTrue; result.ResultIfFalse = Normalize(not); //return result.Type = conditional.Type; return(result); } } #endregion #region Constants: true, false CompileTimeConstant /*?*/ ctc = operand as CompileTimeConstant; if (ctc != null) { if (ExpressionHelper.IsIntegralNonzero(ctc)) //Is true { var val = SetBooleanFalse(ctc); if (val != null) { return(val); } else { return(expression); } } else if (ExpressionHelper.IsIntegralZero(ctc)) //Is false { var val = SetBooleanTrue(ctc); if (val != null) { return(val); } else { return(expression); } } } #endregion } return(expression); }
private static IExpression ConvertToBoolean(IExpression expression) { Contract.Requires(expression != null); Contract.Ensures(Contract.Result <IExpression>() != null); IPlatformType platformType = expression.Type.PlatformType; var cc = expression as CompileTimeConstant; if (cc != null && TypeHelper.IsPrimitiveInteger(cc.Type)) { cc.Value = !ExpressionHelper.IsIntegralZero(cc); cc.Type = platformType.SystemBoolean; return(cc); } var conditional = expression as Conditional; if (conditional != null) { conditional.ResultIfTrue = ConvertToBoolean(conditional.ResultIfTrue); conditional.ResultIfFalse = ConvertToBoolean(conditional.ResultIfFalse); conditional.Type = platformType.SystemBoolean; return(conditional); } object /*?*/ val = null; ITypeReference type = platformType.SystemObject; ITypeReference expressionType = expression.Type; IExpression rightOperand = null; // zero or null, but has to be type-specific switch (expressionType.TypeCode) { case PrimitiveTypeCode.Boolean: { var addrDeref = expression as AddressDereference; Conversion conversion; IManagedPointerTypeReference mgdPtr; if (addrDeref != null && (conversion = addrDeref.Address as Conversion) != null && (mgdPtr = conversion.ValueToConvert.Type as IManagedPointerTypeReference) != null) { expressionType = mgdPtr.TargetType; addrDeref.Address = conversion.ValueToConvert; addrDeref.Type = expressionType; expression = addrDeref; goto default; } return(expression); } case PrimitiveTypeCode.Char: val = (char)0; type = platformType.SystemChar; break; case PrimitiveTypeCode.Float32: val = (float)0; type = platformType.SystemFloat32; break; case PrimitiveTypeCode.Float64: val = (double)0; type = platformType.SystemFloat64; break; case PrimitiveTypeCode.Int16: val = (short)0; type = platformType.SystemInt16; break; case PrimitiveTypeCode.Int32: val = (int)0; type = platformType.SystemInt32; break; case PrimitiveTypeCode.Int64: val = (long)0; type = platformType.SystemInt64; break; case PrimitiveTypeCode.Int8: val = (sbyte)0; type = platformType.SystemInt8; break; case PrimitiveTypeCode.IntPtr: val = IntPtr.Zero; type = platformType.SystemIntPtr; break; case PrimitiveTypeCode.UInt16: val = (ushort)0; type = platformType.SystemUInt16; break; case PrimitiveTypeCode.UInt32: val = (uint)0; type = platformType.SystemUInt32; break; case PrimitiveTypeCode.UInt64: val = (ulong)0; type = platformType.SystemUInt64; break; case PrimitiveTypeCode.UInt8: val = (byte)0; type = platformType.SystemUInt8; break; case PrimitiveTypeCode.UIntPtr: val = UIntPtr.Zero; type = platformType.SystemUIntPtr; break; default: rightOperand = new DefaultValue() { DefaultValueType = expressionType, Type = expressionType, }; break; } if (rightOperand == null) { rightOperand = new CompileTimeConstant() { Value = val, Type = type, }; } NotEquality result = new NotEquality() { LeftOperand = expression, RightOperand = rightOperand, Type = platformType.SystemBoolean, }; return(result); }
private Expression ParseRelationalExpression(TokenSet followers) { TokenSet followerOrRelational = followers|Parser.RelationalOperators; Expression result = this.ParseAdditiveExpression(followerOrRelational); while (Parser.RelationalOperators[this.currentToken]) { SourceLocationBuilder slb = new SourceLocationBuilder(result.SourceLocation); Token operatorToken = this.currentToken; this.GetNextToken(); Expression operand2 = this.ParseAdditiveExpression(followerOrRelational); slb.UpdateToSpan(operand2.SourceLocation); switch (operatorToken){ case Token.Equals: result = new Equality(result, operand2, slb); break; case Token.GreaterThan: result = new GreaterThan(result, operand2, slb); break; case Token.GreaterThanEqualTo: result = new GreaterThanOrEqual(result, operand2, slb); break; case Token.LessThan: result = new LessThan(result, operand2, slb); break; case Token.LessThanEqualTo: result = new LessThanOrEqual(result, operand2, slb); break; case Token.NotEqualTo: result = new NotEquality(result, operand2, slb); break; } } //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile; return result; }