aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-01-10 17:52:18 +0000
committerMichael Williamson <mike@zwobble.org>2016-01-10 17:52:18 +0000
commit8711de89810f1cd6782d98e0e4745c30532a77ac (patch)
treefd99c496f52eeaaa2dee10cfb71ea2dc9580bae8
parent7dab9cb11a7181094144e4319716c4d91262a289 (diff)
Support type literals in the backends
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonBackend.java14
-rw-r--r--src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java20
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java3
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java44
-rw-r--r--src/main/java/org/zwobble/couscous/values/TypeValue.java16
-rw-r--r--src/main/resources/python/runtime/java/lang/String.py2
-rw-r--r--src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java1
-rw-r--r--src/test/java/org/zwobble/couscous/tests/backends/python/PythonMethodRunner.java40
8 files changed, 108 insertions, 32 deletions
diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonBackend.java b/src/main/java/org/zwobble/couscous/backends/python/PythonBackend.java
index de36ed6..731faeb 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonBackend.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonBackend.java
@@ -1,20 +1,17 @@
package org.zwobble.couscous.backends.python;
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.Resources;
+import org.zwobble.couscous.Backend;
+import org.zwobble.couscous.ast.ClassNode;
+
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
-import java.util.stream.Stream;
-
-import com.google.common.collect.ImmutableList;
-import org.zwobble.couscous.Backend;
-import org.zwobble.couscous.ast.ClassNode;
-
-import com.google.common.io.Resources;
-import static java.util.Arrays.asList;
import static org.zwobble.couscous.backends.python.PythonCodeGenerator.generateCode;
import static org.zwobble.couscous.backends.python.PythonSerializer.serialize;
import static org.zwobble.couscous.util.ExtraLists.list;
@@ -24,6 +21,7 @@ public class PythonBackend implements Backend {
"java.lang.Object",
"java.lang.Boolean",
"java.lang.Integer",
+ "java.lang.String",
"_couscous");
private final Path root;
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 311d065..414d04b 100644
--- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
+++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java
@@ -105,6 +105,15 @@ public class PythonCodeGenerator {
return Stream.empty();
}
}
+
+ @Override
+ public Stream<TypeName> visit(LiteralNode literal) {
+ if (literal.getValue() instanceof TypeValue) {
+ return Stream.of(((TypeValue)literal.getValue()).getValue());
+ } else {
+ return Stream.empty();
+ }
+ }
}))
.collect(Collectors.toSet());
}
@@ -134,8 +143,7 @@ public class PythonCodeGenerator {
@Override
public PythonExpressionNode visit(TypeValue value) {
- // TODO:
- throw new UnsupportedOperationException();
+ return typeReference(value.getValue());
}
});
}
@@ -270,7 +278,7 @@ public class PythonCodeGenerator {
@Override
public PythonExpressionNode visit(ConstructorCallNode call) {
final org.zwobble.couscous.ast.TypeName className = call.getType();
- final org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode classReference = pythonVariableReference(className.getSimpleName());
+ final org.zwobble.couscous.backends.python.ast.PythonVariableReferenceNode classReference = typeReference(className);
final java.util.List<org.zwobble.couscous.backends.python.ast.PythonExpressionNode> arguments = generateExpressions(call.getArguments());
return pythonCall(classReference, arguments);
}
@@ -305,7 +313,7 @@ public class PythonCodeGenerator {
@Override
public PythonExpressionNode visit(TypeName receiver) {
- return pythonVariableReference(receiver.getSimpleName());
+ return typeReference(receiver);
}
});
}
@@ -322,6 +330,10 @@ public class PythonCodeGenerator {
return type.equals(IntegerValue.REF) || type.equals(ObjectValues.BOXED_INT);
}
+ private static PythonVariableReferenceNode typeReference(TypeName className) {
+ return pythonVariableReference(className.getSimpleName());
+ }
+
public static String toName(MethodSignature signature) {
return Joiner.on("__").join(Iterables.concat(
list(signature.getName()),
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java
index c405fe3..db33b9d 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java
@@ -39,8 +39,7 @@ public class InterpreterValues {
@Override
public InterpreterValue visit(TypeValue value) {
- // TODO:
- throw new UnsupportedOperationException();
+ return TypeInterpreterValue.of(value.getValue());
}
});
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java
new file mode 100644
index 0000000..97cf6ec
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java
@@ -0,0 +1,44 @@
+package org.zwobble.couscous.interpreter.values;
+
+import org.zwobble.couscous.ast.TypeName;
+import org.zwobble.couscous.interpreter.NoSuchField;
+import org.zwobble.couscous.values.ObjectValues;
+import org.zwobble.couscous.values.PrimitiveValue;
+import org.zwobble.couscous.values.PrimitiveValues;
+
+import java.util.Optional;
+
+public class TypeInterpreterValue implements InterpreterValue {
+ public static final ConcreteType TYPE = ConcreteType.builder(TypeInterpreterValue.class, ObjectValues.CLASS)
+ .build();
+
+ public static InterpreterValue of(TypeName type) {
+ return new TypeInterpreterValue(type);
+ }
+
+ private final TypeName type;
+
+ public TypeInterpreterValue(TypeName type) {
+ this.type = type;
+ }
+
+ @Override
+ public ConcreteType getType() {
+ return TYPE;
+ }
+
+ @Override
+ public Optional<PrimitiveValue> toPrimitiveValue() {
+ return Optional.of(PrimitiveValues.value(type));
+ }
+
+ @Override
+ public InterpreterValue getField(String fieldName) {
+ throw new NoSuchField(fieldName);
+ }
+
+ @Override
+ public void setField(String fieldName, InterpreterValue value) {
+ throw new NoSuchField(fieldName);
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/values/TypeValue.java b/src/main/java/org/zwobble/couscous/values/TypeValue.java
index 43dfc33..269839a 100644
--- a/src/main/java/org/zwobble/couscous/values/TypeValue.java
+++ b/src/main/java/org/zwobble/couscous/values/TypeValue.java
@@ -3,10 +3,14 @@ package org.zwobble.couscous.values;
import org.zwobble.couscous.ast.TypeName;
public class TypeValue implements PrimitiveValue {
- private final TypeName type;
+ private final TypeName value;
- public TypeValue(TypeName type) {
- this.type = type;
+ public TypeValue(TypeName value) {
+ this.value = value;
+ }
+
+ public TypeName getValue() {
+ return value;
}
@Override
@@ -22,7 +26,7 @@ public class TypeValue implements PrimitiveValue {
@Override
public String toString() {
return "TypeValue(" +
- "type=" + type +
+ "value=" + value +
')';
}
@@ -33,12 +37,12 @@ public class TypeValue implements PrimitiveValue {
TypeValue typeValue = (TypeValue) o;
- return type.equals(typeValue.type);
+ return value.equals(typeValue.value);
}
@Override
public int hashCode() {
- return type.hashCode();
+ return value.hashCode();
}
}
diff --git a/src/main/resources/python/runtime/java/lang/String.py b/src/main/resources/python/runtime/java/lang/String.py
new file mode 100644
index 0000000..9a1e025
--- /dev/null
+++ b/src/main/resources/python/runtime/java/lang/String.py
@@ -0,0 +1,2 @@
+class String(object):
+ pass \ No newline at end of file
diff --git a/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java b/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java
index 814cfa6..bdd492d 100644
--- a/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/BackendEvalTests.java
@@ -34,6 +34,7 @@ public abstract class BackendEvalTests {
assertEquals(value(true), evalExpression(literal(true)));
assertEquals(value(false), evalExpression(literal(false)));
assertEquals(value(42), evalExpression(literal(42)));
+ assertEquals(value(StringValue.REF), evalExpression(literal(StringValue.REF)));
}
@Test
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 5818de0..421c1aa 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,23 +1,28 @@
package org.zwobble.couscous.tests.backends.python;
-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;
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.io.CharStreams;
import org.zwobble.couscous.ast.ClassNode;
import org.zwobble.couscous.ast.MethodSignature;
import org.zwobble.couscous.ast.TypeName;
-import org.zwobble.couscous.backends.python.PythonCodeGenerator;
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.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValues;
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.io.CharStreams;
+import org.zwobble.couscous.values.StringValue;
+
+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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import static java.lang.Integer.parseInt;
import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
@@ -63,9 +68,20 @@ public class PythonMethodRunner implements MethodRunner {
return readPrimitive(output);
}
}
-
+
+ private static final Pattern TYPE_REGEX = Pattern.compile("^<class '([^']+)'>$");
+ private static final String TYPE_NAME_PREFIX = "couscous.";
+
private static PrimitiveValue readPrimitive(String output) {
- if (output.equals("None")) {
+ Matcher matcher = TYPE_REGEX.matcher(output);
+ if (matcher.matches()) {
+ String name = matcher.group(1);
+ if (name.equals("couscous.java.lang.String.String")) {
+ return value(StringValue.REF);
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ } else if (output.equals("None")) {
return PrimitiveValues.UNIT;
} else if (output.startsWith("\'")) {
return value(output.substring(1, output.length() - 1));