From 5338a361c6fd8c42e8bd47a637c21c128b122418 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 14 Nov 2015 16:52:37 +0000 Subject: Implement while loops in backends --- .../org/zwobble/couscous/interpreter/Executor.java | 34 ++++++++++++++-------- 1 file changed, 22 insertions(+), 12 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 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> } return UnitInterpreterValue.UNIT; } - + private static Environment buildEnvironment(final Environment environment, final CallableNode method, Optional 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> findDeclarations(method.getBody()).forEach(declaration -> stackFrame.declare(declaration)); return environment.withStackFrame(thisValue, stackFrame.build()); } - + private static Stream findDeclarations(List body) { return body.stream().flatMap(statement -> statement.accept(new StatementNodeMapper>(){ @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); @@ -63,27 +63,27 @@ public class Executor implements StatementNodeMapper> } })); } - + public static Optional 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 visit(ReturnNode returnNode) { return Optional.of(eval(environment, returnNode.getValue())); } - + @Override public Optional visit(ExpressionStatementNode expressionStatement) { eval(environment, expressionStatement.getExpression()); return Optional.empty(); } - + @Override public Optional visit(LocalVariableDeclarationNode localVariableDeclaration) { final org.zwobble.couscous.interpreter.values.InterpreterValue value = eval(environment, localVariableDeclaration.getInitialValue()); @@ -93,8 +93,7 @@ public class Executor implements StatementNodeMapper> @Override public Optional visit(IfStatementNode ifStatement) { - BooleanInterpreterValue condition = (BooleanInterpreterValue) eval(environment, ifStatement.getCondition()); - List body = condition.getValue() + List body = evalCondition(ifStatement.getCondition()) ? ifStatement.getTrueBranch() : ifStatement.getFalseBranch(); return exec(body); @@ -102,7 +101,18 @@ public class Executor implements StatementNodeMapper> @Override public Optional visit(WhileNode whileLoop) { - throw new UnsupportedOperationException(); + while (evalCondition(whileLoop.getCondition())) { + Optional 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 exec(List statements) { -- cgit v1.2.3