aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/interpreter/values
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2015-10-06 16:24:37 +0100
committerMichael Williamson <mike@zwobble.org>2015-10-06 16:24:37 +0100
commite6f463257720bee91a1b4954d97684dbb3398cbf (patch)
treec8d1f04dfe8928d33361108aefee7e7572dae1c7 /src/main/java/org/zwobble/couscous/interpreter/values
parent9685c8fb7fa14d5b75d828f8443dd948715ac4af (diff)
Add support for constructors and fields
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter/values')
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java66
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java1
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java17
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java6
7 files changed, 93 insertions, 15 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
index b98eb20..06e8bee 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.interpreter.values;
import java.util.Optional;
+import org.zwobble.couscous.interpreter.NoSuchField;
import org.zwobble.couscous.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValues;
@@ -30,4 +31,9 @@ public class BooleanInterpreterValue implements InterpreterValue {
public Optional<PrimitiveValue> toPrimitiveValue() {
return Optional.of(PrimitiveValues.value(value));
}
+
+ @Override
+ public InterpreterValue getField(String fieldName) {
+ throw new NoSuchField(fieldName);
+ }
}
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 70ba96a..bd63d7f 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
@@ -2,10 +2,12 @@ package org.zwobble.couscous.interpreter.values;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import org.zwobble.couscous.ast.ClassNode;
+import org.zwobble.couscous.ast.FormalArgumentNode;
import org.zwobble.couscous.ast.TypeName;
import org.zwobble.couscous.interpreter.PositionalArguments;
import org.zwobble.couscous.interpreter.Environment;
@@ -15,6 +17,7 @@ import org.zwobble.couscous.interpreter.UnexpectedValueType;
import org.zwobble.couscous.interpreter.WrongNumberOfArguments;
import org.zwobble.couscous.util.Casts;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import static java.util.stream.Collectors.toMap;
@@ -57,22 +60,38 @@ public class ConcreteType {
}
public ConcreteType build() {
- return new ConcreteType(name, methods.build(), staticMethods.build());
+ return new ConcreteType(
+ name,
+ new MethodValue(
+ ImmutableList.of(),
+ (environment, arguments) -> InterpreterValues.UNIT),
+ methods.build(),
+ staticMethods.build());
}
}
public static ConcreteType fromNode(ClassNode classNode) {
+ val constructor = new MethodValue(
+ getArgumentTypes(classNode.getConstructor().getArguments()),
+ (environment, arguments) -> Executor.callMethod(
+ environment,
+ classNode.getConstructor(),
+ Optional.of(arguments.getReceiver()),
+ arguments.getPositionalArguments()));
+
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());
+ val argumentTypes = getArgumentTypes(method.getArguments());
+
return new MethodValue(argumentTypes, (environment, arguments) -> {
- return Executor.callMethod(environment, method, arguments.getPositionalArguments());
+ return Executor.callMethod(
+ environment,
+ method,
+ Optional.of(arguments.getReceiver()),
+ arguments.getPositionalArguments());
});
}));
@@ -82,29 +101,42 @@ public class ConcreteType {
.collect(toMap(
method -> method.getName(),
method -> {
- List<TypeName> argumentTypes = method.getArguments()
- .stream()
- .map(arg -> arg.getType())
- .collect(Collectors.toList());
+ val argumentTypes = getArgumentTypes(method.getArguments());
+
return new StaticMethodValue(argumentTypes, (environment, arguments) -> {
- return Executor.callMethod(environment, method, arguments);
+ return Executor.callMethod(
+ environment,
+ method,
+ Optional.empty(),
+ arguments);
});
}));
return new ConcreteType(
classNode.getName(),
+ constructor,
methods,
staticMethods);
}
+
+ private static List<TypeName> getArgumentTypes(List<FormalArgumentNode> arguments) {
+ return arguments
+ .stream()
+ .map(arg -> arg.getType())
+ .collect(Collectors.toList());
+ }
- private TypeName name;
- private Map<String, MethodValue> methods;
- private Map<String, StaticMethodValue> staticMethods;
+ private final TypeName name;
+ private final MethodValue constructor;
+ private final Map<String, MethodValue> methods;
+ private final Map<String, StaticMethodValue> staticMethods;
public ConcreteType(
TypeName name,
+ MethodValue constructor,
Map<String, MethodValue> methods,
Map<String, StaticMethodValue> staticMethods) {
this.name = name;
+ this.constructor = constructor;
this.methods = methods;
this.staticMethods = staticMethods;
}
@@ -136,7 +168,11 @@ public class ConcreteType {
public InterpreterValue callConstructor(
Environment environment,
List<InterpreterValue> arguments) {
- return new ObjectInterpreterValue(this);
+ val object = new ObjectInterpreterValue(this);
+ constructor.apply(
+ environment,
+ MethodCallArguments.of(object, new PositionalArguments(arguments)));
+ return object;
}
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/IntegerInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
index 92ba306..1effe6a 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.interpreter.values;
import java.util.Optional;
+import org.zwobble.couscous.interpreter.NoSuchField;
import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValues;
@@ -34,4 +35,9 @@ public class IntegerInterpreterValue implements InterpreterValue {
public Optional<PrimitiveValue> toPrimitiveValue() {
return Optional.of(PrimitiveValues.value(value));
}
+
+ @Override
+ public InterpreterValue getField(String fieldName) {
+ throw new NoSuchField(fieldName);
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java
index 6c3c2ec..78d27d2 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java
@@ -7,4 +7,5 @@ import org.zwobble.couscous.values.PrimitiveValue;
public interface InterpreterValue {
ConcreteType getType();
Optional<PrimitiveValue> toPrimitiveValue();
+ InterpreterValue getField(String fieldName);
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java
index 4383353..acb6ef7 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java
@@ -1,14 +1,18 @@
package org.zwobble.couscous.interpreter.values;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Optional;
import org.zwobble.couscous.values.PrimitiveValue;
public class ObjectInterpreterValue implements InterpreterValue {
private final ConcreteType type;
+ private final Map<String, InterpreterValue> fields;
public ObjectInterpreterValue(ConcreteType type) {
this.type = type;
+ this.fields = new HashMap<>();
}
@Override
@@ -20,4 +24,17 @@ public class ObjectInterpreterValue implements InterpreterValue {
public Optional<PrimitiveValue> toPrimitiveValue() {
return Optional.empty();
}
+
+ @Override
+ public InterpreterValue getField(String fieldName) {
+ if (fields.containsKey(fieldName)) {
+ return fields.get(fieldName);
+ } else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public void setField(String fieldName, InterpreterValue value) {
+ fields.put(fieldName, value);
+ }
}
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 aa3432a..a4dde19 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.interpreter.values;
import java.util.Optional;
+import org.zwobble.couscous.interpreter.NoSuchField;
import org.zwobble.couscous.values.IntegerValue;
import org.zwobble.couscous.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValues;
@@ -39,4 +40,9 @@ public class StringInterpreterValue implements InterpreterValue {
public Optional<PrimitiveValue> toPrimitiveValue() {
return Optional.of(PrimitiveValues.value(value));
}
+
+ @Override
+ public InterpreterValue getField(String fieldName) {
+ throw new NoSuchField(fieldName);
+ }
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java
index 253932f..e221fee 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java
@@ -2,6 +2,7 @@ package org.zwobble.couscous.interpreter.values;
import java.util.Optional;
+import org.zwobble.couscous.interpreter.NoSuchField;
import org.zwobble.couscous.values.PrimitiveValue;
import org.zwobble.couscous.values.PrimitiveValues;
@@ -26,4 +27,9 @@ public class UnitInterpreterValue implements InterpreterValue {
public Optional<PrimitiveValue> toPrimitiveValue() {
return Optional.of(PrimitiveValues.UNIT);
}
+
+ @Override
+ public InterpreterValue getField(String fieldName) {
+ throw new NoSuchField(fieldName);
+ }
}