package ast import "golox/token" type StmtVisitor[T any] interface { VisitErrorStmt(es *ErrorStmt) T VisitBlockStmt(bs *BlockStmt) T VisitExpressionStmt(es *ExpressionStmt) T VisitIfStmt(is *IfStmt) T VisitPrintStmt(ps *PrintStmt) T VisitVarStmt(vs *VarStmt) T VisitWhileStmt(ws *WhileStmt) T } type Stmt interface { Accept(visitor StmtVisitor[any]) any } type ErrorStmt struct { Value string } func (es *ErrorStmt) Accept(v StmtVisitor[any]) any { return v.VisitErrorStmt(es) } type BlockStmt struct { Statements []Stmt } func (bs *BlockStmt) Accept(v StmtVisitor[any]) any { return v.VisitBlockStmt(bs) } type ExpressionStmt struct { Expression Expr } func (es *ExpressionStmt) Accept(v StmtVisitor[any]) any { return v.VisitExpressionStmt(es) } type IfStmt struct { Condition Expr ThenBranch Stmt ElseBranch Stmt } func (is *IfStmt) Accept(v StmtVisitor[any]) any { return v.VisitIfStmt(is) } type PrintStmt struct { Expression Expr } func (ps *PrintStmt) Accept(v StmtVisitor[any]) any { return v.VisitPrintStmt(ps) } type VarStmt struct { Name token.Token Initializer Expr } func (vs *VarStmt) Accept(v StmtVisitor[any]) any { return v.VisitVarStmt(vs) } type WhileStmt struct { Condition Expr Body Stmt } func (ws *WhileStmt) Accept(v StmtVisitor[any]) any { return v.VisitWhileStmt(ws) }