package Ġcom . save kir k . tool Ċ Ċ import Ġjava . io . PrintWriter Ċ import Ġjava . util .* Ċ import Ġkotlin . system . exit Process Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠ Ġif Ġ( args . size Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠSystem . err . println (" Usage : Ġgenerate _ ast Ġ< output Ġdirectory ") ĊĠĠĠĠĠĠĠ Ġexit Process ( 1 ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġoutput Dir Ġ= Ġargs [ 0 ] ĊĠĠĠ Ġval Ġgenerate Ast Ġ= ĠGenerate Ast () ĊĠĠĠ Ġgenerate Ast . define Ast ( output Dir , Ġ" Expr ", ĠArrays . asList ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Binary ĠĠ Ġ-> Ġval Ġleft : ĠExpr , Ġprivate Ġval Ġoperator : ĠToken , Ġprivate Ġval Ġright : ĠExpr ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Grouping Ġ-> Ġval Ġexpression : ĠExpr ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Literal Ġ Ġ-> Ġval Ġvalue : ĠAny ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Unary ĠĠĠ Ġ-> Ġval Ġoperator : ĠToken , Ġprivate Ġval Ġright : ĠExpr " ĊĠĠĠ Ġ)) Ċ } Ċ Ċ /** Ċ Ġ* ĠHelper Ġclass Ġfor Ġgenerating ĠAST Ġtypes Ċ Ġ*/ Ċ class ĠGenerate Ast Ġ{ ĊĠĠĠ Ġfun Ġdefine Ast ( output Dir : ĠString , Ġbase Name : ĠString , Ġtypes : ĠList < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpath Ġ= Ġ"$ output Dir /$ base Name . kt " ĊĠĠĠĠĠĠĠ Ġval Ġwriter Ġ= ĠPrintWriter ( path , Ġ" UTF - 8 ") ĊĊĠĠĠĠĠĠĠ Ġwriter . println (" package Ġcom . save kir k . lox ") ĊĠĠĠĠĠĠĠ Ġwriter . println ("") ĊĠĠĠĠĠĠĠ Ġwriter . println (" abstract Ġclass Ġ$ base Name Ġ{ ") ĊĊĠĠĠĠĠĠĠ Ġdefine Visitor ( writer , Ġbase Name , Ġtypes ) ĊĊĠĠĠĠĠĠĠ Ġ// ĠThe ĠAST Ġclasses ĊĠĠĠĠĠĠĠ Ġfor Ġ( type Ġin Ġtypes ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠclassName Ġ= Ġtype . split (" -> ")[ 0 ]. trim () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfields Ġ= Ġtype . split (" -> ")[ 1 ]. trim () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefine Type ( writer , Ġbase Name , ĠclassName , Ġfields ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwriter . println ("") ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠ Ġabstract Ġfun Ġ< R > Ġaccept ( visitor : ĠVisitor < R >): ĠR ") ĊĠĠĠĠĠĠĠ Ġwriter . println (" }") ĊĠĠĠĠĠĠĠ Ġwriter . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdefine Visitor ( writer : ĠPrintWriter , Ġbase Name : ĠString , Ġtypes : ĠList < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠ Ġinterface ĠVisitor < out ĠR > Ġ{ ") ĊĊĠĠĠĠĠĠĠ Ġtypes ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . split (" -> ")[ 0 ]. trim () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġwriter . println (" ĠĠĠĠĠĠĠ Ġfun Ġvisit $ it $ base Name (${ base Name . toLowerCase ()} : Ġ$ it ): ĠR ") Ġ} ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠ Ġ} ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdefine Type ( writer : ĠPrintWriter , Ġbase Name : ĠString , ĠclassName : ĠString , Ġfield List : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwriter . println ("") ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠ Ġclass Ġ$ className ($ field List ) Ġ: Ġ$ base Name () Ġ{ ") ĊĠĠĠĠĠĠĠ Ġwriter . println ("") ĊĊĠĠĠĠĠĠĠ Ġ// ĠVisitor ĠPattern ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠĠĠĠĠ Ġoverride Ġfun Ġ< R > Ġaccept ( visitor : ĠVisitor < R >): ĠR Ġ{ ") ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠĠĠĠĠĠĠ Ġreturn Ġvisitor . visit $ className $ base Name ( this )") ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠĠĠĠĠ Ġ} ") ĊĠĠĠĠĠĠĠ Ġwriter . println (" ĠĠĠ Ġ} ") ĊĠĠĠ Ġ} ĊĊ Ċ }