From 1771f11749043f56a1ddafb8d26157da4d444050 Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Mon, 4 Nov 2024 10:50:46 +0100 Subject: [PATCH] 5.3 --- Makefile | 6 +- src/com/craftinginterpreters/lox/Expr.java | 73 ++++++++++++++++--- .../tool/GenerateAst.java | 25 ++++++- 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 12b1cd5..7daf5ce 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,10 @@ build: 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 + +gen-ast: + java -cp build/classes com.craftinginterpreters.tool.GenerateAst ./src/com/craftinginterpreters/lox diff --git a/src/com/craftinginterpreters/lox/Expr.java b/src/com/craftinginterpreters/lox/Expr.java index a59ebe4..24d97fe 100644 --- a/src/com/craftinginterpreters/lox/Expr.java +++ b/src/com/craftinginterpreters/lox/Expr.java @@ -1,15 +1,68 @@ package com.craftinginterpreters.lox; -abstract class Expr { - static class Binary extends Expr { - Binary(Expr left, Token operator, Expr right) { - this.left = left; - this.operator = operator; - this.right = right; - } +import java.util.list; - final Expr left; - final Token operator; - final Expr right; +abstract class Expr { + interface Visitor { + 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 accept(Visitor 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 accept(Visitor visitor) { + return visitor.visitGroupingExpr(this); + } + + final Expr expression = Expr expression; + } + static class Literal extends Expr { + Literal(Object value) { + this.value = value; + } + + @Override + R accept(Visitor 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 accept(Visitor visitor) { + return visitor.visitUnaryExpr(this); + } + + final Token operator = Token operator; + final Expr right = Expr right; + } + + abstract R accept(Visitor visitor); } diff --git a/src/com/craftinginterpreters/tool/GenerateAst.java b/src/com/craftinginterpreters/tool/GenerateAst.java index de85393..55b1b1a 100644 --- a/src/com/craftinginterpreters/tool/GenerateAst.java +++ b/src/com/craftinginterpreters/tool/GenerateAst.java @@ -20,7 +20,7 @@ public class GenerateAst { )); } - private static void defineAst(String outputDir, String baseName, List types) throws IOException { + private static void defineAst(String outputDir, String baseName, List types) throws IOException { String path = outputDir + "/" + baseName + ".java"; PrintWriter writer = new PrintWriter(path, "UTF-8"); @@ -30,6 +30,8 @@ public class GenerateAst { writer.println(); writer.println("abstract class " + baseName + " {"); + defineVisitor(writer, baseName, types); + // The AST classes for (String type : types) { String className = type.split(":")[0].trim(); @@ -37,9 +39,23 @@ public class GenerateAst { defineType(writer, baseName, className, fields); } + // the base accept() method + writer.println(); + writer.println(" abstract R accept(Visitor visitor);"); + writer.println("}"); writer.close(); + } + private static void defineVisitor(PrintWriter writer, String baseName, List types) { + writer.println(" interface Visitor {"); + + 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) { @@ -57,6 +73,13 @@ public class GenerateAst { writer.println(" }"); + // visitor pattern + writer.println(); + writer.println(" @Override"); + writer.println(" R accept(Visitor visitor) {"); + writer.println(" return visitor.visit" + className + baseName + "(this);"); + writer.println(" }"); + // Fields writer.println(); for (String field : fields) {