[jlox] Add while statement
This commit is contained in:
@@ -79,6 +79,14 @@ public class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitWhileStmt(Stmt.While stmt) {
|
||||||
|
while (isTruthy(evaluate(stmt.condition()))) {
|
||||||
|
execute(stmt.body());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitAssignExpr(Expr.Assign expr) {
|
public Object visitAssignExpr(Expr.Assign expr) {
|
||||||
var value = evaluate(expr.value());
|
var value = evaluate(expr.value());
|
||||||
|
|||||||
@@ -17,10 +17,13 @@ import static xyz.ctsk.lox.TokenType.*;
|
|||||||
* statement → exprStmt
|
* statement → exprStmt
|
||||||
* | ifStmt
|
* | ifStmt
|
||||||
* | printStmt
|
* | printStmt
|
||||||
|
* | whileStmt
|
||||||
* | block ;
|
* | block ;
|
||||||
* block → "{" declaration* "}" ;
|
* block → "{" declaration* "}" ;
|
||||||
* exprStmt → expression ";" ;
|
* ifStmt → "if" "(" expression ")" statement ( "else" statement )? ;
|
||||||
|
* whileStmt → "while" "(" expression ")" statement ;
|
||||||
* printStmt → "print" expression ";" ;
|
* printStmt → "print" expression ";" ;
|
||||||
|
* exprStmt → expression ";" ;
|
||||||
* expression → equality ;
|
* expression → equality ;
|
||||||
* expression → assignment ;
|
* expression → assignment ;
|
||||||
* assignment → IDENTIFIER "=" assignment
|
* assignment → IDENTIFIER "=" assignment
|
||||||
@@ -81,10 +84,12 @@ public class Parser {
|
|||||||
private Stmt statement() {
|
private Stmt statement() {
|
||||||
if (match(IF)) return ifStatement();
|
if (match(IF)) return ifStatement();
|
||||||
if (match(PRINT)) return printStatement();
|
if (match(PRINT)) return printStatement();
|
||||||
|
if (match(WHILE)) return whileStatement();
|
||||||
if (match(LEFT_BRACE)) return new Stmt.Block(blockStatement());
|
if (match(LEFT_BRACE)) return new Stmt.Block(blockStatement());
|
||||||
return expressionStatement();
|
return expressionStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Stmt ifStatement() {
|
private Stmt ifStatement() {
|
||||||
consume(LEFT_PAREN, "Expect '(' after 'if'.");
|
consume(LEFT_PAREN, "Expect '(' after 'if'.");
|
||||||
Expr condition = expression();
|
Expr condition = expression();
|
||||||
@@ -102,6 +107,15 @@ public class Parser {
|
|||||||
return new Stmt.Print(value);
|
return new Stmt.Print(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stmt whileStatement() {
|
||||||
|
consume(LEFT_PAREN, "Expect '(' after 'while'.");
|
||||||
|
Expr condition = expression();
|
||||||
|
consume(RIGHT_PAREN, "Expect ')' after condition.");
|
||||||
|
|
||||||
|
Stmt body = statement();
|
||||||
|
|
||||||
|
return new Stmt.While(condition, body);
|
||||||
|
}
|
||||||
private List<Stmt> blockStatement() {
|
private List<Stmt> blockStatement() {
|
||||||
var statements = new ArrayList<Stmt>();
|
var statements = new ArrayList<Stmt>();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
@Rule(head = "Expression", body = {"Expr expression"}),
|
@Rule(head = "Expression", body = {"Expr expression"}),
|
||||||
@Rule(head = "If", body = {"Expr condition", "Stmt thenBranch", "Stmt elseBranch"}),
|
@Rule(head = "If", body = {"Expr condition", "Stmt thenBranch", "Stmt elseBranch"}),
|
||||||
@Rule(head = "Print", body = {"Expr expression"}),
|
@Rule(head = "Print", body = {"Expr expression"}),
|
||||||
@Rule(head = "Var", body = {"Token name", "Expr initializer"})
|
@Rule(head = "Var", body = {"Token name", "Expr initializer"}),
|
||||||
|
@Rule(head = "While", body = {"Expr condition", "Stmt body"})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
package xyz.ctsk.lox;
|
package xyz.ctsk.lox;
|
||||||
|
|||||||
Reference in New Issue
Block a user