diff --git a/program.txt b/program.txt index e8f8227..09f8479 100644 --- a/program.txt +++ b/program.txt @@ -13,10 +13,18 @@ if (40 < 50 || 50 > 60) { print "true1\n" print "true2\n" i = 0 + print "do while" + do { + print "i = " + i + "\n" + i = i + 1 + } while (i < 10) + i = 0 + print "while" while (i < 10) { print "i = " + i + "\n" i = i + 1 } + print "for" for i = 0, i < 10, i = i + 1 { print "i = " + i + "\n" } diff --git a/src/com/annimon/ownlang/parser/Lexer.java b/src/com/annimon/ownlang/parser/Lexer.java index e10dd30..849f245 100644 --- a/src/com/annimon/ownlang/parser/Lexer.java +++ b/src/com/annimon/ownlang/parser/Lexer.java @@ -150,6 +150,9 @@ public final class Lexer { case "else": addToken(TokenType.ELSE); break; case "while": addToken(TokenType.WHILE); break; case "for": addToken(TokenType.FOR); break; + case "do": addToken(TokenType.DO); break; + case "break": addToken(TokenType.BREAK); break; + case "continue": addToken(TokenType.CONTINUE); break; default: addToken(TokenType.WORD, word); break; diff --git a/src/com/annimon/ownlang/parser/Parser.java b/src/com/annimon/ownlang/parser/Parser.java index bb48bb0..d78e502 100644 --- a/src/com/annimon/ownlang/parser/Parser.java +++ b/src/com/annimon/ownlang/parser/Parser.java @@ -1,19 +1,6 @@ package com.annimon.ownlang.parser; -import com.annimon.ownlang.parser.ast.PrintStatement; -import com.annimon.ownlang.parser.ast.AssignmentStatement; -import com.annimon.ownlang.parser.ast.BinaryExpression; -import com.annimon.ownlang.parser.ast.BlockStatement; -import com.annimon.ownlang.parser.ast.ConditionalExpression; -import com.annimon.ownlang.parser.ast.VariableExpression; -import com.annimon.ownlang.parser.ast.Expression; -import com.annimon.ownlang.parser.ast.ForStatement; -import com.annimon.ownlang.parser.ast.IfStatement; -import com.annimon.ownlang.parser.ast.ValueExpression; -import com.annimon.ownlang.parser.ast.Statement; -import com.annimon.ownlang.parser.ast.UnaryExpression; -import com.annimon.ownlang.parser.ast.WhileStatement; -import java.util.ArrayList; +import com.annimon.ownlang.parser.ast.*; import java.util.List; /** @@ -66,6 +53,15 @@ public final class Parser { if (match(TokenType.WHILE)) { return whileStatement(); } + if (match(TokenType.DO)) { + return doWhileStatement(); + } + if (match(TokenType.BREAK)) { + return new BreakStatement(); + } + if (match(TokenType.CONTINUE)) { + return new ContinueStatement(); + } if (match(TokenType.FOR)) { return forStatement(); } @@ -101,6 +97,13 @@ public final class Parser { return new WhileStatement(condition, statement); } + private Statement doWhileStatement() { + final Statement statement = statementOrBlock(); + consume(TokenType.WHILE); + final Expression condition = expression(); + return new DoWhileStatement(condition, statement); + } + private Statement forStatement() { final Statement initialization = assignmentStatement(); consume(TokenType.COMMA); diff --git a/src/com/annimon/ownlang/parser/TokenType.java b/src/com/annimon/ownlang/parser/TokenType.java index 524d1e4..4cfa1d1 100644 --- a/src/com/annimon/ownlang/parser/TokenType.java +++ b/src/com/annimon/ownlang/parser/TokenType.java @@ -17,6 +17,9 @@ public enum TokenType { ELSE, WHILE, FOR, + DO, + BREAK, + CONTINUE, PLUS, MINUS, diff --git a/src/com/annimon/ownlang/parser/ast/BreakStatement.java b/src/com/annimon/ownlang/parser/ast/BreakStatement.java new file mode 100644 index 0000000..6bd79e9 --- /dev/null +++ b/src/com/annimon/ownlang/parser/ast/BreakStatement.java @@ -0,0 +1,18 @@ +package com.annimon.ownlang.parser.ast; + +/** + * + * @author aNNiMON + */ +public final class BreakStatement extends RuntimeException implements Statement { + + @Override + public void execute() { + throw this; + } + + @Override + public String toString() { + return "break"; + } +} diff --git a/src/com/annimon/ownlang/parser/ast/ContinueStatement.java b/src/com/annimon/ownlang/parser/ast/ContinueStatement.java new file mode 100644 index 0000000..9a8c459 --- /dev/null +++ b/src/com/annimon/ownlang/parser/ast/ContinueStatement.java @@ -0,0 +1,18 @@ +package com.annimon.ownlang.parser.ast; + +/** + * + * @author aNNiMON + */ +public final class ContinueStatement extends RuntimeException implements Statement { + + @Override + public void execute() { + throw this; + } + + @Override + public String toString() { + return "continue"; + } +} diff --git a/src/com/annimon/ownlang/parser/ast/DoWhileStatement.java b/src/com/annimon/ownlang/parser/ast/DoWhileStatement.java new file mode 100644 index 0000000..fdbfe0b --- /dev/null +++ b/src/com/annimon/ownlang/parser/ast/DoWhileStatement.java @@ -0,0 +1,35 @@ +package com.annimon.ownlang.parser.ast; + +/** + * + * @author aNNiMON + */ +public final class DoWhileStatement implements Statement { + + private final Expression condition; + private final Statement statement; + + public DoWhileStatement(Expression condition, Statement statement) { + this.condition = condition; + this.statement = statement; + } + + @Override + public void execute() { + do { + try { + statement.execute(); + } catch (BreakStatement bs) { + break; + } catch (ContinueStatement cs) { + // continue; + } + } + while (condition.eval().asNumber() != 0); + } + + @Override + public String toString() { + return "do " + statement + " while " + condition; + } +} diff --git a/src/com/annimon/ownlang/parser/ast/ForStatement.java b/src/com/annimon/ownlang/parser/ast/ForStatement.java index b096dd8..fce6d2c 100644 --- a/src/com/annimon/ownlang/parser/ast/ForStatement.java +++ b/src/com/annimon/ownlang/parser/ast/ForStatement.java @@ -21,7 +21,13 @@ public final class ForStatement implements Statement { @Override public void execute() { for (initialization.execute(); termination.eval().asNumber() != 0; increment.execute()) { - statement.execute(); + try { + statement.execute(); + } catch (BreakStatement bs) { + break; + } catch (ContinueStatement cs) { + // continue; + } } } diff --git a/src/com/annimon/ownlang/parser/ast/WhileStatement.java b/src/com/annimon/ownlang/parser/ast/WhileStatement.java index 18c81c3..cab4dde 100644 --- a/src/com/annimon/ownlang/parser/ast/WhileStatement.java +++ b/src/com/annimon/ownlang/parser/ast/WhileStatement.java @@ -17,7 +17,13 @@ public final class WhileStatement implements Statement { @Override public void execute() { while (condition.eval().asNumber() != 0) { - statement.execute(); + try { + statement.execute(); + } catch (BreakStatement bs) { + break; + } catch (ContinueStatement cs) { + // continue; + } } }