private ConstantValue evaluateBinaryExpr( Expression lhs, Expression rhs, Type resultType, ArithmeticBinaryOperation operation) { // Evaluate subexpressions ConstantValue valueLhs = lhs.accept(this, null); ConstantValue valueRhs = rhs.accept(this, null); // Convert to type implied by usual arithmetic conversions final ArithmeticType commonType = TypeUtils.doUsualArithmeticConversions( (ArithmeticType) lhs.getType().get(), (ArithmeticType) rhs.getType().get()); final ConstantType commonConstantType = typeFactory.newConstantType(commonType); final ConstantType resultConstantType = typeFactory.newConstantType(resultType); valueLhs = valueLhs.castTo(commonConstantType); valueRhs = valueRhs.castTo(commonConstantType); // Perform the operation switch (operation) { case ADDITION: return valueLhs.add(valueRhs); case SUBTRACTION: return valueLhs.subtract(valueRhs); case MULTIPLICATION: return valueLhs.multiply(valueRhs); case DIVISION: return valueLhs.divide(valueRhs); case REMAINDER: return valueLhs.remainder(valueRhs); case BITWISE_AND: return valueLhs.bitwiseAnd(valueRhs); case BITWISE_OR: return valueLhs.bitwiseOr(valueRhs); case BITWISE_XOR: return valueLhs.bitwiseXor(valueRhs); case LESS: return valueLhs.less(valueRhs).castTo(resultConstantType); case LESS_OR_EQUAL: return valueLhs.lessOrEqual(valueRhs).castTo(resultConstantType); case GREATER: return valueLhs.greater(valueRhs).castTo(resultConstantType); case GREATER_OR_EQUAL: return valueLhs.greaterOrEqual(valueRhs).castTo(resultConstantType); case EQUAL: return valueLhs.equalTo(valueRhs).castTo(resultConstantType); case NOT_EQUAL: return valueLhs.notEqualTo(valueRhs).castTo(resultConstantType); default: throw new RuntimeException("unexpected arithmetic binary operation '" + operation + "'"); } }