aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java41
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java36
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonAttributeAccessNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java61
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonBooleanLiteralNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonCallNode.java8
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonConditionalExpressionNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonExpressionNode.java2
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonGetSliceNode.java8
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonIntegerLiteralNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonStringLiteralNode.java5
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/ast/PythonVariableReferenceNode.java5
-rw-r--r--src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java37
14 files changed, 168 insertions, 60 deletions
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
index 403e7ac..78624b0 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java
@@ -12,6 +12,7 @@ import org.zwobble.couscous.values.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.function.BiFunction;
import static org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode.pythonAttributeAccess;
import static org.zwobble.couscous.backends.python.ast.PythonBinaryOperation.pythonIs;
@@ -39,7 +40,7 @@ public class PrimitiveMethods {
pythonCall(pythonAttributeAccess(receiver, "lower"), list()))
.put("equals", (receiver, arguments) ->
- PythonBinaryOperation.pythonEq(receiver, arguments.get(0)))
+ PythonBinaryOperation.pythonEqual(receiver, arguments.get(0)))
.build();
@@ -51,8 +52,8 @@ public class PrimitiveMethods {
methods.put("negate", (receiver, arguments) ->
PythonNotNode.pythonNot(receiver));
- addOperation(methods, Operator.BOOLEAN_AND, "and");
- addOperation(methods, Operator.BOOLEAN_OR, "or");
+ addOperation(methods, Operator.BOOLEAN_AND, PythonBinaryOperation::pythonAnd);
+ addOperation(methods, Operator.BOOLEAN_OR, PythonBinaryOperation::pythonOr);
BOOLEAN_METHODS = methods.build();
}
@@ -65,9 +66,9 @@ public class PrimitiveMethods {
methods.put("toString", (receiver, arguments) ->
pythonCall(pythonVariableReference("str"), list(receiver)));
- addOperation(methods, Operator.ADD, "+");
- addOperation(methods, Operator.SUBTRACT, "-");
- addOperation(methods, Operator.MULTIPLY, "*");
+ addOperation(methods, Operator.ADD, PythonBinaryOperation::pythonAdd);
+ addOperation(methods, Operator.SUBTRACT, PythonBinaryOperation::pythonSubtract);
+ addOperation(methods, Operator.MULTIPLY, PythonBinaryOperation::pythonMultiply);
methods.put(Operator.DIVIDE.getMethodName(), (receiver, arguments) ->
pythonCall(
@@ -78,12 +79,12 @@ public class PrimitiveMethods {
internalReference("_mod_round_to_zero"),
list(receiver, arguments.get(0))));
- addOperation(methods, Operator.EQUALS, "==");
- addOperation(methods, Operator.NOT_EQUALS, "!=");
- addOperation(methods, Operator.GREATER_THAN, ">");
- addOperation(methods, Operator.GREATER_THAN_OR_EQUAL, ">=");
- addOperation(methods, Operator.LESS_THAN, "<");
- addOperation(methods, Operator.LESS_THAN_OR_EQUAL, "<=");
+ addOperation(methods, Operator.EQUALS, PythonBinaryOperation::pythonEqual);
+ addOperation(methods, Operator.NOT_EQUALS, PythonBinaryOperation::pythonNotEqual);
+ addOperation(methods, Operator.GREATER_THAN, PythonBinaryOperation::pythonGreaterThan);
+ addOperation(methods, Operator.GREATER_THAN_OR_EQUAL, PythonBinaryOperation::pythonGreatThanOrEqual);
+ addOperation(methods, Operator.LESS_THAN, PythonBinaryOperation::pythonLessThan);
+ addOperation(methods, Operator.LESS_THAN_OR_EQUAL, PythonBinaryOperation::pythonLessThanOrEqual);
INT_METHODS = methods.build();
}
@@ -95,20 +96,18 @@ public class PrimitiveMethods {
private static void addOperation(
Builder<String, PrimitiveMethodGenerator> methods,
Operator operator,
- String operatorSymbol)
+ BiFunction<PythonExpressionNode, PythonExpressionNode, PythonExpressionNode> build)
{
- addOperation(methods, operator.getMethodName(), operatorSymbol);
+ addOperation(methods, operator.getMethodName(), build);
}
private static void addOperation(
- Builder<String, PrimitiveMethodGenerator> methods,
- String methodName,
- String operatorSymbol) {
+ Builder<String, PrimitiveMethodGenerator> methods,
+ String methodName,
+ BiFunction<PythonExpressionNode, PythonExpressionNode, PythonExpressionNode> build)
+ {
methods.put(methodName, (receiver, arguments) ->
- new PythonBinaryOperation(
- operatorSymbol,
- receiver,
- arguments.get(0)));
+ build.apply(receiver, arguments.get(0)));
}
private static final Map<TypeName, Map<String, PrimitiveMethodGenerator>> METHODS =
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
index 6501d1b..45739da 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java
@@ -1,11 +1,12 @@
package org.zwobble.couscous.backends.python;
-import java.util.List;
-import java.util.function.Consumer;
-
import org.zwobble.couscous.backends.python.ast.*;
import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor;
import org.zwobble.couscous.util.Action;
+
+import java.util.List;
+import java.util.function.Consumer;
+
import static com.google.common.collect.Iterables.skip;
public class PythonSerializer implements PythonNodeVisitor {
@@ -48,27 +49,27 @@ public class PythonSerializer implements PythonNodeVisitor {
@Override
public void visit(PythonConditionalExpressionNode conditional) {
- writeParenthesised(conditional.getTrueValue());
+ writeParenthesised(conditional.getTrueValue(), conditional);
writer.writeSpace();
writer.writeKeyword("if");
writer.writeSpace();
- writeParenthesised(conditional.getCondition());
+ writeParenthesised(conditional.getCondition(), conditional);
writer.writeSpace();
writer.writeKeyword("else");
writer.writeSpace();
- writeParenthesised(conditional.getFalseValue());
+ writeParenthesised(conditional.getFalseValue(), conditional);
}
@Override
public void visit(PythonAttributeAccessNode attributeAccess) {
- writeParenthesised(attributeAccess.getLeft());
+ writeParenthesised(attributeAccess.getLeft(), attributeAccess);
writer.writeSymbol(".");
writer.writeIdentifier(attributeAccess.getAttributeName());
}
@Override
public void visit(PythonCallNode call) {
- writeParenthesised(call.getCallee());
+ writeParenthesised(call.getCallee(), call);
writer.writeSymbol("(");
writeWithSeparator(call.getArguments(), this::write, () -> {
writer.writeSymbol(",");
@@ -79,7 +80,7 @@ public class PythonSerializer implements PythonNodeVisitor {
@Override
public void visit(PythonGetSliceNode getSlice) {
- writeParenthesised(getSlice.getReceiver());
+ writeParenthesised(getSlice.getReceiver(), getSlice);
writer.writeSymbol("[");
writeWithSeparator(getSlice.getArguments(), this::write, () -> {
writer.writeSymbol(":");
@@ -91,16 +92,16 @@ public class PythonSerializer implements PythonNodeVisitor {
public void visit(PythonNotNode notOperation) {
writer.writeKeyword("not");
writer.writeSpace();
- writeParenthesised(notOperation.getOperand());
+ writeParenthesised(notOperation.getOperand(), notOperation);
}
@Override
public void visit(PythonBinaryOperation operation) {
- writeParenthesised(operation.getLeft());
+ writeParenthesised(operation.getLeft(), operation);
writer.writeSpace();
writer.writeKeyword(operation.getOperator());
writer.writeSpace();
- writeParenthesised(operation.getRight());
+ writeParenthesised(operation.getRight(), operation);
}
@Override
@@ -198,10 +199,15 @@ public class PythonSerializer implements PythonNodeVisitor {
});
}
- private void writeParenthesised(PythonExpressionNode expression) {
- writer.writeSymbol("(");
+ private void writeParenthesised(PythonExpressionNode expression, PythonExpressionNode parent) {
+ boolean requiresParens = parent.precedence() >= expression.precedence();
+ if (requiresParens) {
+ writer.writeSymbol("(");
+ }
write(expression);
- writer.writeSymbol(")");
+ if (requiresParens) {
+ writer.writeSymbol(")");
+ }
}
private void writeArgumentNames(PythonFunctionDefinitionNode functionDefinition) {
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonAttributeAccessNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonAttributeAccessNode.java
index 95e6cf0..e2b8d8b 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonAttributeAccessNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonAttributeAccessNode.java
@@ -32,4 +32,9 @@ public final class PythonAttributeAccessNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonAttributeAccessNode(left=" + this.getLeft() + ", attributeName=" + this.getAttributeName() + ")";
}
+
+ @Override
+ public int precedence() {
+ return 160;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java
index 8d6b9ce..ecaf038 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java
@@ -4,26 +4,66 @@ import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor;
public class PythonBinaryOperation implements PythonExpressionNode {
public static PythonExpressionNode pythonIs(PythonExpressionNode left, PythonExpressionNode right) {
- return new PythonBinaryOperation("is", left, right);
+ return new PythonBinaryOperation("is", 50, left, right);
+ }
+
+ public static PythonExpressionNode pythonAnd(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("and", 20, left, right);
+ }
+
+ public static PythonExpressionNode pythonOr(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("or", 20, left, right);
}
public static PythonExpressionNode pythonAdd(PythonExpressionNode left, PythonExpressionNode right) {
- return new PythonBinaryOperation("+", left, right);
+ return new PythonBinaryOperation("+", 100, left, right);
+ }
+
+ public static PythonExpressionNode pythonSubtract(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("-", 100, left, right);
}
- public static PythonExpressionNode pythonEq(PythonExpressionNode left, PythonExpressionNode right) {
- return new PythonBinaryOperation("==", left, right);
+ public static PythonExpressionNode pythonMultiply(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("*", 110, left, right);
+ }
+
+ public static PythonExpressionNode pythonEqual(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("==", 50, left, right);
+ }
+
+ public static PythonExpressionNode pythonNotEqual(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("!=", 50, left, right);
+ }
+
+ public static PythonExpressionNode pythonLessThan(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("<", 50, left, right);
+ }
+
+ public static PythonExpressionNode pythonLessThanOrEqual(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation("<=", 50, left, right);
+ }
+
+ public static PythonExpressionNode pythonGreaterThan(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation(">", 50, left, right);
+ }
+
+ public static PythonExpressionNode pythonGreatThanOrEqual(PythonExpressionNode left, PythonExpressionNode right) {
+ return new PythonBinaryOperation(">=", 50, left, right);
}
private final String operator;
+ private final int precedence;
private final PythonExpressionNode left;
private final PythonExpressionNode right;
- public PythonBinaryOperation(
- String operator,
- PythonExpressionNode left,
- PythonExpressionNode right) {
+ private PythonBinaryOperation(
+ String operator,
+ int precedence,
+ PythonExpressionNode left,
+ PythonExpressionNode right)
+ {
this.operator = operator;
+ this.precedence = precedence;
this.left = left;
this.right = right;
}
@@ -44,4 +84,9 @@ public class PythonBinaryOperation implements PythonExpressionNode {
public void accept(PythonNodeVisitor visitor) {
visitor.visit(this);
}
+
+ @Override
+ public int precedence() {
+ return precedence;
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBooleanLiteralNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBooleanLiteralNode.java
index 893f2e1..fd902ee 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBooleanLiteralNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBooleanLiteralNode.java
@@ -26,4 +26,9 @@ public final class PythonBooleanLiteralNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonBooleanLiteralNode(value=" + this.getValue() + ")";
}
+
+ @Override
+ public int precedence() {
+ return Integer.MAX_VALUE;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonCallNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonCallNode.java
index ae3761b..3adb4fb 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonCallNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonCallNode.java
@@ -1,8 +1,9 @@
package org.zwobble.couscous.backends.python.ast;
-import java.util.List;
import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor;
+import java.util.List;
+
public final class PythonCallNode implements PythonExpressionNode {
private final PythonExpressionNode callee;
private final List<PythonExpressionNode> arguments;
@@ -33,4 +34,9 @@ public final class PythonCallNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonCallNode(callee=" + this.getCallee() + ", arguments=" + this.getArguments() + ")";
}
+
+ @Override
+ public int precedence() {
+ return 150;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonConditionalExpressionNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonConditionalExpressionNode.java
index a320cd2..75f9e15 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonConditionalExpressionNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonConditionalExpressionNode.java
@@ -38,4 +38,9 @@ public final class PythonConditionalExpressionNode implements PythonExpressionNo
public java.lang.String toString() {
return "PythonConditionalExpressionNode(condition=" + this.getCondition() + ", trueValue=" + this.getTrueValue() + ", falseValue=" + this.getFalseValue() + ")";
}
+
+ @Override
+ public int precedence() {
+ return 10;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonExpressionNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonExpressionNode.java
index 9c8a259..8105271 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonExpressionNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonExpressionNode.java
@@ -1,5 +1,5 @@
package org.zwobble.couscous.backends.python.ast;
public interface PythonExpressionNode extends PythonNode {
-
+ int precedence();
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonGetSliceNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonGetSliceNode.java
index 70343d8..1a245cd 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonGetSliceNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonGetSliceNode.java
@@ -1,8 +1,9 @@
package org.zwobble.couscous.backends.python.ast;
-import java.util.List;
import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor;
+import java.util.List;
+
public final class PythonGetSliceNode implements PythonExpressionNode {
private final PythonExpressionNode receiver;
private final List<PythonExpressionNode> arguments;
@@ -33,4 +34,9 @@ public final class PythonGetSliceNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonGetSliceNode(receiver=" + this.getReceiver() + ", arguments=" + this.getArguments() + ")";
}
+
+ @Override
+ public int precedence() {
+ return 150;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIntegerLiteralNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIntegerLiteralNode.java
index ce09767..18156ad 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIntegerLiteralNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonIntegerLiteralNode.java
@@ -26,4 +26,9 @@ public final class PythonIntegerLiteralNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonIntegerLiteralNode(value=" + this.getValue() + ")";
}
+
+ @Override
+ public int precedence() {
+ return Integer.MAX_VALUE;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java
index 6fe7dc6..e24d0d8 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java
@@ -21,4 +21,9 @@ public class PythonNotNode implements PythonExpressionNode {
public void accept(PythonNodeVisitor visitor) {
visitor.visit(this);
}
+
+ @Override
+ public int precedence() {
+ return 40;
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonStringLiteralNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonStringLiteralNode.java
index d64be5f..f3ee201 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonStringLiteralNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonStringLiteralNode.java
@@ -26,4 +26,9 @@ public final class PythonStringLiteralNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonStringLiteralNode(value=" + this.getValue() + ")";
}
+
+ @Override
+ public int precedence() {
+ return Integer.MAX_VALUE;
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonVariableReferenceNode.java b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonVariableReferenceNode.java
index 876ac14..f8c2b4a 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/ast/PythonVariableReferenceNode.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonVariableReferenceNode.java
@@ -26,4 +26,9 @@ public final class PythonVariableReferenceNode implements PythonExpressionNode {
public java.lang.String toString() {
return "PythonVariableReferenceNode(name=" + this.getName() + ")";
}
+
+ @Override
+ public int precedence() {
+ return Integer.MAX_VALUE;
+ }
} \ No newline at end of file
diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java
index 59ab22c..7ff9cee 100644
--- a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonSerializerTests.java
@@ -5,11 +5,11 @@ import org.zwobble.couscous.backends.python.ast.PythonClassNode;
import org.zwobble.couscous.backends.python.ast.PythonFunctionDefinitionNode;
import org.zwobble.couscous.backends.python.ast.PythonModuleNode;
-import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.zwobble.couscous.backends.python.PythonSerializer.serialize;
import static org.zwobble.couscous.backends.python.ast.PythonAssignmentNode.pythonAssignment;
import static org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode.pythonAttributeAccess;
+import static org.zwobble.couscous.backends.python.ast.PythonBinaryOperation.pythonAnd;
import static org.zwobble.couscous.backends.python.ast.PythonBinaryOperation.pythonIs;
import static org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode.pythonBooleanLiteral;
import static org.zwobble.couscous.backends.python.ast.PythonCallNode.pythonCall;
@@ -59,36 +59,47 @@ public class PythonSerializerTests {
}
@Test
- public void conditionalExpressionIsSerializedUsingParenthesisedSubExpression() {
- assertEquals("(1) if (True) else (2)", serialize(pythonConditionalExpression(pythonBooleanLiteral(true), pythonIntegerLiteral(1), pythonIntegerLiteral(2))));
+ public void conditionalExpressionIsSerializedUsingSubExpressions() {
+ assertEquals("1 if True else 2", serialize(pythonConditionalExpression(pythonBooleanLiteral(true), pythonIntegerLiteral(1), pythonIntegerLiteral(2))));
}
@Test
- public void attributeAccessIsSerializedUsingParenthesisedSubExpression() {
- assertEquals("(x).y", serialize(pythonAttributeAccess(pythonVariableReference("x"), "y")));
+ public void attributeAccessIsSerializedUsingSubExpression() {
+ assertEquals("x.y", serialize(pythonAttributeAccess(pythonVariableReference("x"), "y")));
}
@Test
- public void callIsSerializedUsingParenthesisedSubExpression() {
- assertEquals("(f)(x, y)", serialize(pythonCall(pythonVariableReference("f"), list(pythonVariableReference("x"), pythonVariableReference("y")))));
+ public void callIsSerializedUsingSubExpression() {
+ assertEquals("f(x, y)", serialize(pythonCall(pythonVariableReference("f"), list(pythonVariableReference("x"), pythonVariableReference("y")))));
}
@Test
- public void getSliceIsSerializedUsingParenthesisedSubExpression() {
- assertEquals("(x)[y:z]", serialize(pythonGetSlice(pythonVariableReference("x"), list(pythonVariableReference("y"), pythonVariableReference("z")))));
+ public void getSliceIsSerializedUsingSubExpression() {
+ assertEquals("x[y:z]", serialize(pythonGetSlice(pythonVariableReference("x"), list(pythonVariableReference("y"), pythonVariableReference("z")))));
}
@Test
- public void notOperationIsSerializedUsingParenthesisedSubExpression() {
- assertEquals("not (x)", serialize(pythonNot(pythonVariableReference("x"))));
+ public void notOperationIsSerializedUsingSubExpression() {
+ assertEquals("not x", serialize(pythonNot(pythonVariableReference("x"))));
}
@Test
- public void binaryOperationIsSerializedUsingParenthesisedSubExpressions() {
+ public void binaryOperationIsSerializedUsingSubExpressions() {
assertEquals(
- "(x) is (y)",
+ "x is y",
serialize(pythonIs(pythonVariableReference("x"), pythonVariableReference("y"))));
}
+
+ @Test
+ public void operationsWithSameOrLowerPrecedenceIsParenthesised() {
+ assertEquals(
+ "not (x and y)",
+ serialize(pythonNot(pythonAnd(pythonVariableReference("x"), pythonVariableReference("y")))));
+
+ assertEquals(
+ "not x and y",
+ serialize(pythonAnd(pythonNot(pythonVariableReference("x")), pythonVariableReference("y"))));
+ }
@Test
public void returnKeywordIsUsedForReturns() {