diff options
Diffstat (limited to 'src/com/craftinginterpreters/lox/Parser.java')
-rw-r--r-- | src/com/craftinginterpreters/lox/Parser.java | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/com/craftinginterpreters/lox/Parser.java b/src/com/craftinginterpreters/lox/Parser.java index a85d70f..7d7b27a 100644 --- a/src/com/craftinginterpreters/lox/Parser.java +++ b/src/com/craftinginterpreters/lox/Parser.java @@ -4,6 +4,7 @@ import static com.craftinginterpreters.lox.TokenType.*; import java.util.ArrayList; import java.util.List; +import java.util.Arrays; class Parser { private static class ParseError extends RuntimeException { @@ -43,6 +44,8 @@ class Parser { } private Stmt statement() { + if (match(FOR)) + return forStatement(); if (match(IF)) return ifStatement(); if (match(PRINT)) @@ -55,6 +58,48 @@ class Parser { return expressionStatement(); } + private Stmt forStatement() { + consume(LEFT_PAREN, "Expect '(' after 'for'."); + + Stmt initializer; + if (match(SEMICOLON)) { + initializer = null; + } else if (match(VAR)) { + initializer = varDeclaration(); + } else { + initializer = expressionStatement(); + } + + Expr condition = null; + if (!check(SEMICOLON)) { + condition = expression(); + } + consume(SEMICOLON, "Expect ';' after loop condition."); + + Expr increment = null; + if (!check(RIGHT_PAREN)) { + increment = expression(); + } + consume(RIGHT_PAREN, "Expect ')' after for clauses."); + Stmt body = statement(); + + if (increment != null) { + body = new Stmt.Block( + Arrays.asList( + body, + new Stmt.Expression(increment))); + } + + if (condition == null) condition = new Expr.Literal(true); + body = new Stmt.While(condition, body); + + if (initializer != null) { + body = new Stmt.Block(Arrays.asList(initializer, body)); + } + + return body; + } + private Stmt ifStatement() { consume(LEFT_PAREN, "Expect '(' after 'if'."); Expr condition = expression(); |