package ast import ( "fmt" ) type Printer struct { } func NewPrinter() *Printer { return &Printer{} } func (ap *Printer) PrintStmts(stmts []Stmt) string { str := "" for _, stmt := range stmts { str += stmt.Accept(ap).(string) + "\n" } return str } func (ap *Printer) PrintExpr(expr Expr) string { return expr.Accept(ap).(string) } func (ap *Printer) VisitErrorStmt(stmt *ErrorStmt) any { return stmt.Value } func (ap *Printer) VisitExpressionStmt(stmt *ExpressionStmt) any { return stmt.Expression.Accept(ap) } func (ap *Printer) VisitPrintStmt(stmt *PrintStmt) any { return ap.parenthesize("print", stmt.Expression) } func (ap *Printer) VisitVarStmt(stmt *VarStmt) any { return ap.parenthesize("var", &LiteralExpr{stmt.Name}, stmt.Initializer) } func (ap *Printer) VisitVariableExpr(expr *VariableExpr) any { return expr.Name.Lexeme } func (ap *Printer) VisitBinaryExpr(expr *BinaryExpr) any { return ap.parenthesize(expr.Operator.Lexeme, expr.Left, expr.Right) } func (ap *Printer) VisitGroupingExpr(expr *GroupingExpr) any { return ap.parenthesize("group", expr.Expression) } func (ap *Printer) VisitLiteralExpr(expr *LiteralExpr) any { if expr.Value == nil { return "nil" } return fmt.Sprint(expr.Value) } func (ap *Printer) VisitUnaryExpr(expr *UnaryExpr) any { return ap.parenthesize(expr.Operator.Lexeme, expr.Right) } func (ap *Printer) VisitErrorExpr(expr *ErrorExpr) any { return expr.Value } func (ap *Printer) VisitAssignExpr(expr *AssignExpr) any { return ap.parenthesize("=", &VariableExpr{expr.Name}, expr.Value) } func (ap *Printer) parenthesize(name string, exprs ...Expr) string { str := "(" + name for _, expr := range exprs { if expr == nil { continue } str += " " + expr.Accept(ap).(string) } return str + ")" }