// ĠCopyright Ġ 2 0 2 0 ĠAndrew ĠSh ul ae v Ċ // Ġ Ċ // Ġ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 . Ċ Ċ import Ġjava . lang . RuntimeException Ċ Ċ abstract Ġclass ĠBuiltin Function ( ĊĠĠĠĠĠĠĠ Ġval Ġname : ĠString Ċ ) Ġ{ ĊĠĠĠ Ġabstract Ġfun Ġeval ( args : ĠList < Int >, Ġheap : ĠHeap ): ĠInt ĊĊĠĠĠ Ġabstract Ġfun Ġtype check ( nodeId : ĠInt , Ġargs : ĠList < Typed Node >): ĠType Ċ } Ċ Ċ data Ġclass ĠTyped Node ( ĊĠĠĠĠĠĠĠ Ġval ĠnodeId : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġtype : ĠType Ċ ) Ċ Ċ object ĠList Get : ĠBuiltin Function (" get ") Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġeval ( args : ĠList < Int >, Ġheap : ĠHeap ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlist Ġ= Ġheap . items [ args [ 0 ]] Ġas ĠList Value ĊĠĠĠĠĠĠĠ Ġreturn Ġlist . items [ args [ 1 ]] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtype check ( nodeId : ĠInt , Ġargs : ĠList < Typed Node >): ĠType Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( args . size Ġ!= Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( nodeId , Ġ"$ name Ġtakes Ġtwo Ġarguments ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġargs [ 0 ] ĊĠĠĠĠĠĠĠ Ġif Ġ( first . type Ġ! is ĠList Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( first . nodeId , Ġ" first Ġargument Ġof Ġ$ name Ġshould Ġbe Ġa Ġlist ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsecond Ġ= Ġargs [ 1 ] ĊĠĠĠĠĠĠĠ Ġif Ġ( second . type Ġ! is ĠInt Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( second . nodeId , Ġ" second Ġargument Ġof Ġ$ name Ġshould Ġbe Ġan Ġinteger ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfirst . type . elem ĊĠĠĠ Ġ} Ċ } Ċ Ċ object ĠVm Step : ĠBuiltin Function (" step ") Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġeval ( args : ĠList < Int >, Ġheap : ĠHeap ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarg Ġ= Ġheap . items [ args [ 0 ]] Ġas ĠChild Vm Value ĊĠĠĠĠĠĠĠ Ġarg . vm . step () ĊĠĠĠĠĠĠĠ Ġreturn Ġarg . vm . is Done (). as Int () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtype check ( nodeId : ĠInt , Ġargs : ĠList < Typed Node >): ĠType Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( args . size Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( nodeId , Ġ"$ name Ġtakes Ġone Ġparameter ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġargs [ 0 ] ĊĠĠĠĠĠĠĠ Ġif Ġ( first . type Ġ! is ĠVm Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( first . nodeId , Ġ" first Ġargument Ġof Ġstep Ġshould Ġbe Ġchild ĠVM ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠBool Type ĊĠĠĠ Ġ} Ċ } Ċ Ċ object ĠVm Extract : ĠBuiltin Function (" extract ") Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġeval ( args : ĠList < Int >, Ġheap : ĠHeap ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarg Ġ= Ġheap . items [ args [ 0 ]] Ġas ĠChild Vm Value ĊĠĠĠĠĠĠĠ Ġif Ġ(! arg . vm . is Done ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException (" try ing Ġto Ġextract Ġvalue Ġbefore Ġit 's Ġfinished ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( arg . vm . stack . size () Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException (" finished Ġstack Ġshould Ġcontain Ġonly Ġone Ġvalue ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġarg . vm . stack [ 0 ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtype check ( nodeId : ĠInt , Ġargs : ĠList < Typed Node >): ĠType Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( args . size Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( nodeId , Ġ"$ name Ġtakes Ġone Ġparameter ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġargs [ 0 ] ĊĠĠĠĠĠĠĠ Ġif Ġ( first . type Ġ! is ĠVm Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( first . nodeId , Ġ" first Ġargument Ġof Ġ$ name Ġshould Ġbe Ġchild ĠVM ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfirst . type . elem ĊĠĠĠ Ġ} Ċ } Ċ Ċ object ĠVm Stack : ĠBuiltin Function (" stack ") Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġeval ( args : ĠList < Int >, Ġheap : ĠHeap ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarg Ġ= Ġheap . items [ args [ 0 ]] Ġas ĠChild Vm Value ĊĠĠĠĠĠĠĠ Ġval Ġstack Ġ= Ġarg . vm . stack ĊĠĠĠĠĠĠĠ Ġval Ġstack Copy Ġ= Ġ( 0 Ġuntil Ġstack . size ()). map Ġ{ Ġstack [ it ] Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġheap . put ( List Value ( stack Copy )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtype check ( nodeId : ĠInt , Ġargs : ĠList < Typed Node >): ĠType Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( args . size Ġ!= Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( nodeId , Ġ"$ name Ġtakes Ġone Ġparameter ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġargs [ 0 ] ĊĠĠĠĠĠĠĠ Ġif Ġ( first . type Ġ! is ĠVm Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠTyp ing Failure ( first . nodeId , Ġ" first Ġargument Ġof Ġ$ name Ġshould Ġbe Ġchild ĠVM ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠList Type ( Int Type ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ val Ġbuiltins : ĠList < Builtin Function > Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ ĠList Get , ĊĠĠĠĠĠĠĠ ĠVm Step , ĊĠĠĠĠĠĠĠ ĠVm Extract , ĊĠĠĠĠĠĠĠ ĠVm Stack Ċ ) Ċ Ċ val Ġbuiltin ByName Ġ= Ġbuiltins . map Ġ{ Ġit . name Ġto Ġit Ġ}. toMap () Ċ