aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/interpreter/values
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-10-06 13:44:18 +0100
committerMichael Williamson <mike@zwobble.org>2015-10-06 13:44:18 +0100
commit7324dc0bd7c70c0be4a28ca2bba5522cceaf277f (patch)
tree14d3df885c13346cd1c9d1cbfa63ffe27a2a01e4 /src/main/java/org/zwobble/couscous/interpreter/values
parentba5bf4a7c4f9097d540352afa1e895d2f1019328 (diff)
Add basic implementation of instance methods
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter/values')
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java43
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/MethodCallArguments.java17
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java8
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java23
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java7
6 files changed, 84 insertions, 20 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
index a4902a4..70ba96a 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
@@ -7,7 +7,7 @@ import java.util.stream.Collectors;
import org.zwobble.couscous.ast.ClassNode;
import org.zwobble.couscous.ast.TypeName;
-import org.zwobble.couscous.interpreter.Arguments;
+import org.zwobble.couscous.interpreter.PositionalArguments;
import org.zwobble.couscous.interpreter.Environment;
import org.zwobble.couscous.interpreter.Executor;
import org.zwobble.couscous.interpreter.NoSuchMethod;
@@ -38,10 +38,11 @@ public class ConcreteType {
public Builder<T> method(
String name,
List<TypeName> argumentsTypes,
- BiFunction<T, Arguments, InterpreterValue> method) {
- methods.put(name, new MethodValue(argumentsTypes, (receiver, arguments) -> {
- return Casts.tryCast(interpreterValueType, receiver)
- .map(typedReceiver -> method.apply(typedReceiver, arguments))
+ BiFunction<Environment, MethodCallArguments<T>, InterpreterValue> method) {
+ methods.put(name, new MethodValue(argumentsTypes, (environment, arguments) -> {
+ return Casts.tryCast(interpreterValueType, arguments.getReceiver())
+ .map(typedReceiver ->
+ method.apply(environment, MethodCallArguments.of(typedReceiver, arguments.getPositionalArguments())))
.orElseThrow(() -> new RuntimeException("receiver is of wrong type"));
}));
return this;
@@ -50,7 +51,7 @@ public class ConcreteType {
public Builder<T> staticMethod(
String name,
List<TypeName> argumentsTypes,
- BiFunction<Environment, Arguments, InterpreterValue> method) {
+ BiFunction<Environment, PositionalArguments, InterpreterValue> method) {
staticMethods.put(name, new StaticMethodValue(argumentsTypes, method));
return this;
}
@@ -61,6 +62,20 @@ public class ConcreteType {
}
public static ConcreteType fromNode(ClassNode classNode) {
+ val methods = classNode.getMethods().stream()
+ .filter(method -> !method.isStatic())
+ .collect(toMap(
+ method -> method.getName(),
+ method -> {
+ List<TypeName> argumentTypes = method.getArguments()
+ .stream()
+ .map(arg -> arg.getType())
+ .collect(Collectors.toList());
+ return new MethodValue(argumentTypes, (environment, arguments) -> {
+ return Executor.callMethod(environment, method, arguments.getPositionalArguments());
+ });
+ }));
+
val staticMethods = classNode.getMethods()
.stream()
.filter(method -> method.isStatic())
@@ -77,7 +92,7 @@ public class ConcreteType {
}));
return new ConcreteType(
classNode.getName(),
- ImmutableMap.of(),
+ methods,
staticMethods);
}
@@ -106,14 +121,22 @@ public class ConcreteType {
return builder(interpreterValueType, TypeName.of(name));
}
- public InterpreterValue callMethod(InterpreterValue receiver, String methodName, List<InterpreterValue> arguments) {
+ public InterpreterValue callMethod(Environment environment, InterpreterValue receiver, String methodName, List<InterpreterValue> arguments) {
val method = findMethod(methods, methodName, arguments);
- return method.apply(receiver, new Arguments(arguments));
+ return method.apply(
+ environment,
+ MethodCallArguments.of(receiver, new PositionalArguments(arguments)));
}
public InterpreterValue callStaticMethod(Environment environment, String methodName, List<InterpreterValue> arguments) {
val method = findMethod(staticMethods, methodName, arguments);
- return method.apply(environment, new Arguments(arguments));
+ return method.apply(environment, new PositionalArguments(arguments));
+ }
+
+ public InterpreterValue callConstructor(
+ Environment environment,
+ List<InterpreterValue> arguments) {
+ return new ObjectInterpreterValue(this);
}
private static <T extends Callable> T findMethod(Map<String, T> methods, String methodName, List<InterpreterValue> arguments) {
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/MethodCallArguments.java b/src/main/java/org/zwobble/couscous/interpreter/values/MethodCallArguments.java
new file mode 100644
index 0000000..9f3e937
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/MethodCallArguments.java
@@ -0,0 +1,17 @@
+package org.zwobble.couscous.interpreter.values;
+
+import org.zwobble.couscous.interpreter.PositionalArguments;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor(staticName="of")
+@Getter
+public class MethodCallArguments<T> {
+ private final T receiver;
+ private final PositionalArguments positionalArguments;
+
+ public InterpreterValue get(int index) {
+ return positionalArguments.get(index);
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java
index c1f2c6e..b5068fc 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java
@@ -4,7 +4,7 @@ import java.util.List;
import java.util.function.BiFunction;
import org.zwobble.couscous.ast.TypeName;
-import org.zwobble.couscous.interpreter.Arguments;
+import org.zwobble.couscous.interpreter.Environment;
import lombok.AccessLevel;
import lombok.Getter;
@@ -14,9 +14,9 @@ import lombok.Value;
public class MethodValue implements Callable {
List<TypeName> argumentTypes;
@Getter(value=AccessLevel.NONE)
- BiFunction<InterpreterValue, Arguments, InterpreterValue> apply;
+ BiFunction<Environment, MethodCallArguments<InterpreterValue>, InterpreterValue> apply;
- public InterpreterValue apply(InterpreterValue receiver, Arguments arguments) {
- return apply.apply(receiver, arguments);
+ public InterpreterValue apply(Environment environment, MethodCallArguments<InterpreterValue> arguments) {
+ return apply.apply(environment, arguments);
}
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java
new file mode 100644
index 0000000..4383353
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java
@@ -0,0 +1,23 @@
+package org.zwobble.couscous.interpreter.values;
+
+import java.util.Optional;
+
+import org.zwobble.couscous.values.PrimitiveValue;
+
+public class ObjectInterpreterValue implements InterpreterValue {
+ private final ConcreteType type;
+
+ public ObjectInterpreterValue(ConcreteType type) {
+ this.type = type;
+ }
+
+ @Override
+ public ConcreteType getType() {
+ return type;
+ }
+
+ @Override
+ public Optional<PrimitiveValue> toPrimitiveValue() {
+ return Optional.empty();
+ }
+}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java
index 4754d80..37f3c56 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java
@@ -4,7 +4,7 @@ import java.util.List;
import java.util.function.BiFunction;
import org.zwobble.couscous.ast.TypeName;
-import org.zwobble.couscous.interpreter.Arguments;
+import org.zwobble.couscous.interpreter.PositionalArguments;
import org.zwobble.couscous.interpreter.Environment;
import lombok.AccessLevel;
@@ -15,9 +15,9 @@ import lombok.Value;
public class StaticMethodValue implements Callable {
List<TypeName> argumentTypes;
@Getter(value=AccessLevel.NONE)
- BiFunction<Environment, Arguments, InterpreterValue> apply;
+ BiFunction<Environment, PositionalArguments, InterpreterValue> apply;
- public InterpreterValue apply(Environment environment, Arguments arguments) {
+ public InterpreterValue apply(Environment environment, PositionalArguments arguments) {
return apply.apply(environment, arguments);
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
index 98165b2..aa3432a 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
@@ -16,13 +16,14 @@ import lombok.val;
public class StringInterpreterValue implements InterpreterValue {
public static final ConcreteType TYPE = ConcreteType.builder(StringInterpreterValue.class, StringValue.REF)
.method("length", asList(),
- (receiver, arguments) -> new IntegerInterpreterValue(receiver.value.length()))
+ (environment, arguments) ->
+ new IntegerInterpreterValue(arguments.getReceiver().value.length()))
.method("substring", asList(IntegerValue.REF, IntegerValue.REF),
- (receiver, arguments) -> {
+ (environment, arguments) -> {
val startIndex = (IntegerInterpreterValue)arguments.get(0);
val endIndex = (IntegerInterpreterValue)arguments.get(1);
- return new StringInterpreterValue(receiver.value.substring(startIndex.getValue(), endIndex.getValue()));
+ return new StringInterpreterValue(arguments.getReceiver().value.substring(startIndex.getValue(), endIndex.getValue()));
})
.build();