package com.craftinginterpreters.lox; import java.util.List; /** * AstPrinter */ class AstPrinter implements Expr.Visitor, Stmt.Visitor { 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 visitLogicalExpr(Expr.Logical expr) { return parenthesize(expr.operator.type.toString(), expr.left, expr.right); } @Override public String visitUnaryExpr(Expr.Unary expr) { return parenthesize(expr.operator.lexeme, expr.right); } @Override public String visitVariableExpr(Expr.Variable expr) { return expr.name.lexeme; } @Override public String visitAssignExpr(Expr.Assign expression) { return parenthesize(expression.name.lexeme + " = ", expression.value); } @Override public String visitVarStmt(Stmt.Var statement) { return parenthesize("define " + statement.name.lexeme + " = ", statement.initializer); } @Override public String visitWhileStmt(Stmt.While statement) { StringBuilder builder = new StringBuilder(); builder.append('('); builder.append(parenthesize("while", statement.condition)); builder.append(parenthesize("do", statement.body)); builder.append(')'); return builder.toString(); } @Override public String visitPrintStmt(Stmt.Print statement) { return parenthesize("print", statement.expression); } @Override public String visitExpressionStmt(Stmt.Expression expression) { return expression.expression.accept(this); } @Override public String visitIfStmt(Stmt.If stmt) { StringBuilder builder = new StringBuilder(); builder.append("("); builder.append(parenthesize("if", stmt.condition)); builder.append(parenthesize("then", stmt.thenBranch)); if (stmt.elseBranch != null) { builder.append(parenthesize("else", stmt.elseBranch)); } return builder.toString(); } @Override public String visitBlockStmt(Stmt.Block block) { return parenthesize("", block.statements); } private String parenthesize(String name, Expr... exprs) { StringBuilder builder = new StringBuilder(); builder.append("(").append(name); for (Expr expr : exprs) { builder.append(" "); builder.append(expr.accept(this)); } builder.append(")"); return builder.toString(); } private String parenthesize(String name, List statements) { StringBuilder builder = new StringBuilder(); builder.append("(").append(name); for (Stmt statement : statements) { builder.append(" "); builder.append(statement.accept(this)); } builder.append(")"); return builder.toString(); } private String parenthesize(String name, Stmt... statements) { return parenthesize(name, statements); } public static void main(String[] args) { Expr expression = new Expr.Binary( new Expr.Unary(new Token(TokenType.MINUS, "-", null, 1), new Expr.Literal(123)), new Token(TokenType.STAR, "*", null, 1), new Expr.Grouping(new Expr.Literal(45.67))); System.out.println(new AstPrinter().print(expression)); } }