This commit is contained in:
Erik Winter 2024-11-04 10:50:46 +01:00
parent fb1a414f90
commit 1771f11749
3 changed files with 92 additions and 12 deletions

View File

@ -3,6 +3,10 @@
build: build:
javac -d build/classes src/com/craftinginterpreters/lox/* javac -d build/classes src/com/craftinginterpreters/lox/*
javac -d build/classes src/com/craftinginterpreters/tool/*
run: lox:
java -cp build/classes com.craftinginterpreters.lox.Lox java -cp build/classes com.craftinginterpreters.lox.Lox
gen-ast:
java -cp build/classes com.craftinginterpreters.tool.GenerateAst ./src/com/craftinginterpreters/lox

View File

@ -1,15 +1,68 @@
package com.craftinginterpreters.lox; package com.craftinginterpreters.lox;
abstract class Expr { import java.util.list;
static class Binary extends Expr {
Binary(Expr left, Token operator, Expr right) {
this.left = left;
this.operator = operator;
this.right = right;
}
final Expr left; abstract class Expr {
final Token operator; interface Visitor<R> {
final Expr right; R visitBinaryExpr(Binary expr);
R visitGroupingExpr(Grouping expr);
R visitLiteralExpr(Literal expr);
R visitUnaryExpr(Unary expr);
}
static class Binary extends Expr {
Binary(Expr left, Token operator, Expr right) {
this.left = left;
this.Token = Token;
this.Expr = Expr;
} }
@Override
<R> R accept(Visitor<R> visitor) {
return visitor.visitBinaryExpr(this);
}
final Expr left = Expr left;
final Token operator = Token operator;
final Expr right = Expr right;
}
static class Grouping extends Expr {
Grouping(Expr expression) {
this.expression = expression;
}
@Override
<R> R accept(Visitor<R> visitor) {
return visitor.visitGroupingExpr(this);
}
final Expr expression = Expr expression;
}
static class Literal extends Expr {
Literal(Object value) {
this.value = value;
}
@Override
<R> R accept(Visitor<R> visitor) {
return visitor.visitLiteralExpr(this);
}
final Object value = Object value;
}
static class Unary extends Expr {
Unary(Token operator, Expr right) {
this.operator = operator;
this.Expr = Expr;
}
@Override
<R> R accept(Visitor<R> visitor) {
return visitor.visitUnaryExpr(this);
}
final Token operator = Token operator;
final Expr right = Expr right;
}
abstract <R> R accept(Visitor<R> visitor);
} }

View File

@ -20,7 +20,7 @@ public class GenerateAst {
)); ));
} }
private static void defineAst(String outputDir, String baseName, List<String> types) throws IOException { private static void defineAst(String outputDir, String baseName, List<String> types) throws IOException {
String path = outputDir + "/" + baseName + ".java"; String path = outputDir + "/" + baseName + ".java";
PrintWriter writer = new PrintWriter(path, "UTF-8"); PrintWriter writer = new PrintWriter(path, "UTF-8");
@ -30,6 +30,8 @@ public class GenerateAst {
writer.println(); writer.println();
writer.println("abstract class " + baseName + " {"); writer.println("abstract class " + baseName + " {");
defineVisitor(writer, baseName, types);
// The AST classes // The AST classes
for (String type : types) { for (String type : types) {
String className = type.split(":")[0].trim(); String className = type.split(":")[0].trim();
@ -37,9 +39,23 @@ public class GenerateAst {
defineType(writer, baseName, className, fields); defineType(writer, baseName, className, fields);
} }
// the base accept() method
writer.println();
writer.println(" abstract <R> R accept(Visitor<R> visitor);");
writer.println("}"); writer.println("}");
writer.close(); writer.close();
}
private static void defineVisitor(PrintWriter writer, String baseName, List<String> types) {
writer.println(" interface Visitor<R> {");
for (String type : types) {
String typeName = type.split(":")[0].trim();
writer.println(" R visit" + typeName + baseName + "(" + typeName + " " + baseName.toLowerCase() + ");");
}
writer.println(" }");
} }
private static void defineType(PrintWriter writer, String baseName, String className, String fieldList) { private static void defineType(PrintWriter writer, String baseName, String className, String fieldList) {
@ -57,6 +73,13 @@ public class GenerateAst {
writer.println(" }"); writer.println(" }");
// visitor pattern
writer.println();
writer.println(" @Override");
writer.println(" <R> R accept(Visitor<R> visitor) {");
writer.println(" return visitor.visit" + className + baseName + "(this);");
writer.println(" }");
// Fields // Fields
writer.println(); writer.println();
for (String field : fields) { for (String field : fields) {