aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/values
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-10-01 21:04:37 +0100
committerMichael Williamson <mike@zwobble.org>2015-10-01 21:04:37 +0100
commit8187130b8a8aabbcf983e530413d6969141d6da2 (patch)
treed72dcb499d08812e7391b95cdf780dff054b3a3c /src/main/java/org/zwobble/couscous/values
parent36f3fdbcad95dcc5bfec785fffca4f42b24d1307 (diff)
Allow static method calls
Diffstat (limited to 'src/main/java/org/zwobble/couscous/values')
-rw-r--r--src/main/java/org/zwobble/couscous/values/BooleanValue.java2
-rw-r--r--src/main/java/org/zwobble/couscous/values/Callable.java7
-rw-r--r--src/main/java/org/zwobble/couscous/values/ConcreteType.java52
-rw-r--r--src/main/java/org/zwobble/couscous/values/IntegerValue.java11
-rw-r--r--src/main/java/org/zwobble/couscous/values/MethodValue.java11
-rw-r--r--src/main/java/org/zwobble/couscous/values/StaticMethodValue.java29
-rw-r--r--src/main/java/org/zwobble/couscous/values/StringValue.java7
-rw-r--r--src/main/java/org/zwobble/couscous/values/UnitValue.java2
8 files changed, 106 insertions, 15 deletions
diff --git a/src/main/java/org/zwobble/couscous/values/BooleanValue.java b/src/main/java/org/zwobble/couscous/values/BooleanValue.java
index 3f1f2a2..aeeb7e3 100644
--- a/src/main/java/org/zwobble/couscous/values/BooleanValue.java
+++ b/src/main/java/org/zwobble/couscous/values/BooleanValue.java
@@ -6,7 +6,7 @@ import lombok.Value;
@Value
public class BooleanValue implements InterpreterValue {
- private static final ConcreteType<BooleanValue> TYPE = ConcreteType.<BooleanValue>builder()
+ private static final ConcreteType<BooleanValue> TYPE = ConcreteType.<BooleanValue>builder("Boolean")
.build();
@Getter(value = AccessLevel.NONE)
diff --git a/src/main/java/org/zwobble/couscous/values/Callable.java b/src/main/java/org/zwobble/couscous/values/Callable.java
new file mode 100644
index 0000000..9f3e486
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/values/Callable.java
@@ -0,0 +1,7 @@
+package org.zwobble.couscous.values;
+
+import java.util.List;
+
+public interface Callable {
+ List<ConcreteType<?>> getArgumentTypes();
+}
diff --git a/src/main/java/org/zwobble/couscous/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/values/ConcreteType.java
index 38b1b6e..db5209e 100644
--- a/src/main/java/org/zwobble/couscous/values/ConcreteType.java
+++ b/src/main/java/org/zwobble/couscous/values/ConcreteType.java
@@ -3,6 +3,8 @@ package org.zwobble.couscous.values;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
import org.zwobble.couscous.interpreter.Arguments;
import org.zwobble.couscous.interpreter.NoSuchMethod;
@@ -17,32 +19,64 @@ public class ConcreteType<T> {
public static class Builder<T> {
private final ImmutableMap.Builder<String, MethodValue<T>> methods =
ImmutableMap.builder();
+ private final ImmutableMap.Builder<String, StaticMethodValue> staticMethods =
+ ImmutableMap.builder();
+ private final String name;
+
+ public Builder(String name) {
+ this.name = name;
+ }
public Builder<T> method(
String name,
- List<ConcreteType<?>> argumentsTypes,
+ Supplier<List<ConcreteType<?>>> argumentsTypes,
BiFunction<T, Arguments, InterpreterValue> method) {
methods.put(name, new MethodValue<T>(argumentsTypes, method));
return this;
}
+ public Builder<T> staticMethod(
+ String name,
+ Supplier<List<ConcreteType<?>>> argumentsTypes,
+ Function<Arguments, InterpreterValue> method) {
+ staticMethods.put(name, new StaticMethodValue(argumentsTypes, method));
+ return this;
+ }
+
public ConcreteType<T> build() {
- return new ConcreteType<T>(methods.build());
+ return new ConcreteType<T>(name, methods.build(), staticMethods.build());
}
}
+ private String name;
private Map<String, MethodValue<T>> methods;
+ private ImmutableMap<String, StaticMethodValue> staticMethods;
- public ConcreteType(Map<String, MethodValue<T>> methods) {
+ public ConcreteType(
+ String name,
+ Map<String, MethodValue<T>> methods,
+ ImmutableMap<String, StaticMethodValue> staticMethods) {
+ this.name = name;
this.methods = methods;
+ this.staticMethods = staticMethods;
}
- public static <T> ConcreteType.Builder<T> builder() {
- return new Builder<>();
+ public static <T> ConcreteType.Builder<T> builder(String name) {
+ return new Builder<>(name);
}
@SuppressWarnings("unchecked")
public InterpreterValue callMethod(InterpreterValue receiver, String methodName, List<InterpreterValue> arguments) {
+ val method = findMethod(methods, methodName, arguments);
+ return method.apply((T)receiver, new Arguments(arguments));
+ }
+
+ public InterpreterValue callStaticMethod(String methodName, List<InterpreterValue> arguments) {
+ val method = findMethod(staticMethods, methodName, arguments);
+ return method.apply(new Arguments(arguments));
+ }
+
+ private static <T extends Callable> T findMethod(Map<String, T> methods, String methodName, List<InterpreterValue> arguments) {
if (!methods.containsKey(methodName)) {
throw new NoSuchMethod(methodName);
}
@@ -58,7 +92,11 @@ public class ConcreteType<T> {
throw new UnexpectedValueType(formalArgumentType, actualArgumentType);
}
}
-
- return method.apply((T)receiver, new Arguments(arguments));
+ return method;
+ }
+
+ @Override
+ public String toString() {
+ return "ConcreteType<" + name + ">";
}
}
diff --git a/src/main/java/org/zwobble/couscous/values/IntegerValue.java b/src/main/java/org/zwobble/couscous/values/IntegerValue.java
index 8b5b423..1b20a01 100644
--- a/src/main/java/org/zwobble/couscous/values/IntegerValue.java
+++ b/src/main/java/org/zwobble/couscous/values/IntegerValue.java
@@ -1,10 +1,19 @@
package org.zwobble.couscous.values;
+import static java.util.Arrays.asList;
+
import lombok.Value;
+import lombok.val;
@Value
public class IntegerValue implements InterpreterValue {
- public static final ConcreteType<?> TYPE = ConcreteType.<IntegerValue>builder()
+ public static final ConcreteType<?> TYPE = ConcreteType.<IntegerValue>builder("Integer")
+ .staticMethod("parseInt", () -> asList(StringValue.TYPE),
+ arguments -> {
+ val value = (StringValue)arguments.get(0);
+ return new IntegerValue(Integer.parseInt(value.getValue()));
+ })
+
.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 fe23f94..df53722 100644
--- a/src/main/java/org/zwobble/couscous/values/MethodValue.java
+++ b/src/main/java/org/zwobble/couscous/values/MethodValue.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.values;
import java.util.List;
import java.util.function.BiFunction;
+import java.util.function.Supplier;
import org.zwobble.couscous.interpreter.Arguments;
@@ -10,11 +11,17 @@ import lombok.Getter;
import lombok.Value;
@Value
-public class MethodValue<T> {
- List<ConcreteType<?>> argumentTypes;
+public class MethodValue<T> implements Callable {
+ @Getter(value=AccessLevel.NONE)
+ Supplier<List<ConcreteType<?>>> argumentTypes;
@Getter(value=AccessLevel.NONE)
BiFunction<T, Arguments, InterpreterValue> apply;
+ @Override
+ public List<ConcreteType<?>> getArgumentTypes() {
+ return argumentTypes.get();
+ }
+
public InterpreterValue apply(T receiver, Arguments arguments) {
return apply.apply(receiver, arguments);
}
diff --git a/src/main/java/org/zwobble/couscous/values/StaticMethodValue.java b/src/main/java/org/zwobble/couscous/values/StaticMethodValue.java
new file mode 100644
index 0000000..15a70d3
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/values/StaticMethodValue.java
@@ -0,0 +1,29 @@
+package org.zwobble.couscous.values;
+
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.zwobble.couscous.interpreter.Arguments;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Value;
+
+@Value
+public class StaticMethodValue implements Callable {
+ @Getter(value=AccessLevel.NONE)
+ Supplier<List<ConcreteType<?>>> argumentTypes;
+ @Getter(value=AccessLevel.NONE)
+ Function<Arguments, InterpreterValue> apply;
+
+ @Override
+ public List<ConcreteType<?>> getArgumentTypes() {
+ return argumentTypes.get();
+ }
+
+ public InterpreterValue apply(Arguments arguments) {
+ return apply.apply(arguments);
+ }
+
+}
diff --git a/src/main/java/org/zwobble/couscous/values/StringValue.java b/src/main/java/org/zwobble/couscous/values/StringValue.java
index 0ade0e1..e8a7c0e 100644
--- a/src/main/java/org/zwobble/couscous/values/StringValue.java
+++ b/src/main/java/org/zwobble/couscous/values/StringValue.java
@@ -7,10 +7,11 @@ import lombok.val;
@Value
public class StringValue implements InterpreterValue {
- public static final ConcreteType<?> TYPE = ConcreteType.<StringValue>builder()
- .method("length", asList(), (receiver, arguments) -> new IntegerValue(receiver.value.length()))
+ public static final ConcreteType<?> TYPE = ConcreteType.<StringValue>builder("String")
+ .method("length", () -> asList(),
+ (receiver, arguments) -> new IntegerValue(receiver.value.length()))
- .method("substring", asList(IntegerValue.TYPE, IntegerValue.TYPE),
+ .method("substring", () -> asList(IntegerValue.TYPE, IntegerValue.TYPE),
(receiver, arguments) -> {
val startIndex = (IntegerValue)arguments.get(0);
val endIndex = (IntegerValue)arguments.get(1);
diff --git a/src/main/java/org/zwobble/couscous/values/UnitValue.java b/src/main/java/org/zwobble/couscous/values/UnitValue.java
index 5742d8a..af00b32 100644
--- a/src/main/java/org/zwobble/couscous/values/UnitValue.java
+++ b/src/main/java/org/zwobble/couscous/values/UnitValue.java
@@ -4,7 +4,7 @@ import lombok.ToString;
@ToString
public class UnitValue implements InterpreterValue {
- private static final ConcreteType<?> TYPE = ConcreteType.<UnitValue>builder()
+ private static final ConcreteType<?> TYPE = ConcreteType.<UnitValue>builder("Unit")
.build();
public static final UnitValue UNIT = new UnitValue();