diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-01 21:49:18 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-01 21:49:18 +0100 |
| commit | 30d2215800deafbdcfb134f1356777ec0139bb7a (patch) | |
| tree | e687fa289e269bd91ab19b027d6d8a96b9c96b4d /src/main/java/org/zwobble/couscous/interpreter | |
| parent | 8187130b8a8aabbcf983e530413d6969141d6da2 (diff) | |
Use normal method call exec in interpreter entry point
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter')
3 files changed, 53 insertions, 64 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Environment.java b/src/main/java/org/zwobble/couscous/interpreter/Environment.java index ea4a5e4..76aa56b 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Environment.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Environment.java @@ -3,14 +3,16 @@ package org.zwobble.couscous.interpreter; import java.util.HashMap; import java.util.Map; +import org.zwobble.couscous.Project; import org.zwobble.couscous.values.ConcreteType; -import org.zwobble.couscous.values.IntegerValue; import org.zwobble.couscous.values.InterpreterValue; public class Environment { - private Map<Integer, InterpreterValue> stackFrame; + private final Map<Integer, InterpreterValue> stackFrame; + private final Project project; - public Environment(Map<Integer, InterpreterValue> stackFrame) { + public Environment(Project project, Map<Integer, InterpreterValue> stackFrame) { + this.project = project; this.stackFrame = new HashMap<>(stackFrame); } @@ -23,10 +25,7 @@ public class Environment { } public ConcreteType<?> findClass(String className) { - if (className == "java.lang.Integer") { - return IntegerValue.TYPE; - } else { - throw new UnsupportedOperationException(); - } + // TODO: handle missing classes + return project.findClass(className); } } diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java new file mode 100644 index 0000000..633bf6b --- /dev/null +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -0,0 +1,34 @@ +package org.zwobble.couscous.interpreter; + +import java.util.Optional; + +import org.zwobble.couscous.ast.ExpressionStatementNode; +import org.zwobble.couscous.ast.ReturnNode; +import org.zwobble.couscous.ast.StatementNode; +import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; +import org.zwobble.couscous.values.InterpreterValue; + +import static org.zwobble.couscous.interpreter.Evaluator.eval; + +public class Executor implements StatementNodeVisitor<Optional<InterpreterValue>> { + public static Optional<InterpreterValue> exec(Environment environment, StatementNode statement) { + return statement.accept(new Executor(environment)); + } + + private final Environment environment; + + private Executor(Environment environment) { + this.environment = environment; + } + + @Override + public Optional<InterpreterValue> visit(ReturnNode returnNode) { + return Optional.of(eval(environment, returnNode.getValue())); + } + + @Override + public Optional<InterpreterValue> visit(ExpressionStatementNode expressionStatement) { + eval(environment, expressionStatement.getExpression()); + return Optional.empty(); + } +} diff --git a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java index bc82fee..884a082 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Interpreter.java @@ -1,20 +1,17 @@ package org.zwobble.couscous.interpreter; import java.util.List; -import java.util.Optional; -import java.util.stream.IntStream; +import java.util.stream.Collectors; import org.zwobble.couscous.Project; -import org.zwobble.couscous.ast.ExpressionStatementNode; -import org.zwobble.couscous.ast.MethodNode; -import org.zwobble.couscous.ast.ReturnNode; -import org.zwobble.couscous.ast.visitors.StatementNodeVisitor; +import org.zwobble.couscous.ast.ExpressionNode; +import org.zwobble.couscous.ast.LiteralNode; import org.zwobble.couscous.values.InterpreterValue; -import static com.google.common.collect.Iterables.find; -import static java.util.stream.Collectors.toMap; +import com.google.common.collect.ImmutableMap; + +import static org.zwobble.couscous.ast.StaticMethodCallNode.staticMethodCall; import static org.zwobble.couscous.interpreter.Evaluator.eval; -import static org.zwobble.couscous.values.UnitValue.UNIT; import lombok.val; @@ -26,52 +23,11 @@ public class Interpreter { } public InterpreterValue run(String className, String methodName, List<InterpreterValue> arguments) { - val clazz = project.findClass(className); - val method = find(clazz.getMethods(), - method -> method.getName().equals(methodName)); - val environment = buildEnvironment(method, arguments); - - for (val statement : method.getBody()) { - val result = statement.accept(new Executor(environment)); - if (result.isPresent()) { - return result.get(); - } - } - return UNIT; - } - - private Environment buildEnvironment( - final MethodNode method, - List<InterpreterValue> arguments) { - - if (method.getArguments().size() != arguments.size()) { - throw new WrongNumberOfArguments(method.getArguments().size(), arguments.size()); - } - - val stackFrame = IntStream.range(0, method.getArguments().size()) - .boxed() - .collect(toMap( - index -> method.getArguments().get(index).getId(), - index -> arguments.get(index))); - return new Environment(stackFrame); - } - - private class Executor implements StatementNodeVisitor<Optional<InterpreterValue>> { - private Environment environment; - - public Executor(Environment environment) { - this.environment = environment; - } - - @Override - public Optional<InterpreterValue> visit(ReturnNode returnNode) { - return Optional.of(eval(environment, returnNode.getValue())); - } - - @Override - public Optional<InterpreterValue> visit(ExpressionStatementNode expressionStatement) { - eval(environment, expressionStatement.getExpression()); - return Optional.empty(); - } + val argumentExpressions = arguments + .stream() + .<ExpressionNode>map(LiteralNode::literal) + .collect(Collectors.toList()); + return eval(new Environment(project, ImmutableMap.of()), + staticMethodCall(className, methodName, argumentExpressions)); } } |
