// (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 (EmitContext ec, Binary.Operator oper,
ref Constant left, ref Constant right,
// 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);
+ else
+ right = new UIntConstant ((uint) ic.Value);
+ 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 either operand is an enum constant, the other one must
left = ((EnumConstant) left).Child;
if (right is EnumConstant)
right = ((EnumConstant) right).Child;
+
+ DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
return;
} else {
Type rt = right.Type;
Type result_type = null;
bool bool_res;
-
+
//
// Enumerator folding
//
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;
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);
+ 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);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
}
break;
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);
+ 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);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
}
break;
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);
+ 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);
+ if (result_type == null)
+ return v;
+ else
+ return new EnumConstant (v, result_type);
}
break;
((IntConstant) right).Value);
result = new IntConstant (res);
+ } 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);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected addition input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
((IntConstant) right).Value);
result = new IntConstant (res);
+ } 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);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected subtraction input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
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);
} else if (left is FloatConstant){
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);
} else if (left is ULongConstant){
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);
} else if (left is LongConstant){
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);
} else if (left is UIntConstant){
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);
} else if (left is IntConstant){
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);
+ } 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);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected multiply input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
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);
} else if (left is FloatConstant){
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);
} else if (left is ULongConstant){
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);
} else if (left is LongConstant){
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);
} else if (left is UIntConstant){
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);
} else if (left is IntConstant){
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);
+ } 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);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected division input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
return new IntConstant (res);
} else {
- throw new Exception ( "Unexepected input: " + left);
+ throw new Exception ( "Unexepected modulus input: " + left);
}
} catch (DivideByZeroException){
Report.Error (020, loc, "Division by constant zero");
((BoolConstant) right).Value);
}
+ if (left is NullLiteral){
+ if (right is NullLiteral)
+ return new BoolConstant (true);
+ else if (right is StringConstant)
+ return new BoolConstant (
+ ((StringConstant) right).Value == null);
+ } else if (right is NullLiteral){
+ if (left is NullLiteral)
+ return new BoolConstant (true);
+ else if (left is StringConstant)
+ return new BoolConstant (
+ ((StringConstant) left).Value == null);
+ }
if (left is StringConstant && right is StringConstant){
return new BoolConstant (
((StringConstant) left).Value ==
((StringConstant) right).Value);
}
-
+
DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
if (left == null || right == null)
return null;
((BoolConstant) left).Value !=
((BoolConstant) right).Value);
}
+ if (left is NullLiteral){
+ if (right is NullLiteral)
+ return new BoolConstant (false);
+ else if (right is StringConstant)
+ return new BoolConstant (
+ ((StringConstant) right).Value != null);
+ } else if (right is NullLiteral){
+ if (left is NullLiteral)
+ return new BoolConstant (false);
+ else if (left is StringConstant)
+ return new BoolConstant (
+ ((StringConstant) left).Value != null);
+ }
if (left is StringConstant && right is StringConstant){
return new BoolConstant (
((StringConstant) left).Value !=