package ast import "golox/token" type StmtVisitor[T any] interface { VisitErrorStmt(es *ErrorStmt) T VisitBlockStmt(bs *BlockStmt) T VisitExpressionStmt(es *ExpressionStmt) T VisitFunctionStmt(fs *FunctionStmt) T VisitIfStmt(is *IfStmt) T VisitPrintStmt(ps *PrintStmt) T VisitReturnStmt(rs *ReturnStmt) 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 FunctionStmt struct { Name token.Token Params []token.Token Body []Stmt } func (fs *FunctionStmt) Accept(v StmtVisitor[any]) any { return v.VisitFunctionStmt(fs) } 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 ReturnStmt struct { Keyword token.Token Value Expr } func (rs *ReturnStmt) Accept(v StmtVisitor[any]) any { return v.VisitReturnStmt(rs) } 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) }