From eff6ead0d0089fae070c6dbb7c937353632322c1 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 31 Oct 2015 13:42:14 +0000 Subject: Support int inequality --- .../org/zwobble/couscous/ast/MethodCallNode.java | 10 +++++++++ .../couscous/backends/python/PrimitiveMethods.java | 11 ++++++++++ .../couscous/backends/python/PythonSerializer.java | 8 ++++++++ .../backends/python/ast/PythonNotNode.java | 24 ++++++++++++++++++++++ .../python/ast/visitors/PythonNodeVisitor.java | 2 ++ .../couscous/frontends/java/JavaReader.java | 19 +++++++++++------ .../values/BooleanInterpreterValue.java | 8 +++++++- 7 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java (limited to 'src/main/java/org') diff --git a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java index a9b8795..c2e0897 100644 --- a/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java +++ b/src/main/java/org/zwobble/couscous/ast/MethodCallNode.java @@ -1,10 +1,20 @@ package org.zwobble.couscous.ast; +import java.util.Collections; import java.util.List; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; +import org.zwobble.couscous.values.BooleanValue; public class MethodCallNode implements ExpressionNode { + public static ExpressionNode not(ExpressionNode value) { + if (value.getType().equals(BooleanValue.REF)) { + return methodCall(value, "negate", Collections.emptyList(), BooleanValue.REF); + } else { + throw new IllegalArgumentException("Can only negate booleans"); + } + } + public static MethodCallNode methodCall( ExpressionNode receiver, String methodName, 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 9639c72..c6aa62d 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java @@ -6,6 +6,8 @@ import java.util.Optional; import org.zwobble.couscous.ast.TypeName; import org.zwobble.couscous.backends.python.ast.PythonExpressionNode; +import org.zwobble.couscous.backends.python.ast.PythonNotNode; +import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.StringValue; @@ -32,6 +34,14 @@ public class PrimitiveMethods { .build(); + private static final Map BOOLEAN_METHODS = + ImmutableMap.builder() + + .put("negate", (receiver, arguments) -> + PythonNotNode.pythonNot(receiver)) + + .build(); + private static final Map INT_METHODS; static { @@ -76,6 +86,7 @@ public class PrimitiveMethods { private static final Map> METHODS = ImmutableMap.>builder() .put(StringValue.REF, STRING_METHODS) + .put(BooleanValue.REF, BOOLEAN_METHODS) .put(IntegerValue.REF, INT_METHODS) .build(); 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 1674e1f..eadb545 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java @@ -16,6 +16,7 @@ import org.zwobble.couscous.backends.python.ast.PythonImportNode; import org.zwobble.couscous.backends.python.ast.PythonIntegerLiteralNode; import org.zwobble.couscous.backends.python.ast.PythonModuleNode; import org.zwobble.couscous.backends.python.ast.PythonNode; +import org.zwobble.couscous.backends.python.ast.PythonNotNode; import org.zwobble.couscous.backends.python.ast.PythonPassNode; import org.zwobble.couscous.backends.python.ast.PythonReturnNode; import org.zwobble.couscous.backends.python.ast.PythonStatementNode; @@ -103,6 +104,13 @@ public class PythonSerializer implements PythonNodeVisitor { }); writer.writeSymbol("]"); } + + @Override + public void visit(PythonNotNode notOperation) { + writer.writeKeyword("not"); + writer.writeSpace(); + writeParenthesised(notOperation.getOperand()); + } @Override public void visit(PythonReturnNode pythonReturn) { 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 new file mode 100644 index 0000000..6fe7dc6 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonNotNode.java @@ -0,0 +1,24 @@ +package org.zwobble.couscous.backends.python.ast; + +import org.zwobble.couscous.backends.python.ast.visitors.PythonNodeVisitor; + +public class PythonNotNode implements PythonExpressionNode { + public static PythonExpressionNode pythonNot(PythonExpressionNode operand) { + return new PythonNotNode(operand); + } + + private final PythonExpressionNode operand; + + private PythonNotNode(PythonExpressionNode operand) { + this.operand = operand; + } + + public PythonExpressionNode getOperand() { + return operand; + } + + @Override + public void accept(PythonNodeVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java index 7632342..59a1fe9 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/backends/python/ast/visitors/PythonNodeVisitor.java @@ -11,6 +11,7 @@ import org.zwobble.couscous.backends.python.ast.PythonGetSliceNode; import org.zwobble.couscous.backends.python.ast.PythonImportNode; import org.zwobble.couscous.backends.python.ast.PythonIntegerLiteralNode; import org.zwobble.couscous.backends.python.ast.PythonModuleNode; +import org.zwobble.couscous.backends.python.ast.PythonNotNode; import org.zwobble.couscous.backends.python.ast.PythonPassNode; import org.zwobble.couscous.backends.python.ast.PythonReturnNode; import org.zwobble.couscous.backends.python.ast.PythonStringLiteralNode; @@ -25,6 +26,7 @@ public interface PythonNodeVisitor { void visit(PythonAttributeAccessNode attributeAccess); void visit(PythonCallNode call); void visit(PythonGetSliceNode getSlice); + void visit(PythonNotNode notOperation); void visit(PythonReturnNode pythonReturn); void visit(PythonPassNode pass); diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java index 99d6a7a..6c4c0c8 100644 --- a/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java +++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaReader.java @@ -57,6 +57,7 @@ import com.google.common.collect.Lists; import static java.util.Arrays.asList; import static org.zwobble.couscous.ast.ExpressionStatementNode.expressionStatement; import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration; +import static org.zwobble.couscous.ast.MethodCallNode.methodCall; import static org.zwobble.couscous.ast.VariableDeclaration.var; import static org.zwobble.couscous.ast.VariableReferenceNode.reference; @@ -261,12 +262,18 @@ public class JavaReader { } private static ExpressionNode readInfixExpression(InfixExpression expression) { - JavaOperator operator = readOperator(expression.getOperator()); - return MethodCallNode.methodCall( - readExpression(expression.getLeftOperand()), - operator.methodName, - asList(readExpression(expression.getRightOperand())), - operator.returnValue); + final ExpressionNode left = readExpression(expression.getLeftOperand()); + final ExpressionNode right = readExpression(expression.getRightOperand()); + if (expression.getOperator() == Operator.NOT_EQUALS) { + return MethodCallNode.not(methodCall(left, "equals", asList(right), BooleanValue.REF)); + } else { + JavaOperator operator = readOperator(expression.getOperator()); + return MethodCallNode.methodCall( + left, + operator.methodName, + asList(right), + operator.returnValue); + } } private static JavaOperator readOperator(Operator operator) { diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java index 8245f87..820c2b1 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java @@ -1,12 +1,18 @@ package org.zwobble.couscous.interpreter.values; +import java.util.Collections; import java.util.Optional; import org.zwobble.couscous.interpreter.NoSuchField; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValues; public final class BooleanInterpreterValue implements InterpreterValue { - private static final ConcreteType TYPE = ConcreteType.builder(BooleanInterpreterValue.class, "Boolean").build(); + private static final ConcreteType TYPE = ConcreteType.builder(BooleanInterpreterValue.class, "boolean") + + .method("negate", Collections.emptyList(), (environment, arguments) -> + new BooleanInterpreterValue(!arguments.getReceiver().getValue())) + + .build(); private final boolean value; public boolean getValue() { -- cgit v1.2.3