package lox; import java.util.List; abstract class Stmt { interface Visitor { R visitBlockStmt(Block stmt); R visitExpressionStmt(Expression stmt); R visitFunctionStmt(Function stmt); R visitIfStmt(If stmt); R visitVarStmt(Var stmt); R visitPrintStmt(Print stmt); R visitReturnStmt(Return stmt); R visitWhileStmt(While stmt); } static class Block extends Stmt { Block(List statements) { this.statements = statements; } @Override R accept(Visitor visitor) { return visitor.visitBlockStmt(this); } final List statements; } static class Expression extends Stmt { Expression(Expr expression) { this.expression = expression; } @Override R accept(Visitor visitor) { return visitor.visitExpressionStmt(this); } final Expr expression; } static class Function extends Stmt { Function(Token name, List params, List body) { this.name = name; this.params = params; this.body = body; } @Override R accept(Visitor visitor) { return visitor.visitFunctionStmt(this); } final Token name; final List params; final List body; } static class If extends Stmt { If(Expr condition, Stmt thenBranch, Stmt elseBranch) { this.condition = condition; this.thenBranch = thenBranch; this.elseBranch = elseBranch; } @Override R accept(Visitor visitor) { return visitor.visitIfStmt(this); } final Expr condition; final Stmt thenBranch; final Stmt elseBranch; } static class Var extends Stmt { Var(Token name, Expr initializer) { this.name = name; this.initializer = initializer; } @Override R accept(Visitor visitor) { return visitor.visitVarStmt(this); } final Token name; final Expr initializer; } static class Print extends Stmt { Print(Expr expression) { this.expression = expression; } @Override R accept(Visitor visitor) { return visitor.visitPrintStmt(this); } final Expr expression; } static class Return extends Stmt { Return(Token keyword, Expr value) { this.keyword = keyword; this.value = value; } @Override R accept(Visitor visitor) { return visitor.visitReturnStmt(this); } final Token keyword; final Expr value; } static class While extends Stmt { While(Expr condition, Stmt body) { this.condition = condition; this.body = body; } @Override R accept(Visitor visitor) { return visitor.visitWhileStmt(this); } final Expr condition; final Stmt body; } abstract R accept(Visitor visitor); }