Support some operators on numbers in PyEvaluator (PY-19856)

This commit is contained in:
Semyon Proshev
2018-02-20 13:56:12 +03:00
parent 2deecc0dcc
commit 5273071ebe
2 changed files with 49 additions and 5 deletions
@@ -116,11 +116,40 @@ public class PyEvaluator {
@Nullable
private Object evaluateBinary(@NotNull PyBinaryExpression expression) {
final PyElementType op = expression.getOperator();
if (op == PyTokenTypes.PLUS) {
final Object lhs = evaluate(expression.getLeftExpression());
final Object rhs = evaluate(expression.getRightExpression());
if (lhs != null && rhs != null) {
return applyPlus(lhs, rhs);
final Object lhs = evaluate(expression.getLeftExpression());
final Object rhs = evaluate(expression.getRightExpression());
if (op == PyTokenTypes.PLUS && lhs != null && rhs != null) {
return applyPlus(lhs, rhs);
}
else if (lhs instanceof Number && rhs instanceof Number) {
final BigInteger first = toBigInteger((Number)lhs);
final BigInteger second = toBigInteger((Number)rhs);
if (op == PyTokenTypes.MINUS) {
return fromBigInteger(first.subtract(second));
}
else if (op == PyTokenTypes.MULT) {
return fromBigInteger(first.multiply(second));
}
else if (op == PyTokenTypes.FLOORDIV) {
return fromBigInteger(first.divide(second));
}
else if (op == PyTokenTypes.LT) {
return first.compareTo(second) < 0;
}
else if (op == PyTokenTypes.LE) {
return first.compareTo(second) <= 0;
}
else if (op == PyTokenTypes.GT) {
return first.compareTo(second) > 0;
}
else if (op == PyTokenTypes.GE) {
return first.compareTo(second) >= 0;
}
else if (op == PyTokenTypes.EQEQ) {
return first.compareTo(second) == 0;
}
else if (op == PyTokenTypes.NE) {
return first.compareTo(second) != 0;
}
}
@@ -234,6 +234,21 @@ public class PyEvaluatorTest extends PyTestCase {
assertEquals(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE), byExpression(Long.MAX_VALUE + "+ 1", BigInteger.class));
}
public void testNumbersSubMulDiv() {
assertEquals(Integer.valueOf(17), byExpression("20 - 3", Integer.class));
assertEquals(Integer.valueOf(60), byExpression("20 * 3", Integer.class));
assertEquals(Integer.valueOf(6), byExpression("20 // 3", Integer.class));
}
public void testNumbersComparison() {
assertTrue(byExpression("1 < 2", Boolean.class));
assertTrue(byExpression("1 <= 1", Boolean.class));
assertTrue(byExpression("2 > 1", Boolean.class));
assertTrue(byExpression("1 >= 1", Boolean.class));
assertTrue(byExpression("1 == 1", Boolean.class));
assertTrue(byExpression("2 != 1", Boolean.class));
}
@NotNull
private <T> T byExpression(@NotNull String expression, @NotNull Class<T> cls) {
final Object value = new PyEvaluator().evaluate(parseExpression(expression));