aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java30
-rw-r--r--src/main/java/org/zwobble/couscous/util/ExtraLists.java12
-rw-r--r--src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java11
-rw-r--r--src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java16
-rw-r--r--src/test/resources/java/for-factorial/com/example/ForFactorial.java11
5 files changed, 80 insertions, 0 deletions
diff --git a/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java b/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java
index a766cce..97a235e 100644
--- a/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java
+++ b/src/main/java/org/zwobble/couscous/frontends/java/JavaStatementReader.java
@@ -7,6 +7,7 @@ import org.zwobble.couscous.values.BooleanValue;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static org.zwobble.couscous.ast.ExpressionStatementNode.expressionStatement;
@@ -15,6 +16,8 @@ import static org.zwobble.couscous.ast.WhileNode.whileLoop;
import static org.zwobble.couscous.frontends.java.JavaExpressionReader.readExpression;
import static org.zwobble.couscous.frontends.java.JavaExpressionReader.readExpressionWithoutBoxing;
import static org.zwobble.couscous.frontends.java.JavaTypes.typeOf;
+import static org.zwobble.couscous.util.ExtraLists.append;
+import static org.zwobble.couscous.util.ExtraLists.concat;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
class JavaStatementReader {
@@ -41,6 +44,9 @@ class JavaStatementReader {
case ASTNode.WHILE_STATEMENT:
return asList(readWhileStatement((WhileStatement)statement));
+ case ASTNode.FOR_STATEMENT:
+ return readForStatement((ForStatement)statement);
+
case ASTNode.VARIABLE_DECLARATION_STATEMENT:
return readVariableDeclarationStatement((VariableDeclarationStatement)statement);
@@ -78,10 +84,34 @@ class JavaStatementReader {
readStatement(statement.getBody()));
}
+ private List<StatementNode> readForStatement(ForStatement statement) {
+ List javaInitialisers = statement.initializers();
+ if (javaInitialisers.size() != 1) {
+ throw new UnsupportedOperationException();
+ }
+ VariableDeclarationExpression javaDeclaration = (VariableDeclarationExpression) javaInitialisers.get(0);
+ @SuppressWarnings("unchecked")
+ List<VariableDeclarationFragment> fragments = javaDeclaration.fragments();
+ @SuppressWarnings("unchecked")
+ List<Expression> updaters = statement.updaters();
+
+ return append(
+ readDeclarationFragments(fragments, typeOf(javaDeclaration.getType())),
+ whileLoop(
+ readExpression(BooleanValue.REF, statement.getExpression()),
+ concat(
+ readStatement(statement.getBody()),
+ eagerMap(updaters, updater -> expressionStatement(readExpressionWithoutBoxing(updater))))));
+ }
+
private static List<StatementNode> readVariableDeclarationStatement(VariableDeclarationStatement statement) {
@SuppressWarnings("unchecked")
List<VariableDeclarationFragment> fragments = statement.fragments();
TypeName type = typeOf(statement.getType());
+ return readDeclarationFragments(fragments, type);
+ }
+
+ private static List<StatementNode> readDeclarationFragments(List<VariableDeclarationFragment> fragments, TypeName type) {
return eagerMap(fragments, fragment ->
localVariableDeclaration(
fragment.resolveBinding().getKey(),
diff --git a/src/main/java/org/zwobble/couscous/util/ExtraLists.java b/src/main/java/org/zwobble/couscous/util/ExtraLists.java
index be8ffb3..8c282e8 100644
--- a/src/main/java/org/zwobble/couscous/util/ExtraLists.java
+++ b/src/main/java/org/zwobble/couscous/util/ExtraLists.java
@@ -7,6 +7,18 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class ExtraLists {
+ public static <T> List<T> cons(T value, List<T> list) {
+ return Stream.concat(Stream.of(value), list.stream()).collect(Collectors.toList());
+ }
+
+ public static <T> List<T> append(List<T> list, T value) {
+ return Stream.concat(list.stream(), Stream.of(value)).collect(Collectors.toList());
+ }
+
+ public static <T> List<T> concat(List<T> first, List<T> second) {
+ return Stream.concat(first.stream(), second.stream()).collect(Collectors.toList());
+ }
+
@SuppressWarnings("unchecked")
public static <T, R, E extends Exception> List<R> map(
Stream<T> stream,
diff --git a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
index f17f42b..8c6c3b1 100644
--- a/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/JavaToPythonTests.java
@@ -69,6 +69,17 @@ public class JavaToPythonTests {
"factorial",
asList(value(6))));
}
+
+ @Test
+ public void forFactorial() throws Exception {
+ assertEquals(
+ value(720),
+ execTestProgram(
+ "for-factorial",
+ TypeName.of("com.example.ForFactorial"),
+ "factorial",
+ asList(value(6))));
+ }
private PrimitiveValue execTestProgram(
String directoryName,
diff --git a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
index ad8bcbb..9d21ed2 100644
--- a/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/frontends/java/JavaReaderTests.java
@@ -24,6 +24,7 @@ import static org.zwobble.couscous.ast.FieldAccessNode.fieldAccess;
import static org.zwobble.couscous.ast.FieldDeclarationNode.field;
import static org.zwobble.couscous.ast.IfStatementNode.ifStatement;
import static org.zwobble.couscous.ast.LiteralNode.literal;
+import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration;
import static org.zwobble.couscous.ast.MethodCallNode.*;
import static org.zwobble.couscous.ast.ReturnNode.returns;
import static org.zwobble.couscous.ast.StaticMethodCallNode.boxBoolean;
@@ -504,6 +505,21 @@ public class JavaReaderTests {
asList(returns(literal(1)))),
readStatement("int", "while (true) { return 1; }"));
}
+
+ @Test
+ public void canReadForLoops() {
+ List<StatementNode> statements = readStatements("int", "for (int x = 0; true; ++x) { return 1; }");
+ LocalVariableDeclarationNode declaration = (LocalVariableDeclarationNode) statements.get(0);
+ assertEquals(
+ asList(
+ localVariableDeclaration(declaration.getDeclaration(), literal(0)),
+ whileLoop(
+ literal(true),
+ asList(
+ returns(literal(1)),
+ expressionStatement(assign(declaration, integerAdd(reference(declaration), literal(1))))))),
+ statements);
+ }
@Test
public void canDeclareConstructor() {
diff --git a/src/test/resources/java/for-factorial/com/example/ForFactorial.java b/src/test/resources/java/for-factorial/com/example/ForFactorial.java
new file mode 100644
index 0000000..a5fef50
--- /dev/null
+++ b/src/test/resources/java/for-factorial/com/example/ForFactorial.java
@@ -0,0 +1,11 @@
+package com.example;
+
+public class ForFactorial {
+ public static int factorial(int n) {
+ int result = 1;
+ for (int i = 2; i <= n; ++i) {
+ result *= i;
+ }
+ return result;
+ }
+}