if ( left.getKind() == GoTypeConstant.Kind.String || right.getKind() == GoTypeConstant.Kind.String)
return GoType.Unknown;
if ( left.getKind() == GoTypeConstant.Kind.Complex || right.getKind() == GoTypeConstant.Kind.Complex ) {
GoNumber leftValue = GoNumber.buildFrom(left.getValue());
GoNumber rightValue = GoNumber.buildFrom(right.getValue());
if ( leftValue == null || rightValue == null )
return GoType.Unknown;
switch (op()) {
case Mul:
return GoTypes.constant(GoTypeConstant.Kind.Complex, leftValue.multiply(rightValue));
case Quotient:
if ( rightValue.equals(GoNumber.ZERO) )
return GoType.Unknown;
return GoTypes.constant(GoTypeConstant.Kind.Complex, leftValue.divide(rightValue));
default:
return GoType.Unknown;
}
}
if ( left.getKind() == GoTypeConstant.Kind.Float || right.getKind() == GoTypeConstant.Kind.Float ) {
BigDecimal leftValue = left.getValueAs(BigDecimal.class);
BigDecimal rightValue = right.getValueAs(BigDecimal.class);
if ( leftValue == null || rightValue == null )
return GoType.Unknown;
switch (op()){
case Mul:
return GoTypes.constant(GoTypeConstant.Kind.Float, leftValue.multiply(rightValue));
case Quotient:
if ( rightValue.compareTo(BigDecimal.ZERO) == 0 )
return GoType.Unknown;
return GoTypes.constant(GoTypeConstant.Kind.Float, leftValue.divide(rightValue, MathContext.DECIMAL128));
case Remainder:
return GoTypes.constant(GoTypeConstant.Kind.Float, leftValue.divideAndRemainder(rightValue)[1]);
case ShiftLeft:
try {
BigInteger leftInteger = leftValue.toBigIntegerExact();
BigInteger rightInteger = rightValue.toBigIntegerExact();
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftInteger.shiftLeft(rightInteger.intValue()));
} catch (ArithmeticException ex) {
return GoType.Unknown;
}
case ShiftRight:
try {
BigInteger leftInteger = leftValue.toBigIntegerExact();
BigInteger rightInteger = rightValue.toBigIntegerExact();
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftInteger.shiftRight(rightInteger.intValue()));
} catch (ArithmeticException ex) {
return GoType.Unknown;
}
default:
return GoType.Unknown;
}
}
if ( left.getKind() == GoTypeConstant.Kind.Integer || right.getKind() == GoTypeConstant.Kind.Integer ) {
BigInteger leftValue = left.getValueAs(BigInteger.class);
BigInteger rightValue = right.getValueAs(BigInteger.class);
if ( leftValue == null || rightValue == null )
return GoType.Unknown;
switch (op()){
case Mul:
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.multiply(rightValue));
case Quotient:
if ( rightValue.compareTo(BigInteger.ZERO) == 0 )
return GoType.Unknown;
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.divide(rightValue));
case Remainder:
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.divideAndRemainder(rightValue)[1]);
case BitAnd:
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.and(rightValue));
case BitClear:
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.andNot(rightValue));
case ShiftLeft:
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.shiftLeft(rightValue.intValue()));
case ShiftRight:
return GoTypes.constant(GoTypeConstant.Kind.Integer, leftValue.shiftRight(rightValue.intValue()));
default:
return GoType.Unknown;
}
}