/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠSeb astian ĠK as par i Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġtiny K . frontend . che es y . parser Ċ Ċ import Ġtiny K . ast . Binary Operation Ċ import Ġtiny K . ast . Con junction Node Ċ import Ġtiny K . ast . Dis junction Node Ċ import Ġtiny K . ast . Equality Node Ċ import Ġtiny K . ast . Expression Node Ċ import Ġtiny K . ast . Function Call Node Ċ import Ġtiny K . ast . Identifier Node Ċ import Ġtiny K . ast . Literal Node Ċ import Ġtiny K . ast . Member Access Node Ċ import Ġtiny K . ast . Property Declaration Node Ċ import Ġtiny K . ast . Script Node Ċ import Ġtiny K . ast . Statement Node Ċ import Ġtiny K . ast . metadata . Type Ċ import Ġtiny K . frontend . che es y . scanner . Token Ċ import Ġtiny K . frontend . che es y . scanner . is Add itive Operator Ċ import Ġtiny K . frontend . che es y . scanner . is Call Suffix Ċ import Ġtiny K . frontend . che es y . scanner . is Declaration Ċ import Ġtiny K . frontend . che es y . scanner . is Equality Operator Ċ import Ġtiny K . frontend . che es y . scanner . is Literal Ċ import Ġtiny K . frontend . che es y . scanner . is Member Access Operator Ċ import Ġtiny K . frontend . che es y . scanner . is Multip lic ative Operator Ċ import Ġtiny K . frontend . che es y . scanner . is Post fix Unary Suffix Ċ import Ġtiny K . frontend . che es y . scanner . is Property Declaration Ċ import Ġtiny K . frontend . che es y . util . Token Reader Ċ Ċ /** Ċ Ġ* ĠAn Ġexception Ġthat Ġhappened Ġduring Ġparsing . Ċ Ġ*/ Ċ class ĠParser Exception ( message : ĠString ) Ġ: ĠException ( message ) Ċ Ċ /** Ċ Ġ* ĠA Ġhand - written Ġrecursive Ġde cent Ġparser Ġsupporting Ġa Ġsubset Ġof Ġthe ĠKotlin Ġprogramming Ġlanguage . Ċ Ġ* Ċ Ġ* ĠKotlin ĠGram mar : Ċ Ġ* Ġhttps :// kotlin lang . org / docs / reference / grammar . html Ċ Ġ* Ċ Ġ* ĠKotlin ĠGram mar Ġin ĠAN TLR 4 Ġnotation : Ċ Ġ* Ġhttps :// github . com / Kotlin / kotlin - spec / blob / release / grammar / src / main / antlr / Kotlin Parser . g 4 Ċ Ġ* Ċ Ġ* ĠC lang ĠAST Ġdocs : Ċ Ġ* Ġhttps :// clang . llvm . org / docs / Introduction To The C lang AST . html Ċ Ġ* Ċ Ġ* ĠKotlin ĠP SI : Ċ Ġ* Ġhttps :// github . com / Jet Brains / kotlin / tree / master / compiler / psi / src / org / jetbrains / kotlin / psi Ċ Ġ*/ Ċ class ĠParser Ġ{ ĊĠĠĠ Ġfun Ġparse ( reader : ĠToken Reader ): ĠScript Node Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstatements Ġ= Ġmutable ListOf < Statement Node >() ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( reader . token (). type Ġ!= ĠToken . Type . EOF ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGram mar : Ġshe bang Line ? Ġfile Annotation * Ġpackage Header Ġimport List Ġ( statement Ġsemi )* ĠEOF ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNote : ĠCurrently Ġwe Ġonly Ġparse Ġstatements Ġhere . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatements . add ( reader . statement ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠScript Node ( statements ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠToken Reader . statement (): ĠStatement Node Ġ{ ĊĠĠĠ Ġ// ĠGram mar : Ġ( label Ġ| Ġannotation )* Ġ( declaration Ġ| Ġassignment Ġ| Ġloop Statement Ġ| Ġexpression ) ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġtoken (). is Declaration () Ġ-> Ġdeclaration () ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġexpression () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠToken Reader . declaration (): ĠStatement Node Ġ{ ĊĠĠĠ Ġ// ĠGram mar : Ġclass Declaration Ġ| Ġobject Declaration Ġ| Ġfunction Declaration Ġ| Ġproperty Declaration Ġ| Ġtype Alias ĊĠĠĠ Ġ// ĠNote : ĠCurrently Ġwe Ġonly Ġsupport Ġproperty Declaration Ġat Ġthis Ġlevel . ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġtoken (). is Property Declaration () Ġ-> Ġproperty Declaration () ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠParser Exception (" Unknown Ġdeclaration : Ġ${ token () }") ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠToken Reader . property Declaration (): ĠStatement Node Ġ{ ĊĠĠĠ Ġ// ĠGram mar : ĊĠĠĠ Ġ// ĠĠ Ġ: Ġmodifiers ? Ġ(' val ' Ġ| Ġ' var ') Ġtype Parameters ? ĊĠĠĠ Ġ// ĠĠĠĠ Ġ( receiver Type Ġ'.') ? ĊĠĠĠ Ġ// ĠĠĠĠ Ġ( multi Variable Declaration Ġ| Ġvariable Declaration ) ĊĠĠĠ Ġ// ĠĠĠĠ Ġtype Constraints ? ĊĠĠĠ Ġ// ĠĠĠĠ Ġ( (' =' Ġexpression ) Ġ| Ġproperty Delegate )? Ġ';' ? ĊĠĠĠ Ġ// ĠĠĠĠ Ġ(( getter ? Ġ( semi ? Ġsetter )? ) Ġ| Ġ( setter ? Ġ( semi ? Ġgetter )? )) ĊĊĠĠĠ Ġ// ĠNote : ĠWe Ġonly Ġsupport Ġa Ġsmall Ġsubset Ġof Ġthe Ġproperty Ġdeclaration Ġgrammar Ġhere Ġcurrently . ĊĠĠĠ Ġval Ġimmutable Ġ= Ġwhen Ġ( token And Pro ceed (). type ) Ġ{ ĊĠĠĠĠĠĠĠ ĠToken . Type . VAR Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ ĠToken . Type . VAL Ġ-> Ġtrue ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠParser Exception (" Expected Ġbeginning Ġof Ġproperty Ġdeclaration .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġidentifier Ġ= Ġtoken And Pro ceed ( Token . Type . IDENTIFIER ). value . toString () ĊĊĠĠĠ Ġval Ġtype Ġ= Ġif Ġ( token (). type Ġ== ĠToken . Type . COL ON ) Ġ{ ĊĠĠĠĠĠĠĠ Ġproceed () ĊĊĠĠĠĠĠĠĠ Ġval Ġtype Identifier Ġ= Ġtoken And Pro ceed ( Token . Type . IDENTIFIER ) ĊĠĠĠĠĠĠĠ ĠType . fromString ( type Identifier . value . toString ()) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠType . Unknown ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġexpression Ġ= Ġif Ġ( check Token And Pro ceed ( Token . Type . EQUAL )) Ġ{ ĊĠĠĠĠĠĠĠ Ġexpression () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠProperty Declaration Node ( immutable , Ġidentifier , Ġtype , Ġexpression ) Ċ } Ċ Ċ private Ġfun ĠToken Reader . expression (): ĠExpression Node Ġ{ ĊĠĠĠ Ġreturn Ġdis junction () Ċ } Ċ Ċ private Ġfun ĠToken Reader . dis junction (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// Ġconjunction Ġ(' || ' Ġconjunction )* ĊĠĠĠ Ġvar Ġconjunction Ġ= Ġconjunction () ĊĊĠĠĠ Ġwhile Ġ( token (). type Ġ== ĠToken . Type . DIS J UN CTION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġproceed () ĊĠĠĠĠĠĠĠ Ġconjunction Ġ= ĠDis junction Node ( conj unction , Ġconjunction ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġconjunction Ċ } Ċ Ċ private Ġfun ĠToken Reader . conj unction (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// Ġequality Ġ(' && ' Ġequality )* ĊĠĠĠ Ġvar Ġequality Ġ= Ġequality () ĊĊĠĠĠ Ġwhile Ġ( token (). type Ġ== ĠToken . Type . CONJ UN CTION ) Ġ{ ĊĠĠĠĠĠĠĠ Ġproceed () ĊĠĠĠĠĠĠĠ Ġequality Ġ= ĠCon junction Node ( equality , Ġequality ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġequality Ċ } Ċ Ċ private Ġfun ĠToken Reader . equality (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// Ġcomparison Ġ( equality Operator Ġcomparison )* ĊĠĠĠ Ġvar Ġexpression Ġ= Ġcomparison () ĊĊĠĠĠ Ġwhile Ġ( token (). is Equality Operator ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġequality Operator Ġ= Ġtoken And Pro ceed (). value . toString () ĊĠĠĠĠĠĠĠ Ġexpression Ġ= ĠE quality Node ( expression , Ġequality Operator , Ġcomparison ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġexpression Ċ } Ċ Ċ private Ġfun ĠToken Reader . comparison (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// Ġgeneric Call Like Comparison Ġ( comparison Operator Ġgeneric Call Like Comparison )* ĊĠĠĠ Ġreturn Ġgeneric Call Like Comparison () Ċ } Ċ Ċ private Ġfun ĠToken Reader . generic Call Like Comparison (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// Ġin fix Operation Ġcall Suffix * ĊĊĠĠĠ Ġval Ġoperation Ġ= Ġin fix Operation () ĊĊĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġtoken (). is Call Suffix () Ġ-> Ġreturn ĠFunction Call Node ( operation , Ġcall Suffix ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġoperation Ċ } Ċ Ċ private Ġfun ĠToken Reader . call Suffix (): ĠList < Expression Node > Ġ{ ĊĠĠĠ Ġ// Ġtype Arguments ? Ġvalue Arguments ? Ġannotated Lambda ĊĠĠĠ Ġ// Ġ| Ġtype Arguments ? Ġvalue Arguments ĊĊĠĠĠ Ġ// ĠNote : ĠWe Ġignore Ġ` type Arguments ` Ġand Ġ` annotated Lambda ` Ġfor Ġnow . ĊĠĠĠ Ġreturn Ġvalue Arguments () Ċ } Ċ Ċ private Ġfun ĠToken Reader . value Arguments (): ĠList < Expression Node > Ġ{ ĊĠĠĠ Ġtoken And Pro ceed ( Token . Type . LEFT _ PAREN TH ESIS ) ĊĊĠĠĠ Ġval Ġarguments Ġ= Ġmutable ListOf < Expression Node >() ĊĊĠĠĠ Ġwhile Ġ( token (). type Ġ!= ĠToken . Type . RIGHT _ PAREN TH ESIS Ġ&& Ġtoken (). type Ġ!= ĠToken . Type . EOF ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( arguments . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoken And Pro ceed ( Token . Type . COMMA ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġarguments . add ( expression ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġtoken And Pro ceed ( Token . Type . RIGHT _ PAREN TH ESIS ) ĊĊĠĠĠ Ġreturn Ġarguments Ċ } Ċ Ċ private Ġfun ĠToken Reader . infix Operation (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// ĠGram mar : Ġel vis Expression Ġ(( in Operator Ġel vis Expression ) Ġ| Ġ( is Operator Ġtype ))* ĊĊĠĠĠ Ġ// ĠNote : ĠWe Ġshortcut Ġto Ġadd itive Expression Ġhere . ĊĠĠĠ Ġreturn Ġadd itive Expression () Ċ } Ċ Ċ private Ġfun ĠToken Reader . add itive Expression (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// ĠGram mar : Ġmultip lic ative Expression Ġ( add itive Operator Ġmultip lic ative Expression )* ĊĊĠĠĠ Ġvar Ġexpression Ġ= Ġmultip lic ative Expression () ĊĊĠĠĠ Ġwhile Ġ( token (). is Add itive Operator ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoperator Ġ= Ġtoken And Pro ceed () ĊĊĠĠĠĠĠĠĠ Ġexpression Ġ= ĠBinary Operation ( expression , Ġoperator . value . toString (), Ġmultip lic ative Expression ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġexpression Ċ } Ċ Ċ private Ġfun ĠToken Reader . multip lic ative Expression (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// ĠGram mar : Ġas Expression Ġ( multip lic ative Operator Ġas Expression )* ĊĊĠĠĠ Ġvar Ġexpression Ġ= Ġas Expression () ĊĊĠĠĠ Ġwhile Ġ( token (). is Multip lic ative Operator ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoperator Ġ= Ġtoken And Pro ceed () ĊĊĠĠĠĠĠĠĠ Ġexpression Ġ= ĠBinary Operation ( expression , Ġoperator . value . toString (), Ġas Expression ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġexpression Ċ } Ċ Ċ private Ġfun ĠToken Reader . as Expression (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// ĠNote : ĠWe Ġshortcut Ġto Ġpostfix Unary Expression Ġhere . ĊĠĠĠ Ġreturn Ġpostfix Unary Expression () Ċ } Ċ Ċ private Ġfun ĠToken Reader . postfix Unary Expression (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// ĠĠ Ġ: Ġprimary Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġprimary Expression Ġpostfix Unary Suffix + ĊĊĠĠĠ Ġvar Ġexpression Ġ= Ġprimary Expression () ĊĊĠĠĠ Ġwhile Ġ( token (). is Post fix Unary Suffix ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoken (). is Member Access Operator () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproceed () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpression Ġ= ĠMember Access Node ( expression , Ġidentifier ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġexpression Ċ } Ċ Ċ private Ġfun ĠToken Reader . primary Expression (): ĠExpression Node Ġ{ ĊĠĠĠ Ġ// ĠĠĠ Ġ: Ġparent hesized Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġsimple Identifier ĊĠĠĠ Ġ// ĠĠ Ġ| Ġliteral Constant ĊĠĠĠ Ġ// ĠĠ Ġ| Ġstring Literal ĊĠĠĠ Ġ// ĠĠ Ġ| Ġcallable Reference ĊĠĠĠ Ġ// ĠĠ Ġ| Ġfunction Literal ĊĠĠĠ Ġ// ĠĠ Ġ| Ġobject Literal ĊĠĠĠ Ġ// ĠĠ Ġ| Ġcollection Literal ĊĠĠĠ Ġ// ĠĠ Ġ| Ġthis Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġsuper Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġif Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġwhen Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġtry Expression ĊĠĠĠ Ġ// ĠĠ Ġ| Ġjump Expression ĊĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġtoken (). is Literal () Ġ-> Ġliteral () ĊĠĠĠĠĠĠĠ Ġcheck Token And Pro ceed ( Token . Type . LEFT _ PAREN TH ESIS ) Ġ-> Ġexpression (). also Ġ{ Ġassert And Pro ceed ( Token . Type . RIGHT _ PAREN TH ESIS ) Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġidentifier () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠToken Reader . literal (): ĠLiteral Node Ġ{ ĊĠĠĠ Ġval Ġtoken Ġ= Ġtoken And Pro ceed () ĊĊĠĠĠ Ġreturn Ġwhen Ġ( token . type ) Ġ{ ĊĠĠĠĠĠĠĠ ĠToken . Type . DOUBLE _ LITERAL Ġ-> ĠLiteral Node . Double Literal Node ( token . value Ġas ĠDouble ) ĊĠĠĠĠĠĠĠ ĠToken . Type . FLOAT _ LITERAL Ġ-> ĠLiteral Node . Float Literal Node ( token . value Ġas ĠFloat ) ĊĠĠĠĠĠĠĠ ĠToken . Type . INTEGER _ LITERAL Ġ-> ĠLiteral Node . Integer Literal Node ( token . value Ġas ĠInt ) ĊĠĠĠĠĠĠĠ ĠToken . Type . BOOLEAN _ LITERAL Ġ-> ĠLiteral Node . Boolean Literal Node ( token . value Ġas ĠBoolean ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠParser Exception (" Expected Ġliteral . ĠGot : Ġ$ token ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠToken Reader . identifier (): ĠIdentifier Node Ġ{ ĊĠĠĠ Ġval Ġtoken Ġ= Ġtoken And Pro ceed ( Token . Type . IDENTIFIER ) ĊĠĠĠ Ġreturn ĠIdentifier Node ( token . value . toString ()) Ċ } Ċ