if (ic != null){
if (ic.Value >= 0){
if (left == other)
- left = new UIntConstant ((uint) ic.Value);
+ left = new UIntConstant ((uint) ic.Value, ic.Location);
else
- right = new UIntConstant ((uint) ic.Value);
+ right = new UIntConstant ((uint) ic.Value, ic.Location);
return;
}
}
right = right.ToDecimal (loc);
return;
} else if (left is EnumConstant || right is EnumConstant){
- //
- // If either operand is an enum constant, the other one must
- // be implicitly convertable to that enum's underlying type.
- //
- EnumConstant match;
- Constant other;
- if (left is EnumConstant){
- other = right;
- match = (EnumConstant) left;
- } else {
- other = left;
- match = (EnumConstant) right;
- }
-
- bool need_check = (other is EnumConstant) ||
- !(oper == Binary.Operator.Addition ||
- oper == Binary.Operator.Subtraction ||
- (other.IsZeroInteger && other is IntConstant));
-
- if (need_check &&
- !Convert.ImplicitConversionExists (ec, match, other.Type)) {
- Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
- left = null;
- right = null;
- return;
- }
-
if (left is EnumConstant)
left = ((EnumConstant) left).Child;
if (right is EnumConstant)
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;
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){
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
ushort res = (ushort) (((UShortConstant)left).Value |
((UShortConstant)right).Value);
- v = new UShortConstant (res);
+ v = new UShortConstant (res, left.Location);
if (result_type == null)
return v;
else
short res = (short) (((ShortConstant)left).Value |
((ShortConstant)right).Value);
- v = new ShortConstant (res);
+ v = new ShortConstant (res, left.Location);
if (result_type == null)
return v;
else
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
ushort res = (ushort) (((UShortConstant)left).Value &
((UShortConstant)right).Value);
- v = new UShortConstant (res);
+ v = new UShortConstant (res, left.Location);
if (result_type == null)
return v;
else
short res = (short) (((ShortConstant)left).Value &
((ShortConstant)right).Value);
- v = new ShortConstant (res);
+ v = new ShortConstant (res, left.Location);
if (result_type == null)
return v;
else
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
ushort res = (ushort) (((UShortConstant)left).Value ^
((UShortConstant)right).Value);
- v = new UShortConstant (res);
+ v = new UShortConstant (res, left.Location);
if (result_type == null)
return v;
else
short res = (short)(((ShortConstant)left).Value ^
((ShortConstant)right).Value);
- v = new ShortConstant (res);
+ v = new ShortConstant (res, left.Location);
if (result_type == null)
return v;
else
if (left_is_string && right_is_string)
return new StringConstant (
((StringConstant) left).Value +
- ((StringConstant) right).Value);
+ ((StringConstant) right).Value, left.Location);
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;
res = unchecked (((DecimalConstant) left).Value +
((DecimalConstant) right).Value);
- result = new DecimalConstant (res);
+ result = new DecimalConstant (res, left.Location);
} else {
throw new Exception ( "Unexepected addition input: " + left);
}
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;
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;
res = unchecked (((DecimalConstant) left).Value -
((DecimalConstant) right).Value);
- return new DecimalConstant (res);
+ return new DecimalConstant (res, left.Location);
} else {
throw new Exception ( "Unexepected subtraction input: " + left);
}
} catch (OverflowException){
Error_CompileTimeOverflow (loc);
}
- if (wrap_as != null)
- return new EnumConstant (result, wrap_as);
- else
- return result;
+
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
+
+ return result;
case Binary.Operator.Multiply:
DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
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 if (left is DecimalConstant) {
decimal res;
res = unchecked (((DecimalConstant) left).Value *
((DecimalConstant) right).Value);
- return new DecimalConstant (res);
+ return new DecimalConstant (res, left.Location);
} else {
throw new Exception ( "Unexepected multiply input: " + left);
}
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 if (left is DecimalConstant) {
decimal res;
res = unchecked (((DecimalConstant) left).Value /
((DecimalConstant) right).Value);
- return new DecimalConstant (res);
+ return new DecimalConstant (res, left.Location);
} else {
throw new Exception ( "Unexepected division input: " + left);
}
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 modulus input: " + left);
}
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);
+ return new BoolConstant (true, left.Location);
else if (right is StringConstant)
return new BoolConstant (
- ((StringConstant) right).Value == null);
+ ((StringConstant) right).Value == null, left.Location);
} else if (right is NullLiteral){
if (left is NullLiteral)
- return new BoolConstant (true);
+ return new BoolConstant (true, left.Location);
else if (left is StringConstant)
return new BoolConstant (
- ((StringConstant) left).Value == null);
+ ((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);
}
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);
+ return new BoolConstant (false, left.Location);
else if (right is StringConstant)
return new BoolConstant (
- ((StringConstant) right).Value != null);
+ ((StringConstant) right).Value != null, left.Location);
} else if (right is NullLiteral){
if (left is NullLiteral)
- return new BoolConstant (false);
+ return new BoolConstant (false, left.Location);
else if (left is StringConstant)
return new BoolConstant (
- ((StringConstant) left).Value != null);
+ ((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 (ec, oper, ref left, ref right, loc);
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.LessThan:
DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.GreaterThan:
DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.GreaterThanOrEqual:
DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
case Binary.Operator.LessThanOrEqual:
DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
else
return null;
- return new BoolConstant (bool_res);
+ return new BoolConstant (bool_res, left.Location);
}
return null;