diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-01-16 14:29:40 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-01-16 14:29:40 +0000 |
| commit | ee11b2bc0f6bf76a483775bc2c825757ea295c85 (patch) | |
| tree | 1c98449d81557c120fb23d4487c5ce85fd1cfac9 /src | |
| parent | c09802a7da260d04809471fd1526a83e488fe3fb (diff) | |
Split out C# serializer
Diffstat (limited to 'src')
4 files changed, 253 insertions, 84 deletions
diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java index 3fe1d5e..b588296 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java @@ -4,9 +4,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.io.Resources; import org.zwobble.couscous.Backend; -import org.zwobble.couscous.ast.*; -import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; -import org.zwobble.couscous.values.PrimitiveValueVisitor; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.MethodNode; +import org.zwobble.couscous.ast.ReturnNode; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -65,87 +65,7 @@ public class CsharpBackend implements Backend { ReturnNode returnNode = (ReturnNode) method.getBody().get(0); return "public static dynamic " + method.getName() + "() {" + - " return " + compileExpression(returnNode.getValue()) + ";" + + " return " + CsharpSerializer.serialize(returnNode.getValue(), namespace) + ";" + "}"; } - - private String compileExpression(ExpressionNode value) { - return value.accept(new ExpressionNodeMapper<String>() { - @Override - public String visit(LiteralNode literal) { - return literal.getValue().accept(new PrimitiveValueVisitor<String>() { - @Override - public String visitInteger(int value) { - return Integer.toString(value); - } - - @Override - public String visitString(String value) { - // TODO: escaping - return "\"" + value + "\""; - } - - @Override - public String visitBoolean(boolean value) { - return value ? "true" : "false"; - } - - @Override - public String visitUnit() { - throw new UnsupportedOperationException(); - } - - @Override - public String visitType(TypeName value) { - return "typeof(" + namespace + "." + value.getQualifiedName() + ")"; - } - }); - } - - @Override - public String visit(VariableReferenceNode variableReference) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(ThisReferenceNode reference) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(AssignmentNode assignment) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(TernaryConditionalNode ternaryConditional) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(MethodCallNode methodCall) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(ConstructorCallNode call) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(FieldAccessNode fieldAccess) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(TypeCoercionNode typeCoercion) { - throw new UnsupportedOperationException(); - } - - @Override - public String visit(CastNode cast) { - throw new UnsupportedOperationException(); - } - }); - } } diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java new file mode 100644 index 0000000..b8d81ad --- /dev/null +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpSerializer.java @@ -0,0 +1,173 @@ +package org.zwobble.couscous.backends.csharp; + +import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.ast.visitors.NodeVisitor; +import org.zwobble.couscous.values.PrimitiveValueVisitor; + +public class CsharpSerializer implements NodeVisitor { + public static String serialize(Node node, String namespace) { + CsharpWriter writer = new CsharpWriter(); + CsharpSerializer serializer = new CsharpSerializer(writer, namespace); + serializer.write(node); + return writer.asString(); + } + + private final CsharpWriter writer; + private final String namespace; + + private CsharpSerializer(CsharpWriter writer, String namespace) { + this.writer = writer; + this.namespace = namespace; + } + + private void write(Node node) { + node.accept(this); + } + + @Override + public void visit(LiteralNode literal) { + literal.getValue().accept(new PrimitiveValueVisitor<Void>() { + @Override + public Void visitInteger(int value) { + writer.writeIntegerLiteral(value); + return null; + } + + @Override + public Void visitString(String value) { + writer.writeStringLiteral(value); + return null; + } + + @Override + public Void visitBoolean(boolean value) { + writer.writeBooleanLiteral(value); + return null; + } + + @Override + public Void visitUnit() { + throw new UnsupportedOperationException(); + } + + @Override + public Void visitType(TypeName value) { + writer.writeKeyword("typeof"); + writer.writeSymbol("("); + writer.writeIdentifier(namespace + "." + value.getQualifiedName()); + writer.writeSymbol(")"); + return null; + } + }); + } + + @Override + public void visit(VariableReferenceNode variableReference) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(ThisReferenceNode reference) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(AssignmentNode assignment) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(TernaryConditionalNode ternaryConditional) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(MethodCallNode methodCall) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(ConstructorCallNode call) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(FieldAccessNode fieldAccess) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(TypeCoercionNode typeCoercion) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(CastNode cast) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(InstanceReceiver receiver) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(StaticReceiver receiver) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(ReturnNode returnNode) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(ExpressionStatementNode expressionStatement) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(LocalVariableDeclarationNode localVariableDeclaration) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(IfStatementNode ifStatement) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(WhileNode whileLoop) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(FormalArgumentNode formalArgumentNode) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(AnnotationNode annotation) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(MethodNode methodNode) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(ConstructorNode constructorNode) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(FieldDeclarationNode declaration) { + throw new UnsupportedOperationException(); + } + + @Override + public void visit(ClassNode classNode) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpWriter.java b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpWriter.java new file mode 100644 index 0000000..7aef7e6 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpWriter.java @@ -0,0 +1,34 @@ +package org.zwobble.couscous.backends.csharp; + +public class CsharpWriter { + private final StringBuilder builder = new StringBuilder(); + + public String asString() { + return builder.toString(); + } + + public void writeIntegerLiteral(int value) { + builder.append(Integer.toString(value)); + } + + public void writeStringLiteral(String value) { + // TODO: escaping + builder.append("\"" + value + "\""); + } + + public void writeBooleanLiteral(boolean value) { + builder.append(value ? "true" : "false"); + } + + public void writeKeyword(String keyword) { + builder.append(keyword); + } + + public void writeSymbol(String symbol) { + builder.append(symbol); + } + + public void writeIdentifier(String identifier) { + builder.append(identifier); + } +} 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 new file mode 100644 index 0000000..39e0e8f --- /dev/null +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpSerializerTests.java @@ -0,0 +1,42 @@ +package org.zwobble.couscous.tests.backends.csharp; + +import org.junit.Test; +import org.zwobble.couscous.ast.Node; +import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.backends.csharp.CsharpSerializer; + +import static org.junit.Assert.assertEquals; +import static org.zwobble.couscous.ast.LiteralNode.literal; + +public class CsharpSerializerTests { + @Test + public void integerLiterals() { + String output = serialize(literal(42)); + assertEquals("42", output); + } + + @Test + public void booleanLiterals() { + String trueOutput = serialize(literal(true)); + assertEquals("true", trueOutput); + + String falseOutput = serialize(literal(false)); + assertEquals("false", falseOutput); + } + + @Test + public void stringLiteralsUseDoubleQuotes() { + String output = serialize(literal("blah")); + assertEquals("\"blah\"", output); + } + + @Test + public void typeLiteralUsesTypeOfOperator() { + String output = serialize(literal(TypeName.of("com.example.Example"))); + assertEquals("typeof(Couscous.com.example.Example)", output); + } + + private String serialize(Node node) { + return CsharpSerializer.serialize(node, "Couscous"); + } +} |
