Add for statement
This commit is contained in:
parent
2a72de9f81
commit
613c2388be
2 changed files with 57 additions and 0 deletions
|
@ -52,6 +52,18 @@ class AstPrinter implements Expr.Visitor<String>, Stmt.Visitor<String> {
|
||||||
return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer);
|
return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visitWhileStmt(Stmt.While statement) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.append('(');
|
||||||
|
builder.append(parenthesize("while", statement.condition));
|
||||||
|
builder.append(parenthesize("do", statement.body));
|
||||||
|
builder.append(')');
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String visitPrintStmt(Stmt.Print statement) {
|
public String visitPrintStmt(Stmt.Print statement) {
|
||||||
return parenthesize("print", statement.expression);
|
return parenthesize("print", statement.expression);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import static com.craftinginterpreters.lox.TokenType.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
private static class ParseError extends RuntimeException {
|
private static class ParseError extends RuntimeException {
|
||||||
|
@ -43,6 +44,8 @@ class Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stmt statement() {
|
private Stmt statement() {
|
||||||
|
if (match(FOR))
|
||||||
|
return forStatement();
|
||||||
if (match(IF))
|
if (match(IF))
|
||||||
return ifStatement();
|
return ifStatement();
|
||||||
if (match(PRINT))
|
if (match(PRINT))
|
||||||
|
@ -55,6 +58,48 @@ class Parser {
|
||||||
return expressionStatement();
|
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() {
|
private Stmt ifStatement() {
|
||||||
consume(LEFT_PAREN, "Expect '(' after 'if'.");
|
consume(LEFT_PAREN, "Expect '(' after 'if'.");
|
||||||
Expr condition = expression();
|
Expr condition = expression();
|
||||||
|
|
Loading…
Reference in a new issue