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;
 | 
					package lox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class Expr {
 | 
					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 {
 | 
					  static class Binary extends Expr {
 | 
				
			||||||
    Binary(Expr left, Token operator, Expr right) {
 | 
					    Binary(Expr left, Token operator, Expr right) {
 | 
				
			||||||
      this.left = left;
 | 
					      this.left = left;
 | 
				
			||||||
@@ -8,6 +17,11 @@ abstract class Expr {
 | 
				
			|||||||
      this.right = right;
 | 
					      this.right = right;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitBinaryExpr(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final Expr left;
 | 
					    final Expr left;
 | 
				
			||||||
    final Token operator;
 | 
					    final Token operator;
 | 
				
			||||||
    final Expr right;
 | 
					    final Expr right;
 | 
				
			||||||
@@ -18,6 +32,11 @@ abstract class Expr {
 | 
				
			|||||||
      this.expression = expression;
 | 
					      this.expression = expression;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitGroupingExpr(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final Expr expression;
 | 
					    final Expr expression;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,6 +45,11 @@ abstract class Expr {
 | 
				
			|||||||
      this.value = value;
 | 
					      this.value = value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitLiteralExpr(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final Object value;
 | 
					    final Object value;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +59,14 @@ abstract class Expr {
 | 
				
			|||||||
      this.right = right;
 | 
					      this.right = right;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    <R> R accept(Visitor<R> visitor) {
 | 
				
			||||||
 | 
					      return visitor.visitUnaryExpr(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final Token operator;
 | 
					    final Token operator;
 | 
				
			||||||
    final Expr right;
 | 
					    final Expr right;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  abstract <R> R accept(Visitor<R> visitor);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,21 +34,45 @@ public class GenerateAST {
 | 
				
			|||||||
    writer.println();
 | 
					    writer.println();
 | 
				
			||||||
    writer.println("abstract class " + baseName + " {");
 | 
					    writer.println("abstract class " + baseName + " {");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    defineVisitor(writer, baseName, types);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (String type : types) {
 | 
					    for (String type : types) {
 | 
				
			||||||
      String className = type.split(":")[0].trim();
 | 
					      String className = type.split(":")[0].trim();
 | 
				
			||||||
      String fields = type.split(":")[1].trim();
 | 
					      String fields = type.split(":")[1].trim();
 | 
				
			||||||
      defineType(writer, baseName, className, fields);
 | 
					      defineType(writer, baseName, className, fields);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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("  }");
 | 
				
			||||||
 | 
					    writer.println();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private static void defineType(
 | 
					  private static void defineType(
 | 
				
			||||||
      PrintWriter writer, String baseName, String className, String fieldList) {
 | 
					      PrintWriter writer, String baseName, String className, String fieldList) {
 | 
				
			||||||
    writer.println("  static class " + className + " extends " + baseName + " {");
 | 
					    writer.println("  static class " + className + " extends " + baseName + " {");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    writer.println("    " + className + "(" + fieldList + ") { ");
 | 
					    writer.println("    " + className + "(" + fieldList + ") {");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    String[] fields = fieldList.split(", ");
 | 
					    String[] fields = fieldList.split(", ");
 | 
				
			||||||
    for (String field : fields) {
 | 
					    for (String field : fields) {
 | 
				
			||||||
@@ -59,6 +83,12 @@ public class GenerateAST {
 | 
				
			|||||||
    writer.println("    }");
 | 
					    writer.println("    }");
 | 
				
			||||||
    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) {
 | 
					    for (String field : fields) {
 | 
				
			||||||
      writer.println("    final " + field + ";");
 | 
					      writer.println("    final " + field + ";");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user