diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-06 13:44:18 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-06 13:44:18 +0100 |
| commit | 7324dc0bd7c70c0be4a28ca2bba5522cceaf277f (patch) | |
| tree | 14d3df885c13346cd1c9d1cbfa63ffe27a2a01e4 /src/main/java/org/zwobble/couscous/interpreter/values | |
| parent | ba5bf4a7c4f9097d540352afa1e895d2f1019328 (diff) | |
Add basic implementation of instance methods
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter/values')
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(); |
