package main // todo: find something better than any here // we can't use generics on either the visitor itself or // each individual method because the adding it to the // visitor itself infects every expr you use with it // and methods cannot have generic parameters type exprVisitor interface { visitBinaryExpr(b *binaryExpr) any visitGroupingExpr(g *groupingExpr) any visitLiteralExpr(g *literalExpr) any visitUnaryExpr(g *unaryExpr) any } type expr interface { accept(v exprVisitor) any } type binaryExpr struct { Left expr Operator *token Right expr } func (b *binaryExpr) accept(v exprVisitor) any { return v.visitBinaryExpr(b) } type groupingExpr struct { Expr expr } func (g *groupingExpr) accept(v exprVisitor) any { return v.visitGroupingExpr(g) } type literalExpr struct { Value any } func (l *literalExpr) accept(v exprVisitor) any { return v.visitLiteralExpr(l) } type unaryExpr struct { Operator *token Right expr } func (u *unaryExpr) accept(v exprVisitor) any { return v.visitUnaryExpr(u) }