From 7663b33d174cbdef3dd88364b1854aadee74f8aa Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 15 Jan 2016 17:48:10 +0000 Subject: Implement literal evaluation in C# --- .../couscous/backends/csharp/CsharpBackend.java | 20 ++++++++++------ .../backends/csharp/CsharpCompilerEvalTests.java | 5 ---- .../tests/backends/csharp/CsharpMethodRunner.java | 28 +++++++++++++++++++--- 3 files changed, 38 insertions(+), 15 deletions(-) (limited to 'src') 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 f8a2d50..adf306f 100644 --- a/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java +++ b/src/main/java/org/zwobble/couscous/backends/csharp/CsharpBackend.java @@ -1,5 +1,6 @@ package org.zwobble.couscous.backends.csharp; +import com.google.common.collect.Iterables; import org.zwobble.couscous.Backend; import org.zwobble.couscous.ast.*; import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper; @@ -11,6 +12,7 @@ import java.nio.file.Path; import java.util.List; import static com.google.common.collect.Iterables.transform; +import static org.zwobble.couscous.util.ExtraLists.list; public class CsharpBackend implements Backend { private final Path directoryPath; @@ -25,10 +27,14 @@ public class CsharpBackend implements Backend { public void compile(List classes) throws IOException { Files.write( directoryPath.resolve("Program.cs"), - transform( - classes, - classNode -> compileClass(classNode) - )); + Iterables.concat( + transform( + classes, + classNode -> compileClass(classNode)), + list( + "namespace " + namespace + ".java.lang {" + + " internal class String { }" + + "}"))); } private String compileClass(ClassNode classNode) { @@ -37,7 +43,7 @@ public class CsharpBackend implements Backend { .map(packageName -> packageName + ".") .orElse(""); return "namespace " + namespace + " {" + - " public class " + classNode.getSimpleName() + " {" + + " internal class " + classNode.getSimpleName() + " {" + String.join("\n", transform(classNode.getMethods(), method -> compileMethod(method))) + " }" + "}"; @@ -46,7 +52,7 @@ public class CsharpBackend implements Backend { private String compileMethod(MethodNode method) { ReturnNode returnNode = (ReturnNode) method.getBody().get(0); return - "public static string " + method.getName() + "() {" + + "public static dynamic " + method.getName() + "() {" + " return " + compileExpression(returnNode.getValue()) + ";" + "}"; } @@ -79,7 +85,7 @@ public class CsharpBackend implements Backend { @Override public String visitType(TypeName value) { - throw new UnsupportedOperationException(); + return "typeof(" + namespace + "." + value.getQualifiedName() + ")"; } }); } diff --git a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpCompilerEvalTests.java b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpCompilerEvalTests.java index 7366942..9c51117 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpCompilerEvalTests.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpCompilerEvalTests.java @@ -10,11 +10,6 @@ import org.zwobble.couscous.values.PrimitiveValue; import java.util.List; public class CsharpCompilerEvalTests extends BackendEvalTests { - @Test - @Ignore - public void canEvaluateLiterals() { - } - @Test @Ignore public void equalityOnReferenceTypesChecksForIdentity() { diff --git a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpMethodRunner.java b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpMethodRunner.java index aee851a..0adb5fc 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpMethodRunner.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpMethodRunner.java @@ -2,6 +2,7 @@ package org.zwobble.couscous.tests.backends.csharp; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; +import org.hamcrest.Matchers; import org.zwobble.couscous.Backend; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.MethodSignature; @@ -12,16 +13,18 @@ import org.zwobble.couscous.tests.MethodRunner; import org.zwobble.couscous.tests.backends.Processes; import org.zwobble.couscous.util.ExtraLists; import org.zwobble.couscous.values.PrimitiveValue; -import org.zwobble.couscous.values.PrimitiveValues; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; +import static java.lang.Integer.parseInt; +import static org.hamcrest.MatcherAssert.assertThat; import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively; import static org.zwobble.couscous.util.ExtraLists.eagerMap; import static org.zwobble.couscous.util.ExtraLists.list; +import static org.zwobble.couscous.values.PrimitiveValues.value; public class CsharpMethodRunner implements MethodRunner { private static final String NAMESPACE = "Couscous"; @@ -56,7 +59,9 @@ public class CsharpMethodRunner implements MethodRunner { String program = "public class MethodRunnerExample { " + " public static void Main() { " + - " System.Console.WriteLine(" + NAMESPACE + "." + className.getQualifiedName() + "." + csharpMethodName + "());" + + " var value = " + NAMESPACE + "." + className.getQualifiedName() + "." + csharpMethodName + "();" + + " System.Console.WriteLine(value.GetType());" + + " System.Console.WriteLine(value);" + " }" + "}"; Files.write(directoryPath.resolve("MethodRunnerExample.cs"), list(program)); @@ -78,7 +83,24 @@ public class CsharpMethodRunner implements MethodRunner { path -> path.toString())); } + private static final String NAMESPACE_PREFIX = "Couscous."; + private static PrimitiveValue readPrimitive(String output) { - return PrimitiveValues.value(output); + String[] lines = output.split("[\\r\\n]+"); + String type = lines[0]; + String value = lines[1]; + switch (type) { + case "System.Int32": + return value(parseInt(value)); + case "System.String": + return value(value); + case "System.Boolean": + return value(value.equals("True")); + case "System.MonoType": + assertThat(value, Matchers.startsWith(NAMESPACE_PREFIX)); + return value(TypeName.of(value.substring(NAMESPACE_PREFIX.length()))); + default: + throw new RuntimeException("Unhandled type: " + type); + } } } -- cgit v1.2.3