From 78cb1521dfb36d973d5fe6ca7a03ab5ca5725ce5 Mon Sep 17 00:00:00 2001 From: ctsk <9384305+ctsk@users.noreply.github.com> Date: Thu, 8 Sep 2022 18:57:34 +0200 Subject: [PATCH] Add ExprStatement PrintStatement --- .../main/java/xyz/ctsk/lox/Interpreter.java | 25 ++++++++++--- jlox/lox/src/main/java/xyz/ctsk/lox/Lox.java | 5 +-- .../src/main/java/xyz/ctsk/lox/Parser.java | 36 ++++++++++++++++--- .../main/java/xyz/ctsk/lox/package-info.java | 5 +++ 4 files changed, 60 insertions(+), 11 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 176877b..f8023d3 100644 --- a/jlox/lox/src/main/java/xyz/ctsk/lox/Interpreter.java +++ b/jlox/lox/src/main/java/xyz/ctsk/lox/Interpreter.java @@ -1,16 +1,21 @@ package xyz.ctsk.lox; -public class Interpreter implements Expr.Visitor { +import java.util.List; - void interpret(Expr expression) { +public class Interpreter implements Expr.Visitor, Stmt.Visitor { + + void interpret(List statements) { try { - Object value = evaluate(expression); - System.out.println(stringify(value)); + statements.forEach(this::execute); } catch (RuntimeError error) { Lox.runtimeError(error); } } + private void execute(Stmt stmt) { + stmt.accept(this); + } + private Object evaluate(Expr expr) { return expr.accept(this); } @@ -26,6 +31,18 @@ public class Interpreter implements Expr.Visitor { return text; } + @Override + public Void visitExpressionStmt(Stmt.Expression stmt) { + evaluate(stmt.expression()); + return null; + } + + @Override + public Void visitPrintStmt(Stmt.Print stmt) { + Object value = evaluate(stmt.expression()); + System.out.println(stringify(value)); + return null; + } @Override public Object visitBinaryExpr(Expr.Binary binary) { diff --git a/jlox/lox/src/main/java/xyz/ctsk/lox/Lox.java b/jlox/lox/src/main/java/xyz/ctsk/lox/Lox.java index 3c43e75..79afdda 100644 --- a/jlox/lox/src/main/java/xyz/ctsk/lox/Lox.java +++ b/jlox/lox/src/main/java/xyz/ctsk/lox/Lox.java @@ -6,6 +6,7 @@ import java.io.InputStreamReader; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.List; public class Lox { private static final Interpreter interpreter = new Interpreter(); @@ -40,11 +41,11 @@ public class Lox { var tokens = scanner.scanTokens(); Parser parser = new Parser(tokens); - Expr expression = parser.parse(); + List statements = parser.parse(); if (hadError) return; - interpreter.interpret(expression); + interpreter.interpret(statements); } private static void runPrompt() throws IOException { 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 0a7aece..274c1a5 100644 --- a/jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java +++ b/jlox/lox/src/main/java/xyz/ctsk/lox/Parser.java @@ -1,5 +1,6 @@ package xyz.ctsk.lox; +import java.util.ArrayList; import java.util.List; import static xyz.ctsk.lox.TokenType.*; @@ -8,6 +9,11 @@ import static xyz.ctsk.lox.TokenType.*; * * A recursive descent parser for the following grammar: *

+ * program → statement* EOF ; + * statement → exprStmt + * | printStmt ; + * exprStmt → expression ";" ; + * printStmt → "print" expression ";" ; * expression → equality ; * equality → comparison ( ( "!=" | "==" ) comparison )* ; * comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ; @@ -27,12 +33,32 @@ public class Parser { this.tokens = tokens; } - Expr parse() { - try { - return expression(); - } catch (ParseError error) { - return null; + List parse() { + List statements = new ArrayList<>(); + + while (!isAtEnd()) { + statements.add(statement()); } + + return statements; + } + + + + private Stmt statement() { + if (match(PRINT)) return printStatement(); + return expressionStatement(); + } + private Stmt printStatement() { + Expr value = expression(); + consume(SEMICOLON, "Expect ';' after value."); + return new Stmt.Print(value); + } + + private Stmt expressionStatement() { + Expr expr = expression(); + consume(SEMICOLON, "Expect ';' after expression."); + return new Stmt.Expression(expr); } private Expr expression() { 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 d2a85bf..ea8249e 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 @@ -5,6 +5,11 @@ @Rule(head = "Grouping", body = {"Expr expression"}), @Rule(head = "Literal", body = {"Object value"}), @Rule(head = "Unary", body = {"Token operator", "Expr right"}) + }), + @Root(name = "Stmt", + rules = { + @Rule(head = "Expression", body = "Expr expression"), + @Rule(head = "Print", body = "Expr expression") }) }) package xyz.ctsk.lox;