diff options
Diffstat (limited to 'src/test/java/org/zwobble')
6 files changed, 225 insertions, 40 deletions
diff --git a/src/test/java/org/zwobble/couscous/tests/MethodRunner.java b/src/test/java/org/zwobble/couscous/tests/MethodRunner.java index 3f69779..1a856ba 100644 --- a/src/test/java/org/zwobble/couscous/tests/MethodRunner.java +++ b/src/test/java/org/zwobble/couscous/tests/MethodRunner.java @@ -1,10 +1,13 @@ package org.zwobble.couscous.tests; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.values.PrimitiveValue; + import java.util.List; -import org.zwobble.couscous.ast.ClassNode; -import org.zwobble.couscous.ast.TypeName; -import org.zwobble.couscous.values.PrimitiveValue; +import static org.zwobble.couscous.util.ExtraLists.list; public interface MethodRunner { PrimitiveValue runMethod( @@ -12,4 +15,19 @@ public interface MethodRunner { TypeName className, String methodName, List<PrimitiveValue> arguments); + + default PrimitiveValue evalExpression(List<ClassNode> classes, ExpressionNode expression) { + ClassNode programNode = ClassNode.builder("Program") + .method(MethodNode.staticMethod("run") + .statement(ReturnNode.returns(expression)) + .build()) + .build(); + return runMethod( + ImmutableList.copyOf(Iterables.concat( + classes, + list(programNode))), + programNode.getName(), + "run", + list()); + } } diff --git a/src/test/java/org/zwobble/couscous/tests/backends/Processes.java b/src/test/java/org/zwobble/couscous/tests/backends/Processes.java new file mode 100644 index 0000000..63e9b35 --- /dev/null +++ b/src/test/java/org/zwobble/couscous/tests/backends/Processes.java @@ -0,0 +1,31 @@ +package org.zwobble.couscous.tests.backends; + +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.util.List; + +public class Processes { + public static String run(List<String> arguments, Path directoryPath) throws IOException, InterruptedException { + Process process = new ProcessBuilder(arguments.toArray(new String[arguments.size()])) + .directory(directoryPath.toFile()) + .start(); + + int exitCode = process.waitFor(); + String output = readString(process.getInputStream()).trim(); + String stderrOutput = readString(process.getErrorStream()); + if (exitCode != 0) { + throw new RuntimeException("stderr was: " + stderrOutput); + } else { + return output; + } + } + + private static String readString(final InputStream stream) throws IOException { + return CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8)); + } +} 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 new file mode 100644 index 0000000..7366942 --- /dev/null +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpCompilerEvalTests.java @@ -0,0 +1,82 @@ +package org.zwobble.couscous.tests.backends.csharp; + +import org.junit.Ignore; +import org.junit.Test; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.ExpressionNode; +import org.zwobble.couscous.tests.BackendEvalTests; +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() { + } + + @Test + @Ignore + public void canEvaluateOperationsOnBooleans() { + } + + @Test + @Ignore + public void canEvaluateOperationsOnIntegers() { + } + + @Test + @Ignore + public void whenConditionIsTrueThenValueOfConditionalTernaryIsTrueBranch() { + } + + @Test + @Ignore + public void whenConditionIsFalseThenValueOfConditionalTernaryIsFalseBranch() { + } + + @Test + @Ignore + public void canCallMethodWithNoArgumentsOnBuiltin() { + } + + @Test + @Ignore + public void canCallMethodWithArgumentsOnBuiltin() { + } + + @Test + @Ignore + public void canCallBuiltinStaticMethod() { + } + + @Test + @Ignore + public void canCallStaticMethodFromUserDefinedStaticMethod() { + } + + @Test + @Ignore + public void canCallInstanceMethodWithNoArgumentsOnUserDefinedClass() { + } + + @Test + @Ignore + public void canCallInstanceMethodWithArgumentsOnUserDefinedClass() { + } + + @Test + @Ignore + public void constructorIsExecutedOnConstruction() { + } + + @Override + protected PrimitiveValue evalExpression(List<ClassNode> classes, ExpressionNode expression) { + return new CsharpMethodRunner().evalExpression(classes, expression); + } +} 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 new file mode 100644 index 0000000..aee851a --- /dev/null +++ b/src/test/java/org/zwobble/couscous/tests/backends/csharp/CsharpMethodRunner.java @@ -0,0 +1,84 @@ +package org.zwobble.couscous.tests.backends.csharp; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterators; +import org.zwobble.couscous.Backend; +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.ast.MethodSignature; +import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.backends.csharp.CsharpBackend; +import org.zwobble.couscous.backends.python.PythonCodeGenerator; +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 org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively; +import static org.zwobble.couscous.util.ExtraLists.eagerMap; +import static org.zwobble.couscous.util.ExtraLists.list; + +public class CsharpMethodRunner implements MethodRunner { + private static final String NAMESPACE = "Couscous"; + + @Override + public PrimitiveValue runMethod(List<ClassNode> classNodes, TypeName className, String methodName, List<PrimitiveValue> arguments) { + try { + Path directoryPath = Files.createTempDirectory(null); + Backend compiler = new CsharpBackend(directoryPath, NAMESPACE); + try { + compiler.compile(classNodes); + return runFunction(directoryPath, className, methodName, arguments); + } finally { + deleteRecursively(directoryPath.toFile()); + } + } catch (final java.lang.Throwable $ex) { + throw new RuntimeException($ex); + } + } + + public static PrimitiveValue runFunction( + Path directoryPath, + TypeName className, + String methodName, + List<PrimitiveValue> arguments) + throws IOException, InterruptedException + { + // TODO: use arguments + String csharpMethodName = PythonCodeGenerator.toName(new MethodSignature( + methodName, + eagerMap(arguments, argument -> argument.getType()))); + String program = + "public class MethodRunnerExample { " + + " public static void Main() { " + + " System.Console.WriteLine(" + NAMESPACE + "." + className.getQualifiedName() + "." + csharpMethodName + "());" + + " }" + + "}"; + Files.write(directoryPath.resolve("MethodRunnerExample.cs"), list(program)); + Processes.run( + ExtraLists.concat( + list("mcs", "-out:MethodRunnerExample.exe"), + findCsharpFiles(directoryPath)), + directoryPath); + String output = Processes.run(list("mono", "MethodRunnerExample.exe"), directoryPath); + return readPrimitive(output); + } + + private static List<String> findCsharpFiles(Path directoryPath) throws IOException { + return ImmutableList.copyOf( + Iterators.transform( + Iterators.filter( + Files.newDirectoryStream(directoryPath).iterator(), + path -> path.toFile().isFile() && path.toString().endsWith(".cs")), + path -> path.toString())); + } + + private static PrimitiveValue readPrimitive(String output) { + return PrimitiveValues.value(output); + } +} diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerEvalTests.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerEvalTests.java index 61f5c38..e4ff1cb 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerEvalTests.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerEvalTests.java @@ -1,32 +1,15 @@ package org.zwobble.couscous.tests.backends.python; -import java.util.List; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.ExpressionNode; -import org.zwobble.couscous.ast.MethodNode; -import org.zwobble.couscous.ast.ReturnNode; import org.zwobble.couscous.tests.BackendEvalTests; import org.zwobble.couscous.values.PrimitiveValue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import static java.util.Arrays.asList; -import static org.zwobble.couscous.util.ExtraLists.list; + +import java.util.List; public class PythonCompilerEvalTests extends BackendEvalTests { @Override protected PrimitiveValue evalExpression(List<ClassNode> classes, ExpressionNode expression) { - ClassNode programNode = ClassNode.builder("Program") - .method(MethodNode.staticMethod("run") - .statement(ReturnNode.returns(expression)) - .build()) - .build(); - PythonMethodRunner runner = new PythonMethodRunner(); - return runner.runMethod( - ImmutableList.copyOf(Iterables.concat( - classes, - list(programNode))), - programNode.getName(), - "run", - list()); + return new PythonMethodRunner().evalExpression(classes, expression); } }
\ No newline at end of file diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java index 572d0b9..14fcf80 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java @@ -1,8 +1,6 @@ package org.zwobble.couscous.tests.backends.python; -import com.google.common.base.Charsets; import com.google.common.base.Joiner; -import com.google.common.io.CharStreams; import org.hamcrest.Matchers; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.MethodSignature; @@ -11,11 +9,10 @@ import org.zwobble.couscous.backends.python.PythonBackend; import org.zwobble.couscous.backends.python.PythonCodeGenerator; import org.zwobble.couscous.backends.python.PythonSerializer; import org.zwobble.couscous.tests.MethodRunner; +import org.zwobble.couscous.tests.backends.Processes; import org.zwobble.couscous.values.PrimitiveValue; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -24,6 +21,7 @@ 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.UNIT; import static org.zwobble.couscous.values.PrimitiveValues.value; @@ -58,15 +56,8 @@ public class PythonMethodRunner implements MethodRunner { String program = "from couscous." + className.getQualifiedName() + " import " + className.getSimpleName() + ";" + "value = " + className.getSimpleName() + "." + pythonMethodName + "(" + argumentsString + ");" + "print(type(value)); print(value)"; - Process process = new ProcessBuilder("python3.4", "-c", program).directory(directoryPath.toFile()).start(); - int exitCode = process.waitFor(); - String output = readString(process.getInputStream()).trim(); - String stderrOutput = readString(process.getErrorStream()); - if (exitCode != 0) { - throw new RuntimeException("stderr was: " + stderrOutput); - } else { - return readPrimitive(output); - } + String output = Processes.run(list("python3.4", "-c", program), directoryPath); + return readPrimitive(output); } private static final String PACKAGE_PREFIX = "couscous."; @@ -92,8 +83,4 @@ public class PythonMethodRunner implements MethodRunner { throw new RuntimeException("Unhandled type: " + type); } } - - private static String readString(final InputStream stream) throws IOException { - return CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8)); - } }
\ No newline at end of file |
