Ver código fonte

Parsing variables -- IfStatement

runningwater 2 anos atrás
pai
commit
b69618d984

+ 2 - 0
README.md

@@ -94,10 +94,12 @@
                          | statement ;
           
              statement      → exprStmt
+                             | ifStmt
                              | printStmt 
                              | block;
             
              block         → "{" declaration* "}"
+             ifStmt        → "if" "(" expression ")" statement ( "else" statement)? ;
             
             varDecl  → "var" IDENTIFIER ( "=" expression )? ";" ;
           ```

+ 8 - 1
src/main/java/com/craftinginterpreters/lox/AstPrinter.java

@@ -37,6 +37,13 @@ public class AstPrinter implements Expr.Visitor<String>, Stmt.Visitor<String> {
   }
 
   @Override
+  public String visitIfStmt(Stmt.If stmt) {
+    String condition = "if (" + parenthesize(null, stmt.condition) + ")";
+    // TODO
+    return condition;
+  }
+
+  @Override
   public String visitPrintStmt(Stmt.Print stmt) {
     return parenthesize("print", stmt.expression);
   }
@@ -80,7 +87,7 @@ public class AstPrinter implements Expr.Visitor<String>, Stmt.Visitor<String> {
 
   private String parenthesize(String name, Expr... exprs) {
     StringBuilder builder = new StringBuilder();
-    builder.append("(").append(name);
+    builder.append("(").append(name == null ? "" : name);
     for (Expr expr : exprs) {
       builder.append(" ");
       builder.append(expr.accept(this));

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

@@ -126,6 +126,16 @@ public class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
   }
 
   @Override
+  public Void visitIfStmt(Stmt.If stmt) {
+    if (isTruthy(evaluate(stmt.condition))) {
+      execute(stmt.thenBranch);
+    } else if (stmt.elseBranch != null) {
+      execute(stmt.elseBranch);
+    }
+    return null;
+  }
+
+  @Override
   public Void visitPrintStmt(Stmt.Print stmt) {
     Object value = evaluate(stmt.expression);
     System.out.println("  " + stringify(value));

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

@@ -53,13 +53,27 @@ public class Parser {
     }
   }
 
-  // statement  → exprStmt | printStmt | block;
+  // statement  → exprStmt | ifStmt | printStmt | block;
   private Stmt statement() {
+    if (match(IF)) return ifStatement();
     if (match(PRINT)) return printStatement();
     if (match(LEFT_BRACE)) return new Stmt.Block(block());
     return expressionStatement();
   }
 
+  //  ifStmt  → "if" "(" expression ")" statement ( "else" statement)? ;
+  private Stmt ifStatement() {
+    consume(LEFT_PARAM, "Expect '(' after if.");
+    Expr condition = expression();
+    consume(RIGHT_PARAM, "Expect ')' after if condition.");
+
+    Stmt thenBranch = statement();
+    Stmt elseBranch = null;
+    if (match(ELSE)) elseBranch = statement();
+
+    return new Stmt.If(condition, thenBranch, elseBranch);
+  }
+
   // block          → "{" declaration* "}" ;
   private List<Stmt> block() {
     List<Stmt> statements = new ArrayList<>();

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

@@ -4,7 +4,7 @@ import java.util.List;
 
 /**
  * @author GenerateAst
- * @date 2023-06-13 10:59
+ * @date 2023-06-14 09:35
  */
 abstract class Stmt {
     interface Visitor<R> {
@@ -12,6 +12,8 @@ abstract class Stmt {
 
         R visitExpressionStmt(Expression stmt);
 
+        R visitIfStmt(If stmt);
+
         R visitPrintStmt(Print stmt);
 
         R visitVarStmt(Var stmt);
@@ -45,6 +47,23 @@ abstract class Stmt {
         final Expr expression;
     }
 
+    static class If extends Stmt {
+        If(Expr condition, Stmt thenBranch, Stmt elseBranch) {
+            this.condition = condition;
+            this.thenBranch = thenBranch;
+            this.elseBranch = elseBranch;
+        }
+
+        @Override
+        <R> R accept(Visitor<R> visitor) {
+            return visitor.visitIfStmt(this);
+        }
+
+        final Expr condition;
+        final  Stmt thenBranch;
+        final  Stmt elseBranch;
+    }
+
     static class Print extends Stmt {
         Print(Expr expression) {
             this.expression = expression;

+ 9 - 8
src/main/java/com/craftinginterpreters/tool/GenerateAst.java

@@ -42,17 +42,18 @@ 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",
-//                "Unary    : Token operator, Expr right",
-//                "Variable : Token name"
-//        ));
+        defineAst(outputDir, "Expr", Arrays.asList(
+                "Assign   : Token name, Expr value",
+                "Binary   : Expr left, Token operator, Expr right",
+                "Grouping : Expr expression",
+                "Literal  : Object value",
+                "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"
         ));