diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-10-04 17:26:27 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-10-04 17:26:27 +0100 |
| commit | 87f73abf5e7dcec6a9f5ebd213f4a9eb0a5d45db (patch) | |
| tree | 9bec5d45a55f728d5d32c4c8c26c165f88bf2dee /src/main/java/org/zwobble/couscous/interpreter/Executor.java | |
| parent | 47fad1a4e01422c16c900d38938c210456337dca (diff) | |
Error if trying to assign to variable not in scope
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter/Executor.java')
| -rw-r--r-- | src/main/java/org/zwobble/couscous/interpreter/Executor.java | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index 49eca3f..95eddad 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -1,18 +1,19 @@ package org.zwobble.couscous.interpreter; +import java.util.List; import java.util.Optional; -import java.util.stream.IntStream; +import java.util.stream.Stream; import org.zwobble.couscous.ast.ExpressionStatementNode; import org.zwobble.couscous.ast.LocalVariableDeclarationNode; import org.zwobble.couscous.ast.MethodNode; 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 static java.util.stream.Collectors.toMap; import static org.zwobble.couscous.interpreter.Evaluator.eval; import lombok.val; @@ -35,14 +36,37 @@ public class Executor implements StatementNodeVisitor<Optional<InterpreterValue> final MethodNode method, Arguments arguments) { - val stackFrame = IntStream.range(0, method.getArguments().size()) - .boxed() - .collect(toMap( - index -> method.getArguments().get(index).getId(), - index -> arguments.get(index))); - return environment.withStackFrame(stackFrame); + val stackFrame = new StackFrameBuilder(); + for (int index = 0; index < method.getArguments().size(); index++) { + stackFrame.declare(method.getArguments().get(index), arguments.get(index)); + } + + findDeclarations(method.getBody()).forEach(declaration -> + stackFrame.declare(declaration)); + + return environment.withStackFrame(stackFrame.build()); } + private static Stream<VariableNode> findDeclarations(List<StatementNode> body) { + return body.stream() + .flatMap(statement -> statement.accept(new StatementNodeVisitor<Stream<VariableNode>>() { + @Override + public Stream<VariableNode> visit(ReturnNode returnNode) { + return Stream.empty(); + } + + @Override + public Stream<VariableNode> visit(ExpressionStatementNode expressionStatement) { + return Stream.empty(); + } + + @Override + public Stream<VariableNode> visit(LocalVariableDeclarationNode localVariableDeclaration) { + return Stream.of(localVariableDeclaration); + } + })); + } + public static Optional<InterpreterValue> exec(Environment environment, StatementNode statement) { return statement.accept(new Executor(environment)); } |
