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;
    }
Beispiel #2
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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;
 }