diff options
| author | Michael Williamson <mike@zwobble.org> | 2016-02-28 19:18:28 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2016-02-29 08:04:42 +0000 |
| commit | b7e0010d6e8e5413fcd66eae158111db509eb27b (patch) | |
| tree | 35fafacd7819788b185f803a0c3797a2f54a1dca /src/main | |
| parent | d3e9fb5ce2a13bdb0ee39e9625494e8c5d2a9383 (diff) | |
Split ConcreteType up into specialised type implementations
Diffstat (limited to 'src/main')
21 files changed, 244 insertions, 169 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index d85013e..75ace0a 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -29,10 +29,10 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> public static InterpreterValue callConstructor( Environment environment, ConstructorNode constructor, - Optional<InterpreterValue> thisValue, + InterpreterValue thisValue, PositionalArguments actualArguments) { - return callMethod(environment, constructor.getArguments(), constructor.getBody(), thisValue, actualArguments); + return callMethod(environment, constructor.getArguments(), constructor.getBody(), Optional.of(thisValue), actualArguments); } private static InterpreterValue callMethod( diff --git a/src/main/java/org/zwobble/couscous/interpreter/InterpreterTypes.java b/src/main/java/org/zwobble/couscous/interpreter/InterpreterTypes.java index b43e926..b9221de 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/InterpreterTypes.java +++ b/src/main/java/org/zwobble/couscous/interpreter/InterpreterTypes.java @@ -2,7 +2,7 @@ package org.zwobble.couscous.interpreter; import org.zwobble.couscous.ast.TypeName; import org.zwobble.couscous.interpreter.errors.UnexpectedValueType; -import org.zwobble.couscous.interpreter.values.ConcreteType; +import org.zwobble.couscous.interpreter.types.InterpreterType; import org.zwobble.couscous.interpreter.values.InterpreterValue; import org.zwobble.couscous.values.ObjectValues; @@ -11,13 +11,13 @@ public class InterpreterTypes { checkIsSubType(type, value.getType()); } - private static void checkIsSubType(TypeName superTypeName, ConcreteType subType) { + private static void checkIsSubType(TypeName superTypeName, InterpreterType subType) { if (!isSubType(superTypeName, subType)) { throw new UnexpectedValueType(superTypeName, subType.getName()); } } - public static boolean isSubType(TypeName superTypeName, ConcreteType subType) { + public static boolean isSubType(TypeName superTypeName, InterpreterType subType) { return superTypeName.equals(subType.getName()) || superTypeName.equals(ObjectValues.OBJECT) || diff --git a/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java b/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java index 8038ce1..f96f0c4 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java +++ b/src/main/java/org/zwobble/couscous/interpreter/JavaProject.java @@ -1,17 +1,17 @@ package org.zwobble.couscous.interpreter; -import java.util.List; - -import org.zwobble.couscous.ast.ClassNode; +import com.google.common.collect.Iterables; import org.zwobble.couscous.ast.TypeNode; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; +import org.zwobble.couscous.interpreter.types.UserDefinedInterpreterType; import org.zwobble.couscous.interpreter.values.BoxedIntegerInterpreterValue; -import org.zwobble.couscous.interpreter.values.ConcreteType; import org.zwobble.couscous.interpreter.values.InternalCouscousInterpreterValue; -import com.google.common.collect.Iterables; +import java.util.List; public class JavaProject { - private static final ConcreteType OBJECT_TYPE = ConcreteType.classBuilder("java.lang.Object") + private static final InterpreterType OBJECT_TYPE = IntrinsicInterpreterType.classBuilder("java.lang.Object") .build(); public static MapBackedProject.Builder builder() { @@ -22,7 +22,7 @@ public class JavaProject { } public static Project of(List<TypeNode> classNodes) { - Iterable<ConcreteType> concreteTypes = Iterables.transform(classNodes, ConcreteType::fromNode); + Iterable<InterpreterType> concreteTypes = Iterables.transform(classNodes, UserDefinedInterpreterType::new); return builder() .addClasses(concreteTypes) .build(); diff --git a/src/main/java/org/zwobble/couscous/interpreter/MapBackedProject.java b/src/main/java/org/zwobble/couscous/interpreter/MapBackedProject.java index 7f16b8f..eca6ba9 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/MapBackedProject.java +++ b/src/main/java/org/zwobble/couscous/interpreter/MapBackedProject.java @@ -1,30 +1,30 @@ package org.zwobble.couscous.interpreter; -import java.util.Map; -import org.zwobble.couscous.ast.TypeName; -import org.zwobble.couscous.interpreter.values.ConcreteType; import com.google.common.collect.ImmutableMap; +import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.interpreter.types.InterpreterType; + +import java.util.Map; public class MapBackedProject implements Project { - public static Builder builder() { return new Builder(); } public static class Builder { - private final ImmutableMap.Builder<TypeName, ConcreteType> classes; + private final ImmutableMap.Builder<TypeName, InterpreterType> classes; private Builder() { classes = ImmutableMap.builder(); } - public Builder addClass(ConcreteType clazz) { + public Builder addClass(InterpreterType clazz) { classes.put(clazz.getName(), clazz); return this; } - public Builder addClasses(Iterable<ConcreteType> classes) { - for (ConcreteType clazz : classes) { + public Builder addClasses(Iterable<InterpreterType> classes) { + for (InterpreterType clazz : classes) { addClass(clazz); } return this; @@ -34,14 +34,15 @@ public class MapBackedProject implements Project { return new MapBackedProject(classes.build()); } } - private Map<TypeName, ConcreteType> classes; + + private Map<TypeName, InterpreterType> classes; - public MapBackedProject(Map<TypeName, ConcreteType> classes) { + public MapBackedProject(Map<TypeName, InterpreterType> classes) { this.classes = classes; } @Override - public ConcreteType findClass(TypeName name) { + public InterpreterType findClass(TypeName name) { if (classes.containsKey(name)) { return classes.get(name); } else { diff --git a/src/main/java/org/zwobble/couscous/interpreter/Project.java b/src/main/java/org/zwobble/couscous/interpreter/Project.java index 287ac9c..7e749b4 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Project.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Project.java @@ -1,8 +1,8 @@ package org.zwobble.couscous.interpreter; import org.zwobble.couscous.ast.TypeName; -import org.zwobble.couscous.interpreter.values.ConcreteType; +import org.zwobble.couscous.interpreter.types.InterpreterType; public interface Project { - ConcreteType findClass(TypeName name); + InterpreterType findClass(TypeName name); } diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java new file mode 100644 index 0000000..f5316ae --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/types/InterpreterType.java @@ -0,0 +1,22 @@ +package org.zwobble.couscous.interpreter.types; + +import org.zwobble.couscous.ast.FieldDeclarationNode; +import org.zwobble.couscous.ast.MethodSignature; +import org.zwobble.couscous.ast.StatementNode; +import org.zwobble.couscous.ast.TypeName; +import org.zwobble.couscous.interpreter.Environment; +import org.zwobble.couscous.interpreter.values.InterpreterValue; + +import java.util.List; +import java.util.Optional; +import java.util.Set; + +public interface InterpreterType { + TypeName getName(); + Set<TypeName> getSuperTypes(); + Optional<FieldDeclarationNode> getField(String fieldName); + List<StatementNode> getStaticConstructor(); + InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments); + InterpreterValue callMethod(Environment environment, InterpreterValue value, MethodSignature signature, List<InterpreterValue> arguments); + InterpreterValue callStaticMethod(Environment environment, MethodSignature signature, List<InterpreterValue> arguments); +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java index ed01d59..5fda40c 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java +++ b/src/main/java/org/zwobble/couscous/interpreter/types/IntrinsicInterpreterType.java @@ -1,34 +1,35 @@ -package org.zwobble.couscous.interpreter.values; +package org.zwobble.couscous.interpreter.types; import com.google.common.collect.ImmutableMap; -import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.ast.FieldDeclarationNode; +import org.zwobble.couscous.ast.MethodSignature; +import org.zwobble.couscous.ast.StatementNode; +import org.zwobble.couscous.ast.TypeName; import org.zwobble.couscous.interpreter.Environment; -import org.zwobble.couscous.interpreter.Executor; -import org.zwobble.couscous.interpreter.InterpreterTypes; import org.zwobble.couscous.interpreter.PositionalArguments; import org.zwobble.couscous.interpreter.errors.NoSuchMethod; -import org.zwobble.couscous.interpreter.errors.WrongNumberOfArguments; +import org.zwobble.couscous.interpreter.values.*; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.BiFunction; -import java.util.stream.Collectors; -import static java.util.stream.Collectors.toMap; import static org.zwobble.couscous.util.Casts.tryCast; import static org.zwobble.couscous.util.ExtraLists.list; -import static org.zwobble.couscous.util.ExtraMaps.map; import static org.zwobble.couscous.util.ExtraSets.set; -public class ConcreteType { - public static <T> ConcreteType.Builder<T> builder(Class<T> interpreterValueType, TypeName reference) { +public class IntrinsicInterpreterType implements InterpreterType { + public static <T> Builder<T> builder(Class<T> interpreterValueType, TypeName reference) { return new Builder<>(interpreterValueType, reference); } - - public static <T> ConcreteType.Builder<T> builder(Class<T> interpreterValueType, String name) { + + public static <T> Builder<T> builder(Class<T> interpreterValueType, String name) { return builder(interpreterValueType, TypeName.of(name)); } - - public static ConcreteType.Builder<ObjectInterpreterValue> classBuilder(String name) { + + public static Builder<ObjectInterpreterValue> classBuilder(String name) { return builder(ObjectInterpreterValue.class, name); } @@ -39,7 +40,7 @@ public class ConcreteType { private final ImmutableMap.Builder<MethodSignature, StaticMethodValue> staticMethods = ImmutableMap.builder(); private final Class<T> interpreterValueType; private final TypeName name; - + public Builder(Class<T> interpreterValueType, TypeName name) { this.interpreterValueType = interpreterValueType; this.name = name; @@ -83,158 +84,85 @@ public class ConcreteType { staticMethods.put(new MethodSignature(name, argumentsTypes, returnType), new StaticMethodValue(argumentsTypes, method)); return this; } - - public ConcreteType build() { - return new ConcreteType( + + public InterpreterType build() { + return new IntrinsicInterpreterType( name, - Collections.emptySet(), fields.build(), - list(), constructor, methods.build(), staticMethods.build()); } } - - public static ConcreteType fromNode(TypeNode typeNode) { - return tryCast(ClassNode.class, typeNode) - .map(ConcreteType::fromNode) - // TODO: tidy this up -- type hierarchy instead of one ConcreteType? - .orElseGet(() -> new ConcreteType( - typeNode.getName(), - set(), - map(), - list(), - null, - map(), - map())); - } - - private static ConcreteType fromNode(ClassNode classNode) { - Map<String, FieldDeclarationNode> fields = classNode.getFields().stream() - .collect(toMap( - field -> field.getName(), - field -> field)); - MethodValue constructor = new MethodValue( - getArgumentTypes(classNode.getConstructor().getArguments()), - (environment, arguments) -> Executor.callConstructor( - environment, - classNode.getConstructor(), - Optional.of(arguments.getReceiver()), - arguments.getPositionalArguments())); - - Map<MethodSignature, MethodValue> methods = classNode.getMethods() - .stream() - .filter(method -> !method.isStatic()) - .collect(toMap(method -> method.signature(), method -> { - List<TypeName> argumentTypes = getArgumentTypes(method.getArguments()); - return new MethodValue(argumentTypes, (environment, arguments) -> { - return Executor.callMethod(environment, method, Optional.of(arguments.getReceiver()), arguments.getPositionalArguments()); - }); - })); - Map<MethodSignature, StaticMethodValue> staticMethods = classNode.getMethods() - .stream() - .filter(method -> method.isStatic()) - .collect(toMap(method -> method.signature(), method -> { - List<TypeName> argumentTypes = getArgumentTypes(method.getArguments()); - return new StaticMethodValue(argumentTypes, (environment, arguments) -> { - return Executor.callMethod(environment, method, Optional.empty(), arguments); - }); - })); - return new ConcreteType( - classNode.getName(), - classNode.getSuperTypes(), - fields, - classNode.getStaticConstructor(), - constructor, - methods, - staticMethods); - } - private static List<TypeName> getArgumentTypes(List<FormalArgumentNode> arguments) { - return arguments.stream().map(arg -> arg.getType()).collect(Collectors.toList()); - } private final TypeName name; - private final Set<TypeName> superTypes; private final Map<String, FieldDeclarationNode> fields; - private final List<StatementNode> staticConstructor; private final MethodValue constructor; private final Map<MethodSignature, MethodValue> methods; private final Map<MethodSignature, StaticMethodValue> staticMethods; - - private ConcreteType( + + private IntrinsicInterpreterType( TypeName name, - Set<TypeName> superTypes, Map<String, FieldDeclarationNode> fields, - List<StatementNode> staticConstructor, MethodValue constructor, Map<MethodSignature, MethodValue> methods, Map<MethodSignature, StaticMethodValue> staticMethods) { this.name = name; - this.superTypes = superTypes; this.fields = fields; - this.staticConstructor = staticConstructor; this.constructor = constructor; this.methods = methods; this.staticMethods = staticMethods; } - + + @Override public TypeName getName() { return name; } + @Override public Set<TypeName> getSuperTypes() { - return superTypes; + return set(); } - public Optional<FieldDeclarationNode> getField(boolean isStatic, String fieldName) { - return Optional.ofNullable(fields.get(fieldName)) - .filter(field -> field.isStatic() == isStatic); + @Override + public Optional<FieldDeclarationNode> getField(String fieldName) { + return Optional.ofNullable(fields.get(fieldName)); } + @Override public List<StatementNode> getStaticConstructor() { - return staticConstructor; + return list(); } + @Override public InterpreterValue callMethod(Environment environment, InterpreterValue receiver, MethodSignature signature, List<InterpreterValue> arguments) { - MethodValue method = findMethod(methods, signature, arguments); + MethodValue method = findMethod(methods, signature); return method.apply(environment, MethodCallArguments.of(receiver, new PositionalArguments(arguments))); } - + + @Override public InterpreterValue callStaticMethod(Environment environment, MethodSignature signature, List<InterpreterValue> arguments) { - StaticMethodValue method = findMethod(staticMethods, signature, arguments); + StaticMethodValue method = findMethod(staticMethods, signature); return method.apply(environment, new PositionalArguments(arguments)); } - + + @Override public InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments) { - final org.zwobble.couscous.interpreter.values.ObjectInterpreterValue object = new ObjectInterpreterValue(this); - checkMethodArguments(constructor, arguments); + ObjectInterpreterValue object = new ObjectInterpreterValue(this); constructor.apply(environment, MethodCallArguments.of(object, new PositionalArguments(arguments))); return object; } - - private static <T extends Callable> T findMethod(Map<MethodSignature, T> methods, MethodSignature signature, List<InterpreterValue> arguments) { + + private static <T extends Callable> T findMethod(Map<MethodSignature, T> methods, MethodSignature signature) { if (!methods.containsKey(signature)) { throw new NoSuchMethod(signature); } - final T method = methods.get(signature); - checkMethodArguments(method, arguments); - return method; - } - - private static void checkMethodArguments(final Callable method, List<InterpreterValue> arguments) { - if (method.getArgumentTypes().size() != arguments.size()) { - throw new WrongNumberOfArguments(method.getArgumentTypes().size(), arguments.size()); - } - for (int index = 0; index < arguments.size(); index++) { - final org.zwobble.couscous.ast.TypeName formalArgumentType = method.getArgumentTypes().get(index); - InterpreterTypes.checkIsInstance(formalArgumentType, arguments.get(index)); - } + return methods.get(signature); } - + @Override public String toString() { - return "ConcreteType<" + name + ">"; + return "IntrinsicInterpreterType<" + name + ">"; } -}
\ No newline at end of file +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java new file mode 100644 index 0000000..a058cc3 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/types/UserDefinedInterpreterType.java @@ -0,0 +1,97 @@ +package org.zwobble.couscous.interpreter.types; + +import org.zwobble.couscous.ast.*; +import org.zwobble.couscous.interpreter.Environment; +import org.zwobble.couscous.interpreter.Executor; +import org.zwobble.couscous.interpreter.PositionalArguments; +import org.zwobble.couscous.interpreter.errors.NoSuchMethod; +import org.zwobble.couscous.interpreter.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.ObjectInterpreterValue; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static com.google.common.collect.Iterables.filter; +import static org.zwobble.couscous.util.Casts.tryCast; +import static org.zwobble.couscous.util.ExtraLists.list; +import static org.zwobble.couscous.util.ExtraMaps.map; +import static org.zwobble.couscous.util.ExtraMaps.toMapWithKeys; + +public class UserDefinedInterpreterType implements InterpreterType { + private final TypeNode type; + private final Map<String, FieldDeclarationNode> fields; + private final Map<MethodSignature, MethodNode> methods; + + public UserDefinedInterpreterType(TypeNode type) { + this.type = type; + this.fields = tryCast(ClassNode.class, type) + .map(classNode -> toMapWithKeys(classNode.getFields(), field -> field.getName())) + .orElse(map()); + this.methods = toMapWithKeys( + filter(type.getMethods(), method -> !method.isAbstract()), + method -> method.signature()); + } + + @Override + public TypeName getName() { + return type.getName(); + } + + @Override + public Set<TypeName> getSuperTypes() { + return type.getSuperTypes(); + } + + @Override + public Optional<FieldDeclarationNode> getField(String fieldName) { + return Optional.ofNullable(fields.get(fieldName)); + } + + @Override + public List<StatementNode> getStaticConstructor() { + return tryCast(ClassNode.class, type) + .map(node -> node.getStaticConstructor()) + .orElse(list()); + } + + @Override + public InterpreterValue callConstructor(Environment environment, List<InterpreterValue> arguments) { + ConstructorNode constructor = tryCast(ClassNode.class, type) + // TODO: add test for this case + .orElseThrow(() -> new RuntimeException("Cannot instantiate non-class types")) + .getConstructor(); + InterpreterValue object = new ObjectInterpreterValue(this); + Executor.callConstructor( + environment, + constructor, + object, + new PositionalArguments(arguments)); + return object; + } + + @Override + public InterpreterValue callMethod(Environment environment, InterpreterValue value, MethodSignature signature, List<InterpreterValue> arguments) { + return Executor.callMethod( + environment, + findMethod(signature, false), + Optional.of(value), + new PositionalArguments(arguments)); + } + + @Override + public InterpreterValue callStaticMethod(Environment environment, MethodSignature signature, List<InterpreterValue> arguments) { + return Executor.callMethod( + environment, + findMethod(signature, true), + Optional.empty(), + new PositionalArguments(arguments)); + } + + private MethodNode findMethod(MethodSignature signature, boolean isStatic) { + return Optional.ofNullable(methods.get(signature)) + .filter(method -> method.isStatic() == isStatic) + .orElseThrow(() -> new NoSuchMethod(signature)); + } +} 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 2ac6e3a..a183206 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,8 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.Operator; import org.zwobble.couscous.interpreter.errors.NoSuchField; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValues; @@ -18,7 +20,7 @@ public final class BooleanInterpreterValue implements InterpreterValue { return value ? TRUE : FALSE; } - private static final ConcreteType TYPE = ConcreteType.builder(BooleanInterpreterValue.class, "boolean") + private static final InterpreterType TYPE = IntrinsicInterpreterType.builder(BooleanInterpreterValue.class, "boolean") .method(Operator.BOOLEAN_NOT.getSymbol(), list(), BooleanValue.REF, (environment, arguments) -> of(!arguments.getReceiver().getValue())) @@ -46,7 +48,7 @@ public final class BooleanInterpreterValue implements InterpreterValue { } @Override - public ConcreteType getType() { + public InterpreterType getType() { return TYPE; } diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java index 951d57d..5c477af 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/BoxedIntegerInterpreterValue.java @@ -1,5 +1,7 @@ package org.zwobble.couscous.interpreter.values; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.ObjectValues; @@ -18,7 +20,7 @@ public class BoxedIntegerInterpreterValue { return obj; } - public static final ConcreteType TYPE = ConcreteType.classBuilder("java.lang.Integer") + public static final InterpreterType TYPE = IntrinsicInterpreterType.classBuilder("java.lang.Integer") .field("value", IntegerValue.REF) .staticMethod("parseInt", list(StringValue.REF), IntegerValue.REF, diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InstanceReceiverValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/InstanceReceiverValue.java index 8179394..cdc2167 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InstanceReceiverValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InstanceReceiverValue.java @@ -2,6 +2,7 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.MethodSignature; import org.zwobble.couscous.interpreter.Environment; +import org.zwobble.couscous.interpreter.types.InterpreterType; import java.util.List; @@ -14,7 +15,7 @@ public class InstanceReceiverValue implements ReceiverValue { @Override public InterpreterValue callMethod(Environment environment, MethodSignature signature, List<InterpreterValue> arguments) { - ConcreteType type = value.getType(); + InterpreterType type = value.getType(); return type.callMethod(environment, value, signature, 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 78da460..f0ce783 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerInterpreterValue.java @@ -3,6 +3,8 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.Operator; import org.zwobble.couscous.interpreter.Environment; import org.zwobble.couscous.interpreter.errors.NoSuchField; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.PrimitiveValue; @@ -14,7 +16,7 @@ import java.util.function.BiFunction; import static org.zwobble.couscous.util.ExtraLists.list; public final class IntegerInterpreterValue implements InterpreterValue { - public static final ConcreteType TYPE = ConcreteType.builder(IntegerInterpreterValue.class, IntegerValue.REF) + public static final InterpreterType TYPE = IntrinsicInterpreterType.builder(IntegerInterpreterValue.class, IntegerValue.REF) .method(Operator.ADD.getSymbol(), list(IntegerValue.REF), IntegerValue.REF, infixReturningInteger((left, right) -> left + right)) .method(Operator.SUBTRACT.getSymbol(), list(IntegerValue.REF), IntegerValue.REF, @@ -71,7 +73,7 @@ public final class IntegerInterpreterValue implements InterpreterValue { private final int value; @Override - public ConcreteType getType() { + public InterpreterType getType() { return TYPE; } diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java index e39f576..faab2a8 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InternalCouscousInterpreterValue.java @@ -1,12 +1,14 @@ package org.zwobble.couscous.interpreter.values; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.BooleanValue; import org.zwobble.couscous.values.ObjectValues; import static org.zwobble.couscous.util.ExtraLists.list; public class InternalCouscousInterpreterValue { - public static final ConcreteType TYPE = ConcreteType.classBuilder("_couscous") + public static final InterpreterType TYPE = IntrinsicInterpreterType.classBuilder("_couscous") .staticMethod("same", list(ObjectValues.OBJECT, ObjectValues.OBJECT), BooleanValue.REF, (environment, arguments) -> BooleanInterpreterValue.of(arguments.get(0) == arguments.get(1))) diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java index 1661ee7..50ed24f 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterFields.java @@ -4,24 +4,25 @@ import org.zwobble.couscous.ast.FieldDeclarationNode; import org.zwobble.couscous.interpreter.InterpreterTypes; import org.zwobble.couscous.interpreter.errors.NoSuchField; import org.zwobble.couscous.interpreter.errors.UnboundField; +import org.zwobble.couscous.interpreter.types.InterpreterType; import java.util.HashMap; import java.util.Map; public class InterpreterFields { - public static InterpreterFields forClass(ConcreteType type) { + public static InterpreterFields forClass(InterpreterType type) { return new InterpreterFields(true, type); } - public static InterpreterFields forInstanceOf(ConcreteType type) { + public static InterpreterFields forInstanceOf(InterpreterType type) { return new InterpreterFields(false, type); } private final boolean isStatic; - private final ConcreteType type; + private final InterpreterType type; private final Map<String, InterpreterValue> fields; - private InterpreterFields(boolean isStatic, ConcreteType type) { + private InterpreterFields(boolean isStatic, InterpreterType type) { this.isStatic = isStatic; this.type = type; this.fields = new HashMap<>(); @@ -43,7 +44,8 @@ public class InterpreterFields { } private FieldDeclarationNode getFieldDefinition(String fieldName) { - return type.getField(isStatic, fieldName) + return type.getField(fieldName) + .filter(field -> field.isStatic() == isStatic) .orElseThrow(() -> 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 e02387b..831ba2c 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java @@ -1,11 +1,12 @@ package org.zwobble.couscous.interpreter.values; -import java.util.Optional; - +import org.zwobble.couscous.interpreter.types.InterpreterType; import org.zwobble.couscous.values.PrimitiveValue; +import java.util.Optional; + public interface InterpreterValue { - ConcreteType getType(); + InterpreterType getType(); Optional<PrimitiveValue> toPrimitiveValue(); InterpreterValue getField(String fieldName); void setField(String fieldName, InterpreterValue value); 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 e15c01d..aadf44b 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ObjectInterpreterValue.java @@ -1,20 +1,21 @@ package org.zwobble.couscous.interpreter.values; +import org.zwobble.couscous.interpreter.types.InterpreterType; import org.zwobble.couscous.values.PrimitiveValue; import java.util.Optional; public class ObjectInterpreterValue implements InterpreterValue { - private final ConcreteType type; + private final InterpreterType type; private final InterpreterFields fields; - public ObjectInterpreterValue(ConcreteType type) { + public ObjectInterpreterValue(InterpreterType type) { this.type = type; this.fields = InterpreterFields.forInstanceOf(type); } @Override - public ConcreteType getType() { + public InterpreterType getType() { return type; } diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java index 2595623..cf2c9b7 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/StaticReceiverValue.java @@ -3,14 +3,15 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.MethodSignature; import org.zwobble.couscous.interpreter.Environment; import org.zwobble.couscous.interpreter.Executor; +import org.zwobble.couscous.interpreter.types.InterpreterType; import java.util.List; public class StaticReceiverValue implements ReceiverValue { - private final ConcreteType type; + private final InterpreterType type; private final InterpreterFields fields; - public StaticReceiverValue(ConcreteType type) { + public StaticReceiverValue(InterpreterType type) { this.type = type; this.fields = InterpreterFields.forClass(type); } 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 ae7d141..2fe72d7 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,8 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.Operator; import org.zwobble.couscous.interpreter.errors.NoSuchField; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.*; import java.util.Optional; @@ -9,7 +11,7 @@ import java.util.Optional; import static org.zwobble.couscous.util.ExtraLists.list; public final class StringInterpreterValue implements InterpreterValue { - public static final ConcreteType TYPE = ConcreteType.builder(StringInterpreterValue.class, StringValue.REF) + public static final InterpreterType TYPE = IntrinsicInterpreterType.builder(StringInterpreterValue.class, StringValue.REF) .method("length", list(), IntegerValue.REF, (environment, arguments) -> new IntegerInterpreterValue(arguments.getReceiver().value.length())) @@ -49,7 +51,7 @@ public final class StringInterpreterValue implements InterpreterValue { } @Override - public ConcreteType getType() { + public InterpreterType getType() { return TYPE; } diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java index 5938ce3..f221ea0 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/TypeInterpreterValue.java @@ -2,6 +2,8 @@ package org.zwobble.couscous.interpreter.values; import org.zwobble.couscous.ast.TypeName; import org.zwobble.couscous.interpreter.errors.NoSuchField; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.ObjectValues; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValues; @@ -9,7 +11,8 @@ import org.zwobble.couscous.values.PrimitiveValues; import java.util.Optional; public class TypeInterpreterValue implements InterpreterValue { - public static final ConcreteType TYPE = ConcreteType.builder(TypeInterpreterValue.class, ObjectValues.CLASS) + public static final InterpreterType TYPE = IntrinsicInterpreterType + .builder(TypeInterpreterValue.class, ObjectValues.CLASS) .build(); public static InterpreterValue of(TypeName type) { @@ -23,7 +26,7 @@ public class TypeInterpreterValue implements InterpreterValue { } @Override - public ConcreteType getType() { + public InterpreterType 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 54f5605..59792c6 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java +++ b/src/main/java/org/zwobble/couscous/interpreter/values/UnitInterpreterValue.java @@ -1,19 +1,22 @@ package org.zwobble.couscous.interpreter.values; -import java.util.Optional; import org.zwobble.couscous.interpreter.errors.NoSuchField; +import org.zwobble.couscous.interpreter.types.InterpreterType; +import org.zwobble.couscous.interpreter.types.IntrinsicInterpreterType; import org.zwobble.couscous.values.PrimitiveValue; import org.zwobble.couscous.values.PrimitiveValues; +import java.util.Optional; + public class UnitInterpreterValue implements InterpreterValue { - private static final ConcreteType TYPE = ConcreteType.builder(UnitInterpreterValue.class, "Unit").build(); + private static final InterpreterType TYPE = IntrinsicInterpreterType.builder(UnitInterpreterValue.class, "Unit").build(); public static final UnitInterpreterValue UNIT = new UnitInterpreterValue(); private UnitInterpreterValue() { } @Override - public ConcreteType getType() { + public InterpreterType getType() { return TYPE; } diff --git a/src/main/java/org/zwobble/couscous/util/ExtraMaps.java b/src/main/java/org/zwobble/couscous/util/ExtraMaps.java index e5d21e9..09339e6 100644 --- a/src/main/java/org/zwobble/couscous/util/ExtraMaps.java +++ b/src/main/java/org/zwobble/couscous/util/ExtraMaps.java @@ -2,6 +2,7 @@ package org.zwobble.couscous.util; import com.google.common.collect.ImmutableMap; +import java.util.AbstractMap; import java.util.Map; import java.util.function.Function; @@ -31,4 +32,8 @@ public class ExtraMaps { return builder.build(); } + + public static <T, K> Map<K, T> toMapWithKeys(Iterable<T> iterable, Function<T, K> function) { + return toMap(iterable, value -> new AbstractMap.SimpleImmutableEntry<K, T>(function.apply(value), value)); + } } |
