// Marek Safar (marek.safar@seznam.cz)
//
// Copyright 2002, 2003 Ximian, Inc.
-// Copyright 2003-2008, Novell, Inc.
+// Copyright 2003-2011, Novell, Inc.
//
using System;
case Binary.Operator.ExclusiveOr:
result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
if (result != null)
- result = result.TryReduce (ec, lt, loc);
+ result = result.Reduce (ec, lt);
return result;
///
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), loc);
+ result = result.Reduce (ec, EnumSpec.GetUnderlyingType (lt));
return result;
///
switch (oper){
case Binary.Operator.BitwiseOr:
//
- // bool? operator &(bool? x, bool? y);
+ // 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, loc).Resolve (ec);
+ var b = new Binary (oper, left, right).ResolveOperator (ec);
// false | null => null
// null | false => null
//
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, loc).Resolve (ec);
+ var b = new Binary (oper, left, right).ResolveOperator (ec);
// false & null => false
// null & false => false
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 both sides are strings, then concatenate
+ //
+ // string operator + (string x, string y)
//
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);
-
+
+ if (lt == InternalType.NullLiteral)
+ return new StringConstant (ec.BuiltinTypes, "" + right.GetValue (), left.Location);
+
+ if (rt == InternalType.NullLiteral)
+ return new StringConstant (ec.BuiltinTypes, left.GetValue () + "", left.Location);
+
return null;
}
+ //
+ // string operator + (string x, object y)
+ //
+ if (lt == InternalType.NullLiteral) {
+ if (rt.BuiltinType == BuiltinTypeSpec.Type.Object)
+ return new StringConstant (ec.BuiltinTypes, "" + right.GetValue (), left.Location);
+
+ if (lt == rt) {
+ ec.Report.Error (34, loc, "Operator `{0}' is ambiguous on operands of type `{1}' and `{2}'",
+ "+", lt.GetSignatureForError (), rt.GetSignatureForError ());
+ return null;
+ }
+
+ return right;
+ }
+
+ //
+ // string operator + (object x, string y)
+ //
+ if (rt == InternalType.NullLiteral) {
+ if (lt.BuiltinType == BuiltinTypeSpec.Type.Object)
+ return new StringConstant (ec.BuiltinTypes, right.GetValue () + "", left.Location);
+
+ return left;
+ }
+
//
// handle "E operator + (E x, U y)"
// handle "E operator + (Y y, E x)"
if (result == null)
return null;
- result = result.TryReduce (ec, lt, loc);
+ result = result.Reduce (ec, lt);
if (result == null)
return null;
return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
}
if (left is FloatConstant){
- float res;
-
+ double a, b, res;
+ a = ((FloatConstant) left).DoubleValue;
+ b = ((FloatConstant) right).DoubleValue;
+
if (ec.ConstantCheckState)
- res = checked (((FloatConstant) left).Value +
- ((FloatConstant) right).Value);
+ res = checked (a + b);
else
- res = unchecked (((FloatConstant) left).Value +
- ((FloatConstant) right).Value);
+ res = unchecked (a + b);
result = new FloatConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is ULongConstant){
if (result == null)
return null;
- result = result.TryReduce (ec, lt, loc);
+ result = result.Reduce (ec, lt);
if (result == null)
return null;
}
if (left is NullLiteral && right is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
result = new DoubleConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is FloatConstant){
- float res;
-
+ double a, b, res;
+ a = ((FloatConstant) left).DoubleValue;
+ b = ((FloatConstant) right).DoubleValue;
+
if (ec.ConstantCheckState)
- res = checked (((FloatConstant) left).Value -
- ((FloatConstant) right).Value);
+ res = checked (a - b);
else
- res = unchecked (((FloatConstant) left).Value -
- ((FloatConstant) right).Value);
+ res = unchecked (a - b);
result = new FloatConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is ULongConstant){
case Binary.Operator.Multiply:
if (left is NullLiteral && right is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is FloatConstant){
- float res;
-
+ double a, b, res;
+ a = ((FloatConstant) left).DoubleValue;
+ b = ((FloatConstant) right).DoubleValue;
+
if (ec.ConstantCheckState)
- res = checked (((FloatConstant) left).Value *
- ((FloatConstant) right).Value);
+ res = checked (a * b);
else
- res = unchecked (((FloatConstant) left).Value *
- ((FloatConstant) right).Value);
+ res = unchecked (a * b);
return new FloatConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is ULongConstant){
case Binary.Operator.Division:
if (left is NullLiteral && right is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is FloatConstant){
- float res;
-
+ double a, b, res;
+ a = ((FloatConstant) left).DoubleValue;
+ b = ((FloatConstant) right).DoubleValue;
+
if (ec.ConstantCheckState)
- res = checked (((FloatConstant) left).Value /
- ((FloatConstant) right).Value);
+ res = checked (a / b);
else
- res = unchecked (((FloatConstant) left).Value /
- ((FloatConstant) right).Value);
+ res = unchecked (a / b);
return new FloatConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is ULongConstant){
case Binary.Operator.Modulus:
if (left is NullLiteral && right is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
return new DoubleConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is FloatConstant){
- float res;
+ double a, b, res;
+ a = ((FloatConstant) left).DoubleValue;
+ b = ((FloatConstant) right).DoubleValue;
if (ec.ConstantCheckState)
- res = checked (((FloatConstant) left).Value %
- ((FloatConstant) right).Value);
+ res = checked (a % b);
else
- res = unchecked (((FloatConstant) left).Value %
- ((FloatConstant) right).Value);
+ res = unchecked (a % b);
return new FloatConstant (ec.BuiltinTypes, res, left.Location);
} else if (left is ULongConstant){
//
case Binary.Operator.LeftShift:
if (left is NullLiteral && right is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
if (ic == null){
- Binary.Error_OperatorCannotBeApplied (ec, left, right, oper, loc);
return null;
}
// null << value => null
if (left is NullLiteral)
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Binary (oper, left, right).ResolveOperator (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;
+ return null;
//
// 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).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (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;
// null >> value => null
if (left is NullLiteral)
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Binary (oper, left, right).ResolveOperator (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;
+ return null;
case Binary.Operator.Equality:
- if (TypeManager.IsReferenceType (lt) && TypeManager.IsReferenceType (rt) ||
+ 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, loc));
+ new Binary (oper, left, right));
}
if (left is StringConstant && right is StringConstant)
bool_res = ((DoubleConstant) left).Value ==
((DoubleConstant) right).Value;
else if (left is FloatConstant)
- bool_res = ((FloatConstant) left).Value ==
- ((FloatConstant) right).Value;
+ bool_res = ((FloatConstant) left).DoubleValue ==
+ ((FloatConstant) right).DoubleValue;
else if (left is ULongConstant)
bool_res = ((ULongConstant) left).Value ==
((ULongConstant) right).Value;
return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);
case Binary.Operator.Inequality:
- if (TypeManager.IsReferenceType (lt) && TypeManager.IsReferenceType (rt) ||
+ 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, loc));
+ new Binary (oper, left, right));
}
if (left is StringConstant && right is StringConstant)
bool_res = ((DoubleConstant) left).Value !=
((DoubleConstant) right).Value;
else if (left is FloatConstant)
- bool_res = ((FloatConstant) left).Value !=
- ((FloatConstant) right).Value;
+ bool_res = ((FloatConstant) left).DoubleValue !=
+ ((FloatConstant) right).DoubleValue;
else if (left is ULongConstant)
bool_res = ((ULongConstant) left).Value !=
((ULongConstant) right).Value;
case Binary.Operator.LessThan:
if (right is NullLiteral) {
if (left is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
- }
-
- if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
}
bool_res = ((DoubleConstant) left).Value <
((DoubleConstant) right).Value;
else if (left is FloatConstant)
- bool_res = ((FloatConstant) left).Value <
- ((FloatConstant) right).Value;
+ bool_res = ((FloatConstant) left).DoubleValue <
+ ((FloatConstant) right).DoubleValue;
else if (left is ULongConstant)
bool_res = ((ULongConstant) left).Value <
((ULongConstant) right).Value;
case Binary.Operator.GreaterThan:
if (right is NullLiteral) {
if (left is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
- }
-
- if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
}
bool_res = ((DoubleConstant) left).Value >
((DoubleConstant) right).Value;
else if (left is FloatConstant)
- bool_res = ((FloatConstant) left).Value >
- ((FloatConstant) right).Value;
+ bool_res = ((FloatConstant) left).DoubleValue >
+ ((FloatConstant) right).DoubleValue;
else if (left is ULongConstant)
bool_res = ((ULongConstant) left).Value >
((ULongConstant) right).Value;
case Binary.Operator.GreaterThanOrEqual:
if (right is NullLiteral) {
if (left is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
- }
-
- if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
}
bool_res = ((DoubleConstant) left).Value >=
((DoubleConstant) right).Value;
else if (left is FloatConstant)
- bool_res = ((FloatConstant) left).Value >=
- ((FloatConstant) right).Value;
+ bool_res = ((FloatConstant) left).DoubleValue >=
+ ((FloatConstant) right).DoubleValue;
else if (left is ULongConstant)
bool_res = ((ULongConstant) left).Value >=
((ULongConstant) right).Value;
case Binary.Operator.LessThanOrEqual:
if (right is NullLiteral) {
if (left is NullLiteral) {
- var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc).ResolveAsTypeTerminal (ec, false);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
- }
-
- if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
+ lifted_int.ResolveAsType (ec);
+ return (Constant) new Binary (oper, lifted_int, right).ResolveOperator (ec);
}
}
bool_res = ((DoubleConstant) left).Value <=
((DoubleConstant) right).Value;
else if (left is FloatConstant)
- bool_res = ((FloatConstant) left).Value <=
- ((FloatConstant) right).Value;
+ bool_res = ((FloatConstant) left).DoubleValue <=
+ ((FloatConstant) right).DoubleValue;
else if (left is ULongConstant)
bool_res = ((ULongConstant) left).Value <=
((ULongConstant) right).Value;
return new BoolConstant (ec.BuiltinTypes, bool_res, left.Location);
}
-
+
return null;
}
}