Support and, or and not on booleans in PyEvaluator (PY-19856)

This commit is contained in:
Semyon Proshev
2018-02-20 13:56:12 +03:00
parent 5273071ebe
commit fbd0af0914
2 changed files with 31 additions and 0 deletions
@@ -98,6 +98,9 @@ public class PyEvaluator {
else if (expression instanceof PyNumericLiteralExpression) {
return evaluateNumeric((PyNumericLiteralExpression)expression);
}
else if (expression instanceof PyPrefixExpression) {
return evaluatePrefix((PyPrefixExpression)expression);
}
return null;
}
@@ -152,6 +155,16 @@ public class PyEvaluator {
return first.compareTo(second) != 0;
}
}
else if (lhs instanceof Boolean && rhs instanceof Boolean) {
final Boolean first = (Boolean)lhs;
final Boolean second = (Boolean)rhs;
if (op == PyTokenTypes.AND_KEYWORD) {
return first && second;
}
else if (op == PyTokenTypes.OR_KEYWORD) {
return first || second;
}
}
return null;
}
@@ -174,6 +187,18 @@ public class PyEvaluator {
return null;
}
@Nullable
private Object evaluatePrefix(@NotNull PyPrefixExpression expression) {
if (expression.getOperator() == PyTokenTypes.NOT_KEYWORD) {
final Boolean value = PyUtil.as(evaluate(expression.getOperand()), Boolean.class);
if (value != null) {
return !value;
}
}
return null;
}
/**
* Evaluates sequence (tuple, list, set, dict)
*
@@ -249,6 +249,12 @@ public class PyEvaluatorTest extends PyTestCase {
assertTrue(byExpression("2 != 1", Boolean.class));
}
public void testBooleanOperators() {
assertTrue(byExpression("True and True", Boolean.class));
assertTrue(byExpression("True or False", Boolean.class));
assertTrue(byExpression("not False", Boolean.class));
}
@NotNull
private <T> T byExpression(@NotNull String expression, @NotNull Class<T> cls) {
final Object value = new PyEvaluator().evaluate(parseExpression(expression));