GetValue() public abstract method

This is used to obtain the actual value of the literal cast into an object.
public abstract GetValue ( ) : object
return object
Beispiel #1
0
        public virtual Constant CreateConstantReference(Location loc)
        {
            if (value == null)
            {
                return(null);
            }

            return(Constant.CreateConstant(value.Type, value.GetValue(), loc));
        }
Beispiel #2
0
        public static CustomAttributeBuilder CreateDecimalConstantAttribute(Constant c)
        {
            PredefinedAttribute pa = PredefinedAttributes.Get.DecimalConstant;
            if (pa.Constructor == null &&
                !pa.ResolveConstructor (c.Location, TypeManager.byte_type, TypeManager.byte_type,
                    TypeManager.uint32_type, TypeManager.uint32_type, TypeManager.uint32_type))
                return null;

            Decimal d = (Decimal) c.GetValue ();
            int [] bits = Decimal.GetBits (d);
            object [] args = new object [] {
                (byte) (bits [3] >> 16),
                (byte) (bits [3] >> 31),
                (uint) bits [2], (uint) bits [1], (uint) bits [0]
            };

            return new CustomAttributeBuilder (pa.Constructor, args);
        }
Beispiel #3
0
        public virtual void ApplyAttributes(MethodBuilder mb, ConstructorBuilder cb, int index)
        {
            if (mb == null)
            {
                builder = cb.DefineParameter(index, Attributes, Name);
            }
            else
            {
                builder = mb.DefineParameter(index, Attributes, Name);
            }

            if (OptAttributes != null)
            {
                OptAttributes.Emit();
            }

            if (HasDefaultValue)
            {
                //
                // Emit constant values for true constants only, the other
                // constant-like expressions will rely on default value expression
                //
                Constant c = default_expr as Constant;
                if (c != null)
                {
                    if (default_expr.Type == TypeManager.decimal_type)
                    {
                        builder.SetCustomAttribute(Const.CreateDecimalConstantAttribute(c));
                    }
                    else
                    {
                        builder.SetConstant(c.GetValue());
                    }
                }
            }

            if (TypeManager.IsDynamicType(parameter_type))
            {
                PredefinedAttributes.Get.Dynamic.EmitAttribute(builder, Location);
            }
        }
Beispiel #4
0
        public static CustomAttributeBuilder CreateDecimalConstantAttribute(Constant c)
        {
            PredefinedAttribute pa = PredefinedAttributes.Get.DecimalConstant;

            if (pa.Constructor == null &&
                !pa.ResolveConstructor(c.Location, TypeManager.byte_type, TypeManager.byte_type,
                                       TypeManager.uint32_type, TypeManager.uint32_type, TypeManager.uint32_type))
            {
                return(null);
            }

            Decimal d = (Decimal)c.GetValue();

            int []    bits = Decimal.GetBits(d);
            object [] args = new object [] {
                (byte)(bits [3] >> 16),
                (byte)(bits [3] >> 31),
                (uint)bits [2], (uint)bits [1], (uint)bits [0]
            };

            return(new CustomAttributeBuilder(pa.Constructor, args));
        }
Beispiel #5
0
			public override object Visit (Constant constant)
			{
				var result = new PrimitiveExpression (constant.GetValue (), Convert (constant.Location), constant.AsString ().Length);
				return result;
			}
Beispiel #6
0
			public override object Visit(Constant constant)
			{
				if (constant.GetValue() == null)
					return new NullReferenceExpression(Convert(constant.Location));
				string literalValue;
				var literalConstant = constant as ILiteralConstant;
				literalValue = literalConstant != null ? new string(literalConstant.ParsedValue) : constant.GetValueAsLiteral();
				object val = constant.GetValue();
				if (val is bool)
					literalValue = (bool)val ? "true" : "false";
				var result = new PrimitiveExpression(val, Convert(constant.Location), literalValue);
				return result;
			}
				public override object Visit (Constant constant)
				{
					return new CodePrimitiveExpression (constant.GetValue ());
				}
        public virtual void ApplyAttributes(MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
        {
            if (builder != null)
            {
                throw new InternalErrorException("builder already exists");
            }

            var pattrs = ParametersCompiled.GetParameterAttribute(modFlags);

            if (HasOptionalExpression)
            {
                pattrs |= ParameterAttributes.Optional;
            }

            if (mb == null)
            {
                builder = cb.DefineParameter(index, pattrs, Name);
            }
            else
            {
                builder = mb.DefineParameter(index, pattrs, Name);
            }

            if (OptAttributes != null)
            {
                OptAttributes.Emit();
            }

            if (HasDefaultValue)
            {
                //
                // Emit constant values for true constants only, the other
                // constant-like expressions will rely on default value expression
                //
                var      def_value = DefaultValue;
                Constant c         = def_value != null ? def_value.Child as Constant : default_expr as Constant;
                if (c != null)
                {
                    if (c.Type.BuiltinType == BuiltinTypeSpec.Type.Decimal)
                    {
                        pa.DecimalConstant.EmitAttribute(builder, (decimal)c.GetValue(), c.Location);
                    }
                    else
                    {
                        builder.SetConstant(c.GetValue());
                    }
                }
                else if (default_expr.Type.IsStruct)
                {
                    //
                    // Handles special case where default expression is used with value-type
                    //
                    // void Foo (S s = default (S)) {}
                    //
                    builder.SetConstant(null);
                }
            }

            if (parameter_type != null)
            {
                if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                {
                    pa.Dynamic.EmitAttribute(builder);
                }
                else if (parameter_type.HasDynamicElement)
                {
                    pa.Dynamic.EmitAttribute(builder, parameter_type, Location);
                }
            }
        }
		/// <summary>
		///   Constant expression folder for binary operations.
		///
		///   Returns null if the expression can not be folded.
		/// </summary>
		static public Constant BinaryFold (ResolveContext ec, Binary.Operator oper,
						     Constant left, Constant right, Location loc)
		{
			Constant result = null;

			if (left is EmptyConstantCast)
				return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);

			if (left is SideEffectConstant) {
				result = BinaryFold (ec, oper, ((SideEffectConstant) left).value, right, loc);
				if (result == null)
					return null;
				return new SideEffectConstant (result, left, loc);
			}

			if (right is EmptyConstantCast)
				return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);

			if (right is SideEffectConstant) {
				result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).value, loc);
				if (result == null)
					return null;
				return new SideEffectConstant (result, right, loc);
			}

			TypeSpec lt = left.Type;
			TypeSpec rt = right.Type;
			bool bool_res;

			if (lt.BuiltinType == BuiltinTypeSpec.Type.Bool && lt == rt) {
				bool lv = (bool) left.GetValue ();
				bool rv = (bool) right.GetValue ();			
				switch (oper) {
				case Binary.Operator.BitwiseAnd:
				case Binary.Operator.LogicalAnd:
					return new BoolConstant (ec.BuiltinTypes, lv && rv, left.Location);
				case Binary.Operator.BitwiseOr:
				case Binary.Operator.LogicalOr:
					return new BoolConstant (ec.BuiltinTypes, lv || rv, left.Location);
				case Binary.Operator.ExclusiveOr:
					return new BoolConstant (ec.BuiltinTypes, lv ^ rv, left.Location);
				case Binary.Operator.Equality:
					return new BoolConstant (ec.BuiltinTypes, lv == rv, left.Location);
				case Binary.Operator.Inequality:
					return new BoolConstant (ec.BuiltinTypes, lv != rv, left.Location);
				}
				return null;
			}

			//
			// During an enum evaluation, none of the rules are valid
			// Not sure whether it is bug in csc or in documentation
			//
			if (ec.HasSet (ResolveContext.Options.EnumScope)){
				if (left is EnumConstant)
					left = ((EnumConstant) left).Child;
				
				if (right is EnumConstant)
					right = ((EnumConstant) right).Child;
			} else if (left is EnumConstant && rt == lt) {
				switch (oper){
					///
					/// E operator |(E x, E y);
					/// E operator &(E x, E y);
					/// E operator ^(E x, E y);
					/// 
					case Binary.Operator.BitwiseOr:
					case Binary.Operator.BitwiseAnd:
					case Binary.Operator.ExclusiveOr:
						result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
						if (result != null)
							result = result.TryReduce (ec, lt);
						return result;

					///
					/// U operator -(E x, E y);
					/// 
					case Binary.Operator.Subtraction:
						result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
						if (result != null)
							result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt));
						return result;

					///
					/// bool operator ==(E x, E y);
					/// bool operator !=(E x, E y);
					/// bool operator <(E x, E y);
					/// bool operator >(E x, E y);
					/// bool operator <=(E x, E y);
					/// bool operator >=(E x, E y);
					/// 
					case Binary.Operator.Equality:				
					case Binary.Operator.Inequality:
					case Binary.Operator.LessThan:				
					case Binary.Operator.GreaterThan:
					case Binary.Operator.LessThanOrEqual:				
					case Binary.Operator.GreaterThanOrEqual:
						return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
				}
				return null;
			}

			switch (oper){
			case Binary.Operator.BitwiseOr:
				//
				// bool? operator &(bool? x, bool? y);
				//
				if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
					(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) {
					var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);

					// false | null => null
					// null | false => null
					if ((right is NullLiteral && left.IsDefaultValue) || (left is NullLiteral && right.IsDefaultValue))
						return Nullable.LiftedNull.CreateFromExpression (ec, b);

					// true | null => true
					// null | true => true
					return ReducedExpression.Create (new BoolConstant (ec.BuiltinTypes, true, loc), b);					
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				if (left is IntConstant){
					int res = ((IntConstant) left).Value | ((IntConstant) right).Value;

					return new IntConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is UIntConstant){
					uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;

					return new UIntConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is LongConstant){
					long res = ((LongConstant)left).Value | ((LongConstant)right).Value;

					return new LongConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is ULongConstant){
					ulong res = ((ULongConstant)left).Value |
						((ULongConstant)right).Value;

					return new ULongConstant (ec.BuiltinTypes, res, left.Location);
				}
				break;
				
			case Binary.Operator.BitwiseAnd:
				//
				// bool? operator &(bool? x, bool? y);
				//
				if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
					(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) {
					var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);

					// false & null => false
					// null & false => false
					if ((right is NullLiteral && left.IsDefaultValue) || (left is NullLiteral && right.IsDefaultValue))
						return ReducedExpression.Create (new BoolConstant (ec.BuiltinTypes, false, loc), b);

					// true & null => null
					// null & true => null
					return Nullable.LiftedNull.CreateFromExpression (ec, b);
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;
				
				///
				/// int operator &(int x, int y);
				/// uint operator &(uint x, uint y);
				/// long operator &(long x, long y);
				/// ulong operator &(ulong x, ulong y);
				///
				if (left is IntConstant){
					int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
					return new IntConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is UIntConstant){
					uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
					return new UIntConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is LongConstant){
					long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
					return new LongConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is ULongConstant){
					ulong res = ((ULongConstant)left).Value &
						((ULongConstant)right).Value;

					return new ULongConstant (ec.BuiltinTypes, res, left.Location);
				}
				break;

			case Binary.Operator.ExclusiveOr:
				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;
				
				if (left is IntConstant){
					int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
					return new IntConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is UIntConstant){
					uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;

					return new UIntConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is LongConstant){
					long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;

					return new LongConstant (ec.BuiltinTypes, res, left.Location);
				}
				if (left is ULongConstant){
					ulong res = ((ULongConstant)left).Value ^
						((ULongConstant)right).Value;

					return new ULongConstant (ec.BuiltinTypes, res, left.Location);
				}
				break;

			case Binary.Operator.Addition:
				if (lt == InternalType.NullLiteral)
					return right;

				if (rt == InternalType.NullLiteral)
					return left;

				//
				// If both sides are strings, then concatenate, if
				// one is a string, and the other is not, then defer
				// to runtime concatenation
				//
				if (lt.BuiltinType == BuiltinTypeSpec.Type.String || rt.BuiltinType == BuiltinTypeSpec.Type.String){
					if (lt == rt)
						return new StringConstant (ec.BuiltinTypes, (string)left.GetValue () + (string)right.GetValue (),
							left.Location);
					
					return null;
				}

				//
				// handle "E operator + (E x, U y)"
				// handle "E operator + (Y y, E x)"
				//
				EnumConstant lc = left as EnumConstant;
				EnumConstant rc = right as EnumConstant;
				if (lc != null || rc != null){
					if (lc == null) {
						lc = rc;
						lt = lc.Type;
						right = left;
					}

					// U has to be implicitly convetible to E.base
					right = right.ConvertImplicitly (lc.Child.Type);
					if (right == null)
						return null;

					result = BinaryFold (ec, oper, lc.Child, right, loc);
					if (result == null)
						return null;

					result = result.TryReduce (ec, lt);
					if (result == null)
						return null;

					return new EnumConstant (result, lt);
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value +
								       ((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value +
									 ((DoubleConstant) right).Value);

						return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
					}
					if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value +
								       ((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value +
									 ((FloatConstant) right).Value);

						result = new FloatConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value +
								       ((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value +
									 ((ULongConstant) right).Value);

						result = new ULongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value +
								       ((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value +
									 ((LongConstant) right).Value);

						result = new LongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value +
								       ((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value +
									 ((UIntConstant) right).Value);

						result = new UIntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value +
								       ((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value +
									 ((IntConstant) right).Value);

						result = new IntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value +
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value +
								((DecimalConstant) right).Value);

						result = new DecimalConstant (ec.BuiltinTypes, res, left.Location);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (ec, loc);
				}

				return result;

			case Binary.Operator.Subtraction:
				//
				// handle "E operator - (E x, U y)"
				// handle "E operator - (Y y, E x)"
				//
				lc = left as EnumConstant;
				rc = right as EnumConstant;
				if (lc != null || rc != null){
					if (lc == null) {
						lc = rc;
						lt = lc.Type;
						right = left;
					}

					// U has to be implicitly convetible to E.base
					right = right.ConvertImplicitly (lc.Child.Type);
					if (right == null)
						return null;

					result = BinaryFold (ec, oper, lc.Child, right, loc);
					if (result == null)
						return null;

					result = result.TryReduce (ec, lt);
					if (result == null)
						return null;

					return new EnumConstant (result, lt);
				}

				if (left is NullLiteral && right is NullLiteral) {
					var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
					lifted_int.ResolveAsType (ec);
					return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value -
								       ((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value -
									 ((DoubleConstant) right).Value);

						result = new DoubleConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value -
								       ((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value -
									 ((FloatConstant) right).Value);

						result = new FloatConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value -
								       ((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value -
									 ((ULongConstant) right).Value);

						result = new ULongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value -
								       ((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value -
									 ((LongConstant) right).Value);

						result = new LongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value -
								       ((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value -
									 ((UIntConstant) right).Value);

						result = new UIntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value -
								       ((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value -
									 ((IntConstant) right).Value);

						result = new IntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value -
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value -
								((DecimalConstant) right).Value);

						return new DecimalConstant (ec.BuiltinTypes, res, left.Location);
					} else {
						throw new Exception ( "Unexepected subtraction input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (ec, loc);
				}

				return result;
				
			case Binary.Operator.Multiply:
				if (left is NullLiteral && right is NullLiteral) {
					var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
					lifted_int.ResolveAsType (ec);
					return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value *
								((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value *
								((DoubleConstant) right).Value);

						return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value *
								((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value *
								((FloatConstant) right).Value);

						return new FloatConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value *
								((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value *
								((ULongConstant) right).Value);

						return new ULongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value *
								((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value *
								((LongConstant) right).Value);

						return new LongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value *
								((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value *
								((UIntConstant) right).Value);

						return new UIntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value *
								((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value *
								((IntConstant) right).Value);

						return new IntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value *
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value *
								((DecimalConstant) right).Value);

						return new DecimalConstant (ec.BuiltinTypes, res, left.Location);
					} else {
						throw new Exception ( "Unexepected multiply input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (ec, loc);
				}
				break;

			case Binary.Operator.Division:
				if (left is NullLiteral && right is NullLiteral) {
					var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
					lifted_int.ResolveAsType (ec);
					return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value /
								((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value /
								((DoubleConstant) right).Value);

						return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value /
								((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value /
								((FloatConstant) right).Value);

						return new FloatConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value /
								((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value /
								((ULongConstant) right).Value);

						return new ULongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value /
								((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value /
								((LongConstant) right).Value);

						return new LongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value /
								((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value /
								((UIntConstant) right).Value);

						return new UIntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value /
								((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value /
								((IntConstant) right).Value);

						return new IntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value /
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value /
								((DecimalConstant) right).Value);

						return new DecimalConstant (ec.BuiltinTypes, res, left.Location);
					} else {
						throw new Exception ( "Unexepected division input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (ec, loc);

				} catch (DivideByZeroException) {
					ec.Report.Error (20, loc, "Division by constant zero");
				}
				
				break;
				
			case Binary.Operator.Modulus:
				if (left is NullLiteral && right is NullLiteral) {
					var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
					lifted_int.ResolveAsType (ec);
					return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value %
								       ((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value %
									 ((DoubleConstant) right).Value);

						return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value %
								       ((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value %
									 ((FloatConstant) right).Value);

						return new FloatConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value %
								       ((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value %
									 ((ULongConstant) right).Value);

						return new ULongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value %
								       ((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value %
									 ((LongConstant) right).Value);

						return new LongConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value %
								       ((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value %
									 ((UIntConstant) right).Value);

						return new UIntConstant (ec.BuiltinTypes, res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value %
								       ((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value %
									 ((IntConstant) right).Value);

						return new IntConstant (ec.BuiltinTypes, res, left.Location);
					} else {
						throw new Exception ( "Unexepected modulus input: " + left);
					}
				} catch (DivideByZeroException){
					ec.Report.Error (20, loc, "Division by constant zero");
				} catch (OverflowException){
					Error_CompileTimeOverflow (ec, loc);
				}
				break;

				//
				// There is no overflow checking on left shift
				//
			case Binary.Operator.LeftShift:
				if (left is NullLiteral && right is NullLiteral) {
					var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
					lifted_int.ResolveAsType (ec);
					return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
				}

				IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
				if (ic == null){
					Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
					return null;
				}

				int lshift_val = ic.Value;
				switch (left.Type.BuiltinType) {
				case BuiltinTypeSpec.Type.ULong:
					return new ULongConstant (ec.BuiltinTypes, ((ULongConstant) left).Value << lshift_val, left.Location);
				case BuiltinTypeSpec.Type.Long:
					return new LongConstant (ec.BuiltinTypes, ((LongConstant) left).Value << lshift_val, left.Location);
				case BuiltinTypeSpec.Type.UInt:
					return new UIntConstant (ec.BuiltinTypes, ((UIntConstant) left).Value << lshift_val, left.Location);
				}

				// null << value => null
				if (left is NullLiteral)
					return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);

				left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
				if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
					return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value << lshift_val, left.Location);

				Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
				break;

				//
				// There is no overflow checking on right shift
				//
			case Binary.Operator.RightShift:
				if (left is NullLiteral && right is NullLiteral) {
					var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
					lifted_int.ResolveAsType (ec);
					return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
				}

				IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
				if (sic == null){
					Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc); ;
					return null;
				}
				int rshift_val = sic.Value;
				switch (left.Type.BuiltinType) {
				case BuiltinTypeSpec.Type.ULong:
					return new ULongConstant (ec.BuiltinTypes, ((ULongConstant) left).Value >> rshift_val, left.Location);
				case BuiltinTypeSpec.Type.Long:
					return new LongConstant (ec.BuiltinTypes, ((LongConstant) left).Value >> rshift_val, left.Location);
				case BuiltinTypeSpec.Type.UInt:
					return new UIntConstant (ec.BuiltinTypes, ((UIntConstant) left).Value >> rshift_val, left.Location);
				}

				// null >> value => null
				if (left is NullLiteral)
					return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);

				left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
				if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
					return new IntConstant (ec.BuiltinTypes, ((IntConstant) left).Value >> rshift_val, left.Location);

				Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
				break;

			case Binary.Operator.Equality:
				if (TypeSpec.IsReferenceType (lt) && TypeSpec.IsReferenceType (rt) ||
					(left is Nullable.LiftedNull && right.IsNull) ||
					(right is Nullable.LiftedNull && left.IsNull)) {
					if (left.IsNull || right.IsNull) {
						return ReducedExpression.Create (
							new BoolConstant (ec.BuiltinTypes, left.IsNull == right.IsNull, left.Location),
							new Binary (oper, left, right));
					}

					if (left is StringConstant && right is StringConstant)
						return new BoolConstant (ec.BuiltinTypes,
							((StringConstant) left).Value == ((StringConstant) right).Value, left.Location);

					return null;
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value ==
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value ==
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value ==
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value ==
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value ==
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value ==
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);

			case Binary.Operator.Inequality:
				if (TypeSpec.IsReferenceType (lt) && TypeSpec.IsReferenceType (rt) ||
					(left is Nullable.LiftedNull && right.IsNull) ||
					(right is Nullable.LiftedNull && left.IsNull)) {
					if (left.IsNull || right.IsNull) {
						return ReducedExpression.Create (
							new BoolConstant (ec.BuiltinTypes, left.IsNull != right.IsNull, left.Location),
							new Binary (oper, left, right));
					}

					if (left is StringConstant && right is StringConstant)
						return new BoolConstant (ec.BuiltinTypes,
							((StringConstant) left).Value != ((StringConstant) right).Value, left.Location);

					return null;
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value !=
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value !=
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value !=
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value !=
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value !=
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value !=
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);

			case Binary.Operator.LessThan:
				if (right is NullLiteral) {
					if (left is NullLiteral) {
						var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
						lifted_int.ResolveAsType (ec);
						return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
					}

					if (left is Nullable.LiftedNull) {
						return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
					}
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value <
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value <
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value <
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value <
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value <
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value <
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);
				
			case Binary.Operator.GreaterThan:
				if (right is NullLiteral) {
					if (left is NullLiteral) {
						var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
						lifted_int.ResolveAsType (ec);
						return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
					}

					if (left is Nullable.LiftedNull) {
						return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
					}
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value >
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value >
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value >
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value >
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value >
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value >
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);

			case Binary.Operator.GreaterThanOrEqual:
				if (right is NullLiteral) {
					if (left is NullLiteral) {
						var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
						lifted_int.ResolveAsType (ec);
						return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
					}

					if (left is Nullable.LiftedNull) {
						return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
					}
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value >=
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value >=
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value >=
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value >=
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value >=
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value >=
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);

			case Binary.Operator.LessThanOrEqual:
				if (right is NullLiteral) {
					if (left is NullLiteral) {
						var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
						lifted_int.ResolveAsType (ec);
						return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
					}

					if (left is Nullable.LiftedNull) {
						return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
					}
				}

				if (!DoBinaryNumericPromotions (ec, ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value <=
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value <=
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value <=
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value <=
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value <=
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value <=
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);
			}
					
			return null;
		}
			public override object Visit (Constant constant)
			{
				if (constant.GetValue () == null) 
					return new NullReferenceExpression (Convert (constant.Location));
				string literalValue;
				if (constant is ILiteralConstant) {
					literalValue = new string (((ILiteralConstant)constant).ParsedValue);
				} else {
					literalValue = constant.GetValueAsLiteral ();
				}
				var result = new PrimitiveExpression (constant.GetValue (), Convert (constant.Location), literalValue);
				return result;
			}
Beispiel #11
0
			public override object Visit (Constant constant)
			{
				if (constant.GetValue () == null) 
					return new NullReferenceExpression (Convert (constant.Location));
				var result = new PrimitiveExpression (constant.GetValue (), Convert (constant.Location), constant.GetValueAsLiteral ().Length);
				return result;
			}
		// <summary>
		//   This routine will attempt to simplify the unary expression when the
		//   argument is a constant.
		// </summary>
		Constant TryReduceConstant (ResolveContext ec, Constant e)
		{
			if (e is EmptyConstantCast)
				return TryReduceConstant (ec, ((EmptyConstantCast) e).child);
			
			if (e is SideEffectConstant) {
				Constant r = TryReduceConstant (ec, ((SideEffectConstant) e).value);
				return r == null ? null : new SideEffectConstant (r, e, r.Location);
			}

			Type expr_type = e.Type;
			
			switch (Oper){
			case Operator.UnaryPlus:
				// Unary numeric promotions
				if (expr_type == TypeManager.byte_type)
					return new IntConstant (((ByteConstant)e).Value, e.Location);
				if (expr_type == TypeManager.sbyte_type)
					return new IntConstant (((SByteConstant)e).Value, e.Location);
				if (expr_type == TypeManager.short_type)
					return new IntConstant (((ShortConstant)e).Value, e.Location);
				if (expr_type == TypeManager.ushort_type)
					return new IntConstant (((UShortConstant)e).Value, e.Location);
				if (expr_type == TypeManager.char_type)
					return new IntConstant (((CharConstant)e).Value, e.Location);
				
				// Predefined operators
				if (expr_type == TypeManager.int32_type || expr_type == TypeManager.uint32_type ||
				    expr_type == TypeManager.int64_type || expr_type == TypeManager.uint64_type ||
				    expr_type == TypeManager.float_type || expr_type == TypeManager.double_type ||
				    expr_type == TypeManager.decimal_type) {
					return e;
				}
				
				return null;
				
			case Operator.UnaryNegation:
				// Unary numeric promotions
				if (expr_type == TypeManager.byte_type)
					return new IntConstant (-((ByteConstant)e).Value, e.Location);
				if (expr_type == TypeManager.sbyte_type)
					return new IntConstant (-((SByteConstant)e).Value, e.Location);
				if (expr_type == TypeManager.short_type)
					return new IntConstant (-((ShortConstant)e).Value, e.Location);
				if (expr_type == TypeManager.ushort_type)
					return new IntConstant (-((UShortConstant)e).Value, e.Location);
				if (expr_type == TypeManager.char_type)
					return new IntConstant (-((CharConstant)e).Value, e.Location);
				
				// Predefined operators
				if (expr_type == TypeManager.int32_type) {
					int value = ((IntConstant)e).Value;
					if (value == int.MinValue) {
						if (ec.ConstantCheckState) {
							ConstantFold.Error_CompileTimeOverflow (ec, loc);
							return null;
						}
						return e;
					}
					return new IntConstant (-value, e.Location);
				}
				if (expr_type == TypeManager.int64_type) {
					long value = ((LongConstant)e).Value;
					if (value == long.MinValue) {
						if (ec.ConstantCheckState) {
							ConstantFold.Error_CompileTimeOverflow (ec, loc);
							return null;
						}
						return e;
					}
					return new LongConstant (-value, e.Location);
				}
				
				if (expr_type == TypeManager.uint32_type) {
					UIntLiteral uil = e as UIntLiteral;
					if (uil != null) {
						if (uil.Value == 2147483648)
							return new IntLiteral (int.MinValue, e.Location);
						return new LongLiteral (-uil.Value, e.Location);
					}
					return new LongConstant (-((UIntConstant)e).Value, e.Location);
				}
				
				if (expr_type == TypeManager.uint64_type) {
					ULongLiteral ull = e as ULongLiteral;
					if (ull != null && ull.Value == 9223372036854775808)
						return new LongLiteral (long.MinValue, e.Location);
					return null;
				}
				
				if (expr_type == TypeManager.float_type) {
					FloatLiteral fl = e as FloatLiteral;
					// For better error reporting
					if (fl != null)
						return new FloatLiteral (-fl.Value, e.Location);

					return new FloatConstant (-((FloatConstant)e).Value, e.Location);
				}
				if (expr_type == TypeManager.double_type) {
					DoubleLiteral dl = e as DoubleLiteral;
					// For better error reporting
					if (dl != null)
						return new DoubleLiteral (-dl.Value, e.Location);

					return new DoubleConstant (-((DoubleConstant)e).Value, e.Location);
				}
				if (expr_type == TypeManager.decimal_type)
					return new DecimalConstant (-((DecimalConstant)e).Value, e.Location);
				
				return null;
				
			case Operator.LogicalNot:
				if (expr_type != TypeManager.bool_type)
					return null;
				
				bool b = (bool)e.GetValue ();
				return new BoolConstant (!b, e.Location);
				
			case Operator.OnesComplement:
				// Unary numeric promotions
				if (expr_type == TypeManager.byte_type)
					return new IntConstant (~((ByteConstant)e).Value, e.Location);
				if (expr_type == TypeManager.sbyte_type)
					return new IntConstant (~((SByteConstant)e).Value, e.Location);
				if (expr_type == TypeManager.short_type)
					return new IntConstant (~((ShortConstant)e).Value, e.Location);
				if (expr_type == TypeManager.ushort_type)
					return new IntConstant (~((UShortConstant)e).Value, e.Location);
				if (expr_type == TypeManager.char_type)
					return new IntConstant (~((CharConstant)e).Value, e.Location);
				
				// Predefined operators
				if (expr_type == TypeManager.int32_type)
					return new IntConstant (~((IntConstant)e).Value, e.Location);
				if (expr_type == TypeManager.uint32_type)
					return new UIntConstant (~((UIntConstant)e).Value, e.Location);
				if (expr_type == TypeManager.int64_type)
					return new LongConstant (~((LongConstant)e).Value, e.Location);
				if (expr_type == TypeManager.uint64_type){
					return new ULongConstant (~((ULongConstant)e).Value, e.Location);
				}
				if (e is EnumConstant) {
					e = TryReduceConstant (ec, ((EnumConstant)e).Child);
					if (e != null)
						e = new EnumConstant (e, expr_type);
					return e;
				}
				return null;
			}
			throw new Exception ("Can not constant fold: " + Oper.ToString());
		}
Beispiel #13
0
        // <summary>
        //   Resolve is used in method definitions
        // </summary>
        public virtual Type Resolve(IMemberContext rc)
        {
            if (parameter_type != null)
            {
                return(parameter_type);
            }

            if (attributes != null)
            {
                attributes.AttachTo(this, rc);
            }

            TypeExpr texpr = TypeName.ResolveAsTypeTerminal(rc, false);

            if (texpr == null)
            {
                return(null);
            }

            parameter_type = texpr.Type;

            // Ignore all checks for dummy members
            AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;

            if (pem != null && pem.IsDummy)
            {
                return(parameter_type);
            }

            if (default_expr != null)
            {
                ResolveContext ec = new ResolveContext(rc);
                default_expr = default_expr.Resolve(ec);
                if (default_expr != null)
                {
                    Constant value = default_expr as Constant;
                    if (value == null)
                    {
                        if (default_expr != null)
                        {
                            bool is_valid = false;
                            if (default_expr is DefaultValueExpression)
                            {
                                is_valid = true;
                            }
                            else if (default_expr is New && ((New)default_expr).IsDefaultValueType)
                            {
                                is_valid = TypeManager.IsEqual(parameter_type, default_expr.Type) ||
                                           (TypeManager.IsNullableType(parameter_type) &&
                                            Convert.ImplicitNulableConversion(ec, default_expr, parameter_type) != EmptyExpression.Null);
                            }
                            else
                            {
                                rc.Compiler.Report.Error(1736, default_expr.Location,
                                                         "The expression being assigned to optional parameter `{0}' must be a constant or default value",
                                                         Name);
                                is_valid = true;
                            }

                            if (!is_valid)
                            {
                                default_expr = null;
                                ec.Compiler.Report.Error(1763, Location,
                                                         "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
                                                         Name, GetSignatureForError());
                            }
                        }
                    }
                    else
                    {
                        Constant c = value.ConvertImplicitly(parameter_type);
                        if (c == null)
                        {
                            if (parameter_type == TypeManager.object_type)
                            {
                                rc.Compiler.Report.Error(1763, Location,
                                                         "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
                                                         Name, GetSignatureForError());
                            }
                            else
                            {
                                rc.Compiler.Report.Error(1750, Location,
                                                         "Optional parameter value `{0}' cannot be converted to parameter type `{1}'",
                                                         value.GetValue(), GetSignatureForError());
                            }
                            default_expr = null;
                        }
                    }
                }
            }

            if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
                TypeManager.IsSpecialType(parameter_type))
            {
                rc.Compiler.Report.Error(1601, Location, "Method or delegate parameter cannot be of type `{0}'",
                                         GetSignatureForError());
                return(null);
            }

            TypeManager.CheckTypeVariance(parameter_type,
                                          (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
                                          rc);

            if (TypeManager.IsGenericParameter(parameter_type))
            {
                return(parameter_type);
            }

            if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute)
            {
                rc.Compiler.Report.Error(721, Location, "`{0}': static types cannot be used as parameters",
                                         texpr.GetSignatureForError());
                return(parameter_type);
            }

            if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || TypeManager.IsDynamicType(parameter_type)))
            {
                rc.Compiler.Report.Error(1103, Location, "The extension method cannot be of type `{0}'",
                                         TypeManager.CSharpName(parameter_type));
            }

            return(parameter_type);
        }
Beispiel #14
0
		/// <summary>
		///   Constant expression folder for binary operations.
		///
		///   Returns null if the expression can not be folded.
		/// </summary>
		static public Constant BinaryFold (EmitContext ec, Binary.Operator oper,
						     Constant left, Constant right, Location loc)
		{
			Constant result = null;

			if (left is EmptyConstantCast)
				return BinaryFold (ec, oper, ((EmptyConstantCast)left).child, right, loc);

			if (left is SideEffectConstant) {
				result = BinaryFold (ec, oper, ((SideEffectConstant) left).value, right, loc);
				if (result == null)
					return null;
				return new SideEffectConstant (result, left, loc);
			}

			if (right is EmptyConstantCast)
				return BinaryFold (ec, oper, left, ((EmptyConstantCast)right).child, loc);

			if (right is SideEffectConstant) {
				result = BinaryFold (ec, oper, left, ((SideEffectConstant) right).value, loc);
				if (result == null)
					return null;
				return new SideEffectConstant (result, right, loc);
			}

			Type lt = left.Type;
			Type rt = right.Type;
			bool bool_res;

			if (lt == TypeManager.bool_type && lt == rt) {
				bool lv = (bool) left.GetValue ();
				bool rv = (bool) right.GetValue ();			
				switch (oper) {
				case Binary.Operator.BitwiseAnd:
				case Binary.Operator.LogicalAnd:
					return new BoolConstant (lv && rv, left.Location);
				case Binary.Operator.BitwiseOr:
				case Binary.Operator.LogicalOr:
					return new BoolConstant (lv || rv, left.Location);
				case Binary.Operator.ExclusiveOr:
					return new BoolConstant (lv ^ rv, left.Location);
				case Binary.Operator.Equality:
					return new BoolConstant (lv == rv, left.Location);
				case Binary.Operator.Inequality:
					return new BoolConstant (lv != rv, left.Location);
				}
				return null;
			}

			//
			// During an enum evaluation, none of the rules are valid
			// Not sure whether it is bug in csc or in documentation
			//
			if (ec.InEnumContext){
				if (left is EnumConstant)
					left = ((EnumConstant) left).Child;
				
				if (right is EnumConstant)
					right = ((EnumConstant) right).Child;
			} else if (left is EnumConstant && rt == lt) {
				switch (oper){
					///
					/// E operator |(E x, E y);
					/// E operator &(E x, E y);
					/// E operator ^(E x, E y);
					/// 
					case Binary.Operator.BitwiseOr:
					case Binary.Operator.BitwiseAnd:
					case Binary.Operator.ExclusiveOr:
						return BinaryFold (ec, oper, ((EnumConstant)left).Child,
								((EnumConstant)right).Child, loc).TryReduce (ec, lt, loc);

					///
					/// U operator -(E x, E y);
					/// 
					case Binary.Operator.Subtraction:
						result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
						return result.TryReduce (ec, ((EnumConstant)left).Child.Type, loc);

					///
					/// bool operator ==(E x, E y);
					/// bool operator !=(E x, E y);
					/// bool operator <(E x, E y);
					/// bool operator >(E x, E y);
					/// bool operator <=(E x, E y);
					/// bool operator >=(E x, E y);
					/// 
					case Binary.Operator.Equality:				
					case Binary.Operator.Inequality:
					case Binary.Operator.LessThan:				
					case Binary.Operator.GreaterThan:
					case Binary.Operator.LessThanOrEqual:				
					case Binary.Operator.GreaterThanOrEqual:
						return BinaryFold(ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
				}
				return null;
			}

			switch (oper){
			case Binary.Operator.BitwiseOr:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				if (left is IntConstant){
					int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
					
					return new IntConstant (res, left.Location);
				}
				if (left is UIntConstant){
					uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
					
					return new UIntConstant (res, left.Location);
				}
				if (left is LongConstant){
					long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
					
					return new LongConstant (res, left.Location);
				}
				if (left is ULongConstant){
					ulong res = ((ULongConstant)left).Value |
						((ULongConstant)right).Value;
					
					return new ULongConstant (res, left.Location);
				}
				break;
				
			case Binary.Operator.BitwiseAnd:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;
				
				///
				/// int operator &(int x, int y);
				/// uint operator &(uint x, uint y);
				/// long operator &(long x, long y);
				/// ulong operator &(ulong x, ulong y);
				///
				if (left is IntConstant){
					int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
					return new IntConstant (res, left.Location);
				}
				if (left is UIntConstant){
					uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
					return new UIntConstant (res, left.Location);
				}
				if (left is LongConstant){
					long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
					return new LongConstant (res, left.Location);
				}
				if (left is ULongConstant){
					ulong res = ((ULongConstant)left).Value &
						((ULongConstant)right).Value;
					
					return new ULongConstant (res, left.Location);
				}
				break;

			case Binary.Operator.ExclusiveOr:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;
				
				if (left is IntConstant){
					int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
					return new IntConstant (res, left.Location);
				}
				if (left is UIntConstant){
					uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
					
					return  new UIntConstant (res, left.Location);
				}
				if (left is LongConstant){
					long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
					
					return new LongConstant (res, left.Location);
				}
				if (left is ULongConstant){
					ulong res = ((ULongConstant)left).Value ^
						((ULongConstant)right).Value;
					
					return new ULongConstant (res, left.Location);
				}
				break;

			case Binary.Operator.Addition:
				//
				// If both sides are strings, then concatenate, if
				// one is a string, and the other is not, then defer
				// to runtime concatenation
				//
				if (lt == TypeManager.string_type || rt == TypeManager.string_type){
					if (lt == TypeManager.string_type && rt == TypeManager.string_type)
						return new StringConstant (
							((StringConstant) left).Value +
							((StringConstant) right).Value, left.Location);
					
					return null;
				}

				if (lt == TypeManager.null_type && lt == rt)
					return left;

				//
				// handle "E operator + (E x, U y)"
				// handle "E operator + (Y y, E x)"
				//
				EnumConstant lc = left as EnumConstant;
				EnumConstant rc = right as EnumConstant;
				if (lc != null || rc != null){
					if (lc == null) {
						lc = rc;
						lt = lc.Type;
						right = left;
					}

					// U has to be implicitly convetible to E.base
					right = right.ConvertImplicitly (lc.Child.Type);
					if (right == null)
						return null;

					result = BinaryFold (ec, oper, lc.Child, right, loc);
					if (result == null)
						return null;

					result = result.TryReduce (ec, lt, loc);
					if (result == null)
						return null;

					return new EnumConstant (result, lt);
				}

				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value +
								       ((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value +
									 ((DoubleConstant) right).Value);
						
						return new DoubleConstant (res, left.Location);
					}
					if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value +
								       ((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value +
									 ((FloatConstant) right).Value);
						
						result = new FloatConstant (res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value +
								       ((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value +
									 ((ULongConstant) right).Value);

						result = new ULongConstant (res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value +
								       ((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value +
									 ((LongConstant) right).Value);
						
						result = new LongConstant (res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value +
								       ((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value +
									 ((UIntConstant) right).Value);
						
						result = new UIntConstant (res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value +
								       ((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value +
									 ((IntConstant) right).Value);

						result = new IntConstant (res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value +
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value +
								((DecimalConstant) right).Value);

						result = new DecimalConstant (res, left.Location);
					} else {
						throw new Exception ( "Unexepected addition input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (loc);
				}

				return result;

			case Binary.Operator.Subtraction:
				//
				// handle "E operator - (E x, U y)"
				// handle "E operator - (Y y, E x)"
				//
				lc = left as EnumConstant;
				rc = right as EnumConstant;
				if (lc != null || rc != null){
					if (lc == null) {
						lc = rc;
						lt = lc.Type;
						right = left;
					}

					// U has to be implicitly convetible to E.base
					right = right.ConvertImplicitly (lc.Child.Type);
					if (right == null)
						return null;

					result = BinaryFold (ec, oper, lc.Child, right, loc);
					if (result == null)
						return null;

					result = result.TryReduce (ec, lt, loc);
					if (result == null)
						return null;

					return new EnumConstant (result, lt);
				}

				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value -
								       ((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value -
									 ((DoubleConstant) right).Value);
						
						result = new DoubleConstant (res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value -
								       ((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value -
									 ((FloatConstant) right).Value);
						
						result = new FloatConstant (res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value -
								       ((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value -
									 ((ULongConstant) right).Value);
						
						result = new ULongConstant (res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value -
								       ((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value -
									 ((LongConstant) right).Value);
						
						result = new LongConstant (res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value -
								       ((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value -
									 ((UIntConstant) right).Value);
						
						result = new UIntConstant (res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value -
								       ((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value -
									 ((IntConstant) right).Value);

						result = new IntConstant (res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value -
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value -
								((DecimalConstant) right).Value);

						return new DecimalConstant (res, left.Location);
					} else {
						throw new Exception ( "Unexepected subtraction input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (loc);
				}

				return result;
				
			case Binary.Operator.Multiply:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value *
								((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value *
								((DoubleConstant) right).Value);
						
						return new DoubleConstant (res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value *
								((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value *
								((FloatConstant) right).Value);
						
						return new FloatConstant (res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value *
								((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value *
								((ULongConstant) right).Value);
						
						return new ULongConstant (res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value *
								((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value *
								((LongConstant) right).Value);
						
						return new LongConstant (res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value *
								((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value *
								((UIntConstant) right).Value);
						
						return new UIntConstant (res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value *
								((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value *
								((IntConstant) right).Value);

						return new IntConstant (res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value *
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value *
								((DecimalConstant) right).Value);

						return new DecimalConstant (res, left.Location);
					} else {
						throw new Exception ( "Unexepected multiply input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (loc);
				}
				break;

			case Binary.Operator.Division:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value /
								((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value /
								((DoubleConstant) right).Value);
						
						return new DoubleConstant (res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value /
								((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value /
								((FloatConstant) right).Value);
						
						return new FloatConstant (res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value /
								((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value /
								((ULongConstant) right).Value);
						
						return new ULongConstant (res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value /
								((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value /
								((LongConstant) right).Value);
						
						return new LongConstant (res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value /
								((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value /
								((UIntConstant) right).Value);
						
						return new UIntConstant (res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value /
								((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value /
								((IntConstant) right).Value);

						return new IntConstant (res, left.Location);
					} else if (left is DecimalConstant) {
						decimal res;

						if (ec.ConstantCheckState)
							res = checked (((DecimalConstant) left).Value /
								((DecimalConstant) right).Value);
						else
							res = unchecked (((DecimalConstant) left).Value /
								((DecimalConstant) right).Value);

						return new DecimalConstant (res, left.Location);
					} else {
						throw new Exception ( "Unexepected division input: " + left);
					}
				} catch (OverflowException){
					Error_CompileTimeOverflow (loc);

				} catch (DivideByZeroException) {
					Report.Error (020, loc, "Division by constant zero");
				}
				
				break;
				
			case Binary.Operator.Modulus:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				try {
					if (left is DoubleConstant){
						double res;
						
						if (ec.ConstantCheckState)
							res = checked (((DoubleConstant) left).Value %
								       ((DoubleConstant) right).Value);
						else
							res = unchecked (((DoubleConstant) left).Value %
									 ((DoubleConstant) right).Value);
						
						return new DoubleConstant (res, left.Location);
					} else if (left is FloatConstant){
						float res;
						
						if (ec.ConstantCheckState)
							res = checked (((FloatConstant) left).Value %
								       ((FloatConstant) right).Value);
						else
							res = unchecked (((FloatConstant) left).Value %
									 ((FloatConstant) right).Value);
						
						return new FloatConstant (res, left.Location);
					} else if (left is ULongConstant){
						ulong res;
						
						if (ec.ConstantCheckState)
							res = checked (((ULongConstant) left).Value %
								       ((ULongConstant) right).Value);
						else
							res = unchecked (((ULongConstant) left).Value %
									 ((ULongConstant) right).Value);
						
						return new ULongConstant (res, left.Location);
					} else if (left is LongConstant){
						long res;
						
						if (ec.ConstantCheckState)
							res = checked (((LongConstant) left).Value %
								       ((LongConstant) right).Value);
						else
							res = unchecked (((LongConstant) left).Value %
									 ((LongConstant) right).Value);
						
						return new LongConstant (res, left.Location);
					} else if (left is UIntConstant){
						uint res;
						
						if (ec.ConstantCheckState)
							res = checked (((UIntConstant) left).Value %
								       ((UIntConstant) right).Value);
						else
							res = unchecked (((UIntConstant) left).Value %
									 ((UIntConstant) right).Value);
						
						return new UIntConstant (res, left.Location);
					} else if (left is IntConstant){
						int res;

						if (ec.ConstantCheckState)
							res = checked (((IntConstant) left).Value %
								       ((IntConstant) right).Value);
						else
							res = unchecked (((IntConstant) left).Value %
									 ((IntConstant) right).Value);

						return new IntConstant (res, left.Location);
					} else {
						throw new Exception ( "Unexepected modulus input: " + left);
					}
				} catch (DivideByZeroException){
					Report.Error (020, loc, "Division by constant zero");
				} catch (OverflowException){
					Error_CompileTimeOverflow (loc);
				}
				break;

				//
				// There is no overflow checking on left shift
				//
			case Binary.Operator.LeftShift:
				IntConstant ic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
				if (ic == null){
					Binary.Error_OperatorCannotBeApplied (left, right, oper, loc);
					return null;
				}

				int lshift_val = ic.Value;
				if (left.Type == TypeManager.uint64_type)
					return new ULongConstant (((ULongConstant)left).Value << lshift_val, left.Location);
				if (left.Type == TypeManager.int64_type)
					return new LongConstant (((LongConstant)left).Value << lshift_val, left.Location);
				if (left.Type == TypeManager.uint32_type)
					return new UIntConstant (((UIntConstant)left).Value << lshift_val, left.Location);

				left = left.ConvertImplicitly (TypeManager.int32_type);
				if (left.Type == TypeManager.int32_type)
					return new IntConstant (((IntConstant)left).Value << lshift_val, left.Location);

				Binary.Error_OperatorCannotBeApplied (left, right, oper, loc);
				break;

				//
				// There is no overflow checking on right shift
				//
			case Binary.Operator.RightShift:
				IntConstant sic = right.ConvertImplicitly (TypeManager.int32_type) as IntConstant;
				if (sic == null){
					Binary.Error_OperatorCannotBeApplied (left, right, oper, loc); ;
					return null;
				}
				int rshift_val = sic.Value;
				if (left.Type == TypeManager.uint64_type)
					return new ULongConstant (((ULongConstant)left).Value >> rshift_val, left.Location);
				if (left.Type == TypeManager.int64_type)
					return new LongConstant (((LongConstant)left).Value >> rshift_val, left.Location);
				if (left.Type == TypeManager.uint32_type)
					return new UIntConstant (((UIntConstant)left).Value >> rshift_val, left.Location);

				left = left.ConvertImplicitly (TypeManager.int32_type);
				if (left.Type == TypeManager.int32_type)
					return new IntConstant (((IntConstant)left).Value >> rshift_val, left.Location);

				Binary.Error_OperatorCannotBeApplied (left, right, oper, loc);
				break;

			case Binary.Operator.Equality:
				if (left is NullLiteral){
					if (right is NullLiteral)
						return new BoolConstant (true, left.Location);
					else if (right is StringConstant)
						return new BoolConstant (
							((StringConstant) right).Value == null, left.Location);
				} else if (right is NullLiteral) {
					if (left is NullLiteral)
						return new BoolConstant (true, left.Location);
					else if (left is StringConstant)
						return new BoolConstant (
							((StringConstant) left).Value == null, left.Location);
				}
				if (left is StringConstant && right is StringConstant){
					return new BoolConstant (
						((StringConstant) left).Value ==
						((StringConstant) right).Value, left.Location);
					
				}

				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value ==
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value ==
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value ==
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value ==
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value ==
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value ==
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (bool_res, left.Location);

			case Binary.Operator.Inequality:
				if (left is NullLiteral) {
					if (right is NullLiteral)
						return new BoolConstant (false, left.Location);
					else if (right is StringConstant)
						return new BoolConstant (
							((StringConstant) right).Value != null, left.Location);
				} else if (right is NullLiteral) {
					if (left is NullLiteral)
						return new BoolConstant (false, left.Location);
					else if (left is StringConstant)
						return new BoolConstant (
							((StringConstant) left).Value != null, left.Location);
				}
				if (left is StringConstant && right is StringConstant){
					return new BoolConstant (
						((StringConstant) left).Value !=
						((StringConstant) right).Value, left.Location);
					
				}

				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value !=
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value !=
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value !=
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value !=
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value !=
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value !=
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (bool_res, left.Location);

			case Binary.Operator.LessThan:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value <
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value <
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value <
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value <
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value <
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value <
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (bool_res, left.Location);
				
			case Binary.Operator.GreaterThan:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value >
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value >
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value >
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value >
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value >
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value >
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (bool_res, left.Location);

			case Binary.Operator.GreaterThanOrEqual:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value >=
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value >=
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value >=
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value >=
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value >=
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value >=
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (bool_res, left.Location);

			case Binary.Operator.LessThanOrEqual:
				if (!DoBinaryNumericPromotions (ref left, ref right))
					return null;

				bool_res = false;
				if (left is DoubleConstant)
					bool_res = ((DoubleConstant) left).Value <=
						((DoubleConstant) right).Value;
				else if (left is FloatConstant)
					bool_res = ((FloatConstant) left).Value <=
						((FloatConstant) right).Value;
				else if (left is ULongConstant)
					bool_res = ((ULongConstant) left).Value <=
						((ULongConstant) right).Value;
				else if (left is LongConstant)
					bool_res = ((LongConstant) left).Value <=
						((LongConstant) right).Value;
				else if (left is UIntConstant)
					bool_res = ((UIntConstant) left).Value <=
						((UIntConstant) right).Value;
				else if (left is IntConstant)
					bool_res = ((IntConstant) left).Value <=
						((IntConstant) right).Value;
				else
					return null;

				return new BoolConstant (bool_res, left.Location);
			}
					
			return null;
		}