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){
Error_CompileTimeOverflow (loc);
}
- if (wrap_as != null)
- return result.TryReduce (ec, wrap_as, loc);
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
else
return result;
Error_CompileTimeOverflow (loc);
}
- if (wrap_as != null)
- return result.TryReduce (ec, wrap_as, loc);
+ if (wrap_as != null) {
+ try {
+ return result.TryReduce (ec, wrap_as, loc);
+ }
+ catch (OverflowException) {
+ return null;
+ }
+ }
return result;
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, left.Location);
- }
- break;
-
- case Binary.Operator.LogicalOr:
- if (left is BoolConstant && right is BoolConstant){
- return new BoolConstant (
- ((BoolConstant) left).Value ||
- ((BoolConstant) right).Value, left.Location);
- }
- break;
-
case Binary.Operator.Equality:
if (left is BoolConstant && right is BoolConstant){
return new BoolConstant (