From 2f9374c7f32a761413da4c5484bec88a76c855d2 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Mon, 5 Oct 2015 12:29:48 +0100 Subject: Move interpreter values into interpreter package --- .../java/org/zwobble/couscous/JavaProject.java | 2 +- .../org/zwobble/couscous/MapBackedProject.java | 2 +- src/main/java/org/zwobble/couscous/Project.java | 2 +- .../java/org/zwobble/couscous/ast/LiteralNode.java | 8 +- .../backends/python/PythonCodeGenerator.java | 4 +- .../zwobble/couscous/interpreter/Arguments.java | 2 +- .../interpreter/ConditionMustBeBoolean.java | 2 +- .../zwobble/couscous/interpreter/Environment.java | 4 +- .../zwobble/couscous/interpreter/Evaluator.java | 4 +- .../org/zwobble/couscous/interpreter/Executor.java | 4 +- .../zwobble/couscous/interpreter/Interpreter.java | 2 +- .../couscous/interpreter/StackFrameBuilder.java | 2 +- .../couscous/interpreter/values/BooleanValue.java | 23 ++++ .../couscous/interpreter/values/Callable.java | 9 ++ .../couscous/interpreter/values/ConcreteType.java | 141 +++++++++++++++++++++ .../couscous/interpreter/values/IntegerValue.java | 30 +++++ .../interpreter/values/InterpreterValue.java | 5 + .../interpreter/values/InterpreterValues.java | 13 ++ .../couscous/interpreter/values/MethodValue.java | 22 ++++ .../interpreter/values/StaticMethodValue.java | 24 ++++ .../couscous/interpreter/values/StringValue.java | 34 +++++ .../couscous/interpreter/values/UnitValue.java | 19 +++ .../org/zwobble/couscous/values/BooleanValue.java | 23 ---- .../java/org/zwobble/couscous/values/Callable.java | 7 - .../org/zwobble/couscous/values/ConcreteType.java | 140 -------------------- .../org/zwobble/couscous/values/IntegerValue.java | 28 ---- .../zwobble/couscous/values/InterpreterValue.java | 5 - .../zwobble/couscous/values/InterpreterValues.java | 13 -- .../org/zwobble/couscous/values/MethodValue.java | 21 --- .../zwobble/couscous/values/StaticMethodValue.java | 23 ---- .../org/zwobble/couscous/values/StringValue.java | 32 ----- .../org/zwobble/couscous/values/UnitValue.java | 19 --- .../org/zwobble/couscous/tests/BackendTests.java | 6 +- .../org/zwobble/couscous/tests/MethodRunner.java | 2 +- .../tests/backends/python/PythonCompilerTests.java | 6 +- .../couscous/tests/interpreter/EvaluatorTests.java | 6 +- .../tests/interpreter/InterpreterTests.java | 8 +- 37 files changed, 353 insertions(+), 344 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/BooleanValue.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/Callable.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/IntegerValue.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/StringValue.java create mode 100644 src/main/java/org/zwobble/couscous/interpreter/values/UnitValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/BooleanValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/Callable.java delete mode 100644 src/main/java/org/zwobble/couscous/values/ConcreteType.java delete mode 100644 src/main/java/org/zwobble/couscous/values/IntegerValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/InterpreterValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/InterpreterValues.java delete mode 100644 src/main/java/org/zwobble/couscous/values/MethodValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/StaticMethodValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/StringValue.java delete mode 100644 src/main/java/org/zwobble/couscous/values/UnitValue.java (limited to 'src') diff --git a/src/main/java/org/zwobble/couscous/JavaProject.java b/src/main/java/org/zwobble/couscous/JavaProject.java index e9d2ba4..a13399c 100644 --- a/src/main/java/org/zwobble/couscous/JavaProject.java +++ b/src/main/java/org/zwobble/couscous/JavaProject.java @@ -1,6 +1,6 @@ package org.zwobble.couscous; -import org.zwobble.couscous.values.IntegerValue; +import org.zwobble.couscous.interpreter.values.IntegerValue; public class JavaProject { public static MapBackedProject.Builder builder() { diff --git a/src/main/java/org/zwobble/couscous/MapBackedProject.java b/src/main/java/org/zwobble/couscous/MapBackedProject.java index f8e457f..5fc0395 100644 --- a/src/main/java/org/zwobble/couscous/MapBackedProject.java +++ b/src/main/java/org/zwobble/couscous/MapBackedProject.java @@ -2,7 +2,7 @@ package org.zwobble.couscous; import java.util.Map; -import org.zwobble.couscous.values.ConcreteType; +import org.zwobble.couscous.interpreter.values.ConcreteType; import com.google.common.collect.ImmutableMap; diff --git a/src/main/java/org/zwobble/couscous/Project.java b/src/main/java/org/zwobble/couscous/Project.java index 56b439f..86299ca 100644 --- a/src/main/java/org/zwobble/couscous/Project.java +++ b/src/main/java/org/zwobble/couscous/Project.java @@ -1,6 +1,6 @@ package org.zwobble.couscous; -import org.zwobble.couscous.values.ConcreteType; +import org.zwobble.couscous.interpreter.values.ConcreteType; public interface Project { ConcreteType findClass(String name); diff --git a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java index 0869653..6bc498a 100644 --- a/src/main/java/org/zwobble/couscous/ast/LiteralNode.java +++ b/src/main/java/org/zwobble/couscous/ast/LiteralNode.java @@ -1,10 +1,10 @@ package org.zwobble.couscous.ast; import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; -import org.zwobble.couscous.values.BooleanValue; -import org.zwobble.couscous.values.IntegerValue; -import org.zwobble.couscous.values.InterpreterValue; -import org.zwobble.couscous.values.StringValue; +import org.zwobble.couscous.interpreter.values.BooleanValue; +import org.zwobble.couscous.interpreter.values.IntegerValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.StringValue; import lombok.Value; diff --git a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java index 816a80d..4c26a0a 100644 --- a/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java +++ b/src/main/java/org/zwobble/couscous/backends/python/PythonCodeGenerator.java @@ -21,8 +21,8 @@ import org.zwobble.couscous.backends.python.ast.PythonExpressionNode; import org.zwobble.couscous.backends.python.ast.PythonFunctionDefinitionNode; import org.zwobble.couscous.backends.python.ast.PythonModuleNode; import org.zwobble.couscous.backends.python.ast.PythonStatementNode; -import org.zwobble.couscous.values.IntegerValue; -import org.zwobble.couscous.values.StringValue; +import org.zwobble.couscous.interpreter.values.IntegerValue; +import org.zwobble.couscous.interpreter.values.StringValue; import static java.util.Arrays.asList; import static org.zwobble.couscous.backends.python.ast.PythonClassNode.pythonClass; diff --git a/src/main/java/org/zwobble/couscous/interpreter/Arguments.java b/src/main/java/org/zwobble/couscous/interpreter/Arguments.java index af674a1..f34a456 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Arguments.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Arguments.java @@ -2,7 +2,7 @@ package org.zwobble.couscous.interpreter; import java.util.List; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; public class Arguments { private List values; diff --git a/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java b/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java index c69c290..7f2e901 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java +++ b/src/main/java/org/zwobble/couscous/interpreter/ConditionMustBeBoolean.java @@ -1,6 +1,6 @@ package org.zwobble.couscous.interpreter; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; import lombok.EqualsAndHashCode; import lombok.Value; diff --git a/src/main/java/org/zwobble/couscous/interpreter/Environment.java b/src/main/java/org/zwobble/couscous/interpreter/Environment.java index 6838ba5..5e6e231 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Environment.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Environment.java @@ -6,8 +6,8 @@ import java.util.Optional; import org.zwobble.couscous.Project; import org.zwobble.couscous.ast.VariableDeclaration; import org.zwobble.couscous.ast.VariableNode; -import org.zwobble.couscous.values.ConcreteType; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.ConcreteType; +import org.zwobble.couscous.interpreter.values.InterpreterValue; import org.zwobble.couscous.values.TypeReference; import static java.util.stream.Collectors.toMap; diff --git a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java index 6287348..6b61b7f 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Evaluator.java @@ -11,8 +11,8 @@ import org.zwobble.couscous.ast.StaticMethodCallNode; import org.zwobble.couscous.ast.TernaryConditionalNode; import org.zwobble.couscous.ast.VariableReferenceNode; import org.zwobble.couscous.ast.visitors.ExpressionNodeVisitor; -import org.zwobble.couscous.values.BooleanValue; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.BooleanValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; import lombok.val; diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index 95eddad..2f12e0c 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -11,8 +11,8 @@ import org.zwobble.couscous.ast.ReturnNode; import org.zwobble.couscous.ast.StatementNode; import org.zwobble.couscous.ast.VariableNode; import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; -import org.zwobble.couscous.values.InterpreterValue; -import org.zwobble.couscous.values.UnitValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.UnitValue; import static org.zwobble.couscous.interpreter.Evaluator.eval; diff --git a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java index 884a082..39191ce 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java @@ -6,7 +6,7 @@ import java.util.stream.Collectors; import org.zwobble.couscous.Project; import org.zwobble.couscous.ast.ExpressionNode; import org.zwobble.couscous.ast.LiteralNode; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; import com.google.common.collect.ImmutableMap; diff --git a/src/main/java/org/zwobble/couscous/interpreter/StackFrameBuilder.java b/src/main/java/org/zwobble/couscous/interpreter/StackFrameBuilder.java index 3b163f3..c546807 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/StackFrameBuilder.java +++ b/src/main/java/org/zwobble/couscous/interpreter/StackFrameBuilder.java @@ -4,7 +4,7 @@ import java.util.Map; import org.zwobble.couscous.ast.VariableDeclaration; import org.zwobble.couscous.ast.VariableNode; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; import com.google.common.collect.ImmutableMap; diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/BooleanValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanValue.java new file mode 100644 index 0000000..1837d6f --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/BooleanValue.java @@ -0,0 +1,23 @@ +package org.zwobble.couscous.interpreter.values; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Value; + +@Value +public class BooleanValue implements InterpreterValue { + private static final ConcreteType TYPE = ConcreteType.builder("Boolean") + .build(); + + @Getter(value = AccessLevel.NONE) + boolean value; + + public boolean getValue() { + return value; + } + + @Override + public ConcreteType getType() { + return TYPE; + } +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/Callable.java b/src/main/java/org/zwobble/couscous/interpreter/values/Callable.java new file mode 100644 index 0000000..dc372bb --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/Callable.java @@ -0,0 +1,9 @@ +package org.zwobble.couscous.interpreter.values; + +import java.util.List; + +import org.zwobble.couscous.values.TypeReference; + +public interface Callable { + List getArgumentTypes(); +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java new file mode 100644 index 0000000..b2abd2b --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/ConcreteType.java @@ -0,0 +1,141 @@ +package org.zwobble.couscous.interpreter.values; + +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.stream.Collectors; + +import org.zwobble.couscous.ast.ClassNode; +import org.zwobble.couscous.interpreter.Arguments; +import org.zwobble.couscous.interpreter.Environment; +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.values.TypeReference; + +import com.google.common.collect.ImmutableMap; + +import static java.util.stream.Collectors.toMap; +import static org.zwobble.couscous.values.TypeReference.typeRef; + +import lombok.val; + +public class ConcreteType { + public static class Builder { + private final ImmutableMap.Builder> methods = + ImmutableMap.builder(); + private final ImmutableMap.Builder staticMethods = + ImmutableMap.builder(); + private final String name; + + public Builder(String name) { + this.name = name; + } + + public Builder method( + String name, + List argumentsTypes, + BiFunction method) { + methods.put(name, new MethodValue(argumentsTypes, method)); + return this; + } + + public Builder staticMethod( + String name, + List argumentsTypes, + BiFunction method) { + staticMethods.put(name, new StaticMethodValue(argumentsTypes, method)); + return this; + } + + public ConcreteType build() { + return new ConcreteType(name, methods.build(), staticMethods.build()); + } + } + + public static ConcreteType fromNode(ClassNode classNode) { + val staticMethods = classNode.getMethods() + .stream() + .filter(method -> method.isStatic()) + .collect(toMap( + method -> method.getName(), + method -> { + List argumentTypes = method.getArguments() + .stream() + .map(arg -> arg.getType()) + .collect(Collectors.toList()); + return new StaticMethodValue(argumentTypes, (environment, arguments) -> { + return Executor.callMethod(environment, method, arguments); + }); + })); + return new ConcreteType( + classNode.getName(), + ImmutableMap.of(), + staticMethods); + } + + private String name; + private Map> methods; + private Map staticMethods; + + public ConcreteType( + String name, + Map> methods, + Map staticMethods) { + this.name = name; + this.methods = methods; + this.staticMethods = staticMethods; + } + + public String getName() { + return name; + } + + public static ConcreteType.Builder builder(TypeReference reference) { + return new Builder<>(reference.getName()); + } + + public static ConcreteType.Builder builder(String name) { + return new Builder<>(name); + } + + @SuppressWarnings("unchecked") + public InterpreterValue callMethod(InterpreterValue receiver, String methodName, List arguments) { + val method = findMethod(methods, methodName, arguments); + return method.apply((T)receiver, new Arguments(arguments)); + } + + public InterpreterValue callStaticMethod(Environment environment, String methodName, List arguments) { + val method = findMethod(staticMethods, methodName, arguments); + return method.apply(environment, new Arguments(arguments)); + } + + private static T findMethod(Map methods, String methodName, List arguments) { + if (!methods.containsKey(methodName)) { + throw new NoSuchMethod(methodName); + } + val method = methods.get(methodName); + if (method.getArgumentTypes().size() != arguments.size()) { + throw new WrongNumberOfArguments(method.getArgumentTypes().size(), arguments.size()); + } + + for (int index = 0; index < arguments.size(); index++) { + val formalArgumentType = method.getArgumentTypes().get(index); + val actualArgumentType = arguments.get(index).getType(); + if (!formalArgumentType.equals(actualArgumentType.getReference())) { + throw new UnexpectedValueType(formalArgumentType, actualArgumentType.getReference()); + } + } + return method; + } + + public TypeReference getReference() { + return typeRef(name); + } + + @Override + public String toString() { + return "ConcreteType<" + name + ">"; + } +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/IntegerValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerValue.java new file mode 100644 index 0000000..89fd056 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/IntegerValue.java @@ -0,0 +1,30 @@ +package org.zwobble.couscous.interpreter.values; + +import org.zwobble.couscous.values.TypeReference; + +import static java.util.Arrays.asList; +import static org.zwobble.couscous.values.TypeReference.typeRef; + +import lombok.Value; +import lombok.val; + +@Value +public class IntegerValue implements InterpreterValue { + public static final TypeReference REF = typeRef("java.lang.Integer"); + + public static final ConcreteType TYPE = ConcreteType.builder(REF) + .staticMethod("parseInt", asList(StringValue.REF), + (environment, arguments) -> { + val value = (StringValue)arguments.get(0); + return new IntegerValue(Integer.parseInt(value.getValue())); + }) + + .build(); + + int value; + + @Override + 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 new file mode 100644 index 0000000..cf2aa5b --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValue.java @@ -0,0 +1,5 @@ +package org.zwobble.couscous.interpreter.values; + +public interface InterpreterValue { + ConcreteType getType(); +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java new file mode 100644 index 0000000..ec2d97f --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/InterpreterValues.java @@ -0,0 +1,13 @@ +package org.zwobble.couscous.interpreter.values; + +public class InterpreterValues { + public static final UnitValue UNIT = UnitValue.UNIT; + + public static InterpreterValue value(int value) { + return new IntegerValue(value); + } + + public static InterpreterValue value(String value) { + return new StringValue(value); + } +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java new file mode 100644 index 0000000..ea76870 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/MethodValue.java @@ -0,0 +1,22 @@ +package org.zwobble.couscous.interpreter.values; + +import java.util.List; +import java.util.function.BiFunction; + +import org.zwobble.couscous.interpreter.Arguments; +import org.zwobble.couscous.values.TypeReference; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Value; + +@Value +public class MethodValue implements Callable { + List argumentTypes; + @Getter(value=AccessLevel.NONE) + BiFunction apply; + + public InterpreterValue apply(T receiver, Arguments arguments) { + return apply.apply(receiver, arguments); + } +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java new file mode 100644 index 0000000..21697b1 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/StaticMethodValue.java @@ -0,0 +1,24 @@ +package org.zwobble.couscous.interpreter.values; + +import java.util.List; +import java.util.function.BiFunction; + +import org.zwobble.couscous.interpreter.Arguments; +import org.zwobble.couscous.interpreter.Environment; +import org.zwobble.couscous.values.TypeReference; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Value; + +@Value +public class StaticMethodValue implements Callable { + List argumentTypes; + @Getter(value=AccessLevel.NONE) + BiFunction apply; + + public InterpreterValue apply(Environment environment, Arguments arguments) { + return apply.apply(environment, arguments); + } + +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/StringValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/StringValue.java new file mode 100644 index 0000000..43a4bde --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/StringValue.java @@ -0,0 +1,34 @@ +package org.zwobble.couscous.interpreter.values; + +import org.zwobble.couscous.values.TypeReference; + +import static java.util.Arrays.asList; +import static org.zwobble.couscous.values.TypeReference.typeRef; + +import lombok.Value; +import lombok.val; + +@Value +public class StringValue implements InterpreterValue { + public static final TypeReference REF = typeRef("java.lang.String"); + + public static final ConcreteType TYPE = ConcreteType.builder(REF) + .method("length", asList(), + (receiver, arguments) -> new IntegerValue(receiver.value.length())) + + .method("substring", asList(IntegerValue.REF, IntegerValue.REF), + (receiver, arguments) -> { + val startIndex = (IntegerValue)arguments.get(0); + val endIndex = (IntegerValue)arguments.get(1); + return new StringValue(receiver.value.substring(startIndex.getValue(), endIndex.getValue())); + }) + + .build(); + + String value; + + @Override + public ConcreteType getType() { + return TYPE; + } +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/values/UnitValue.java b/src/main/java/org/zwobble/couscous/interpreter/values/UnitValue.java new file mode 100644 index 0000000..4e2eb2c --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/values/UnitValue.java @@ -0,0 +1,19 @@ +package org.zwobble.couscous.interpreter.values; + +import lombok.ToString; + +@ToString +public class UnitValue implements InterpreterValue { + private static final ConcreteType TYPE = ConcreteType.builder("Unit") + .build(); + + public static final UnitValue UNIT = new UnitValue(); + + private UnitValue() { + } + + @Override + public ConcreteType getType() { + return TYPE; + } +} diff --git a/src/main/java/org/zwobble/couscous/values/BooleanValue.java b/src/main/java/org/zwobble/couscous/values/BooleanValue.java deleted file mode 100644 index aeeb7e3..0000000 --- a/src/main/java/org/zwobble/couscous/values/BooleanValue.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.zwobble.couscous.values; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Value; - -@Value -public class BooleanValue implements InterpreterValue { - private static final ConcreteType TYPE = ConcreteType.builder("Boolean") - .build(); - - @Getter(value = AccessLevel.NONE) - boolean value; - - public boolean getValue() { - return value; - } - - @Override - public ConcreteType getType() { - return TYPE; - } -} diff --git a/src/main/java/org/zwobble/couscous/values/Callable.java b/src/main/java/org/zwobble/couscous/values/Callable.java deleted file mode 100644 index 5065598..0000000 --- a/src/main/java/org/zwobble/couscous/values/Callable.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.zwobble.couscous.values; - -import java.util.List; - -public interface Callable { - List getArgumentTypes(); -} diff --git a/src/main/java/org/zwobble/couscous/values/ConcreteType.java b/src/main/java/org/zwobble/couscous/values/ConcreteType.java deleted file mode 100644 index f3c226c..0000000 --- a/src/main/java/org/zwobble/couscous/values/ConcreteType.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.zwobble.couscous.values; - -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.stream.Collectors; - -import org.zwobble.couscous.ast.ClassNode; -import org.zwobble.couscous.interpreter.Arguments; -import org.zwobble.couscous.interpreter.Environment; -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 com.google.common.collect.ImmutableMap; - -import static java.util.stream.Collectors.toMap; -import static org.zwobble.couscous.values.TypeReference.typeRef; - -import lombok.val; - -public class ConcreteType { - public static class Builder { - private final ImmutableMap.Builder> methods = - ImmutableMap.builder(); - private final ImmutableMap.Builder staticMethods = - ImmutableMap.builder(); - private final String name; - - public Builder(String name) { - this.name = name; - } - - public Builder method( - String name, - List argumentsTypes, - BiFunction method) { - methods.put(name, new MethodValue(argumentsTypes, method)); - return this; - } - - public Builder staticMethod( - String name, - List argumentsTypes, - BiFunction method) { - staticMethods.put(name, new StaticMethodValue(argumentsTypes, method)); - return this; - } - - public ConcreteType build() { - return new ConcreteType(name, methods.build(), staticMethods.build()); - } - } - - public static ConcreteType fromNode(ClassNode classNode) { - val staticMethods = classNode.getMethods() - .stream() - .filter(method -> method.isStatic()) - .collect(toMap( - method -> method.getName(), - method -> { - List argumentTypes = method.getArguments() - .stream() - .map(arg -> arg.getType()) - .collect(Collectors.toList()); - return new StaticMethodValue(argumentTypes, (environment, arguments) -> { - return Executor.callMethod(environment, method, arguments); - }); - })); - return new ConcreteType( - classNode.getName(), - ImmutableMap.of(), - staticMethods); - } - - private String name; - private Map> methods; - private Map staticMethods; - - public ConcreteType( - String name, - Map> methods, - Map staticMethods) { - this.name = name; - this.methods = methods; - this.staticMethods = staticMethods; - } - - public String getName() { - return name; - } - - public static ConcreteType.Builder builder(TypeReference reference) { - return new Builder<>(reference.getName()); - } - - public static ConcreteType.Builder builder(String name) { - return new Builder<>(name); - } - - @SuppressWarnings("unchecked") - public InterpreterValue callMethod(InterpreterValue receiver, String methodName, List arguments) { - val method = findMethod(methods, methodName, arguments); - return method.apply((T)receiver, new Arguments(arguments)); - } - - public InterpreterValue callStaticMethod(Environment environment, String methodName, List arguments) { - val method = findMethod(staticMethods, methodName, arguments); - return method.apply(environment, new Arguments(arguments)); - } - - private static T findMethod(Map methods, String methodName, List arguments) { - if (!methods.containsKey(methodName)) { - throw new NoSuchMethod(methodName); - } - val method = methods.get(methodName); - if (method.getArgumentTypes().size() != arguments.size()) { - throw new WrongNumberOfArguments(method.getArgumentTypes().size(), arguments.size()); - } - - for (int index = 0; index < arguments.size(); index++) { - val formalArgumentType = method.getArgumentTypes().get(index); - val actualArgumentType = arguments.get(index).getType(); - if (!formalArgumentType.equals(actualArgumentType.getReference())) { - throw new UnexpectedValueType(formalArgumentType, actualArgumentType.getReference()); - } - } - return method; - } - - public TypeReference getReference() { - return typeRef(name); - } - - @Override - public String toString() { - return "ConcreteType<" + name + ">"; - } -} diff --git a/src/main/java/org/zwobble/couscous/values/IntegerValue.java b/src/main/java/org/zwobble/couscous/values/IntegerValue.java deleted file mode 100644 index c87bd27..0000000 --- a/src/main/java/org/zwobble/couscous/values/IntegerValue.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.zwobble.couscous.values; - -import static java.util.Arrays.asList; -import static org.zwobble.couscous.values.TypeReference.typeRef; - -import lombok.Value; -import lombok.val; - -@Value -public class IntegerValue implements InterpreterValue { - public static final TypeReference REF = typeRef("java.lang.Integer"); - - public static final ConcreteType TYPE = ConcreteType.builder(REF) - .staticMethod("parseInt", asList(StringValue.REF), - (environment, arguments) -> { - val value = (StringValue)arguments.get(0); - return new IntegerValue(Integer.parseInt(value.getValue())); - }) - - .build(); - - int value; - - @Override - public ConcreteType getType() { - return TYPE; - } -} diff --git a/src/main/java/org/zwobble/couscous/values/InterpreterValue.java b/src/main/java/org/zwobble/couscous/values/InterpreterValue.java deleted file mode 100644 index f1afa85..0000000 --- a/src/main/java/org/zwobble/couscous/values/InterpreterValue.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.zwobble.couscous.values; - -public interface InterpreterValue { - ConcreteType getType(); -} diff --git a/src/main/java/org/zwobble/couscous/values/InterpreterValues.java b/src/main/java/org/zwobble/couscous/values/InterpreterValues.java deleted file mode 100644 index 6b220d0..0000000 --- a/src/main/java/org/zwobble/couscous/values/InterpreterValues.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.zwobble.couscous.values; - -public class InterpreterValues { - public static final UnitValue UNIT = UnitValue.UNIT; - - public static InterpreterValue value(int value) { - return new IntegerValue(value); - } - - public static InterpreterValue value(String value) { - return new StringValue(value); - } -} diff --git a/src/main/java/org/zwobble/couscous/values/MethodValue.java b/src/main/java/org/zwobble/couscous/values/MethodValue.java deleted file mode 100644 index 495f608..0000000 --- a/src/main/java/org/zwobble/couscous/values/MethodValue.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.zwobble.couscous.values; - -import java.util.List; -import java.util.function.BiFunction; - -import org.zwobble.couscous.interpreter.Arguments; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Value; - -@Value -public class MethodValue implements Callable { - List argumentTypes; - @Getter(value=AccessLevel.NONE) - BiFunction apply; - - public InterpreterValue apply(T receiver, Arguments arguments) { - return apply.apply(receiver, arguments); - } -} diff --git a/src/main/java/org/zwobble/couscous/values/StaticMethodValue.java b/src/main/java/org/zwobble/couscous/values/StaticMethodValue.java deleted file mode 100644 index e291914..0000000 --- a/src/main/java/org/zwobble/couscous/values/StaticMethodValue.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.zwobble.couscous.values; - -import java.util.List; -import java.util.function.BiFunction; - -import org.zwobble.couscous.interpreter.Arguments; -import org.zwobble.couscous.interpreter.Environment; - -import lombok.AccessLevel; -import lombok.Getter; -import lombok.Value; - -@Value -public class StaticMethodValue implements Callable { - List argumentTypes; - @Getter(value=AccessLevel.NONE) - BiFunction apply; - - public InterpreterValue apply(Environment environment, Arguments arguments) { - return apply.apply(environment, arguments); - } - -} diff --git a/src/main/java/org/zwobble/couscous/values/StringValue.java b/src/main/java/org/zwobble/couscous/values/StringValue.java deleted file mode 100644 index 0e24ac6..0000000 --- a/src/main/java/org/zwobble/couscous/values/StringValue.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.zwobble.couscous.values; - -import static java.util.Arrays.asList; -import static org.zwobble.couscous.values.TypeReference.typeRef; - -import lombok.Value; -import lombok.val; - -@Value -public class StringValue implements InterpreterValue { - public static final TypeReference REF = typeRef("java.lang.String"); - - public static final ConcreteType TYPE = ConcreteType.builder(REF) - .method("length", asList(), - (receiver, arguments) -> new IntegerValue(receiver.value.length())) - - .method("substring", asList(IntegerValue.REF, IntegerValue.REF), - (receiver, arguments) -> { - val startIndex = (IntegerValue)arguments.get(0); - val endIndex = (IntegerValue)arguments.get(1); - return new StringValue(receiver.value.substring(startIndex.getValue(), endIndex.getValue())); - }) - - .build(); - - String value; - - @Override - public ConcreteType getType() { - return TYPE; - } -} diff --git a/src/main/java/org/zwobble/couscous/values/UnitValue.java b/src/main/java/org/zwobble/couscous/values/UnitValue.java deleted file mode 100644 index af00b32..0000000 --- a/src/main/java/org/zwobble/couscous/values/UnitValue.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.zwobble.couscous.values; - -import lombok.ToString; - -@ToString -public class UnitValue implements InterpreterValue { - private static final ConcreteType TYPE = ConcreteType.builder("Unit") - .build(); - - public static final UnitValue UNIT = new UnitValue(); - - private UnitValue() { - } - - @Override - public ConcreteType getType() { - return TYPE; - } -} diff --git a/src/test/java/org/zwobble/couscous/tests/BackendTests.java b/src/test/java/org/zwobble/couscous/tests/BackendTests.java index 86818af..216ede0 100644 --- a/src/test/java/org/zwobble/couscous/tests/BackendTests.java +++ b/src/test/java/org/zwobble/couscous/tests/BackendTests.java @@ -4,14 +4,14 @@ import org.junit.Test; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.ast.MethodNode; import org.zwobble.couscous.ast.ReturnNode; -import org.zwobble.couscous.values.InterpreterValue; -import org.zwobble.couscous.values.StringValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.StringValue; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.zwobble.couscous.ast.LiteralNode.literal; import static org.zwobble.couscous.ast.MethodNode.staticMethod; -import static org.zwobble.couscous.values.UnitValue.UNIT; +import static org.zwobble.couscous.interpreter.values.UnitValue.UNIT; import lombok.val; diff --git a/src/test/java/org/zwobble/couscous/tests/MethodRunner.java b/src/test/java/org/zwobble/couscous/tests/MethodRunner.java index 29c15fe..8fc4cf1 100644 --- a/src/test/java/org/zwobble/couscous/tests/MethodRunner.java +++ b/src/test/java/org/zwobble/couscous/tests/MethodRunner.java @@ -3,7 +3,7 @@ package org.zwobble.couscous.tests; import java.util.List; import org.zwobble.couscous.ast.ClassNode; -import org.zwobble.couscous.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; public interface MethodRunner { InterpreterValue runMethod(ClassNode classNode, String methodName, List arguments); diff --git a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerTests.java b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerTests.java index 7419aca..76893c8 100644 --- a/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerTests.java +++ b/src/test/java/org/zwobble/couscous/tests/backends/python/PythonCompilerTests.java @@ -8,18 +8,18 @@ import java.util.List; import org.zwobble.couscous.ast.ClassNode; import org.zwobble.couscous.backends.python.PythonCompiler; +import org.zwobble.couscous.interpreter.values.InterpreterValue; import org.zwobble.couscous.tests.BackendTests; import org.zwobble.couscous.tests.MethodRunner; -import org.zwobble.couscous.values.InterpreterValue; import com.google.common.base.Charsets; import com.google.common.io.CharStreams; import static java.lang.Integer.parseInt; import static java.util.Arrays.asList; +import static org.zwobble.couscous.interpreter.values.InterpreterValues.UNIT; +import static org.zwobble.couscous.interpreter.values.InterpreterValues.value; import static org.zwobble.couscous.tests.util.ExtraFiles.deleteRecursively; -import static org.zwobble.couscous.values.InterpreterValues.UNIT; -import static org.zwobble.couscous.values.InterpreterValues.value; import lombok.SneakyThrows; import lombok.val; diff --git a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java index 9575843..bdd2590 100644 --- a/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java +++ b/src/test/java/org/zwobble/couscous/tests/interpreter/EvaluatorTests.java @@ -13,9 +13,9 @@ import org.zwobble.couscous.interpreter.NoSuchMethod; import org.zwobble.couscous.interpreter.StackFrameBuilder; import org.zwobble.couscous.interpreter.UnexpectedValueType; import org.zwobble.couscous.interpreter.WrongNumberOfArguments; -import org.zwobble.couscous.values.ConcreteType; -import org.zwobble.couscous.values.IntegerValue; -import org.zwobble.couscous.values.StringValue; +import org.zwobble.couscous.interpreter.values.ConcreteType; +import org.zwobble.couscous.interpreter.values.IntegerValue; +import org.zwobble.couscous.interpreter.values.StringValue; import com.google.common.collect.ImmutableMap; diff --git a/src/test/java/org/zwobble/couscous/tests/interpreter/InterpreterTests.java b/src/test/java/org/zwobble/couscous/tests/interpreter/InterpreterTests.java index 98271f7..3f2bbcd 100644 --- a/src/test/java/org/zwobble/couscous/tests/interpreter/InterpreterTests.java +++ b/src/test/java/org/zwobble/couscous/tests/interpreter/InterpreterTests.java @@ -14,12 +14,12 @@ import org.zwobble.couscous.interpreter.UnboundVariable; import org.zwobble.couscous.interpreter.UnexpectedValueType; import org.zwobble.couscous.interpreter.VariableNotInScope; import org.zwobble.couscous.interpreter.WrongNumberOfArguments; +import org.zwobble.couscous.interpreter.values.ConcreteType; +import org.zwobble.couscous.interpreter.values.IntegerValue; +import org.zwobble.couscous.interpreter.values.InterpreterValue; +import org.zwobble.couscous.interpreter.values.StringValue; import org.zwobble.couscous.tests.BackendTests; import org.zwobble.couscous.tests.MethodRunner; -import org.zwobble.couscous.values.ConcreteType; -import org.zwobble.couscous.values.IntegerValue; -import org.zwobble.couscous.values.InterpreterValue; -import org.zwobble.couscous.values.StringValue; import com.google.common.collect.ImmutableMap; -- cgit v1.2.3