private ConstantValue evaluateLogicalExpr( Expression lhs, Expression rhs, Type resultType, LogicalBinaryOperation operation) { // Evaluate the first subexpression final ConstantValue valueLhs = lhs.accept(this, null); // Get the factory for the result type final ConstantType resultConstantType = typeFactory.newConstantType(resultType); checkArgument( resultConstantType.getType() == ConstantType.Type.SIGNED_INTEGER, "result of logical AND or logical OR expression has not a signed integer type"); final boolean resultValue; /* Determine the result - we use the fact the Java '&&' and '||' operators are evaluated lazily. */ switch (operation) { case LOGICAL_AND: resultValue = valueLhs.logicalValue() && rhs.accept(this, null).logicalValue(); break; case LOGICAL_OR: resultValue = valueLhs.logicalValue() || rhs.accept(this, null).logicalValue(); break; default: throw new RuntimeException("unexpected logical binary operation '" + operation + "'"); } return UnsignedIntegerConstantValue.getLogicalValue(resultValue).castTo(resultConstantType); }
@Override public ConstantValue visitConditional(Conditional expr, Void arg) { final ConstantValue conditionValue = expr.getCondition().accept(this, null); final ConstantType resultConstantType = typeFactory.newConstantType(expr.getType().get()); final ConstantValue resultValue; if (conditionValue.logicalValue()) { resultValue = expr.getOnTrueExp().isPresent() ? expr.getOnTrueExp().get().accept(this, null) : conditionValue; } else { resultValue = expr.getOnFalseExp().accept(this, null); } return resultValue.castTo(resultConstantType); }
private ConstantValue evaluateUnaryExpr( Expression opParam, Type resultType, UnaryArithmeticOperation operation) { // Evaluate the subexpression ConstantValue paramValue = opParam.accept(this, null); // Make the integer promotion final ConstantType resultConstantType = typeFactory.newConstantType(resultType); paramValue = paramValue.castTo(resultConstantType); // Perform the operation switch (operation) { case IDENTITY: return paramValue; case NEGATION: return paramValue.negate(); case BITWISE_NOT: return paramValue.bitwiseNot(); default: throw new RuntimeException("unexpected unary arithmetic operation '" + operation + "'"); } }
private ConstantValue evaluateShiftExpr( Expression lhs, Expression rhs, Type resultType, ShiftOperation operation) { // Evaluate subexpressions ConstantValue valueLhs = lhs.accept(this, null); ConstantValue valueRhs = rhs.accept(this, null); // Make integer promotions final ConstantType leftPromotedType = typeFactory.newConstantType(resultType); final ConstantType rightPromotedType = typeFactory.newConstantType(rhs.getType().get().promote()); valueLhs = valueLhs.castTo(leftPromotedType); valueRhs = valueRhs.castTo(rightPromotedType); // Perform the operation switch (operation) { case LEFT_SHIFT: return valueLhs.shiftLeft(valueRhs); case RIGHT_SHIFT: return valueLhs.shiftRight(valueRhs); default: throw new RuntimeException("unexpected shift operation kind '" + operation + "'"); } }
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 + "'"); } }