package main import ( "fmt" "strconv" ) type astPrinter struct { result string } // visitBinaryExpr implements exprVisitor. func (p *astPrinter) visitBinaryExpr(b *binaryExpr) any { return p.parenthesize(b.Operator.Lexeme, b.Left, b.Right) } // visitGroupingExpr implements exprVisitor. func (p *astPrinter) visitGroupingExpr(g *groupingExpr) any { return p.parenthesize("group", g.Expr) } // visitLiteralExpr implements exprVisitor. func (p *astPrinter) visitLiteralExpr(g *literalExpr) any { switch t := g.Value.(type) { case string: return t case bool: if t { return "true" } return "false" case float64: return strconv.FormatFloat(t, 'f', 3, 64) case nil: return "nil" } return fmt.Sprintf("%v", g.Value) } // visitUnaryExpr implements exprVisitor. func (p *astPrinter) visitUnaryExpr(g *unaryExpr) any { return p.parenthesize(g.Operator.Lexeme, g.Right) } func (p *astPrinter) parenthesize(name string, expressions ...expr) string { val := "(" + name for _, e := range expressions { exprStr, ok := (e.accept(p)).(string) if !ok { panic("badly implemented visitor") } val += " " + exprStr } val += ")" return val } func (p *astPrinter) print(e expr) string { str, ok := (e.accept(p)).(string) if !ok { panic("badly implemented visitor") } return str }