// Author:
// Miguel de Icaza (miguel@ximian.com)
//
-// (C) 2002 Ximian, Inc.
+// (C) 2002, 2003 Ximian, Inc.
//
using System;
// (long, long)
// (uint, uint)
// (int, int)
+ // (short, short) (Happens with enumerations with underlying short type)
+ // (ushort, ushort) (Happens with enumerations with underlying short type)
//
- static void DoConstantNumericPromotions (Binary.Operator oper,
+ static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
ref Constant left, ref Constant right,
Location loc)
{
// converted to type ulong. or an error ocurrs if the other
// operand is of type sbyte, short, int or long
//
+#if WRONG
Constant match, other;
+#endif
if (left is ULongConstant){
+#if WRONG
other = right;
match = left;
+#endif
if (!(right is ULongConstant))
right = right.ToULong (loc);
} else {
+#if WRONG
other = left;
match = right;
+#endif
left = left.ToULong (loc);
}
// operand is of type sbyte, short or int, the operands are
// converted to type long.
//
- Constant match, other;
- if (left is UIntConstant){
+ Constant other;
+ if (left is UIntConstant)
other = right;
- match = left;
- } else {
+ else
other = left;
- match = right;
- }
// Nothing to do.
if (other is UIntConstant)
return;
- if (other is SByteConstant || other is ShortConstant ||
- other is IntConstant){
+ IntConstant ic = other as IntConstant;
+ if (ic != null){
+ if (ic.Value >= 0){
+ if (left == other)
+ left = new UIntConstant ((uint) ic.Value, ic.Location);
+ else
+ right = new UIntConstant ((uint) ic.Value, ic.Location);
+ return;
+ }
+ }
+
+ if (other is SByteConstant || other is ShortConstant || ic != null){
left = left.ToLong (loc);
right = right.ToLong (loc);
+ } else {
+ left = left.ToUInt (loc);
+ right = left.ToUInt (loc);
}
return;
+ } else if (left is DecimalConstant || right is DecimalConstant) {
+ if (!(left is DecimalConstant))
+ left = left.ToDecimal (loc);
+ else if (!(right is DecimalConstant))
+ right = right.ToDecimal (loc);
+ return;
+ } else if (left is EnumConstant || right is EnumConstant){
+ if (left is EnumConstant)
+ left = ((EnumConstant) left).Child;
+ if (right is EnumConstant)
+ right = ((EnumConstant) right).Child;
+
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+ return;
+
} else {
//
// Force conversions to int32
static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
Constant left, Constant right, Location loc)
{
+ if (left is NullCast)
+ return BinaryFold (ec, oper, ((NullCast)left).child, right, loc);
+
+ if (right is NullCast)
+ return BinaryFold (ec, oper, left, ((NullCast)right).child, loc);
+
Type lt = left.Type;
Type rt = right.Type;
Type result_type = null;
bool bool_res;
-
+
//
// Enumerator folding
//
if (right is EnumConstant)
right = ((EnumConstant) right).Child;
}
-
+
+ if (left is BoolConstant && right is BoolConstant) {
+ bool lv = ((BoolConstant) left ).Value;
+ bool rv = ((BoolConstant) right).Value;
+ 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);
+ default:
+ throw new InternalErrorException ("Invalid operator on booleans: " + oper);
+ }
+ }
+
+ Type wrap_as;
+ Constant result = null;
switch (oper){
case Binary.Operator.BitwiseOr:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
-
+
if (left is IntConstant){
IntConstant v;
int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
- v = new IntConstant (res);
+ v = new IntConstant (res, left.Location);
if (result_type == null)
return v;
else
UIntConstant v;
uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
- v = new UIntConstant (res);
+ v = new UIntConstant (res, left.Location);
if (result_type == null)
return v;
else
LongConstant v;
long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
- v = new LongConstant (res);
+ v = new LongConstant (res, left.Location);
if (result_type == null)
return v;
else
ulong res = ((ULongConstant)left).Value |
((ULongConstant)right).Value;
- v = new ULongConstant (res);
+ v = new ULongConstant (res, left.Location);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
+ } else if (left is UShortConstant){
+ UShortConstant v;
+ ushort res = (ushort) (((UShortConstant)left).Value |
+ ((UShortConstant)right).Value);
+
+ v = new UShortConstant (res, left.Location);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
+ } else if (left is ShortConstant){
+ ShortConstant v;
+ short res = (short) (((ShortConstant)left).Value |
+ ((ShortConstant)right).Value);
+
+ v = new ShortConstant (res, left.Location);
if (result_type == null)
return v;
else
break;
case Binary.Operator.BitwiseAnd:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
IntConstant v;
int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
- v = new IntConstant (res);
+ v = new IntConstant (res, left.Location);
if (result_type == null)
return v;
else
UIntConstant v;
uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
- v = new UIntConstant (res);
+ v = new UIntConstant (res, left.Location);
if (result_type == null)
return v;
else
LongConstant v;
long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
- v = new LongConstant (res);
+ v = new LongConstant (res, left.Location);
if (result_type == null)
return v;
else
ulong res = ((ULongConstant)left).Value &
((ULongConstant)right).Value;
- v = new ULongConstant (res);
+ v = new ULongConstant (res, left.Location);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
+ } else if (left is UShortConstant){
+ UShortConstant v;
+ ushort res = (ushort) (((UShortConstant)left).Value &
+ ((UShortConstant)right).Value);
+
+ v = new UShortConstant (res, left.Location);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
+ } else if (left is ShortConstant){
+ ShortConstant v;
+ short res = (short) (((ShortConstant)left).Value &
+ ((ShortConstant)right).Value);
+
+ v = new ShortConstant (res, left.Location);
if (result_type == null)
return v;
else
break;
case Binary.Operator.ExclusiveOr:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
IntConstant v;
int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
- v = new IntConstant (res);
+ v = new IntConstant (res, left.Location);
if (result_type == null)
return v;
else
UIntConstant v;
uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
- v = new UIntConstant (res);
+ v = new UIntConstant (res, left.Location);
if (result_type == null)
return v;
else
LongConstant v;
long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
- v = new LongConstant (res);
+ v = new LongConstant (res, left.Location);
if (result_type == null)
return v;
else
ulong res = ((ULongConstant)left).Value ^
((ULongConstant)right).Value;
- v = new ULongConstant (res);
+ v = new ULongConstant (res, left.Location);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
+ } else if (left is UShortConstant){
+ UShortConstant v;
+ ushort res = (ushort) (((UShortConstant)left).Value ^
+ ((UShortConstant)right).Value);
+
+ v = new UShortConstant (res, left.Location);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
+ } else if (left is ShortConstant){
+ ShortConstant v;
+ short res = (short)(((ShortConstant)left).Value ^
+ ((ShortConstant)right).Value);
+
+ v = new ShortConstant (res, left.Location);
if (result_type == null)
return v;
else
break;
case Binary.Operator.Addition:
- Constant result;
bool left_is_string = left is StringConstant;
bool right_is_string = right is StringConstant;
// one is a string, and the other is not, then defer
// to runtime concatenation
//
+ wrap_as = null;
if (left_is_string || right_is_string){
if (left_is_string && right_is_string)
return new StringConstant (
((StringConstant) left).Value +
- ((StringConstant) right).Value);
+ ((StringConstant) right).Value, left.Location);
return null;
}
//
// note that E operator + (E x, E y) is invalid
//
- Type wrap_as = null;
if (left is EnumConstant){
if (right is EnumConstant){
return null;
}
- if (((EnumConstant) left).Child.Type != right.Type)
+
+ right = right.ToType (((EnumConstant) left).Child.Type, loc);
+ if (right == null)
return null;
wrap_as = left.Type;
} else if (right is EnumConstant){
- if (((EnumConstant) right).Child.Type != left.Type)
+ left = left.ToType (((EnumConstant) right).Child.Type, loc);
+ if (left == null)
return null;
+
wrap_as = right.Type;
}
result = null;
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
res = unchecked (((DoubleConstant) left).Value +
((DoubleConstant) right).Value);
- result = new DoubleConstant (res);
+ result = new DoubleConstant (res, left.Location);
} else if (left is FloatConstant){
float res;
res = unchecked (((FloatConstant) left).Value +
((FloatConstant) right).Value);
- result = new FloatConstant (res);
+ result = new FloatConstant (res, left.Location);
} else if (left is ULongConstant){
ulong res;
res = unchecked (((ULongConstant) left).Value +
((ULongConstant) right).Value);
- result = new ULongConstant (res);
+ result = new ULongConstant (res, left.Location);
} else if (left is LongConstant){
long res;
res = unchecked (((LongConstant) left).Value +
((LongConstant) right).Value);
- result = new LongConstant (res);
+ result = new LongConstant (res, left.Location);
} else if (left is UIntConstant){
uint res;
res = unchecked (((UIntConstant) left).Value +
((UIntConstant) right).Value);
- result = new UIntConstant (res);
+ result = new UIntConstant (res, left.Location);
} else if (left is IntConstant){
int res;
res = unchecked (((IntConstant) left).Value +
((IntConstant) right).Value);
- result = new IntConstant (res);
+ 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 input: " + left);
+ throw new Exception ( "Unexepected addition input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
}
- if (wrap_as != null)
- return new EnumConstant (result, wrap_as);
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
else
return result;
case Binary.Operator.Subtraction:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ //
+ // handle "E operator - (E x, U y)"
+ // handle "E operator - (Y y, E x)"
+ // handle "U operator - (E x, E y)"
+ //
+ wrap_as = null;
+ if (left is EnumConstant){
+ if (right is EnumConstant){
+ if (left.Type != right.Type) {
+ Binary.Error_OperatorCannotBeApplied (loc, "-", left.Type, right.Type);
+ return null;
+ }
+
+ wrap_as = TypeManager.EnumToUnderlying (left.Type);
+ right = ((EnumConstant) right).Child.ToType (wrap_as, loc);
+ if (right == null)
+ return null;
+
+ left = ((EnumConstant) left).Child.ToType (wrap_as, loc);
+ if (left == null)
+ return null;
+ }
+ else {
+ right = right.ToType (((EnumConstant) left).Child.Type, loc);
+ if (right == null)
+ return null;
+
+ wrap_as = left.Type;
+ }
+ } else if (right is EnumConstant){
+ left = left.ToType (((EnumConstant) right).Child.Type, loc);
+ if (left == null)
+ return null;
+
+ wrap_as = right.Type;
+ }
+
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
res = unchecked (((DoubleConstant) left).Value -
((DoubleConstant) right).Value);
- return new DoubleConstant (res);
+ result = new DoubleConstant (res, left.Location);
} else if (left is FloatConstant){
float res;
res = unchecked (((FloatConstant) left).Value -
((FloatConstant) right).Value);
- return new FloatConstant (res);
+ result = new FloatConstant (res, left.Location);
} else if (left is ULongConstant){
ulong res;
res = unchecked (((ULongConstant) left).Value -
((ULongConstant) right).Value);
- return new ULongConstant (res);
+ result = new ULongConstant (res, left.Location);
} else if (left is LongConstant){
long res;
res = unchecked (((LongConstant) left).Value -
((LongConstant) right).Value);
- return new LongConstant (res);
+ result = new LongConstant (res, left.Location);
} else if (left is UIntConstant){
uint res;
res = unchecked (((UIntConstant) left).Value -
((UIntConstant) right).Value);
- return new UIntConstant (res);
+ result = new UIntConstant (res, left.Location);
} else if (left is IntConstant){
int res;
res = unchecked (((IntConstant) left).Value -
((IntConstant) right).Value);
- return new IntConstant (res);
+ 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 input: " + left);
+ throw new Exception ( "Unexepected subtraction input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
}
- break;
+
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
+
+ return result;
case Binary.Operator.Multiply:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
if (ec.ConstantCheckState)
res = checked (((DoubleConstant) left).Value *
- ((DoubleConstant) right).Value);
+ ((DoubleConstant) right).Value);
else
res = unchecked (((DoubleConstant) left).Value *
- ((DoubleConstant) right).Value);
+ ((DoubleConstant) right).Value);
- return new DoubleConstant (res);
+ return new DoubleConstant (res, left.Location);
} else if (left is FloatConstant){
float res;
if (ec.ConstantCheckState)
res = checked (((FloatConstant) left).Value *
- ((FloatConstant) right).Value);
+ ((FloatConstant) right).Value);
else
res = unchecked (((FloatConstant) left).Value *
- ((FloatConstant) right).Value);
+ ((FloatConstant) right).Value);
- return new FloatConstant (res);
+ return new FloatConstant (res, left.Location);
} else if (left is ULongConstant){
ulong res;
if (ec.ConstantCheckState)
res = checked (((ULongConstant) left).Value *
- ((ULongConstant) right).Value);
+ ((ULongConstant) right).Value);
else
res = unchecked (((ULongConstant) left).Value *
- ((ULongConstant) right).Value);
+ ((ULongConstant) right).Value);
- return new ULongConstant (res);
+ return new ULongConstant (res, left.Location);
} else if (left is LongConstant){
long res;
if (ec.ConstantCheckState)
res = checked (((LongConstant) left).Value *
- ((LongConstant) right).Value);
+ ((LongConstant) right).Value);
else
res = unchecked (((LongConstant) left).Value *
- ((LongConstant) right).Value);
+ ((LongConstant) right).Value);
- return new LongConstant (res);
+ return new LongConstant (res, left.Location);
} else if (left is UIntConstant){
uint res;
if (ec.ConstantCheckState)
res = checked (((UIntConstant) left).Value *
- ((UIntConstant) right).Value);
+ ((UIntConstant) right).Value);
else
res = unchecked (((UIntConstant) left).Value *
- ((UIntConstant) right).Value);
+ ((UIntConstant) right).Value);
- return new UIntConstant (res);
+ return new UIntConstant (res, left.Location);
} else if (left is IntConstant){
int res;
if (ec.ConstantCheckState)
res = checked (((IntConstant) left).Value *
- ((IntConstant) right).Value);
+ ((IntConstant) right).Value);
else
res = unchecked (((IntConstant) left).Value *
- ((IntConstant) right).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 IntConstant (res);
+ return new DecimalConstant (res, left.Location);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected multiply input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
break;
case Binary.Operator.Division:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
if (ec.ConstantCheckState)
res = checked (((DoubleConstant) left).Value /
- ((DoubleConstant) right).Value);
+ ((DoubleConstant) right).Value);
else
res = unchecked (((DoubleConstant) left).Value /
- ((DoubleConstant) right).Value);
+ ((DoubleConstant) right).Value);
- return new DoubleConstant (res);
+ return new DoubleConstant (res, left.Location);
} else if (left is FloatConstant){
float res;
if (ec.ConstantCheckState)
res = checked (((FloatConstant) left).Value /
- ((FloatConstant) right).Value);
+ ((FloatConstant) right).Value);
else
res = unchecked (((FloatConstant) left).Value /
- ((FloatConstant) right).Value);
+ ((FloatConstant) right).Value);
- return new FloatConstant (res);
+ return new FloatConstant (res, left.Location);
} else if (left is ULongConstant){
ulong res;
if (ec.ConstantCheckState)
res = checked (((ULongConstant) left).Value /
- ((ULongConstant) right).Value);
+ ((ULongConstant) right).Value);
else
res = unchecked (((ULongConstant) left).Value /
- ((ULongConstant) right).Value);
+ ((ULongConstant) right).Value);
- return new ULongConstant (res);
+ return new ULongConstant (res, left.Location);
} else if (left is LongConstant){
long res;
if (ec.ConstantCheckState)
res = checked (((LongConstant) left).Value /
- ((LongConstant) right).Value);
+ ((LongConstant) right).Value);
else
res = unchecked (((LongConstant) left).Value /
- ((LongConstant) right).Value);
+ ((LongConstant) right).Value);
- return new LongConstant (res);
+ return new LongConstant (res, left.Location);
} else if (left is UIntConstant){
uint res;
if (ec.ConstantCheckState)
res = checked (((UIntConstant) left).Value /
- ((UIntConstant) right).Value);
+ ((UIntConstant) right).Value);
else
res = unchecked (((UIntConstant) left).Value /
- ((UIntConstant) right).Value);
+ ((UIntConstant) right).Value);
- return new UIntConstant (res);
+ return new UIntConstant (res, left.Location);
} else if (left is IntConstant){
int res;
if (ec.ConstantCheckState)
res = checked (((IntConstant) left).Value /
- ((IntConstant) right).Value);
+ ((IntConstant) right).Value);
else
res = unchecked (((IntConstant) left).Value /
- ((IntConstant) right).Value);
+ ((IntConstant) right).Value);
+
+ return new IntConstant (res, left.Location);
+ } else if (left is DecimalConstant) {
+ decimal res;
- return new IntConstant (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 input: " + left);
+ throw new Exception ( "Unexepected division input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
break;
case Binary.Operator.Modulus:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
res = unchecked (((DoubleConstant) left).Value %
((DoubleConstant) right).Value);
- return new DoubleConstant (res);
+ return new DoubleConstant (res, left.Location);
} else if (left is FloatConstant){
float res;
res = unchecked (((FloatConstant) left).Value %
((FloatConstant) right).Value);
- return new FloatConstant (res);
+ return new FloatConstant (res, left.Location);
} else if (left is ULongConstant){
ulong res;
res = unchecked (((ULongConstant) left).Value %
((ULongConstant) right).Value);
- return new ULongConstant (res);
+ return new ULongConstant (res, left.Location);
} else if (left is LongConstant){
long res;
res = unchecked (((LongConstant) left).Value %
((LongConstant) right).Value);
- return new LongConstant (res);
+ return new LongConstant (res, left.Location);
} else if (left is UIntConstant){
uint res;
res = unchecked (((UIntConstant) left).Value %
((UIntConstant) right).Value);
- return new UIntConstant (res);
+ return new UIntConstant (res, left.Location);
} else if (left is IntConstant){
int res;
res = unchecked (((IntConstant) left).Value %
((IntConstant) right).Value);
- return new IntConstant (res);
+ return new IntConstant (res, left.Location);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected modulus input: " + left);
}
+ } catch (DivideByZeroException){
+ Report.Error (020, loc, "Division by constant zero");
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
}
IntConstant lic;
if ((lic = left.ConvertToInt ()) != null)
- return new IntConstant (lic.Value << lshift_val);
+ return new IntConstant (lic.Value << lshift_val, left.Location);
UIntConstant luic;
if ((luic = left.ConvertToUInt ()) != null)
- return new UIntConstant (luic.Value << lshift_val);
+ return new UIntConstant (luic.Value << lshift_val, left.Location);
LongConstant llc;
if ((llc = left.ConvertToLong ()) != null)
- return new LongConstant (llc.Value << lshift_val);
+ return new LongConstant (llc.Value << lshift_val, left.Location);
ULongConstant lulc;
if ((lulc = left.ConvertToULong ()) != null)
- return new ULongConstant (lulc.Value << lshift_val);
+ return new ULongConstant (lulc.Value << lshift_val, left.Location);
Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
break;
IntConstant ric;
if ((ric = left.ConvertToInt ()) != null)
- return new IntConstant (ric.Value >> rshift_val);
+ return new IntConstant (ric.Value >> rshift_val, left.Location);
UIntConstant ruic;
if ((ruic = left.ConvertToUInt ()) != null)
- return new UIntConstant (ruic.Value >> rshift_val);
+ return new UIntConstant (ruic.Value >> rshift_val, left.Location);
LongConstant rlc;
if ((rlc = left.ConvertToLong ()) != null)
- return new LongConstant (rlc.Value >> rshift_val);
+ return new LongConstant (rlc.Value >> rshift_val, left.Location);
ULongConstant rulc;
if ((rulc = left.ConvertToULong ()) != null)
- return new ULongConstant (rulc.Value >> rshift_val);
+ return new ULongConstant (rulc.Value >> rshift_val, left.Location);
Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
break;
- case Binary.Operator.LogicalAnd:
- if (left is BoolConstant && right is BoolConstant){
- return new BoolConstant (
- ((BoolConstant) left).Value &&
- ((BoolConstant) right).Value);
- }
- break;
-
- case Binary.Operator.LogicalOr:
- if (left is BoolConstant && right is BoolConstant){
- return new BoolConstant (
- ((BoolConstant) left).Value ||
- ((BoolConstant) right).Value);
- }
- break;
-
case Binary.Operator.Equality:
if (left is BoolConstant && right is BoolConstant){
return new BoolConstant (
((BoolConstant) left).Value ==
- ((BoolConstant) right).Value);
+ ((BoolConstant) right).Value, left.Location);
}
+ 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);
+ ((StringConstant) right).Value, left.Location);
}
-
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.Inequality:
if (left is BoolConstant && right is BoolConstant){
return new BoolConstant (
((BoolConstant) left).Value !=
- ((BoolConstant) right).Value);
+ ((BoolConstant) right).Value, left.Location);
+ }
+ 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);
+ ((StringConstant) right).Value, left.Location);
}
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.LessThan:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.GreaterThan:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.GreaterThanOrEqual:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.LessThanOrEqual:
- DoConstantNumericPromotions (oper, ref left, ref right, loc);
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
}
return null;