package ast import ( "fmt" ) type Printer struct { } func NewPrinter() *Printer { return &Printer{} } func (ap *Printer) Print(expr Expr) string { return expr.Accept(ap).(string) } 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) parenthesize(name string, exprs ...Expr) string { str := "(" + name for _, expr := range exprs { str += " " + expr.Accept(ap).(string) } return str + ")" }