From 87f73abf5e7dcec6a9f5ebd213f4a9eb0a5d45db Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 4 Oct 2015 17:26:27 +0100 Subject: Error if trying to assign to variable not in scope --- .../org/zwobble/couscous/interpreter/Executor.java | 40 +++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'src/main/java/org/zwobble/couscous/interpreter/Executor.java') 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 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 findDeclarations(List body) { + return body.stream() + .flatMap(statement -> statement.accept(new StatementNodeVisitor>() { + @Override + public Stream visit(ReturnNode returnNode) { + return Stream.empty(); + } + + @Override + public Stream visit(ExpressionStatementNode expressionStatement) { + return Stream.empty(); + } + + @Override + public Stream visit(LocalVariableDeclarationNode localVariableDeclaration) { + return Stream.of(localVariableDeclaration); + } + })); + } + public static Optional exec(Environment environment, StatementNode statement) { return statement.accept(new Executor(environment)); } -- cgit v1.2.3