/* Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠMIT Ġlicense Ġthat Ġcan Ġbe Ċ Ġ* Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . rust . lang . utils . evaluation Ċ Ċ import Ġorg . rust . lang . core . psi .* Ċ import Ġorg . rust . lang . core . psi . ext .* Ċ import Ġorg . rust . lang . core . types . ty . Ty Ċ import Ġorg . rust . lang . core . types . ty . Ty Integer Ċ import Ġorg . rust . lang . core . types . ty . Ty Primitive Ċ import Ġorg . rust . lang . core . types . type Ċ Ċ object ĠRs Const Expr Evaluator Ġ{ ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ EXPR _ DEPTH : ĠInt Ġ= Ġ 6 4 ĊĊĠĠĠ Ġprivate Ġval Ġdefault Expr Path Resolver : Ġ( Rs Path Expr ) Ġ-> ĠRs Element ? Ġ= Ġ{ Ġit . path . reference . resolve () Ġ} ĊĊĠĠĠ Ġfun Ġevaluate ( ĊĠĠĠĠĠĠĠ Ġexpr : ĠRs Expr , ĊĠĠĠĠĠĠĠ Ġexpected Ty : ĠTy Ġ= Ġexpr . type , ĊĠĠĠĠĠĠĠ Ġpath Expr Resolver : Ġ(( Rs Path Expr ) Ġ-> ĠRs Element ?) Ġ= Ġdefault Expr Path Resolver ĊĠĠĠ Ġ): ĠExpr Value ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( expected Ty ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠTy Integer Ġ-> Ġevaluate Integer ( expr , Ġexpected Ty , Ġpath Expr Resolver ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkind Ġ= Ġ( expr Ġas ? ĠRs Lit Expr )?. kind ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( kind ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Literal Kind . Boolean Ġ-> ĠExpr Value . Bool ( kind . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Literal Kind . Float Ġ-> ĠExpr Value . Float ( kind . value Ġ?: Ġreturn Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Literal Kind . String Ġ-> ĠExpr Value . Str ( kind . value Ġ?: Ġreturn Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Literal Kind . Char Ġ-> ĠExpr Value . Char ( kind . value Ġ?: Ġreturn Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġevaluate Integer ( ĊĠĠĠĠĠĠĠ Ġexpr : ĠRs Expr , ĊĠĠĠĠĠĠĠ Ġexpected Ty : ĠTy Integer , ĊĠĠĠĠĠĠĠ Ġpath Expr Resolver : Ġ(( Rs Path Expr ) Ġ-> ĠRs Element ?) ĊĠĠĠ Ġ): ĠExpr Value . Integer ? Ġ{ ĊĊĠĠĠĠĠĠĠ Ġfun ĠRs Lit Expr . eval ( expected Ty : ĠTy Integer ): ĠLong ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtext Value Ġ= Ġinteger Literal Value ?. remove Suffix ( expected Ty . name ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( start , Ġradix ) Ġ= Ġwhen Ġ( text Value . take ( 2 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" 0 x " Ġ-> Ġ 2 Ġto Ġ 1 6 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" 0 o " Ġ-> Ġ 2 Ġto Ġ 8 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" 0 b " Ġ-> Ġ 2 Ġto Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 0 Ġto Ġ 1 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclean Text Value Ġ= Ġtext Value . substring ( start ). filter Ġ{ Ġit Ġ!= Ġ'_' Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjava . lang . Long . parse Long ( clean Text Value , Ġradix ). valid Value OrNull ( expected Ty ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠNumber FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġeval ( expr : ĠRs Expr ?, Ġdepth : ĠInt ): ĠLong ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTo Ġprevent ĠSO Ġwe Ġrestrict Ġmax Ġdepth Ġof Ġexpression ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( depth Ġ>= ĠMAX _ EXPR _ DEPTH ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( expr ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Lit Expr Ġ-> Ġexpr . eval ( expected Ty ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Path Expr Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconst Ġ= Ġpath Expr Resolver ( expr ) Ġas ? ĠRs Constant Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! const . is Const ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpath Ġ= Ġ( const . type Reference ?. type Element Ġas ? ĠRs BaseType )?. path Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinteger Type Ġ= ĠTy Primitive . from Path ( path ) Ġas ? ĠTy Integer Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( integer Type Ġ== Ġexpected Ty ) Ġeval ( const . expr , Ġdepth Ġ+ Ġ 1 ) Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Paren Expr Ġ-> Ġeval ( expr . expr , Ġdepth Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Unary Expr Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( expr . operator Type Ġ!= ĠUnary Operator . MINUS ) Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġeval ( expr . expr , Ġdepth Ġ+ Ġ 1 ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ(- value ). valid Value OrNull ( expected Ty ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRs Binary Expr Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġop Ġ= Ġexpr . operator Type Ġas ? ĠArithmetic Op Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġleft Value Ġ= Ġeval ( expr . left , Ġdepth Ġ+ Ġ 1 ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġright Value Ġ= Ġeval ( expr . right , Ġdepth Ġ+ Ġ 1 ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġcheck Ġoverflow ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġwhen Ġ( op ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . ADD Ġ-> Ġleft Value Ġ+ Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . SUB Ġ-> Ġleft Value Ġ- Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . MUL Ġ-> Ġleft Value Ġ* Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . DIV Ġ-> Ġif Ġ( right Value Ġ== Ġ 0 L ) Ġnull Ġelse Ġleft Value Ġ/ Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . REM Ġ-> Ġif Ġ( right Value Ġ== Ġ 0 L ) Ġnull Ġelse Ġleft Value Ġ% Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . BIT _ AND Ġ-> Ġleft Value Ġand Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . BIT _ OR Ġ-> Ġleft Value Ġor Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . BIT _ XOR Ġ-> Ġleft Value Ġxor Ġright Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġcan 't Ġsimply Ġconvert Ġ` right Value ` Ġto ĠInt ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbecause Ġafter Ġconversion Ġof Ġquite Ġlarge ĠLong Ġvalues Ġ(> Ġ 2 ^ 3 1 Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġcan Ġget Ġany ĠInt Ġvalue Ġincluding Ġnegative Ġone ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġso Ġit Ġcan Ġlead Ġto Ġincorrect Ġresult . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBut Ġif Ġ` right Value ` Ġ>= Ġ` java . lang . Long . BYTES ` ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġknow Ġresult Ġwithout Ġcomputation : ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġoverflow Ġin Ġ' sh l ' Ġcase Ġand Ġ 0 Ġin Ġ' shr ' Ġcase . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . SH L Ġ-> Ġif Ġ( right Value Ġ>= Ġjava . lang . Long . BYTES ) Ġnull Ġelse Ġleft Value Ġshl Ġright Value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArithmetic Op . SH R Ġ-> Ġif Ġ( right Value Ġ>= Ġjava . lang . Long . BYTES ) Ġ 0 Ġelse Ġleft Value Ġshr Ġright Value . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult ?. valid Value OrNull ( expected Ty ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġeval ( expr , Ġ 0 )?. let ( Expr Value :: Integer ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ // ĠIt Ġreturns Ġwrong Ġvalues Ġfor Ġlarge Ġtypes Ġlike Ġ` i 1 2 8 ` Ġor Ġ` usize ` Ċ // ĠBut Ġlooks Ġlike Ġlike Ġit 's Ġenough Ġfor Ġreal Ġcases Ċ private Ġval ĠTy Integer . valid Values Range : ĠLong Range Ġget () Ġ= Ġwhen Ġ( this ) Ġ{ ĊĠĠĠ ĠTy Integer . U 8 Ġ-> ĠLong Range ( 0 , Ġ 1 L Ġshl Ġ 8 ) ĊĠĠĠ ĠTy Integer . U 1 6 Ġ-> ĠLong Range ( 0 , Ġ 1 L Ġshl Ġ 1 6 ) ĊĠĠĠ ĠTy Integer . U 3 2 Ġ-> ĠLong Range ( 0 , Ġ 1 L Ġshl Ġ 3 2 ) ĊĠĠĠ ĠTy Integer . U 6 4 Ġ-> ĠLong Range ( 0 , ĠLong . MAX _ VALUE ) ĊĠĠĠ ĠTy Integer . U 1 2 8 Ġ-> ĠLong Range ( 0 , ĠLong . MAX _ VALUE ) ĊĠĠĠ ĠTy Integer . U Size Ġ-> ĠLong Range ( 0 , ĠLong . MAX _ VALUE ) ĊĠĠĠ ĠTy Integer . I 8 Ġ-> ĠLong Range (- ( 1 L Ġshl Ġ 7 ), Ġ( 1 L Ġshl Ġ 7 ) Ġ- Ġ 1 ) ĊĠĠĠ ĠTy Integer . I 1 6 Ġ-> ĠLong Range (- ( 1 L Ġshl Ġ 1 5 ), Ġ( 1 L Ġshl Ġ 1 5 ) Ġ- Ġ 1 ) ĊĠĠĠ ĠTy Integer . I 3 2 Ġ-> ĠLong Range (- ( 1 L Ġshl Ġ 3 1 ), Ġ( 1 L Ġshl Ġ 3 1 ) Ġ- Ġ 1 ) ĊĠĠĠ ĠTy Integer . I 6 4 Ġ-> ĠLong Range ( Long . MIN _ VALUE , ĠLong . MAX _ VALUE ) ĊĠĠĠ ĠTy Integer . I 1 2 8 Ġ-> ĠLong Range ( Long . MIN _ VALUE , ĠLong . MAX _ VALUE ) ĊĠĠĠ ĠTy Integer . I Size Ġ-> ĠLong Range ( Long . MIN _ VALUE , ĠLong . MAX _ VALUE ) Ċ } Ċ Ċ private Ġfun ĠLong . valid Value OrNull ( ty : ĠTy Integer ): ĠLong ? Ġ= Ġif Ġ( this Ġin Ġty . valid Values Range ) Ġthis Ġelse Ġnull Ċ