aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-09-30 20:14:04 +0100
committerMichael Williamson <mike@zwobble.org>2015-09-30 20:14:04 +0100
commit37968a7c65eaf96ff0ab937f0a7827e0891c8880 (patch)
tree5b2122a46752a28741112189d613d8b4c770751f /src/main/java/org/zwobble
parentc1de40d3615a8efc852fd1a12832437ee3ce4318 (diff)
Throw error on wrong number of arguments
Diffstat (limited to 'src/main/java/org/zwobble')
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Arguments.java18
-rw-r--r--src/main/java/org/zwobble/couscous/values/ConcreteType.java17
-rw-r--r--src/main/java/org/zwobble/couscous/values/IntegerValue.java2
-rw-r--r--src/main/java/org/zwobble/couscous/values/MethodValue.java18
-rw-r--r--src/main/java/org/zwobble/couscous/values/StringValue.java15
5 files changed, 41 insertions, 29 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Arguments.java b/src/main/java/org/zwobble/couscous/interpreter/Arguments.java
index d08393d..af674a1 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Arguments.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Arguments.java
@@ -4,26 +4,14 @@ import java.util.List;
import org.zwobble.couscous.values.InterpreterValue;
-import lombok.val;
-
public class Arguments {
- private int index = 0;
private List<InterpreterValue> values;
public Arguments(List<InterpreterValue> values) {
this.values = values;
}
-
- @SuppressWarnings("unchecked")
- public <T extends InterpreterValue> T pop(Class<T> valueType) {
- val value = values.get(index);
- index++;
- if (valueType.isInstance(value)) {
- return (T) value;
- } else {
- // TODO: throw a more specific error
- throw new UnsupportedOperationException();
- }
-
+
+ public InterpreterValue get(int index) {
+ return values.get(index);
}
}
diff --git a/src/main/java/org/zwobble/couscous/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/values/ConcreteType.java
index c3ead74..ef6665e 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.WrongNumberOfArguments;
import com.google.common.collect.ImmutableMap;
@@ -13,11 +14,14 @@ import lombok.val;
public class ConcreteType<T> {
public static class Builder<T> {
- private final ImmutableMap.Builder<String, BiFunction<T, Arguments, InterpreterValue>> methods =
+ private final ImmutableMap.Builder<String, MethodValue<T>> methods =
ImmutableMap.builder();
- public Builder<T> method(String name, BiFunction<T, Arguments, InterpreterValue> method) {
- methods.put(name, method);
+ public Builder<T> method(
+ String name,
+ List<ConcreteType<?>> argumentsTypes,
+ BiFunction<T, Arguments, InterpreterValue> method) {
+ methods.put(name, new MethodValue<T>(argumentsTypes, method));
return this;
}
@@ -26,9 +30,9 @@ public class ConcreteType<T> {
}
}
- private Map<String, BiFunction<T, Arguments, InterpreterValue>> methods;
+ private Map<String, MethodValue<T>> methods;
- public ConcreteType(Map<String, BiFunction<T, Arguments, InterpreterValue>> methods) {
+ public ConcreteType(Map<String, MethodValue<T>> methods) {
this.methods = methods;
}
@@ -41,6 +45,9 @@ public class ConcreteType<T> {
throw new NoSuchMethod(methodName);
}
val method = methods.get(methodName);
+ if (method.getArgumentTypes().size() != arguments.size()) {
+ throw new WrongNumberOfArguments(method.getArgumentTypes().size(), arguments.size());
+ }
return method.apply((T)receiver, new Arguments(arguments));
}
}
diff --git a/src/main/java/org/zwobble/couscous/values/IntegerValue.java b/src/main/java/org/zwobble/couscous/values/IntegerValue.java
index eb7031d..8b5b423 100644
--- a/src/main/java/org/zwobble/couscous/values/IntegerValue.java
+++ b/src/main/java/org/zwobble/couscous/values/IntegerValue.java
@@ -4,7 +4,7 @@ import lombok.Value;
@Value
public class IntegerValue implements InterpreterValue {
- private static final ConcreteType<?> TYPE = ConcreteType.<IntegerValue>builder()
+ public static final ConcreteType<?> TYPE = ConcreteType.<IntegerValue>builder()
.build();
int value;
diff --git a/src/main/java/org/zwobble/couscous/values/MethodValue.java b/src/main/java/org/zwobble/couscous/values/MethodValue.java
index 38ef1d5..fe23f94 100644
--- a/src/main/java/org/zwobble/couscous/values/MethodValue.java
+++ b/src/main/java/org/zwobble/couscous/values/MethodValue.java
@@ -1,7 +1,21 @@
package org.zwobble.couscous.values;
import java.util.List;
+import java.util.function.BiFunction;
-public interface MethodValue {
- InterpreterValue call(List<InterpreterValue> arguments);
+import org.zwobble.couscous.interpreter.Arguments;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Value;
+
+@Value
+public class MethodValue<T> {
+ List<ConcreteType<?>> argumentTypes;
+ @Getter(value=AccessLevel.NONE)
+ BiFunction<T, Arguments, InterpreterValue> apply;
+
+ public InterpreterValue apply(T receiver, Arguments arguments) {
+ return apply.apply(receiver, arguments);
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/values/StringValue.java b/src/main/java/org/zwobble/couscous/values/StringValue.java
index da45f02..2d4bf17 100644
--- a/src/main/java/org/zwobble/couscous/values/StringValue.java
+++ b/src/main/java/org/zwobble/couscous/values/StringValue.java
@@ -1,18 +1,21 @@
package org.zwobble.couscous.values;
+import static java.util.Arrays.asList;
+
import lombok.Value;
import lombok.val;
@Value
public class StringValue implements InterpreterValue {
private static final ConcreteType<?> TYPE = ConcreteType.<StringValue>builder()
- .method("length", (receiver, arguments) -> new IntegerValue(receiver.value.length()))
+ .method("length", asList(), (receiver, arguments) -> new IntegerValue(receiver.value.length()))
- .method("substring", (receiver, arguments) -> {
- val startIndex = arguments.pop(IntegerValue.class);
- val endIndex = arguments.pop(IntegerValue.class);
- return new StringValue(receiver.value.substring(startIndex.getValue(), endIndex.getValue()));
- })
+ .method("substring", asList(IntegerValue.TYPE, IntegerValue.TYPE),
+ (receiver, arguments) -> {
+ val startIndex = (IntegerValue)arguments.get(0);
+ val endIndex = (IntegerValue)arguments.get(1);
+ return new StringValue(receiver.value.substring(startIndex.getValue(), endIndex.getValue()));
+ })
.build();