package cobalt.lang; import java.util.List; abstract class Expr { interface Visitor { R visitBinaryExpr(Binary expr); R visitGroupingExpr(Grouping expr); R visitLiteralExpr(Literal expr); R visitUnaryExpr(Unary expr); R visitVarExpr(Variable expr); R visitAssignExpr(Assign expr); } static class Binary extends Expr { Binary(Expr left, Token operator, Expr right) { this.left = left; this.operator = operator; this.right = right; } R accept(Visitor visitor) { return visitor.visitBinaryExpr(this); } final Expr left; final Token operator; final Expr right; } static class Grouping extends Expr { Grouping(Expr expression) { this.expression = expression; } R accept(Visitor visitor) { return visitor.visitGroupingExpr(this); } final Expr expression; } static class Literal extends Expr { Literal(Object value) { this.value = value; } R accept(Visitor visitor) { return visitor.visitLiteralExpr(this); } final Object value; } static class Unary extends Expr { Unary(Token operator, Expr right) { this.operator = operator; this.right = right; } R accept(Visitor visitor) { return visitor.visitUnaryExpr(this); } final Token operator; final Expr right; } static class Variable extends Expr { Variable(Token name, boolean nullable) { this.name = name; this.nullable = nullable; } R accept(Visitor visitor) { return visitor.visitVarExpr(this); } final Token name; final boolean nullable; } static class Assign extends Expr { Assign(Token name, Expr value) { this.name = name; this.value = value; } R accept(Visitor visitor) { return visitor.visitAssignExpr(this); } final Token name; final Expr value; } abstract R accept(Visitor visitor); }