finish off chapter 5
This commit is contained in:
		
							
								
								
									
										42
									
								
								src/lox/ASTPrinter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/lox/ASTPrinter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
package lox;
 | 
			
		||||
 | 
			
		||||
class ASTPrinter implements Expr.Visitor<String> {
 | 
			
		||||
  String print(Expr expr) {
 | 
			
		||||
    return expr.accept(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String visitBinaryExpr(Expr.Binary expr) {
 | 
			
		||||
    return parenthesize(expr.operator.lexeme, expr.left, expr.right);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String visitGroupingExpr(Expr.Grouping expr) {
 | 
			
		||||
    return parenthesize("group", expr.expression);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String visitLiteralExpr(Expr.Literal expr) {
 | 
			
		||||
    if (expr.value == null) {
 | 
			
		||||
      return "nil";
 | 
			
		||||
    }
 | 
			
		||||
    return expr.value.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String visitUnaryExpr(Expr.Unary expr) {
 | 
			
		||||
    return parenthesize(expr.operator.lexeme, expr.right);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private String parenthesize(String name, Expr... exprs) {
 | 
			
		||||
    StringBuilder builder = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
    builder.append("(").append(name);
 | 
			
		||||
    for (Expr expr : exprs) {
 | 
			
		||||
      builder.append(" ").append(expr.accept(this));
 | 
			
		||||
    }
 | 
			
		||||
    builder.append(")");
 | 
			
		||||
 | 
			
		||||
    return builder.toString();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,15 @@
 | 
			
		||||
package lox;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
abstract class Expr {
 | 
			
		||||
  interface Visitor<R> {
 | 
			
		||||
    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;
 | 
			
		||||
@@ -8,6 +17,11 @@ abstract class Expr {
 | 
			
		||||
      this.right = right;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    <R> R accept(Visitor<R> visitor) {
 | 
			
		||||
      return visitor.visitBinaryExpr(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final Expr left;
 | 
			
		||||
    final Token operator;
 | 
			
		||||
    final Expr right;
 | 
			
		||||
@@ -18,6 +32,11 @@ abstract class Expr {
 | 
			
		||||
      this.expression = expression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    <R> R accept(Visitor<R> visitor) {
 | 
			
		||||
      return visitor.visitGroupingExpr(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final Expr expression;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -26,6 +45,11 @@ abstract class Expr {
 | 
			
		||||
      this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    <R> R accept(Visitor<R> visitor) {
 | 
			
		||||
      return visitor.visitLiteralExpr(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final Object value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -35,7 +59,14 @@ abstract class Expr {
 | 
			
		||||
      this.right = right;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    <R> R accept(Visitor<R> visitor) {
 | 
			
		||||
      return visitor.visitUnaryExpr(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final Token operator;
 | 
			
		||||
    final Expr right;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  abstract <R> R accept(Visitor<R> visitor);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,16 +34,40 @@ public class GenerateAST {
 | 
			
		||||
    writer.println();
 | 
			
		||||
    writer.println("abstract class " + baseName + " {");
 | 
			
		||||
 | 
			
		||||
    defineVisitor(writer, baseName, types);
 | 
			
		||||
 | 
			
		||||
    for (String type : types) {
 | 
			
		||||
      String className = type.split(":")[0].trim();
 | 
			
		||||
      String fields = type.split(":")[1].trim();
 | 
			
		||||
      defineType(writer, baseName, className, fields);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    writer.println("  abstract <R> R accept(Visitor<R> visitor);");
 | 
			
		||||
 | 
			
		||||
    writer.println("}");
 | 
			
		||||
    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("  }");
 | 
			
		||||
    writer.println();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void defineType(
 | 
			
		||||
      PrintWriter writer, String baseName, String className, String fieldList) {
 | 
			
		||||
    writer.println("  static class " + className + " extends " + baseName + " {");
 | 
			
		||||
@@ -59,6 +83,12 @@ public class GenerateAST {
 | 
			
		||||
    writer.println("    }");
 | 
			
		||||
    writer.println();
 | 
			
		||||
 | 
			
		||||
    writer.println("    @Override");
 | 
			
		||||
    writer.println("    <R> R accept(Visitor<R> visitor) {");
 | 
			
		||||
    writer.println("      return visitor.visit" + className + baseName + "(this);");
 | 
			
		||||
    writer.println("    }");
 | 
			
		||||
    writer.println();
 | 
			
		||||
 | 
			
		||||
    for (String field : fields) {
 | 
			
		||||
      writer.println("    final " + field + ";");
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user