Add ExprStatement PrintStatement
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user