aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-03-03 19:02:00 +0000
committerMichael Williamson <mike@zwobble.org>2016-03-03 19:02:00 +0000
commitf211e82e7c1373b534f070a52b705d61f547da53 (patch)
treed7413568dd1aead9229f4531d58edcaeb3716452 /src/main/java/org
parentac3615f1f8c94d636dcc20bc706db2d208851e74 (diff)
Add back constructor argument type check in interpreter
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java14
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java19
2 files changed, 25 insertions, 8 deletions
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 5fda40c..5bfc221 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java
@@ -147,13 +147,6 @@ public class IntrinsicInterpreterType implements InterpreterType {
return method.apply(environment, new PositionalArguments(arguments));
}
- @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;
- }
-
private static <T extends Callable> T findMethod(Map<MethodSignature, T> methods, MethodSignature signature) {
if (!methods.containsKey(signature)) {
throw new NoSuchMethod(signature);
@@ -162,6 +155,13 @@ 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;
+ }
+
+ @Override
public String toString() {
return "IntrinsicInterpreterType<" + name + ">";
}
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 a058cc3..a253180 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java
@@ -3,8 +3,10 @@ package org.zwobble.couscous.interpreter.types;
import org.zwobble.couscous.ast.*;
import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.Executor;
+import org.zwobble.couscous.interpreter.InterpreterTypes;
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;
@@ -15,6 +17,7 @@ import java.util.Set;
import static com.google.common.collect.Iterables.filter;
import static org.zwobble.couscous.util.Casts.tryCast;
+import static org.zwobble.couscous.util.ExtraLists.eagerMap;
import static org.zwobble.couscous.util.ExtraLists.list;
import static org.zwobble.couscous.util.ExtraMaps.map;
import static org.zwobble.couscous.util.ExtraMaps.toMapWithKeys;
@@ -27,7 +30,7 @@ public class UserDefinedInterpreterType implements InterpreterType {
public UserDefinedInterpreterType(TypeNode type) {
this.type = type;
this.fields = tryCast(ClassNode.class, type)
- .map(classNode -> toMapWithKeys(classNode.getFields(), field -> field.getName()))
+ .map(classNode -> toMapWithKeys(classNode.getFields(), FieldDeclarationNode::getName))
.orElse(map());
this.methods = toMapWithKeys(
filter(type.getMethods(), method -> !method.isAbstract()),
@@ -62,6 +65,10 @@ public class UserDefinedInterpreterType implements InterpreterType {
// TODO: add test for this case
.orElseThrow(() -> new RuntimeException("Cannot instantiate non-class types"))
.getConstructor();
+ List<TypeName> formalArgumentTypes = eagerMap(
+ constructor.getArguments(),
+ FormalArgumentNode::getType);
+ checkMethodArguments(formalArgumentTypes, arguments);
InterpreterValue object = new ObjectInterpreterValue(this);
Executor.callConstructor(
environment,
@@ -71,6 +78,16 @@ public class UserDefinedInterpreterType implements InterpreterType {
return object;
}
+ private static void checkMethodArguments(final List<TypeName> argumentTypes, List<InterpreterValue> arguments) {
+ if (argumentTypes.size() != arguments.size()) {
+ throw new WrongNumberOfArguments(argumentTypes.size(), arguments.size());
+ }
+ for (int index = 0; index < arguments.size(); index++) {
+ TypeName formalArgumentType = argumentTypes.get(index);
+ InterpreterTypes.checkIsInstance(formalArgumentType, arguments.get(index));
+ }
+ }
+
@Override
public InterpreterValue callMethod(Environment environment, InterpreterValue value, MethodSignature signature, List<InterpreterValue> arguments) {
return Executor.callMethod(