diff options
Diffstat (limited to 'src/main/java/org/zwobble/couscous/backends/python')
6 files changed, 92 insertions, 8 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 c6aa62d..6605fc9 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PrimitiveMethods.java @@ -9,6 +9,7 @@ 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.InternalCouscousValue; import org.zwobble.couscous.values.StringValue; import com.google.common.collect.ImmutableMap; @@ -16,6 +17,7 @@ import com.google.common.collect.ImmutableMap.Builder; import static java.util.Arrays.asList; import static org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode.pythonAttributeAccess; +import static org.zwobble.couscous.backends.python.ast.PythonBinaryOperation.pythonIs; import static org.zwobble.couscous.backends.python.ast.PythonCallNode.pythonCall; import static org.zwobble.couscous.backends.python.ast.PythonGetSliceNode.pythonGetSlice; import static org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode.pythonVariableReference; @@ -90,6 +92,18 @@ public class PrimitiveMethods { .put(IntegerValue.REF, INT_METHODS) .build(); + private static final Map<String, PrimitiveStaticMethodGenerator> INTERNAL_METHODS = + ImmutableMap.<String, PrimitiveStaticMethodGenerator>builder() + + .put("same", arguments -> pythonIs(arguments.get(0), arguments.get(1))) + + .build(); + + private static final Map<TypeName, Map<String, PrimitiveStaticMethodGenerator>> STATIC_METHODS = + ImmutableMap.<TypeName, Map<String, PrimitiveStaticMethodGenerator>>builder() + .put(InternalCouscousValue.REF, INTERNAL_METHODS) + .build(); + public static boolean isPrimitive(TypeName type) { return METHODS.containsKey(type); } @@ -103,4 +117,14 @@ public class PrimitiveMethods { public interface PrimitiveMethodGenerator { PythonExpressionNode generate(PythonExpressionNode receiver, List<PythonExpressionNode> arguments); } + + public static Optional<PrimitiveStaticMethodGenerator> getPrimitiveStaticMethod(TypeName type, String methodName) { + return Optional.ofNullable(STATIC_METHODS.get(type)) + .flatMap(methodsForType -> Optional.ofNullable(methodsForType.get(methodName))); + } + + @FunctionalInterface + public interface PrimitiveStaticMethodGenerator { + PythonExpressionNode generate(List<PythonExpressionNode> arguments); + } } diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java index 54d56ed..fb1851c 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -29,6 +29,7 @@ import org.zwobble.couscous.ast.visitors.NodeVisitorWithEmptyDefaults; import org.zwobble.couscous.ast.visitors.NodeVisitors; import org.zwobble.couscous.ast.visitors.StatementNodeMapper; import org.zwobble.couscous.backends.python.PrimitiveMethods.PrimitiveMethodGenerator; +import org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode; import org.zwobble.couscous.backends.python.ast.PythonBlock; import org.zwobble.couscous.backends.python.ast.PythonClassNode; import org.zwobble.couscous.backends.python.ast.PythonExpressionNode; @@ -39,6 +40,7 @@ import org.zwobble.couscous.backends.python.ast.PythonStatementNode; import org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; +import org.zwobble.couscous.values.InternalCouscousValue; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValueVisitor; import org.zwobble.couscous.values.StringValue; @@ -92,7 +94,9 @@ public class PythonCodeGenerator { private static Stream<PythonImportNode> generateImports(ClassNode classNode) { Set<TypeName> classes = findReferencedClasses(classNode); - return classes.stream().map(name -> pythonImport(importPathToRoot(classNode) + name.getQualifiedName(), asList(pythonImportAlias(name.getSimpleName())))); + return classes.stream() + .filter(name -> !name.equals(InternalCouscousValue.REF)) + .map(name -> pythonImport(importPathToRoot(classNode) + name.getQualifiedName(), asList(pythonImportAlias(name.getSimpleName())))); } private static String importPathToRoot(ClassNode classNode) { @@ -243,11 +247,14 @@ public class PythonCodeGenerator { @Override public PythonExpressionNode visit(StaticMethodCallNode staticMethodCall) { - final org.zwobble.couscous.ast.TypeName className = staticMethodCall.getClassName(); - final org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName()); - final org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode methodReference = pythonAttributeAccess(classReference, staticMethodCall.getMethodName()); - final java.util.List<org.zwobble.couscous.backends.python.ast.PythonExpressionNode> arguments = generateExpressions(staticMethodCall.getArguments()); - return pythonCall(methodReference, arguments); + TypeName className = staticMethodCall.getClassName(); + PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName()); + PythonAttributeAccessNode methodReference = pythonAttributeAccess(classReference, staticMethodCall.getMethodName()); + List<PythonExpressionNode> arguments = generateExpressions(staticMethodCall.getArguments()); + + return PrimitiveMethods.getPrimitiveStaticMethod(className, staticMethodCall.getMethodName()) + .map(generator -> generator.generate(arguments)) + .orElseGet(() -> pythonCall(methodReference, arguments)); } @Override diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java index c8f9932..d077736 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCompiler.java @@ -17,7 +17,9 @@ import static org.zwobble.couscous.backends.python.PythonSerializer.serialize; public class PythonCompiler { private static final List<String> RUNTIME_FILES = asList( - "java.lang.Integer", "_couscous"); + "java.lang.Object", + "java.lang.Integer", + "_couscous"); private final Path root; private final String packageName; 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 eadb545..2fb341f 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonSerializer.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.function.Consumer; import org.zwobble.couscous.backends.python.ast.PythonAssignmentNode; import org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode; +import org.zwobble.couscous.backends.python.ast.PythonBinaryOperation; import org.zwobble.couscous.backends.python.ast.PythonBlock; import org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode; import org.zwobble.couscous.backends.python.ast.PythonCallNode; @@ -34,7 +35,7 @@ public class PythonSerializer implements PythonNodeVisitor { return writer.asString(); } - private PythonWriter writer; + private final PythonWriter writer; private PythonSerializer(PythonWriter writer) { this.writer = writer; @@ -111,6 +112,15 @@ public class PythonSerializer implements PythonNodeVisitor { writer.writeSpace(); writeParenthesised(notOperation.getOperand()); } + + @Override + public void visit(PythonBinaryOperation operation) { + writeParenthesised(operation.getLeft()); + writer.writeSpace(); + writer.writeKeyword(operation.getOperator()); + writer.writeSpace(); + writeParenthesised(operation.getRight()); + } @Override public void visit(PythonReturnNode pythonReturn) { 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 new file mode 100644 index 0000000..1fc87c3 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/backends/python/ast/PythonBinaryOperation.java @@ -0,0 +1,39 @@ +package org.zwobble.couscous.backends.python.ast; + +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); + } + + private final String operator; + private final PythonExpressionNode left; + private final PythonExpressionNode right; + + public PythonBinaryOperation( + String operator, + PythonExpressionNode left, + PythonExpressionNode right) { + this.operator = operator; + this.left = left; + this.right = right; + } + + public String getOperator() { + return operator; + } + + public PythonExpressionNode getLeft() { + return left; + } + + public PythonExpressionNode getRight() { + return right; + } + + @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 59a1fe9..a1ed7d5 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 @@ -2,6 +2,7 @@ package org.zwobble.couscous.backends.python.ast.visitors; import org.zwobble.couscous.backends.python.ast.PythonAssignmentNode; import org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode; +import org.zwobble.couscous.backends.python.ast.PythonBinaryOperation; import org.zwobble.couscous.backends.python.ast.PythonBooleanLiteralNode; import org.zwobble.couscous.backends.python.ast.PythonCallNode; import org.zwobble.couscous.backends.python.ast.PythonClassNode; @@ -27,6 +28,7 @@ public interface PythonNodeVisitor { void visit(PythonCallNode call); void visit(PythonGetSliceNode getSlice); void visit(PythonNotNode notOperation); + void visit(PythonBinaryOperation operation); void visit(PythonReturnNode pythonReturn); void visit(PythonPassNode pass); |
