Jelajahi Sumber

Parsing variables -- While statements

runningwater 2 tahun lalu
induk
melakukan
746a2b3646

+ 8 - 1
README.md

@@ -110,4 +110,11 @@
               | logic_or ;
               logic_or       → logic_and ( "or" logic_and )* ;
               logic_and      → equality ( "and" equality )* ;
-            ```
+            ```
+            statement      → exprStmt
+            | ifStmt
+            | printStmt
+            | whileStmt
+            | block ;
+
+            whileStmt      → "while" "(" expression ")" statement ;

+ 2 - 10
src/main/java/com/craftinginterpreters/lox/AstPrinter.java

@@ -2,22 +2,14 @@
  * All right reserved.*/
 package com.craftinginterpreters.lox;
 
-import java.util.List;
-
 /**
  * @author simon
  * @date 2023-06-05 13:19
  * @desc
  */
 public class AstPrinter implements Expr.Visitor<String> {
-  String print(List<Stmt> statements) {
-    StringBuilder builder = new StringBuilder();
-    for (Stmt statement : statements) {
-      builder.append("\n    ");
-      builder.append(statement.accept(this));
-      builder.append("\n");
-    }
-    return builder.toString();
+  String print(Expr expr) {
+    return expr.accept(this);
   }
 
   @Override

+ 8 - 0
src/main/java/com/craftinginterpreters/lox/Interpreter.java

@@ -165,6 +165,14 @@ public class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
     return null;
   }
 
+  @Override
+  public Void visitWhileStmt(Stmt.While stmt) {
+    while (isTruthy(evaluate(stmt.condition))) {
+      execute(stmt.body);
+    }
+    return null;
+  }
+
   private void execute(Stmt stmt) {
     stmt.accept(this);
   }

+ 1 - 1
src/main/java/com/craftinginterpreters/lox/Lox.java

@@ -76,7 +76,7 @@ public class Lox {
     // Stop if there was a syntax error.
     if (hadError) return;
 
-    System.out.println("  ...AST: " + new AstPrinter().print(statements));
+    // System.out.println("  ...AST: " + new AstPrinter().print(statements));
     interpreter.interpret(statements);
   }
 

+ 12 - 1
src/main/java/com/craftinginterpreters/lox/Parser.java

@@ -53,14 +53,25 @@ public class Parser {
     }
   }
 
-  // statement  → exprStmt | ifStmt | printStmt | block;
+  // statement  → exprStmt | ifStmt | printStmt | whileStmt | block;
   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(block());
     return expressionStatement();
   }
 
+  // whileStmt      → "while" "(" expression ")" statement ;
+  private Stmt whileStatement() {
+    consume(LEFT_PARAM, "Expect '(' after 'while'.");
+    Expr condition = expression();
+    consume(RIGHT_PARAM, "Expect ')' after 'while'.");
+    Stmt body = statement();
+
+    return new Stmt.While(condition, body);
+  }
+
   //  ifStmt  → "if" "(" expression ")" statement ( "else" statement)? ;
   private Stmt ifStatement() {
     consume(LEFT_PARAM, "Expect '(' after if.");

+ 18 - 1
src/main/java/com/craftinginterpreters/lox/Stmt.java

@@ -4,7 +4,7 @@ import java.util.List;
 
 /**
  * @author GenerateAst
- * @date 2023-06-14 09:35
+ * @date 2023-06-14 13:37
  */
 abstract class Stmt {
     interface Visitor<R> {
@@ -18,6 +18,8 @@ abstract class Stmt {
 
         R visitVarStmt(Var stmt);
 
+        R visitWhileStmt(While stmt);
+
     }
 
 
@@ -92,5 +94,20 @@ abstract class Stmt {
         final  Expr initializer;
     }
 
+    static class While extends Stmt {
+        While(Expr condition, Stmt body) {
+            this.condition = condition;
+            this.body = body;
+        }
+
+        @Override
+        <R> R accept(Visitor<R> visitor) {
+            return visitor.visitWhileStmt(this);
+        }
+
+        final Expr condition;
+        final  Stmt body;
+    }
+
     abstract <R> R accept(Visitor<R> visitor);
 }

+ 16 - 15
src/main/java/com/craftinginterpreters/tool/GenerateAst.java

@@ -42,22 +42,23 @@ public class GenerateAst {
             System.exit(64);
         }
         String outputDir = args[0];
-        defineAst(outputDir, "Expr", Arrays.asList(
-                "Assign   : Token name, Expr value",
-                "Binary   : Expr left, Token operator, Expr right",
-                "Grouping : Expr expression",
-                "Literal  : Object value",
-                "Logical  : Expr left, Token operator, Expr right",
-                "Unary    : Token operator, Expr right",
-                "Variable : Token name"
-        ));
-//        defineAst(outputDir, "Stmt", Arrays.asList(
-//                "Block       : List<Stmt> statements",
-//                "Expression  : Expr expression",
-//                "If          : Expr condition, Stmt thenBranch, Stmt elseBranch",
-//                "Print       : Expr expression",
-//                "Var         : Token name, Expr initializer"
+//        defineAst(outputDir, "Expr", Arrays.asList(
+//                "Assign   : Token name, Expr value",
+//                "Binary   : Expr left, Token operator, Expr right",
+//                "Grouping : Expr expression",
+//                "Literal  : Object value",
+//                "Logical  : Expr left, Token operator, Expr right",
+//                "Unary    : Token operator, Expr right",
+//                "Variable : Token name"
 //        ));
+        defineAst(outputDir, "Stmt", Arrays.asList(
+                "Block       : List<Stmt> statements",
+                "Expression  : Expr expression",
+                "If          : Expr condition, Stmt thenBranch, Stmt elseBranch",
+                "Print       : Expr expression",
+                "Var         : Token name, Expr initializer",
+                "While       : Expr condition, Stmt body"
+        ));
     }
 
     private static void defineAst(String outputDir, String baseName, List<String> types)

+ 1 - 7
src/test/java/com/craftinginterpreters/lox/AstPrinterTest.java

@@ -1,7 +1,5 @@
 package com.craftinginterpreters.lox;
 
-import java.util.ArrayList;
-import java.util.List;
 import org.junit.Test;
 
 /* Copyright (C) 2019-2023 Hangzhou HSH Co. Ltd.
@@ -16,10 +14,6 @@ public class AstPrinterTest {
             new Token(TokenType.STAR, "*", null, 1),
             new Expr.Grouping(new Expr.Literal(45.67)));
 
-    List<Stmt> stmts = new ArrayList<>();
-    Stmt.Expression stmtExpr = new Stmt.Expression(expression);
-    stmts.add(stmtExpr);
-
-    System.out.println(new AstPrinter().print(stmts));
+    System.out.println(new AstPrinter().print(expression));
   }
 }