aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-07-15 14:34:15 +0100
committerMichael Williamson <mike@zwobble.org>2016-07-15 14:34:15 +0100
commit351567960bd825fbdd4a3f15719f7074a13cdfd3 (patch)
treec9b70be8a2724d9849b0382ddda780d982044c81
parentbc06840e00425db342bc5a021c0900d9e63b71f0 (diff)
Generate switch statements in C# backend
-rw-r--r--src/main/java/org/zwobble/couscous/ast/NodeTypes.java4
-rw-r--r--src/main/java/org/zwobble/couscous/backends/SourceCodeWriter.java12
-rw-r--r--src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java6
-rw-r--r--src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java32
-rw-r--r--src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java17
5 files changed, 64 insertions, 7 deletions
diff --git a/src/main/java/org/zwobble/couscous/ast/NodeTypes.java b/src/main/java/org/zwobble/couscous/ast/NodeTypes.java
index 86703ff..41ba8af 100644
--- a/src/main/java/org/zwobble/couscous/ast/NodeTypes.java
+++ b/src/main/java/org/zwobble/couscous/ast/NodeTypes.java
@@ -1,6 +1,8 @@
package org.zwobble.couscous.ast;
import com.google.common.collect.ImmutableMap;
+import org.zwobble.couscous.ast.sugar.SwitchCaseNode;
+import org.zwobble.couscous.ast.sugar.SwitchNode;
import java.util.Map;
@@ -69,6 +71,8 @@ public class NodeTypes {
.put(OperationNode.class, OPERATION)
.put(ReturnNode.class, RETURN)
.put(StaticReceiver.class, STATIC_RECEIVER)
+ .put(SwitchNode.class, SWITCH)
+ .put(SwitchCaseNode.class, SWITCH_CASE)
.put(TernaryConditionalNode.class, TERNARY_CONDITIONAL)
.put(ThisReferenceNode.class, THIS_REFERENCE)
.put(ThrowNode.class, THROW)
diff --git a/src/main/java/org/zwobble/couscous/backends/SourceCodeWriter.java b/src/main/java/org/zwobble/couscous/backends/SourceCodeWriter.java
index 57959fd..eb29a4e 100644
--- a/src/main/java/org/zwobble/couscous/backends/SourceCodeWriter.java
+++ b/src/main/java/org/zwobble/couscous/backends/SourceCodeWriter.java
@@ -69,15 +69,23 @@ public class SourceCodeWriter {
public void startBlock() {
runAction(blockStart);
- depth++;
+ indent();
builder.append("\n");
}
public void endBlock() {
- depth--;
+ dedent();
runAction(blockEnd);
}
+ public void indent() {
+ depth++;
+ }
+
+ public void dedent() {
+ depth--;
+ }
+
public void writeStatement(Action action) {
startStatement();
action.run();
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 23743d0..537184c 100644
--- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpCodeGenerator.java
@@ -7,8 +7,6 @@ import org.zwobble.couscous.ast.Node;
import org.zwobble.couscous.ast.Receiver;
import org.zwobble.couscous.ast.visitors.NodeTransformer;
import org.zwobble.couscous.backends.naming.Naming;
-import org.zwobble.couscous.frontends.java.Scope;
-import org.zwobble.couscous.transforms.DesugarSwitchToIfElse;
import org.zwobble.couscous.types.*;
import java.util.Map;
@@ -50,9 +48,7 @@ public class CsharpCodeGenerator {
}
private Node generateCode(Node node) {
- return node
- .transform(DesugarSwitchToIfElse.transformer(Scope.create()))
- .transform(nodeTransformer);
+ return node.transform(nodeTransformer);
}
private Type transformType(Type type) {
diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java
index 91a4400..6164d04 100644
--- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java
+++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java
@@ -2,6 +2,8 @@ package org.zwobble.couscous.backends.csharp;
import com.google.common.collect.ImmutableSet;
import org.zwobble.couscous.ast.*;
+import org.zwobble.couscous.ast.sugar.SwitchCaseNode;
+import org.zwobble.couscous.ast.sugar.SwitchNode;
import org.zwobble.couscous.ast.visitors.DynamicNodeMapper;
import org.zwobble.couscous.ast.visitors.DynamicNodeVisitor;
import org.zwobble.couscous.backends.SourceCodeWriter;
@@ -366,6 +368,36 @@ public class CsharpSerializer {
}
}
+ public void visit(SwitchNode switchNode) {
+ writer.writeStatement(() -> {
+ writer.writeKeyword("switch");
+ writer.writeSpace();
+ writer.writeSymbol("(");
+ write(switchNode.getValue());
+ writer.writeSymbol(")");
+ writer.startBlock();
+ switchNode.getCases().forEach(this::visit);
+ writer.endBlock();
+ });
+ }
+
+ private void visit(SwitchCaseNode switchCase) {
+ writer.writeStatement(() -> {
+ if (switchCase.getValue().isPresent()) {
+ writer.writeKeyword("case");
+ writer.writeSpace();
+ write(switchCase.getValue().get());
+ } else {
+ writer.writeKeyword("default");
+ }
+ writer.writeSymbol(":");
+ });
+ writer.indent();
+ writeAll(switchCase.getStatements());
+ writer.dedent();
+
+ }
+
public void visit(WhileNode whileLoop) {
writer.writeStatement(() -> {
writer.writeKeyword("while");
diff --git a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java
index 3cb723e..40653af 100644
--- a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java
@@ -3,6 +3,7 @@ package org.zwobble.couscous.tests.backends.csharp;
import org.junit.Test;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.ast.identifiers.Identifiers;
+import org.zwobble.couscous.ast.sugar.SwitchNode;
import org.zwobble.couscous.backends.csharp.CsharpSerializer;
import org.zwobble.couscous.tests.TestIds;
import org.zwobble.couscous.types.ScalarType;
@@ -35,6 +36,7 @@ import static org.zwobble.couscous.ast.TryNode.tryStatement;
import static org.zwobble.couscous.ast.VariableDeclaration.var;
import static org.zwobble.couscous.ast.VariableReferenceNode.reference;
import static org.zwobble.couscous.ast.WhileNode.whileLoop;
+import static org.zwobble.couscous.ast.sugar.SwitchCaseNode.switchCase;
import static org.zwobble.couscous.types.TypeParameter.typeParameter;
import static org.zwobble.couscous.util.ExtraLists.list;
@@ -308,6 +310,21 @@ public class CsharpSerializerTests {
}
@Test
+ public void switchStatement() {
+ Node node = new SwitchNode(
+ literal(1),
+ list(
+ switchCase(literal(1), list(returns(literal(10)))),
+ switchCase(list(returns(literal(0))))
+ )
+ );
+
+ String output = serialize(node);
+
+ assertEquals("switch (1) {\n case 1:\n return 10;\n default:\n return 0;\n}\n", output);
+ }
+
+ @Test
public void whileLoopPrintsConditionAndBody() {
String output = serialize(whileLoop(
literal(true),