aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-03-30 19:58:01 +0100
committerMichael Williamson <mike@zwobble.org>2016-03-30 19:58:01 +0100
commitc58796cf60fcb109ab56ae2b1c0872c58771f3e1 (patch)
tree99cf51fff2d1a2a90e318362b715d6ca51ff5306 /src
parent3b29956d75a827743b26b873c3e43386779f1175 (diff)
Add code generation for Python backend for arrays
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java10
-rw-r--r--src/test/java/org/zwobble/couscous/tests/backends/python/PythonCodeGeneratorTests.java62
2 files changed, 69 insertions, 3 deletions
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 1ed223e..9aa679a 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -23,6 +23,7 @@ import java.util.stream.Stream;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Iterators.singletonIterator;
+import static org.zwobble.couscous.backends.python.ast.PythonArrayNode.pythonArray;
import static org.zwobble.couscous.types.Types.erasure;
import static org.zwobble.couscous.backends.python.ast.PythonAssignmentNode.pythonAssignment;
import static org.zwobble.couscous.backends.python.ast.PythonAttributeAccessNode.pythonAttributeAccess;
@@ -42,6 +43,7 @@ import static org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNo
import static org.zwobble.couscous.backends.python.ast.PythonWhileNode.pythonWhile;
import static org.zwobble.couscous.backends.python.ast.visitors.PythonExpressionStatement.pythonExpressionStatement;
import static org.zwobble.couscous.util.Casts.tryCast;
+import static org.zwobble.couscous.util.ExtraLists.eagerMap;
import static org.zwobble.couscous.util.ExtraLists.list;
public class PythonCodeGenerator {
@@ -225,7 +227,7 @@ public class PythonCodeGenerator {
}
}
- private static PythonExpressionNode generateExpression(ExpressionNode expression) {
+ public static PythonExpressionNode generateExpression(ExpressionNode expression) {
return expression.accept(EXPRESSION_GENERATOR);
}
@@ -251,8 +253,10 @@ public class PythonCodeGenerator {
}
@Override
- public PythonExpressionNode visit(ArrayNode arrayNode) {
- throw new UnsupportedOperationException();
+ public PythonExpressionNode visit(ArrayNode array) {
+ return pythonArray(eagerMap(
+ array.getElements(),
+ PythonCodeGenerator::generateExpression));
}
@Override
diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCodeGeneratorTests.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCodeGeneratorTests.java
new file mode 100644
index 0000000..1b043bc
--- /dev/null
+++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCodeGeneratorTests.java
@@ -0,0 +1,62 @@
+package org.zwobble.couscous.tests.backends.python;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+import org.junit.Test;
+import org.zwobble.couscous.backends.python.PythonCodeGenerator;
+import org.zwobble.couscous.backends.python.ast.PythonArrayNode;
+import org.zwobble.couscous.backends.python.ast.PythonExpressionNode;
+import org.zwobble.couscous.backends.python.ast.PythonStringLiteralNode;
+import org.zwobble.couscous.types.Types;
+
+import java.util.List;
+import java.util.function.Function;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.zwobble.couscous.ast.ArrayNode.array;
+import static org.zwobble.couscous.ast.LiteralNode.literal;
+import static org.zwobble.couscous.util.ExtraLists.list;
+
+public class PythonCodeGeneratorTests {
+ @Test
+ public void arrayIsConvertedToPythonList() {
+ assertThat(
+ PythonCodeGenerator.generateExpression(array(Types.STRING, list(
+ literal("one"),
+ literal("two")))),
+ isPythonList(list(isPythonLiteral("one"), isPythonLiteral("two"))));
+ }
+
+ private <T> Matcher<PythonExpressionNode> isPythonLiteral(String value) {
+ return isA(PythonStringLiteralNode.class, hasFeature(
+ "value",
+ node -> node.getValue(),
+ equalTo(value)));
+ }
+
+ private static <T, U> Matcher<T> isA(Class<U> type, Matcher<? super U> downcastMatcher) {
+ return allOf(instanceOf(type), (Matcher<? super T>) downcastMatcher);
+ }
+
+ private static Matcher<PythonExpressionNode> isPythonList(
+ List<Matcher<? super PythonExpressionNode>> expectedElements)
+ {
+ return isA(PythonArrayNode.class, hasFeature(
+ "elements",
+ list -> list.getElements(),
+ contains(expectedElements)));
+ }
+
+ private static <T, U> Matcher<T> hasFeature(
+ String name,
+ Function<? super T, U> extract,
+ Matcher<? super U> subMatcher) {
+ return new FeatureMatcher<T, U>(subMatcher, name, name) {
+ @Override
+ protected U featureValueOf(T actual) {
+ return extract.apply(actual);
+ }
+ };
+ }
+}