diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-09-30 21:26:17 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-09-30 21:26:40 +0100 |
| commit | 36f3fdbcad95dcc5bfec785fffca4f42b24d1307 (patch) | |
| tree | 8bb7e01684cf5d7ba97ef73727712852dc16817a /src | |
| parent | d45c00b1a101c7679b2174ae816a2d1c2f8ef416 (diff) | |
Check argument types
Diffstat (limited to 'src')
4 files changed, 35 insertions, 1 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/UnexpectedValueType.java b/src/main/java/org/zwobble/couscous/interpreter/UnexpectedValueType.java new file mode 100644 index 0000000..59ea2d0 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/UnexpectedValueType.java @@ -0,0 +1,15 @@ +package org.zwobble.couscous.interpreter; + +import org.zwobble.couscous.values.ConcreteType; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper=false) +public class UnexpectedValueType extends InterpreterException { + private static final long serialVersionUID = 1L; + + ConcreteType<?> expected; + ConcreteType<?> actual; +} diff --git a/src/main/java/org/zwobble/couscous/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/values/ConcreteType.java index d45222b..38b1b6e 100644 --- a/src/main/java/org/zwobble/couscous/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/values/ConcreteType.java @@ -6,6 +6,7 @@ import java.util.function.BiFunction; import org.zwobble.couscous.interpreter.Arguments; import org.zwobble.couscous.interpreter.NoSuchMethod; +import org.zwobble.couscous.interpreter.UnexpectedValueType; import org.zwobble.couscous.interpreter.WrongNumberOfArguments; import com.google.common.collect.ImmutableMap; @@ -49,6 +50,15 @@ public class ConcreteType<T> { if (method.getArgumentTypes().size() != arguments.size()) { throw new WrongNumberOfArguments(method.getArgumentTypes().size(), arguments.size()); } + + for (int index = 0; index < arguments.size(); index++) { + val formalArgumentType = method.getArgumentTypes().get(index); + val actualArgumentType = arguments.get(index).getType(); + if (formalArgumentType != actualArgumentType) { + throw new UnexpectedValueType(formalArgumentType, actualArgumentType); + } + } + return method.apply((T)receiver, new Arguments(arguments)); } } diff --git a/src/main/java/org/zwobble/couscous/values/StringValue.java b/src/main/java/org/zwobble/couscous/values/StringValue.java index 2d4bf17..0ade0e1 100644 --- a/src/main/java/org/zwobble/couscous/values/StringValue.java +++ b/src/main/java/org/zwobble/couscous/values/StringValue.java @@ -7,7 +7,7 @@ import lombok.val; @Value public class StringValue implements InterpreterValue { - private static final ConcreteType<?> TYPE = ConcreteType.<StringValue>builder() + public static final ConcreteType<?> TYPE = ConcreteType.<StringValue>builder() .method("length", asList(), (receiver, arguments) -> new IntegerValue(receiver.value.length())) .method("substring", asList(IntegerValue.TYPE, IntegerValue.TYPE), 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 5ebb948..d4cb2f1 100644 --- a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java +++ b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java @@ -6,6 +6,7 @@ import org.zwobble.couscous.ast.TernaryConditionalNode; import org.zwobble.couscous.interpreter.ConditionMustBeBoolean; import org.zwobble.couscous.interpreter.Environment; import org.zwobble.couscous.interpreter.NoSuchMethod; +import org.zwobble.couscous.interpreter.UnexpectedValueType; import org.zwobble.couscous.interpreter.WrongNumberOfArguments; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.StringValue; @@ -82,6 +83,14 @@ public class EvaluatorTests { assertEquals(new WrongNumberOfArguments(2, 1), exception); } + @Test + public void errorIfArgumentIsWrongType() { + val exception = assertThrows(UnexpectedValueType.class, + () -> eval(emptyEnvironment(), + methodCall(literal("hello"), "substring", literal(0), literal("")))); + assertEquals(new UnexpectedValueType(IntegerValue.TYPE, StringValue.TYPE), exception); + } + private static Environment emptyEnvironment() { return new Environment(ImmutableMap.of()); } |
