Add ExprStatement PrintStatement

This commit is contained in:
ctsk
2022-09-08 18:57:34 +02:00
parent 57681d2eeb
commit 78cb1521df
4 changed files with 60 additions and 11 deletions

View File

@@ -1,16 +1,21 @@
package xyz.ctsk.lox; package xyz.ctsk.lox;
public class Interpreter implements Expr.Visitor<Object> { import java.util.List;
void interpret(Expr expression) { public class Interpreter implements Expr.Visitor<Object>, Stmt.Visitor<Void> {
void interpret(List<Stmt> statements) {
try { try {
Object value = evaluate(expression); statements.forEach(this::execute);
System.out.println(stringify(value));
} catch (RuntimeError error) { } catch (RuntimeError error) {
Lox.runtimeError(error); Lox.runtimeError(error);
} }
} }
private void execute(Stmt stmt) {
stmt.accept(this);
}
private Object evaluate(Expr expr) { private Object evaluate(Expr expr) {
return expr.accept(this); return expr.accept(this);
} }
@@ -26,6 +31,18 @@ public class Interpreter implements Expr.Visitor<Object> {
return text; 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 @Override
public Object visitBinaryExpr(Expr.Binary binary) { public Object visitBinaryExpr(Expr.Binary binary) {

View File

@@ -6,6 +6,7 @@ import java.io.InputStreamReader;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List;
public class Lox { public class Lox {
private static final Interpreter interpreter = new Interpreter(); private static final Interpreter interpreter = new Interpreter();
@@ -40,11 +41,11 @@ public class Lox {
var tokens = scanner.scanTokens(); var tokens = scanner.scanTokens();
Parser parser = new Parser(tokens); Parser parser = new Parser(tokens);
Expr expression = parser.parse(); List<Stmt> statements = parser.parse();
if (hadError) return; if (hadError) return;
interpreter.interpret(expression); interpreter.interpret(statements);
} }
private static void runPrompt() throws IOException { private static void runPrompt() throws IOException {

View File

@@ -1,5 +1,6 @@
package xyz.ctsk.lox; package xyz.ctsk.lox;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static xyz.ctsk.lox.TokenType.*; import static xyz.ctsk.lox.TokenType.*;
@@ -8,6 +9,11 @@ import static xyz.ctsk.lox.TokenType.*;
* *
* A recursive descent parser for the following grammar: * A recursive descent parser for the following grammar:
* <p> * <p>
* program → statement* EOF ;
* statement → exprStmt
* | printStmt ;
* exprStmt → expression ";" ;
* printStmt → "print" expression ";" ;
* expression → equality ; * expression → equality ;
* equality → comparison ( ( "!=" | "==" ) comparison )* ; * equality → comparison ( ( "!=" | "==" ) comparison )* ;
* comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ; * comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
@@ -27,12 +33,32 @@ public class Parser {
this.tokens = tokens; this.tokens = tokens;
} }
Expr parse() { List<Stmt> parse() {
try { List<Stmt> statements = new ArrayList<>();
return expression();
} catch (ParseError error) { while (!isAtEnd()) {
return null; 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() { private Expr expression() {

View File

@@ -5,6 +5,11 @@
@Rule(head = "Grouping", body = {"Expr expression"}), @Rule(head = "Grouping", body = {"Expr expression"}),
@Rule(head = "Literal", body = {"Object value"}), @Rule(head = "Literal", body = {"Object value"}),
@Rule(head = "Unary", body = {"Token operator", "Expr right"}) @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; package xyz.ctsk.lox;