import { TokenType } from "../data/constants" ; import { Token , TokenValue } from "../structures/token" ; export interface Visitor < T > { visitAssignExpr : ( expr : Assign ) => T ; visitBinaryExpr : ( expr : Binary ) => T ; visitCallExpr : ( expr : Call ) => T ; visitGetExpr : ( expr : Get ) => T ; visitGroupingExpr : ( expr : Grouping ) => T ; visitLiteralExpr : ( expr : Literal ) => T ; visitLogicalExpr : ( expr : Logical ) => T ; visitSelfExpr : ( expr : Self ) => T ; visitSetExpr : ( expr : Set ) => T ; visitSuperExpr : ( expr : Super ) => T ; visitUnaryExpr : ( expr : Unary ) => T ; visitVariableExpr : ( expr : Variable ) => T ; } let ExprArray = [ "Assign" , "Binary" , "Call" , "Get" , "Grouping" , "Literal" , "Logical" , "Self" , "Set" , "Super" , "Unary" , "Variable" ] ; export function isExpr ( value ) { if ( Array . isArray ( value ) ) return true ; return ExprArray . includes ( value . constructor . name ) ; } export type Expr = Assign | Binary | Call | Get | Grouping | Literal | Logical | Self | Set | Super | Unary | Variable | Expr [ ] ; export class Assign { name : Token ; value : Expr ; constructor ( name , value ) { this . name = name ; this . value = value ; } accept < T > ( visitor ) { return visitor . visitAssignExpr ( this ) ; } } export class Binary { left : Expr ; operator : Token ; right : Expr ; constructor ( left , operator , right ) { this . left = left ; this . operator = operator ; this . right = right ; } accept < T > ( visitor ) { return visitor . visitBinaryExpr ( this ) ; } } export class Call { callee : Expr ; paren : Token ; args : Expr [ ] ; constructor ( callee , paren , args ) { this . callee = callee ; this . paren = paren ; this . args = args ; } accept < T > ( visitor ) { return visitor . visitCallExpr ( this ) ; } } export class Get { obj : Expr ; name : Token ; constructor ( obj , name ) { this . obj = obj ; this . name = name ; } accept < T > ( visitor ) { return visitor . visitGetExpr ( this ) ; } } export class Grouping { expression : Expr ; constructor ( expression ) { this . expression = expression ; } accept < T > ( visitor ) { return visitor . visitGroupingExpr ( this ) ; } } export class Literal { type : TokenType ; value : TokenValue ; line : number ; rowpos : number ; constructor ( type , value , line , rowpos ) { this . type = type ; this . value = value ; this . line = line ; this . rowpos = rowpos ; } accept < T > ( visitor ) { return visitor . visitLiteralExpr ( this ) ; } } export class Logical { left : Expr ; operator : Token ; right : Expr ; constructor ( left , operator , right ) { this . left = left ; this . operator = operator ; this . right = right ; } accept < T > ( visitor ) { return visitor . visitLogicalExpr ( this ) ; } } export class Self { keyword : Token ; constructor ( keyword ) { this . keyword = keyword ; } accept < T > ( visitor ) { return visitor . visitSelfExpr ( this ) ; } } export class Set { obj : Expr ; name : Token ; value : Expr ; constructor ( obj , name , value ) { this . obj = obj ; this . name = name ; this . value = value ; } accept < T > ( visitor ) { return visitor . visitSetExpr ( this ) ; } } export class Super { keyword : Token ; method : Token ; constructor ( keyword , method ) { this . keyword = keyword ; this . method = method ; } accept < T > ( visitor ) { return visitor . visitSuperExpr ( this ) ; } } export class Unary { operator : Token ; right : Expr ; constructor ( operator , right ) { this . operator = operator ; this . right = right ; } accept < T > ( visitor ) { return visitor . visitUnaryExpr ( this ) ; } } export class Variable { name : Token ; constructor ( name ) { this . name = name ; } accept < T > ( visitor ) { return visitor . visitVariableExpr ( this ) ; } }