package fr.celticinfo.lox /** * The ExprVisitor interface is used to visit the different types of expressions that can be parsed by the Parser. */ interface ExprVisitor { fun visitAssign(expr: Assign): R fun visitBinary(expr: Binary): R fun visitCall(expr: Call): R fun visitGet(expr: Get): R fun visitGrouping(expr: Grouping): R fun visitLiteral(expr: Literal): R fun visitLogical(expr: Logical): R fun visitSet(expr: Set): R fun visitSuper(expr: Super): R fun visitThis(expr: This): R fun visitUnary(expr: Unary): R fun visitVariable(expr: Variable): R } /** * The Expr class represents the different types of expressions that can be parsed by the Parser. */ sealed class Expr { abstract fun accept(visitor: ExprVisitor): R } data class Assign( val name: Token, val value: Expr ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitAssign(this) } } data class Binary( val left: Expr, val operator: Token, val right: Expr ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitBinary(this) } } data class Call( val callee: Expr, val paren: Token, val arguments: List ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitCall(this) } } data class Get( val obj: Expr, val name: Token ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitGet(this) } } data class Grouping( val expression: Expr ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitGrouping(this) } } data class Literal( val value: Any? ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitLiteral(this) } } data class Logical( val left: Expr, val operator: Token, val right: Expr ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitLogical(this) } } data class Set( val obj: Expr, val name: Token, val value: Expr ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitSet(this) } } data class Super( val keyword: Token, val method: Token ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitSuper(this) } } data class This( val keyword: Token ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitThis(this) } } data class Unary( val operator: Token, val right: Expr ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitUnary(this) } } data class Variable( val name: Token ) : Expr() { override fun accept(visitor: ExprVisitor): R { return visitor.visitVariable(this) } }