66 lines
1.1 KiB
Go
66 lines
1.1 KiB
Go
package ast
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
type Printer struct {
|
|
result string
|
|
}
|
|
|
|
var _ ExprVisitor = new(Printer)
|
|
|
|
func (p *Printer) VisitBinaryExpr(b *BinaryExpr) any {
|
|
return p.Parenthesize(b.Op.Lexeme, b.Left, b.Right)
|
|
}
|
|
|
|
func (p *Printer) VisitGroupingExpr(g *GroupingExpr) any {
|
|
return p.Parenthesize("group", g.Expr)
|
|
}
|
|
|
|
func (p *Printer) 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)
|
|
}
|
|
|
|
func (p *Printer) VisitUnaryExpr(g *UnaryExpr) any {
|
|
return p.Parenthesize(g.Op.Lexeme, g.Right)
|
|
}
|
|
|
|
func (p *Printer) 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 *Printer) Print(e Expr) string {
|
|
str, ok := (e.Accept(p)).(string)
|
|
if !ok {
|
|
panic("badly implemented visitor")
|
|
}
|
|
return str
|
|
}
|