From a4c1076008e1e7be767d7a8cbf9e5287b73d6c92 Mon Sep 17 00:00:00 2001 From: ctsk <9384305+ctsk@users.noreply.github.com> Date: Sat, 10 Sep 2022 11:21:25 +0200 Subject: [PATCH] [jlox] Add while statement --- .../src/main/java/xyz/ctsk/lox/Interpreter.java | 8 ++++++++ jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java | 16 +++++++++++++++- .../src/main/java/xyz/ctsk/lox/package-info.java | 3 ++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/jlox/lox/src/main/java/xyz/ctsk/lox/Interpreter.java b/jlox/lox/src/main/java/xyz/ctsk/lox/Interpreter.java index b08512f..177acd8 100644 --- a/jlox/lox/src/main/java/xyz/ctsk/lox/Interpreter.java +++ b/jlox/lox/src/main/java/xyz/ctsk/lox/Interpreter.java @@ -79,6 +79,14 @@ public class Interpreter implements Expr.Visitor, Stmt.Visitor { return null; } + @Override + public Void visitWhileStmt(Stmt.While stmt) { + while (isTruthy(evaluate(stmt.condition()))) { + execute(stmt.body()); + } + return null; + } + @Override public Object visitAssignExpr(Expr.Assign expr) { var value = evaluate(expr.value()); diff --git a/jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java b/jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java index d2e3323..7e40615 100644 --- a/jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java +++ b/jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java @@ -17,10 +17,13 @@ import static xyz.ctsk.lox.TokenType.*; * statement → exprStmt * | ifStmt * | printStmt + * | whileStmt * | block ; * block → "{" declaration* "}" ; - * exprStmt → expression ";" ; + * ifStmt → "if" "(" expression ")" statement ( "else" statement )? ; + * whileStmt → "while" "(" expression ")" statement ; * printStmt → "print" expression ";" ; + * exprStmt → expression ";" ; * expression → equality ; * expression → assignment ; * assignment → IDENTIFIER "=" assignment @@ -81,10 +84,12 @@ public class Parser { private Stmt statement() { if (match(IF)) return ifStatement(); if (match(PRINT)) return printStatement(); + if (match(WHILE)) return whileStatement(); if (match(LEFT_BRACE)) return new Stmt.Block(blockStatement()); return expressionStatement(); } + private Stmt ifStatement() { consume(LEFT_PAREN, "Expect '(' after 'if'."); Expr condition = expression(); @@ -102,6 +107,15 @@ public class Parser { 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 blockStatement() { var statements = new ArrayList(); diff --git a/jlox/lox/src/main/java/xyz/ctsk/lox/package-info.java b/jlox/lox/src/main/java/xyz/ctsk/lox/package-info.java index 153f3be..7f75faf 100644 --- a/jlox/lox/src/main/java/xyz/ctsk/lox/package-info.java +++ b/jlox/lox/src/main/java/xyz/ctsk/lox/package-info.java @@ -15,7 +15,8 @@ @Rule(head = "Expression", body = {"Expr expression"}), @Rule(head = "If", body = {"Expr condition", "Stmt thenBranch", "Stmt elseBranch"}), @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;