aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-03-31 19:50:44 +0100
committerMichael Williamson <mike@zwobble.org>2016-03-31 19:50:44 +0100
commit73fd96aa67f29e2cce3ac5d0042a4446c08eb034 (patch)
tree78dddaa11bcb9f61b2fb2b49d74b4f4e49d75b76
parentd4c5596cc4c20d884e33d0eb0faab87505483e46 (diff)
Create parameterised types with correct interpreter type
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Evaluator.java8
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java2
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/ParameterizedInterpreterType.java65
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java16
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java12
-rw-r--r--src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java2
7 files changed, 93 insertions, 18 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
index 8c3d355..64f28ad 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java
@@ -6,13 +6,17 @@ import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
import org.zwobble.couscous.interpreter.errors.ConditionMustBeBoolean;
import org.zwobble.couscous.interpreter.errors.InvalidCast;
import org.zwobble.couscous.interpreter.values.*;
+import org.zwobble.couscous.types.ParameterizedType;
import org.zwobble.couscous.types.ScalarType;
+import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.types.Types;
import java.util.List;
+import java.util.Optional;
import java.util.stream.Collectors;
import static org.zwobble.couscous.types.Types.erasure;
+import static org.zwobble.couscous.util.Casts.tryCast;
import static org.zwobble.couscous.util.ExtraLists.eagerMap;
public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
@@ -105,7 +109,9 @@ public class Evaluator implements ExpressionNodeMapper<InterpreterValue> {
public InterpreterValue visit(ConstructorCallNode call) {
StaticReceiverValue clazz = environment.findClass(erasure(call.getType()));
List<InterpreterValue> arguments = evalArguments(call.getArguments());
- return clazz.callConstructor(environment, arguments);
+ Optional<List<Type>> typeParameters = tryCast(ParameterizedType.class, call.getType())
+ .map(type -> type.getParameters());
+ return clazz.callConstructor(environment, typeParameters, arguments);
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java
index 8c5bdb9..7ffe5d5 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java
@@ -16,7 +16,7 @@ public interface InterpreterType {
Set<Type> getSuperTypes();
Optional<FieldDeclarationNode> getField(String fieldName);
List<StatementNode> getStaticConstructor();
- InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments);
+ void callConstructor(Environment environment, InterpreterValue thisValue, List<InterpreterValue> arguments);
InterpreterValue callMethod(Environment environment, InterpreterValue value, MethodSignature signature, List<InterpreterValue> arguments);
InterpreterValue callStaticMethod(Environment environment, MethodSignature signature, List<InterpreterValue> arguments);
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java
index 190908b..29b4fe1 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java
@@ -156,10 +156,8 @@ public class IntrinsicInterpreterType implements InterpreterType {
}
@Override
- public InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments) {
- ObjectInterpreterValue object = new ObjectInterpreterValue(this);
- constructor.apply(environment, MethodCallArguments.of(object, new PositionalArguments(arguments)));
- return object;
+ public void callConstructor(Environment environment, InterpreterValue thisValue, List<InterpreterValue> arguments) {
+ constructor.apply(environment, MethodCallArguments.of(thisValue, new PositionalArguments(arguments)));
}
@Override
diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/ParameterizedInterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/ParameterizedInterpreterType.java
new file mode 100644
index 0000000..f890fb1
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/ParameterizedInterpreterType.java
@@ -0,0 +1,65 @@
+package org.zwobble.couscous.interpreter.types;
+
+import org.zwobble.couscous.ast.FieldDeclarationNode;
+import org.zwobble.couscous.ast.MethodSignature;
+import org.zwobble.couscous.ast.StatementNode;
+import org.zwobble.couscous.interpreter.Environment;
+import org.zwobble.couscous.interpreter.values.InterpreterValue;
+import org.zwobble.couscous.types.ScalarType;
+import org.zwobble.couscous.types.Type;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.zwobble.couscous.types.ParameterizedType.parameterizedType;
+
+public class ParameterizedInterpreterType implements InterpreterType {
+ private final InterpreterType rawType;
+ private final List<Type> parameters;
+
+ public ParameterizedInterpreterType(InterpreterType rawType, List<Type> parameters) {
+ this.rawType = rawType;
+ this.parameters = parameters;
+ }
+
+ @Override
+ public Type getType() {
+ return parameterizedType((ScalarType) rawType.getType(), parameters);
+ }
+
+ // TODO: implement the other methods properly.
+ // Possibly worth splitting off a separate notion of interpreter type.
+ // For instance, callConstructor is arguably not relevant here.
+ // (Or that we should be instantiating this type before the call to callConstructor)
+
+ @Override
+ public Set<Type> getSuperTypes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Optional<FieldDeclarationNode> getField(String fieldName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<StatementNode> getStaticConstructor() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void callConstructor(Environment environment, InterpreterValue thisValue, List<InterpreterValue> arguments) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public InterpreterValue callMethod(Environment environment, InterpreterValue value, MethodSignature signature, List<InterpreterValue> arguments) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public InterpreterValue callStaticMethod(Environment environment, MethodSignature signature, List<InterpreterValue> arguments) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
index cc072bf..d702720 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
@@ -1,8 +1,6 @@
package org.zwobble.couscous.interpreter.types;
import org.zwobble.couscous.ast.*;
-import org.zwobble.couscous.types.ScalarType;
-import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.Executor;
import org.zwobble.couscous.interpreter.InterpreterTypes;
@@ -10,9 +8,13 @@ import org.zwobble.couscous.interpreter.PositionalArguments;
import org.zwobble.couscous.interpreter.errors.NoSuchMethod;
import org.zwobble.couscous.interpreter.errors.WrongNumberOfArguments;
import org.zwobble.couscous.interpreter.values.InterpreterValue;
-import org.zwobble.couscous.interpreter.values.ObjectInterpreterValue;
+import org.zwobble.couscous.types.ScalarType;
+import org.zwobble.couscous.types.Type;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import static com.google.common.collect.Iterables.filter;
import static org.zwobble.couscous.util.Casts.tryCast;
@@ -59,7 +61,7 @@ public class UserDefinedInterpreterType implements InterpreterType {
}
@Override
- public InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments) {
+ public void callConstructor(Environment environment, InterpreterValue thisValue, List<InterpreterValue> arguments) {
ConstructorNode constructor = tryCast(ClassNode.class, type)
// TODO: add test for this case
.orElseThrow(() -> new RuntimeException("Cannot instantiate non-class types"))
@@ -68,13 +70,11 @@ public class UserDefinedInterpreterType implements InterpreterType {
constructor.getArguments(),
FormalArgumentNode::getType);
checkMethodArguments(formalArgumentTypes, arguments);
- InterpreterValue object = new ObjectInterpreterValue(this);
Executor.callConstructor(
environment,
constructor,
- object,
+ thisValue,
new PositionalArguments(arguments));
- return object;
}
private static void checkMethodArguments(final List<Type> argumentTypes, List<InterpreterValue> arguments) {
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java
index cf2c9b7..deca938 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java
@@ -4,8 +4,11 @@ import org.zwobble.couscous.ast.MethodSignature;
import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.Executor;
import org.zwobble.couscous.interpreter.types.InterpreterType;
+import org.zwobble.couscous.interpreter.types.ParameterizedInterpreterType;
+import org.zwobble.couscous.types.Type;
import java.util.List;
+import java.util.Optional;
public class StaticReceiverValue implements ReceiverValue {
private final InterpreterType type;
@@ -35,7 +38,12 @@ public class StaticReceiverValue implements ReceiverValue {
Executor.exec(environment, type.getStaticConstructor());
}
- public InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments) {
- return type.callConstructor(environment, arguments);
+ public InterpreterValue callConstructor(Environment environment, Optional<List<Type>> typeParameters, List<InterpreterValue> arguments) {
+ InterpreterType objectType = typeParameters
+ .<InterpreterType>map(parameters -> new ParameterizedInterpreterType(type, parameters))
+ .orElse(type);
+ ObjectInterpreterValue value = new ObjectInterpreterValue(objectType);
+ type.callConstructor(environment, value, arguments);
+ return value;
}
}
diff --git a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java
index 9fe84e6..e6316b5 100644
--- a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java
+++ b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java
@@ -2,7 +2,6 @@ package org.zwobble.couscous.tests.interpreter;
import com.google.common.collect.ImmutableMap;
import org.hamcrest.Matcher;
-import org.junit.Ignore;
import org.junit.Test;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.interpreter.*;
@@ -250,7 +249,6 @@ public class EvaluatorTests extends BackendEvalTests {
}
@Test
- @Ignore("WIP")
public void typeOfValueCanBeParameterisedType() {
ScalarType rawType = ScalarType.of("Box");
ClassNode classNode = ClassNode.builder(rawType)