aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/couscous/JavaProject.java2
-rw-r--r--src/main/java/org/zwobble/couscous/MapBackedProject.java12
-rw-r--r--src/main/java/org/zwobble/couscous/Project.java2
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/Environment.java2
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java4
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java40
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java4
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java2
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java6
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java4
-rw-r--r--src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java4
-rw-r--r--src/main/java/org/zwobble/couscous/util/Casts.java13
12 files changed, 58 insertions, 37 deletions
diff --git a/src/main/java/org/zwobble/couscous/JavaProject.java b/src/main/java/org/zwobble/couscous/JavaProject.java
index d54bd9c..833f06f 100644
--- a/src/main/java/org/zwobble/couscous/JavaProject.java
+++ b/src/main/java/org/zwobble/couscous/JavaProject.java
@@ -17,7 +17,7 @@ public class JavaProject {
}
public static Project of(List<ClassNode> classNodes) {
- val concreteTypes = (Iterable)Iterables.transform(classNodes, ConcreteType::fromNode);
+ val concreteTypes = Iterables.transform(classNodes, ConcreteType::fromNode);
return builder()
.addClasses(concreteTypes)
.build();
diff --git a/src/main/java/org/zwobble/couscous/MapBackedProject.java b/src/main/java/org/zwobble/couscous/MapBackedProject.java
index 3150279..7a243f4 100644
--- a/src/main/java/org/zwobble/couscous/MapBackedProject.java
+++ b/src/main/java/org/zwobble/couscous/MapBackedProject.java
@@ -15,18 +15,18 @@ public class MapBackedProject implements Project {
}
public static class Builder {
- private final ImmutableMap.Builder<TypeName, ConcreteType<?>> classes;
+ private final ImmutableMap.Builder<TypeName, ConcreteType> classes;
private Builder() {
classes = ImmutableMap.builder();
}
- public Builder addClass(ConcreteType<?> clazz) {
+ public Builder addClass(ConcreteType clazz) {
classes.put(clazz.getName(), clazz);
return this;
}
- public Builder addClasses(Iterable<ConcreteType<?>> classes) {
+ public Builder addClasses(Iterable<ConcreteType> classes) {
for (val clazz : classes) {
addClass(clazz);
}
@@ -38,14 +38,14 @@ public class MapBackedProject implements Project {
}
}
- private Map<TypeName, ConcreteType<?>> classes;
+ private Map<TypeName, ConcreteType> classes;
- public MapBackedProject(Map<TypeName, ConcreteType<?>> classes) {
+ public MapBackedProject(Map<TypeName, ConcreteType> classes) {
this.classes = classes;
}
@Override
- public ConcreteType<?> findClass(TypeName name) {
+ public ConcreteType findClass(TypeName name) {
return classes.get(name);
}
}
diff --git a/src/main/java/org/zwobble/couscous/Project.java b/src/main/java/org/zwobble/couscous/Project.java
index fee0cd2..40f5560 100644
--- a/src/main/java/org/zwobble/couscous/Project.java
+++ b/src/main/java/org/zwobble/couscous/Project.java
@@ -4,5 +4,5 @@ import org.zwobble.couscous.ast.TypeName;
import org.zwobble.couscous.interpreter.values.ConcreteType;
public interface Project {
- ConcreteType<?> findClass(TypeName name);
+ ConcreteType findClass(TypeName name);
}
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Environment.java b/src/main/java/org/zwobble/couscous/interpreter/Environment.java
index 37df9f5..6da54ce 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/Environment.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/Environment.java
@@ -46,7 +46,7 @@ public class Environment {
put(variable.getDeclaration().getId(), value);
}
- public ConcreteType<?> findClass(TypeName className) {
+ public ConcreteType findClass(TypeName className) {
// TODO: handle missing classes
return project.findClass(className);
}
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 4ab2d18..b98eb20 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanInterpreterValue.java
@@ -11,7 +11,7 @@ import lombok.Value;
@Value
public class BooleanInterpreterValue implements InterpreterValue {
- private static final ConcreteType<BooleanInterpreterValue> TYPE = ConcreteType.<BooleanInterpreterValue>builder("Boolean")
+ private static final ConcreteType TYPE = ConcreteType.builder(BooleanInterpreterValue.class, "Boolean")
.build();
@Getter(value = AccessLevel.NONE)
@@ -22,7 +22,7 @@ public class BooleanInterpreterValue implements InterpreterValue {
}
@Override
- public ConcreteType<?> getType() {
+ public ConcreteType getType() {
return TYPE;
}
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 52cd14a..18259f0 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java
@@ -13,6 +13,7 @@ import org.zwobble.couscous.interpreter.Executor;
import org.zwobble.couscous.interpreter.NoSuchMethod;
import org.zwobble.couscous.interpreter.UnexpectedValueType;
import org.zwobble.couscous.interpreter.WrongNumberOfArguments;
+import org.zwobble.couscous.util.Casts;
import com.google.common.collect.ImmutableMap;
@@ -20,15 +21,17 @@ import static java.util.stream.Collectors.toMap;
import lombok.val;
-public class ConcreteType<T> {
+public class ConcreteType {
public static class Builder<T> {
- private final ImmutableMap.Builder<String, MethodValue<T>> methods =
+ private final ImmutableMap.Builder<String, MethodValue> methods =
ImmutableMap.builder();
private final ImmutableMap.Builder<String, StaticMethodValue> staticMethods =
ImmutableMap.builder();
+ private Class<T> interpreterValueType;
private final TypeName name;
- public Builder(TypeName name) {
+ public Builder(Class<T> interpreterValueType, TypeName name) {
+ this.interpreterValueType = interpreterValueType;
this.name = name;
}
@@ -36,7 +39,13 @@ public class ConcreteType<T> {
String name,
List<TypeName> argumentsTypes,
BiFunction<T, Arguments, InterpreterValue> method) {
- methods.put(name, new MethodValue<T>(argumentsTypes, method));
+ methods.put(name, new MethodValue(argumentsTypes, (receiver, arguments) -> {
+ return Casts.tryCast(interpreterValueType, receiver)
+ .map(typedReceiver -> method.apply(typedReceiver, arguments))
+ .orElseThrow(() -> {
+ throw new RuntimeException("receiver is of wrong type");
+ });
+ }));
return this;
}
@@ -48,12 +57,12 @@ public class ConcreteType<T> {
return this;
}
- public ConcreteType<T> build() {
- return new ConcreteType<T>(name, methods.build(), staticMethods.build());
+ public ConcreteType build() {
+ return new ConcreteType(name, methods.build(), staticMethods.build());
}
}
- public static ConcreteType<?> fromNode(ClassNode classNode) {
+ public static ConcreteType fromNode(ClassNode classNode) {
val staticMethods = classNode.getMethods()
.stream()
.filter(method -> method.isStatic())
@@ -68,19 +77,19 @@ public class ConcreteType<T> {
return Executor.callMethod(environment, method, arguments);
});
}));
- return new ConcreteType<Void>(
+ return new ConcreteType(
classNode.getName(),
ImmutableMap.of(),
staticMethods);
}
private TypeName name;
- private Map<String, MethodValue<T>> methods;
+ private Map<String, MethodValue> methods;
private Map<String, StaticMethodValue> staticMethods;
public ConcreteType(
TypeName name,
- Map<String, MethodValue<T>> methods,
+ Map<String, MethodValue> methods,
Map<String, StaticMethodValue> staticMethods) {
this.name = name;
this.methods = methods;
@@ -91,18 +100,17 @@ public class ConcreteType<T> {
return name;
}
- public static <T> ConcreteType.Builder<T> builder(TypeName reference) {
- return new Builder<>(reference);
+ public static <T> ConcreteType.Builder<T> builder(Class<T> interpreterValueType, TypeName reference) {
+ return new Builder<>(interpreterValueType, reference);
}
- public static <T> ConcreteType.Builder<T> builder(String name) {
- return builder(TypeName.of(name));
+ public static <T> ConcreteType.Builder<T> builder(Class<T> interpreterValueType, String name) {
+ return builder(interpreterValueType, TypeName.of(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));
+ return method.apply(receiver, new Arguments(arguments));
}
public InterpreterValue callStaticMethod(Environment environment, 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 c7d7be3..92ba306 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java
@@ -14,7 +14,7 @@ import lombok.val;
@Value
public class IntegerInterpreterValue implements InterpreterValue {
- public static final ConcreteType<?> TYPE = ConcreteType.<IntegerInterpreterValue>builder(IntegerValue.REF)
+ public static final ConcreteType TYPE = ConcreteType.builder(IntegerInterpreterValue.class, IntegerValue.REF)
.staticMethod("parseInt", asList(StringValue.REF),
(environment, arguments) -> {
val value = (StringInterpreterValue)arguments.get(0);
@@ -26,7 +26,7 @@ public class IntegerInterpreterValue implements InterpreterValue {
int value;
@Override
- public ConcreteType<?> getType() {
+ public ConcreteType getType() {
return TYPE;
}
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 7696ff2..6c3c2ec 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java
@@ -5,6 +5,6 @@ import java.util.Optional;
import org.zwobble.couscous.values.PrimitiveValue;
public interface InterpreterValue {
- ConcreteType<?> getType();
+ ConcreteType getType();
Optional<PrimitiveValue> toPrimitiveValue();
}
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 f2e2cc1..c1f2c6e 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java
@@ -11,12 +11,12 @@ import lombok.Getter;
import lombok.Value;
@Value
-public class MethodValue<T> implements Callable {
+public class MethodValue implements Callable {
List<TypeName> argumentTypes;
@Getter(value=AccessLevel.NONE)
- BiFunction<T, Arguments, InterpreterValue> apply;
+ BiFunction<InterpreterValue, Arguments, InterpreterValue> apply;
- public InterpreterValue apply(T receiver, Arguments arguments) {
+ public InterpreterValue apply(InterpreterValue receiver, Arguments arguments) {
return apply.apply(receiver, 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 f17cdd5..98165b2 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/StringInterpreterValue.java
@@ -14,7 +14,7 @@ import lombok.val;
@Value
public class StringInterpreterValue implements InterpreterValue {
- public static final ConcreteType<?> TYPE = ConcreteType.<StringInterpreterValue>builder(StringValue.REF)
+ public static final ConcreteType TYPE = ConcreteType.builder(StringInterpreterValue.class, StringValue.REF)
.method("length", asList(),
(receiver, arguments) -> new IntegerInterpreterValue(receiver.value.length()))
@@ -30,7 +30,7 @@ public class StringInterpreterValue implements InterpreterValue {
String value;
@Override
- public ConcreteType<?> getType() {
+ public ConcreteType getType() {
return TYPE;
}
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 e34882b..253932f 100644
--- a/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java
+++ b/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java
@@ -9,7 +9,7 @@ import lombok.ToString;
@ToString
public class UnitInterpreterValue implements InterpreterValue {
- private static final ConcreteType<?> TYPE = ConcreteType.<UnitInterpreterValue>builder("Unit")
+ private static final ConcreteType TYPE = ConcreteType.builder(UnitInterpreterValue.class, "Unit")
.build();
public static final UnitInterpreterValue UNIT = new UnitInterpreterValue();
@@ -18,7 +18,7 @@ public class UnitInterpreterValue implements InterpreterValue {
}
@Override
- public ConcreteType<?> getType() {
+ public ConcreteType getType() {
return TYPE;
}
diff --git a/src/main/java/org/zwobble/couscous/util/Casts.java b/src/main/java/org/zwobble/couscous/util/Casts.java
new file mode 100644
index 0000000..95d2bbe
--- /dev/null
+++ b/src/main/java/org/zwobble/couscous/util/Casts.java
@@ -0,0 +1,13 @@
+package org.zwobble.couscous.util;
+
+import java.util.Optional;
+
+public class Casts {
+ public static <T> Optional<T> tryCast(Class<T> type, Object value) {
+ try {
+ return Optional.of(type.cast(value));
+ } catch (ClassCastException exception) {
+ return Optional.empty();
+ }
+ }
+}