68 lines
1.3 KiB
Go
68 lines
1.3 KiB
Go
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
|
|
}
|