From 903963a7c2b6345c41568f00de4d4752466f02f0 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 31 Jul 2016 19:18:13 +0100 Subject: Desugar foreach to for rather than while --- .../backends/csharp/CsharpCodeGenerator.java | 4 +- .../backends/python/PythonCodeGenerator.java | 4 +- .../couscous/transforms/DesugarForEachToFor.java | 53 ++++++++++++++++++++++ .../couscous/transforms/DesugarForEachToWhile.java | 49 -------------------- 4 files changed, 57 insertions(+), 53 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/transforms/DesugarForEachToFor.java delete mode 100644 src/main/java/org/zwobble/couscous/transforms/DesugarForEachToWhile.java (limited to 'src/main/java') diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java index 28d2a3e..2245782 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java @@ -5,7 +5,7 @@ import org.zwobble.couscous.ast.Node; import org.zwobble.couscous.ast.visitors.NodeTransformer; import org.zwobble.couscous.backends.csharp.primitives.CsharpPrimitiveMethods; import org.zwobble.couscous.backends.naming.Naming; -import org.zwobble.couscous.transforms.DesugarForEachToWhile; +import org.zwobble.couscous.transforms.DesugarForEachToFor; import org.zwobble.couscous.transforms.DesugarForToWhile; import org.zwobble.couscous.types.*; @@ -47,7 +47,7 @@ public class CsharpCodeGenerator { return nodeTransformer.transform( CsharpPrimitiveMethods.TRANSFORMER.transform( DesugarForToWhile.transformer().transform( - DesugarForEachToWhile.transformer().transform( + DesugarForEachToFor.transformer().transform( node ) ) 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 29e7274..2190f66 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -10,7 +10,7 @@ import org.zwobble.couscous.ast.visitors.DynamicNodeMapper; import org.zwobble.couscous.ast.visitors.NodeTransformer; import org.zwobble.couscous.backends.naming.Names; import org.zwobble.couscous.backends.python.ast.*; -import org.zwobble.couscous.transforms.DesugarForEachToWhile; +import org.zwobble.couscous.transforms.DesugarForEachToFor; import org.zwobble.couscous.transforms.DesugarForToWhile; import org.zwobble.couscous.transforms.DesugarSwitchToIfElse; import org.zwobble.couscous.types.ScalarType; @@ -63,7 +63,7 @@ public class PythonCodeGenerator { public static PythonModuleNode generateCode(TypeNode sugaredTypeNode) { NodeTransformer switchTransformer = DesugarSwitchToIfElse.transformer(); NodeTransformer forTransformer = DesugarForToWhile.transformer(); - NodeTransformer forEachTransformer = DesugarForEachToWhile.transformer(); + NodeTransformer forEachTransformer = DesugarForEachToFor.transformer(); TypeNode typeNode = forTransformer.transformTypeDeclaration( forEachTransformer.transformTypeDeclaration( switchTransformer.transformTypeDeclaration(sugaredTypeNode) diff --git a/src/main/java/org/zwobble/couscous/transforms/DesugarForEachToFor.java b/src/main/java/org/zwobble/couscous/transforms/DesugarForEachToFor.java new file mode 100644 index 0000000..bdae29a --- /dev/null +++ b/src/main/java/org/zwobble/couscous/transforms/DesugarForEachToFor.java @@ -0,0 +1,53 @@ +package org.zwobble.couscous.transforms; + +import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.ast.visitors.NodeTransformer; +import org.zwobble.couscous.frontends.java.JavaTypes; +import org.zwobble.couscous.frontends.java.Scope; +import org.zwobble.couscous.types.Type; +import org.zwobble.couscous.types.Types; + +import java.util.List; +import java.util.Optional; + +import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration; +import static org.zwobble.couscous.ast.MethodCallNode.methodCall; +import static org.zwobble.couscous.ast.VariableReferenceNode.reference; +import static org.zwobble.couscous.types.BoundTypeParameter.boundTypeParameter; +import static org.zwobble.couscous.util.ExtraLists.cons; +import static org.zwobble.couscous.util.ExtraLists.list; + +public class DesugarForEachToFor { + public static NodeTransformer transformer() { + Scope scope = Scope.create().temporaryPrefix("_couscous_desugar_foreach_to_for"); + return NodeTransformer.builder() + .transformStatement(statement -> { + if (statement.type() == NodeTypes.FOR_EACH) { + return Optional.of(desugar(scope, ((ForEachNode) statement))); + } else { + return Optional.empty(); + } + }) + .build(); + } + + public static List desugar(Scope scope, ForEachNode forEach) { + Type elementType = forEach.getTarget().getType(); + ExpressionNode iteratorValue = methodCall(forEach.getIterable(), "iterator", list(), JavaTypes.iterator(elementType)); + LocalVariableDeclarationNode iterator = scope.temporaryVariable(iteratorValue); + + ExpressionNode hasNext = methodCall(reference(iterator), "hasNext", list(), Types.BOOLEAN); + ExpressionNode next = methodCall(reference(iterator), "next", list(), boundTypeParameter(JavaTypes.ITERATOR_TYPE_PARAMETER, elementType)); + ForNode loop = new ForNode( + list(iterator), + hasNext, + list(), + cons( + localVariableDeclaration(forEach.getTarget(), next), + forEach.getStatements() + ) + ); + + return list(loop); + } +} diff --git a/src/main/java/org/zwobble/couscous/transforms/DesugarForEachToWhile.java b/src/main/java/org/zwobble/couscous/transforms/DesugarForEachToWhile.java deleted file mode 100644 index 7b6147b..0000000 --- a/src/main/java/org/zwobble/couscous/transforms/DesugarForEachToWhile.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.zwobble.couscous.transforms; - -import org.zwobble.couscous.ast.*; -import org.zwobble.couscous.ast.visitors.NodeTransformer; -import org.zwobble.couscous.frontends.java.JavaTypes; -import org.zwobble.couscous.frontends.java.Scope; -import org.zwobble.couscous.types.Type; -import org.zwobble.couscous.types.Types; - -import java.util.List; -import java.util.Optional; - -import static org.zwobble.couscous.ast.LocalVariableDeclarationNode.localVariableDeclaration; -import static org.zwobble.couscous.ast.MethodCallNode.methodCall; -import static org.zwobble.couscous.ast.VariableReferenceNode.reference; -import static org.zwobble.couscous.ast.WhileNode.whileLoop; -import static org.zwobble.couscous.types.BoundTypeParameter.boundTypeParameter; -import static org.zwobble.couscous.util.ExtraLists.cons; -import static org.zwobble.couscous.util.ExtraLists.list; - -public class DesugarForEachToWhile { - public static NodeTransformer transformer() { - Scope scope = Scope.create().temporaryPrefix("_couscous_desugar_foreach_to_while"); - return NodeTransformer.builder() - .transformStatement(statement -> { - if (statement.type() == NodeTypes.FOR_EACH) { - return Optional.of(desugar(scope, ((ForEachNode) statement))); - } else { - return Optional.empty(); - } - }) - .build(); - } - - public static List desugar(Scope scope, ForEachNode forEach) { - Type elementType = forEach.getTarget().getType(); - ExpressionNode iteratorValue = methodCall(forEach.getIterable(), "iterator", list(), JavaTypes.iterator(elementType)); - LocalVariableDeclarationNode iterator = scope.temporaryVariable(iteratorValue); - - ExpressionNode hasNext = methodCall(reference(iterator), "hasNext", list(), Types.BOOLEAN); - ExpressionNode next = methodCall(reference(iterator), "next", list(), boundTypeParameter(JavaTypes.ITERATOR_TYPE_PARAMETER, elementType)); - WhileNode loop = whileLoop(hasNext, cons( - localVariableDeclaration(forEach.getTarget(), next), - forEach.getStatements() - )); - - return list(new StatementBlockNode(list(iterator, loop))); - } -} -- cgit v1.2.3