diff options
| author | Michael Williamson <mike@zwobble.org> | 2015-11-14 16:52:37 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2015-11-14 16:52:37 +0000 |
| commit | 5338a361c6fd8c42e8bd47a637c21c128b122418 (patch) | |
| tree | cb78e617f497af5cc2d66215ac285ecc002f37b1 /src/main/java/org/zwobble/couscous/interpreter/Executor.java | |
| parent | 4708229e8cfc4c8909c720395efb680c8775edea (diff) | |
Implement while loops in backends
Diffstat (limited to 'src/main/java/org/zwobble/couscous/interpreter/Executor.java')
| -rw-r--r-- | src/main/java/org/zwobble/couscous/interpreter/Executor.java | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/src/main/java/org/zwobble/couscous/interpreter/Executor.java b/src/main/java/org/zwobble/couscous/interpreter/Executor.java index 1d9a327..8909acc 100644 --- a/src/main/java/org/zwobble/couscous/interpreter/Executor.java +++ b/src/main/java/org/zwobble/couscous/interpreter/Executor.java @@ -23,7 +23,7 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> } return UnitInterpreterValue.UNIT; } - + private static Environment buildEnvironment(final Environment environment, final CallableNode method, Optional<InterpreterValue> thisValue, PositionalArguments arguments) { final org.zwobble.couscous.interpreter.StackFrameBuilder stackFrame = new StackFrameBuilder(); for (int index = 0; index < method.getArguments().size(); index++) { @@ -32,19 +32,19 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> findDeclarations(method.getBody()).forEach(declaration -> stackFrame.declare(declaration)); return environment.withStackFrame(thisValue, stackFrame.build()); } - + private static Stream<VariableNode> findDeclarations(List<StatementNode> body) { return body.stream().flatMap(statement -> statement.accept(new StatementNodeMapper<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); @@ -63,27 +63,27 @@ public class Executor implements StatementNodeMapper<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(); } - + @Override public Optional<InterpreterValue> visit(LocalVariableDeclarationNode localVariableDeclaration) { final org.zwobble.couscous.interpreter.values.InterpreterValue value = eval(environment, localVariableDeclaration.getInitialValue()); @@ -93,8 +93,7 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> @Override public Optional<InterpreterValue> visit(IfStatementNode ifStatement) { - BooleanInterpreterValue condition = (BooleanInterpreterValue) eval(environment, ifStatement.getCondition()); - List<StatementNode> body = condition.getValue() + List<StatementNode> body = evalCondition(ifStatement.getCondition()) ? ifStatement.getTrueBranch() : ifStatement.getFalseBranch(); return exec(body); @@ -102,7 +101,18 @@ public class Executor implements StatementNodeMapper<Optional<InterpreterValue>> @Override public Optional<InterpreterValue> visit(WhileNode whileLoop) { - throw new UnsupportedOperationException(); + while (evalCondition(whileLoop.getCondition())) { + Optional<InterpreterValue> result = exec(whileLoop.getBody()); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } + + private boolean evalCondition(ExpressionNode conditionExpression) { + BooleanInterpreterValue condition = (BooleanInterpreterValue) eval(environment, conditionExpression); + return condition.getValue(); } private Optional<InterpreterValue> exec(List<StatementNode> statements) { |
