private static bool BothWithNegativeSigns(BoxedExpression left, BoxedExpression right, out BoxedExpression minusLeft, out BoxedExpression minusRight, ConstFor GetConst) { if (left.IsUnary && left.UnaryOp == UnaryOperator.Neg) { // case -left, -right if (right.IsUnary && right.UnaryOp == UnaryOperator.Neg) { minusLeft = left.UnaryArgument; minusRight = right.UnaryArgument; return(true); } Int32 value; // case -left, constant if (right.IsConstant && TryInt32Constant(right.Constant, out value)) { minusLeft = left.UnaryArgument; minusRight = GetConst(-value); return(true); } } else if (right.IsUnary && right.UnaryOp == UnaryOperator.Neg) { Int32 value; // case constant, -right if (left.IsConstant && TryInt32Constant(left.Constant, out value)) { minusLeft = GetConst(-value); minusRight = right.UnaryArgument; return(true); } } minusLeft = minusRight = null; return(false); }
private static BoxedExpression MakeItPrettier(BoxedExpression result, ConstFor GetConst) { BinaryOperator binop; BoxedExpression left, right, mLeft, mRight; if (result.IsBinaryExpression(out binop, out left, out right)) { #region All the cases switch (binop) { case BinaryOperator.Add: case BinaryOperator.Add_Ovf: case BinaryOperator.Add_Ovf_Un: return(result); case BinaryOperator.And: return(BoxedExpression.Binary(BinaryOperator.And, MakeItPrettier(left, GetConst), MakeItPrettier(right, GetConst))); case BinaryOperator.Ceq: // -left == -right -> left == right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Ceq, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cge: // -left >= -right -> left <= right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cle, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cge_Un: // -left >= -right -> left <= right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cle_Un, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cgt: // -left > -right -> left < right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Clt, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cgt_Un: // -left > -right -> left < right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Clt_Un, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cle: // -left <= -right -> left >= right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cge, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cle_Un: // -left <= -right -> left >= right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cge_Un, mLeft, mRight)); } else { return(result); } case BinaryOperator.Clt: // -left < -right -> left > right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cgt, mLeft, mRight)); } else { return(result); } case BinaryOperator.Clt_Un: // -left < -right -> left > right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cgt_Un, mLeft, mRight)); } else { return(result); } case BinaryOperator.Cne_Un: // -left != -right -> left != right if (BothWithNegativeSigns(left, right, out mLeft, out mRight, GetConst)) { return(BoxedExpression.Binary(BinaryOperator.Cne_Un, mLeft, mRight)); } else { return(result); } case BinaryOperator.Div: case BinaryOperator.Div_Un: case BinaryOperator.Mul: case BinaryOperator.Mul_Ovf: case BinaryOperator.Mul_Ovf_Un: return(result); case BinaryOperator.Or: return(BoxedExpression.Binary(BinaryOperator.Or, MakeItPrettier(left, GetConst), MakeItPrettier(right, GetConst))); case BinaryOperator.Rem: case BinaryOperator.Rem_Un: case BinaryOperator.Shl: case BinaryOperator.Shr: case BinaryOperator.Shr_Un: case BinaryOperator.Sub: case BinaryOperator.Sub_Ovf: case BinaryOperator.Sub_Ovf_Un: case BinaryOperator.Xor: return(result); // Should be unreachable default: return(result); } #endregion } else { return(result); } }