package Ġinterpreter Ċ Ċ import Ġlexer . Token Ċ import Ġlexer . TokenType Ċ import Ġlo x . L ox Call Error Ċ import Ġlo x . L ox RuntimeError Ċ import Ġlo x . isEqual Ċ import Ġlo x . is Truthy Ċ import Ġparser .* Ċ import Ġjava . util .* Ċ import Ġkotlin . collections . ArrayList Ċ import Ġkotlin . collections . set Ċ import Ġkotlin . math . pow Ċ import Ġkotlin . reflect . K Function 1 Ċ Ċ private Ġfun Ġcheck Ints Oper ands ( operator : ĠToken , Ġvar arg Ġoperands : ĠAny ?) Ġ{ ĊĠĠĠ Ġfor Ġ( operand Ġin Ġoperands ) ĊĠĠĠĠĠĠĠ Ġif Ġ( operand Ġ! is ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( operator , Ġ" Oper ands Ġmust Ġbe Ġints .") Ċ } Ċ Ċ private Ġfun Ġcheck Number Oper ands ( operator : ĠToken , Ġvar arg Ġoperands : ĠAny ?) Ġ{ ĊĠĠĠ Ġfor Ġ( operand Ġin Ġoperands ) ĊĠĠĠĠĠĠĠ Ġif Ġ( operand Ġ! is ĠDouble Ġ&& Ġoperand Ġ! is ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( operator , Ġ" Oper ands Ġmust Ġbe Ġints Ġor Ġfloats .") Ċ } ĊĊ Ċ // ĠThis Ġexception Ġis Ġused Ġwhen Ġreturning Ġfrom Ġa Ġfunction Ġin Ġlo x Ċ data Ġclass ĠL ox ReturnValue ( val Ġvalue : ĠAny ?) Ġ: ĠRuntimeException () ĊĊ Ċ class ĠL ox Interpreter ( val Ġinterpreter Error Reporter : ĠK Function 1 < L ox RuntimeError , ĠUnit >) Ġ: ĊĠĠĠ ĠInterpreter < Any ?> Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġglobal Scope : ĠScope Ġ= ĠScope () ĊĊĠĠĠ Ġ// ĠDefine Ġbuiltin Ġfunctions ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" print ", ĠL ox Print Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" clock ", ĠL ox Clock Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" readline ", ĠL ox ReadLine Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" int ", ĠL ox Int Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" float ", ĠL ox Float Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" str ", ĠL ox Str Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" type ", ĠL ox Type Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" len ", ĠL ox Len Function ) ĊĠĠĠĠĠĠĠ Ġglobal Scope . define (" list ", ĠL ox List Instance . New List ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠInitialize Ġthe Ġinterpreter 's Ġfirst Ġscope Ġto Ġbe Ġthe Ġglobal Ġscope ĊĠĠĠ Ġprivate Ġvar Ġcurrent Scope : ĠScope Ġ= Ġglobal Scope ĊĊĠĠĠ Ġ// ĠMapping Ġof Ġexpressions Ġto Ġscope Ġdepth s Ġ( how Ġmany Ġjumps Ġto Ġdo Ġin Ġscope Ġstack Ġto Ġfind Ġthe Ġintended Ġexpression ) ĊĠĠĠ Ġprivate Ġval Ġlocals : ĠMutable Map < Expression , ĠInt > Ġ= ĠHashMap () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġis Ġused Ġby Ġthe Ġresolver . ĠWhen Ġthe Ġinterpreter Ġstarts Ġto Ġinterpret , Ġ( after Ġthe Ġresolver Ġfinishes ), Ġthe Ġ' locals ' Ġhash map Ġis Ġfilled Ġwith Ġvalues Ġfor Ġevery Ġexpression ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġresolve ( expr : ĠExpression , Ġscope Depth : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlocals [ expr ] Ġ= Ġscope Depth ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInter pret Ġa Ġlist Ġof Ġstatements ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġinterpret ( statements : ĠList < Stmt >) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( statement Ġin Ġstatements ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute ( statement ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠL ox RuntimeError ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinterpreter Error Reporter ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExecute Ġa Ġstatement ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġexecute ( statement : ĠStmt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstatement . interpret By ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEvaluate Ġan Ġexpression ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġeval ( expr : ĠExpression ): ĠAny ? Ġ= Ġexpr . interpret By ( this ) ĊĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Unary Expr ( expr : ĠUnary Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġright Value : ĠAny ? Ġ= Ġeval ( expr . right Expr ) ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( expr . operator . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . MINUS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( right Value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠInt Ġ-> Ġ- right Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDouble Ġ-> Ġ- right Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" check Number Operand Ġshould Ġhave Ġthrown Ġa Ġruntime Ġexception ...") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . B ANG Ġ-> Ġ! is Truthy ( right Value ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ NOT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . operator , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( right Value Ġas ĠInt ). inv () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" This Ġthrows Ġan Ġerror ĠTODO Ġcheck Ġlater Ġwhat Ġshould ĠI Ġdo Ġhere ") Ġ// ĠTODO Ġi Ġam Ġpretty Ġsure Ġwe Ġneed Ġto Ġerror () Ġhere ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Binary Expr ( expr : ĠBinary Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġleft Value : ĠAny ? Ġ= Ġeval ( expr . left Expr ) ĊĠĠĠĠĠĠĠ Ġval Ġright Value : ĠAny ? Ġ= Ġeval ( expr . right Expr ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( expr . operator . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠArithmetic Ġ( and Ġstring Ġconcat enation ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PLUS Ġ-> Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠString Ġconcat enation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠString Ġ&& Ġright Value Ġis ĠString Ġ-> Ġleft Value Ġ+ Ġright Value ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn ts Ġ/ ĠDouble s ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMake Ġsure Ġwe Ġare Ġdealing Ġwith ĠIn ts Ġ/ ĠDouble s ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠL ox RuntimeError ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpr . operator , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Operator Ġ+ Ġnot Ġused Ġcorrectly ( can Ġonly Ġadd Ġtwo Ġnumbers , Ġor Ġtwo Ġstrings ): Ġ{$ left Value } Ġ+ Ġ{$ right Value }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġone Ġis Ġof Ġthe Ġoperands Ġis Ġdouble , Ġcast Ġresult Ġto Ġdouble ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ+ Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġany Ġother Ġcase , Ġboth Ġare Ġint , Ġso Ġcast Ġthe Ġresult Ġto Ġint ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ+ Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . MINUS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ- Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ- Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . STAR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ* Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ* Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PERCENT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ% Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ% Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . SL ASH Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( right Value Ġas ĠNumber Ġ== Ġ 0 . 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expr . operator , Ġ" Division Ġby Ġzero !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ/ Ġright Value . toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ/ Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . DOUBLE _ STAR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ|| Ġ( right Value Ġas ĠInt ) Ġ< Ġ 0 Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. pow (( right Value Ġas ĠNumber ). toDouble ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ(( left Value Ġas ĠInt ). toDouble ()). pow ( right Value . toDouble ()). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBit wise Ġexpressions ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ OR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( left Value Ġas ĠInt ) Ġor Ġ( right Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ XOR Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( left Value Ġas ĠInt ) Ġxor Ġ( right Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ AND Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( left Value Ġas ĠInt ) Ġand Ġ( right Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ SHIFT _ LEFT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( left Value Ġas ĠInt ) Ġshl Ġ( right Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ SHIFT _ RIGHT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( left Value Ġas ĠInt ) Ġshr Ġ( right Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLogic Ġexpressions ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . EQUAL _ EQUAL Ġ-> Ġis Equal ( left Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . B ANG _ EQUAL Ġ-> Ġ! isEqual ( left Value , Ġright Value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . GRE ATER Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ> Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ> Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . GRE ATER _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ>= Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ>= Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . LESS Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ< Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ( left Value Ġas ĠInt ) Ġ< Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . LESS _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . operator , Ġleft Value , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġleft Value Ġis ĠDouble Ġ|| Ġright Value Ġis ĠDouble Ġ-> Ġ( left Value Ġas ĠNumber ). toDouble () Ġ<= Ġ( right Value Ġas ĠNumber ). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġleft Value Ġas ĠInt Ġ<= Ġright Value Ġas ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Something Ġunexpected Ġhappened .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Grouping Expr ( expr : ĠGroup ing Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġeval ( expr . expression ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Square Br ackets Expr ( expression : ĠSquare Br ackets Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠL ox List Instance (). apply Ġ{ Ġlist . addAll ( expression . arguments . map Ġ{ Ġt Ġ-> Ġeval ( t ) Ġ}) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Set Square Br ackets Expression ( expression : ĠSet Square Br ackets Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcal lee Ġ= Ġeval ( expression . callee ) ĊĠĠĠĠĠĠĠ Ġif Ġ( callee Ġ! is ĠL ox List Instance ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expression . paren , Ġ" Can Ġonly Ġset Ġwith Ġsquare Ġbrackets Ġon Ġlists ") ĊĊĠĠĠĠĠĠĠ Ġval Ġargs Ġ= Ġexpression . arguments . map Ġ{ Ġeval ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġeval ( expression . value ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( args . size Ġ!= Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expression . paren , Ġ" Currently , Ġsquare Ġbrackets Ġnotation Ġonly Ġsupports Ġ 1 Ġargument .") ĊĠĠĠĠĠĠĠ Ġcal lee . set At ( args [ 0 ], Ġvalue ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Literal Expr ( expr : ĠLiteral Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġexpr . value ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Fun Stmt ( stmt : ĠFun Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfunctions Ġ= ĠL ox Function ( stmt , Ġcurrent Scope ) ĊĠĠĠĠĠĠĠ Ġcurrent Scope . define ( stmt . name . lex eme , Ġfunctions ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Expression Stmt ( stmt : ĠExpression Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġeval ( stmt . expression ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Var Stmt ( stmt : ĠVar Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġvalue : ĠAny ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( stmt . initializer Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġeval ( stmt . initializer ) ĊĊĠĠĠĠĠĠĠ Ġcurrent Scope . define ( stmt . name . lex eme , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Variable Expression ( expr : ĠVariable Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġlookup Variable ( expr . name , Ġexpr ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlookup Variable ( name : ĠToken , Ġexpr : ĠExpression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdepth Ġ= Ġlocals [ expr ] ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( depth Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġglobal Scope . get ( name ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope . get At ( depth , Ġname . lex eme ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Return Stmt ( stmt : ĠReturn Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġret Value Ġ= Ġwhen Ġ( stmt . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġeval ( stmt . value ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠReturn Ġthe Ġvalue Ġto Ġthe Ġcalling Ġfunction ĊĠĠĠĠĠĠĠ Ġthrow ĠL ox ReturnValue ( ret Value ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Assignment Expression ( expr : ĠAssignment Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġright Value Ġ= Ġeval ( expr . value ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( val Ġdepth Ġ= Ġlocals [ expr ]) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġwhen Ġ( expr . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġglobal Scope . assign ( expr . name , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PLUS _ EQUAL , ĠTokenType . MINUS _ EQUAL , ĠTokenType . STAR _ EQUAL , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . SL ASH _ EQUAL , ĠTokenType . DOUBLE _ STAR _ EQUAL , ĠTokenType . PERCENT _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Val Ġ= Ġglobal Scope . get ( expr . name ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMake Ġsure Ġwe Ġare Ġdealing Ġwith Ġnumbers ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . name , Ġcurrent Val , Ġright Value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewVal Ġ= ĠnewVal Number Operation ( expr . type , Ġcurrent Val Ġas ĠNumber , Ġright Value Ġas ĠNumber ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġglobal Scope . assign ( expr . name , ĠnewVal ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewVal ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBit Ġoperations ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ OR _ EQUAL , ĠTokenType . BIT _ XOR _ EQUAL , ĠTokenType . BIT _ AND _ EQUAL , ĠTokenType . BIT _ SHIFT _ LEFT _ EQUAL , ĠTokenType . BIT _ SHIFT _ RIGHT _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Val Ġ= Ġglobal Scope . get ( expr . name ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġbits Ġoperations , Ġmake Ġsure Ġwe Ġare Ġdealing Ġwith Ġints ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . name , Ġcurrent Val , Ġright Value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewVal Ġ= ĠnewVal Bit Operation ( expr . type , Ġcurrent Val Ġas ĠInt , Ġright Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġglobal Scope . assign ( expr . name , ĠnewVal ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewVal ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unexpected Ġoperation ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdepth Ġ!= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġwhen Ġ( expr . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope . assign At ( depth , Ġexpr . name , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PLUS _ EQUAL , ĠTokenType . MINUS _ EQUAL , ĠTokenType . STAR _ EQUAL , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . SL ASH _ EQUAL , ĠTokenType . DOUBLE _ STAR _ EQUAL , ĠTokenType . PERCENT _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Val Ġ= Ġcurrent Scope . get At ( depth , Ġexpr . name . lex eme ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMake Ġsure Ġwe Ġare Ġdealing Ġwith Ġnumbers ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . name , Ġcurrent Val , Ġright Value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewVal Ġ= ĠnewVal Number Operation ( expr . type , Ġcurrent Val Ġas ĠNumber , Ġright Value Ġas ĠNumber ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope . assign At ( depth , Ġexpr . name , ĠnewVal ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewVal ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ OR _ EQUAL , ĠTokenType . BIT _ XOR _ EQUAL , ĠTokenType . BIT _ AND _ EQUAL , ĠTokenType . BIT _ SHIFT _ LEFT _ EQUAL , ĠTokenType . BIT _ SHIFT _ RIGHT _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBit Ġoperations ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Val Ġ= Ġcurrent Scope . get At ( depth , Ġexpr . name . lex eme ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġbits Ġoperations , Ġmake Ġsure Ġwe Ġare Ġdealing Ġwith Ġints ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . name , Ġcurrent Val , Ġright Value ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewVal Ġ= ĠnewVal Bit Operation ( expr . type , Ġcurrent Val Ġas ĠInt , Ġright Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope . assign At ( depth , Ġexpr . name , ĠnewVal ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewVal ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unexpected Ġoperation ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠnewVal Number Operation ( type : ĠTokenType , Ġcurrent Val : ĠNumber , Ġright Value : ĠNumber ): ĠNumber Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PLUS _ EQUAL Ġ-> Ġif Ġ( current Val Ġis ĠInt Ġ&& Ġright Value Ġis ĠInt ) Ġcurrent Val Ġ+ Ġright Value Ġelse Ġcurrent Val . toDouble () Ġ+ Ġright Value . toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . MINUS _ EQUAL Ġ-> Ġif Ġ( current Val Ġis ĠInt Ġ&& Ġright Value Ġis ĠInt ) Ġcurrent Val Ġ- Ġright Value Ġelse Ġcurrent Val . toDouble () Ġ- Ġright Value . toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . STAR _ EQUAL Ġ-> Ġif Ġ( current Val Ġis ĠInt Ġ&& Ġright Value Ġis ĠInt ) Ġcurrent Val Ġ* Ġright Value Ġelse Ġcurrent Val . toDouble () Ġ* Ġright Value . toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . SL ASH _ EQUAL Ġ-> Ġif Ġ( current Val Ġis ĠInt Ġ&& Ġright Value Ġis ĠInt ) Ġcurrent Val Ġ/ Ġright Value Ġelse Ġcurrent Val . toDouble () Ġ/ Ġright Value . toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PERCENT _ EQUAL Ġ-> Ġif Ġ( current Val Ġis ĠInt Ġ&& Ġright Value Ġis ĠInt ) Ġcurrent Val Ġ% Ġright Value Ġelse Ġcurrent Val . toDouble () Ġ% Ġright Value . toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . DOUBLE _ STAR _ EQUAL Ġ-> Ġcurrent Val . toDouble (). pow ( right Value . toDouble ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unexpected Ġoperation ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠnewVal Bit Operation ( ĊĠĠĠĠĠĠĠ Ġtype : ĠTokenType , ĊĠĠĠĠĠĠĠ Ġcurrent Val : ĠInt , ĊĠĠĠĠĠĠĠ Ġright Value : ĠInt ĊĠĠĠ Ġ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ OR _ EQUAL Ġ-> Ġcurrent Val Ġor Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ XOR _ EQUAL Ġ-> Ġcurrent Val Ġxor Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ AND _ EQUAL Ġ-> Ġcurrent Val Ġand Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ SHIFT _ LEFT _ EQUAL Ġ-> Ġcurrent Val Ġshl Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ SHIFT _ RIGHT _ EQUAL Ġ-> Ġcurrent Val Ġshr Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unexpected Ġoperation ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Logical Expr ( expr : ĠLogical Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġleft Value Ġ= Ġeval ( expr . left Expr ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( expr . operator . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . OR Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Truthy ( left Value )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġleft Value ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . AND Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Truthy ( left Value )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġleft Value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unknown Ġlogical Ġexpression ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġeval ( expr . right Expr ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Block Stmt ( stmt : ĠBlock Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġexecute Block ( stmt . statements , ĠScope ( current Scope )) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġexecute Block ( statements : ĠList < Stmt >, Ġscope : ĠScope ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprevious Ġ= Ġcurrent Scope ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= Ġscope ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( statement Ġin Ġstatements ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute ( statement ) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . current Scope Ġ= Ġprevious ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret If Stmt ( stmt : ĠIf Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Truthy ( eval ( stmt . condition ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecute ( stmt . then Branch ) ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ( stmt . else Branch Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecute ( stmt . else Branch ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Call Expression ( expr : ĠCall Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcal lee Ġ= Ġeval ( expr . callee ) ĊĠĠĠĠĠĠĠ Ġval Ġarguments : ĠMutable List < Any ?> Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠ Ġfor Ġ( arg Ġin Ġexpr . arguments ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarguments Ġ+= Ġeval ( arg ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( callee ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠL ox List Instance Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcal lee . get At ( arguments [ 0 ]) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( callee Ġ! is ĠL ox Callable ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expr . paren , Ġ" Can Ġonly Ġcall Ġfunctions Ġand Ġclasses .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( arguments . size Ġ!= Ġcal lee . arity ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpr . paren , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Expected Ġ${ callee . arity } Ġarguments Ġbut Ġgot Ġ${ arguments . size } Ġ. " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcal lee . call ( this , Ġarguments ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠL ox Call Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expr . paren , Ġe . msg ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret While Stmt ( stmt : ĠWhile Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( is Truthy ( eval ( stmt . condition ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecute ( stmt . body ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Class Stmt ( stmt : ĠClass Statement ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġsuperclass : ĠAny ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġif Ġ( stmt . super class Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuperclass Ġ= Ġeval ( stmt . super class ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( super class Ġ! is ĠL ox Class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( stmt . super class . name , Ġ" Super class Ġmust Ġbe Ġa Ġclass .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcurrent Scope . define ( stmt . name . lex eme , Ġnull ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( stmt . super class Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= ĠScope ( current Scope ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope . define (" super ", Ġsuperclass ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġmethods : ĠMutable Map < String , ĠL ox Function > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġfor Ġ( method Ġin Ġstmt . methods ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfunction Ġ= ĠL ox Function ( method , Ġcurrent Scope , Ġmethod . name . lex eme Ġ== Ġ" init ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmethods [ method . name . lex eme ] Ġ= Ġfunction ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġlo x Class Ġ= ĠL ox Class ( stmt . name . lex eme , Ġsuperclass Ġas ĠL ox Class ?, Ġmethods ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( super class Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Scope Ġ= Ġcurrent Scope . enc lo sing Scope Ġ?: Ġerror (" Unexpected . ĠThis Ġshould Ġnot Ġever Ġbe Ġnull .") ĊĊĠĠĠĠĠĠĠ Ġcurrent Scope . assign ( stmt . name , Ġlo x Class ) ĊĠĠĠĠĠĠĠ Ġreturn ĠUnit ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Get Expression ( expr : ĠGet Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlo x Object Ġ= Ġeval ( expr . lox Object ) ĊĠĠĠĠĠĠĠ Ġif Ġ( lox Object Ġis ĠL ox Instance Base ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlo x Object . get ( expr . name ) ĊĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expr . name , Ġ" Only Ġinstances Ġhave Ġproperties .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Set Expression ( expr : ĠSet Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlo x Object Ġ= Ġeval ( expr . lox Object ) ĊĠĠĠĠĠĠĠ Ġif Ġ( lox Object Ġ! is ĠL ox Instance Base ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠL ox RuntimeError ( expr . name , Ġ" Only Ġinstances Ġhave Ġfields .") ĊĊĠĠĠĠĠĠĠ Ġval Ġright Value Ġ= Ġeval ( expr . value ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcurrent Val Ġ= Ġif Ġ( expr . type Ġ!= ĠTokenType . EQUAL ) Ġlo x Object . get ( expr . name ) Ġelse Ġnull ĊĊĠĠĠĠĠĠĠ Ġval ĠnewVal Ġ= Ġwhen Ġ( expr . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . EQUAL Ġ-> Ġright Value ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . PLUS _ EQUAL , ĠTokenType . MINUS _ EQUAL , ĠTokenType . STAR _ EQUAL , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . SL ASH _ EQUAL , ĠTokenType . DOUBLE _ STAR _ EQUAL , ĠTokenType . PERCENT _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMake Ġsure Ġwe Ġare Ġdealing Ġwith Ġnumbers ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Number Oper ands ( expr . name , Ġcurrent Val , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewVal Number Operation ( expr . type , Ġcurrent Val Ġas ĠNumber , Ġright Value Ġas ĠNumber ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBit Ġoperations ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTokenType . BIT _ OR _ EQUAL , ĠTokenType . BIT _ XOR _ EQUAL , ĠTokenType . BIT _ AND _ EQUAL , ĠTokenType . BIT _ SHIFT _ LEFT _ EQUAL , ĠTokenType . BIT _ SHIFT _ RIGHT _ EQUAL Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġbits Ġoperations , Ġmake Ġsure Ġwe Ġare Ġdealing Ġwith Ġints ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ints Oper ands ( expr . name , Ġcurrent Val , Ġright Value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠnewVal Bit Operation ( expr . type , Ġcurrent Val Ġas ĠInt , Ġright Value Ġas ĠInt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unexpected Ġoperation ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlo x Object . set ( expr . name , ĠnewVal ) ĊĠĠĠĠĠĠĠ Ġreturn ĠnewVal ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret This Expression ( expr : ĠThis Expression ): ĠAny ? Ġ= Ġlookup Variable ( expr . keyword , Ġexpr ) ĊĊĠĠĠ Ġoverride Ġfun Ġinterpret Super Expression ( expr : ĠSuper Expression ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdepth Ġ= Ġlocals . getValue ( expr ) ĊĊĠĠĠĠĠĠĠ Ġval Ġsuperclass Ġ= Ġcurrent Scope . get At ( depth , Ġ" super ") Ġas ĠL ox Class ĊĠĠĠĠĠĠĠ Ġval Ġlo x Instance Ġ= Ġcurrent Scope . get At ( depth Ġ- Ġ 1 , Ġ" this ") Ġas ĠL ox Instance ĊĠĠĠĠĠĠĠ Ġval Ġmethod Ġ= Ġsuperclass . find Method ( expr . method . lex eme ) Ġ?: Ġthrow ĠL ox RuntimeError ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpr . method , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Undefined Ġproperty Ġ'${ expr . method . lex eme }'. " ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġmethod . bind ( lox Instance ) ĊĠĠĠ Ġ} Ċ }