133 lines
3.7 KiB
Java
133 lines
3.7 KiB
Java
package com.craftinginterpreters.lox;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* AstPrinter
|
|
*/
|
|
class AstPrinter implements Expr.Visitor<String>, Stmt.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 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<Stmt> 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));
|
|
}
|
|
}
|