@ file : Opt In ( Experimental Unsigned Types :: class ) Ċ Ċ package Ġorg . mar io ari as . monkey . compiler Ċ Ċ import Ġorg . mar io ari as . monkey . ast .* Ċ import Ġorg . mar io ari as . monkey . code .* Ċ import Ġorg . mar io ari as . monkey . objects .* Ċ Ċ data Ġclass ĠE mitted Instruction ( var Ġop : ĠOpcode Ġ= Ġ 0 u , Ġval Ġposition : ĠInt Ġ= Ġ 0 ) Ċ Ċ data Ġclass ĠCompilation Scope ( ĊĠĠĠ Ġvar Ġinstructions : ĠInstructions Ġ= Ġ ubyte ArrayOf (), ĊĠĠĠ Ġvar Ġlast Instruction : ĠE mitted Instruction Ġ= ĠE mitted Instruction (), ĊĠĠĠ Ġvar Ġprevious Instruction : ĠE mitted Instruction Ġ= ĠE mitted Instruction () Ċ ) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġ=== Ġother ) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( other Ġ! is ĠCompilation Scope ) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! instructions . content Equals ( other . instructions )) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( last Instruction Ġ!= Ġother . last Instruction ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( previous Instruction Ġ!= Ġother . previous Instruction ) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġinstructions . content HashCode () ĊĠĠĠĠĠĠĠ Ġresult Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġlast Instruction . hashCode () ĊĠĠĠĠĠĠĠ Ġresult Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġprevious Instruction . hashCode () ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠM Compiler ( ĊĠĠĠ Ġprivate Ġvar Ġconstants : ĠMutable List < M Object > Ġ= Ġmutable ListOf (), ĊĠĠĠ Ġvar Ġsymbol Table : ĠSymbol Table Ġ= ĠSymbol Table () Ċ ) Ġ{ ĊĠĠĠ Ġvar Ġscopes Ġ= Ġmutable ListOf ( Compilation Scope ()) ĊĠĠĠ Ġvar Ġscope Index Ġ= Ġ 0 ĊĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġbuiltins . forEach Indexed Ġ{ Ġi , Ġ( name , Ġ_) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsymbol Table . define Builtin ( i , Ġname ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ@ Throws ( M Compiler Exception :: class ) ĊĠĠĠ Ġfun Ġcompile ( node : ĠNode ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠProgram Ġ-> Ġnode . statements . forEach ( this :: compile ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠExpression Statement Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . expression !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Pop ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠIn fix Expression Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node . operator Ġ== Ġ"< ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . right !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . left !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op GreaterThan ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . left !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . right !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( node . operator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" +" Ġ-> Ġemit ( Op Add ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"-" Ġ-> Ġemit ( Op Sub ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"*" Ġ-> Ġemit ( Op Mul ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"/" Ġ-> Ġemit ( Op Div ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" >" Ġ-> Ġemit ( Op GreaterThan ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ==" Ġ-> Ġemit ( Op Equal ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"! =" Ġ-> Ġemit ( Op NotEqual ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠM Compiler Exception (" unknown Ġoperator Ġ${ node . operator }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPrefix Expression Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . right !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( node . operator ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" !" Ġ-> Ġemit ( Op Bang ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"-" Ġ-> Ġemit ( Op Minus ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠM Compiler Exception (" unknown Ġoperator Ġ${ node . operator }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠInteger Literal Ġ-> Ġemit ( Op Constant , Ġadd Constant ( M Integer ( node . value ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBoolean Literal Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node . value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op True ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op False ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠIf Expression Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . condition !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjump Not Truthy Pos Ġ= Ġemit ( Op Jump Not Truthy , Ġ 9 9 9 9 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . con sequence !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Last Instruction Pop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Last Pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjump Pos Ġ= Ġemit ( Op Jump , Ġ 9 9 9 9 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġafter Con sequence Pos Ġ= Ġcurrent Instructions (). size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Operand ( jump Not Truthy Pos , Ġafter Con sequence Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node . alternative Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . alternative ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Last Instruction Pop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove Last Pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġafter Alternative Pos Ġ= Ġcurrent Instructions (). size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchange Operand ( jump Pos , Ġafter Alternative Pos ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBlock Statement Ġ-> Ġnode . statements !!. forEach Ġ{ Ġstatement Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( statement !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLet Statement Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsymbol Ġ= Ġsymbol Table . define ( node . name . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . value !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( symbol . scope Ġ== ĠSymbol Scope . GLOBAL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Set Global , Ġsymbol . index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Set Local , Ġsymbol . index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠIdentifier Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsymbol Ġ= Ġsymbol Table . resolve ( node . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Symbol ( symbol ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠString Literal Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstr Ġ= ĠM String ( node . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Constant , Ġadd Constant ( str )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠArray Literal Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . elements !!. forEach Ġ{ Ġelement Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( element !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Array , Ġnode . elements . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠHash Literal Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkeys Ġ= Ġnode . pairs . keys . sorted By Ġ{ Ġkey Ġ-> Ġkey . toString () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkeys . forEach Ġ{ Ġkey Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . pairs [ key ] !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Hash , Ġnode . pairs . size Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠIndex Expression Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . left !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . index !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Index ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠFunction Literal Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenter Scope () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node . name . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsymbol Table . define FunctionName ( node . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . parameters ?. forEach Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsymbol Table . define ( parameter . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . body !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Last Instruction Pop ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreplace Last Pop With Return () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! last Instruction Is ( Op ReturnValue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Return ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfree Symbols Ġ= Ġsymbol Table . free Symbols ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnum Local s Ġ= Ġsymbol Table . num Definitions ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinstructions Ġ= Ġleave Scope () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfree Symbols . forEach ( this :: load Symbol ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompiled Fn Ġ= ĠM Compiled Function ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions Ġ= Ġinstructions , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnum Local s Ġ= Ġnum Local s , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnum Parameters Ġ= Ġnode . parameters !!. size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Closure , Ġadd Constant ( compiled Fn ), Ġfree Symbols . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠReturn Statement Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . returnValue !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op ReturnValue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCall Expression Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( node . function !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . arguments !!. forEach Ġ{ Ġarg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcompile ( arg !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( Op Call , Ġnode . arguments . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload Symbol ( symbol : ĠSymbol ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġopcode Ġ= Ġwhen Ġ( symbol . scope ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSymbol Scope . GLOBAL Ġ-> ĠOp Get Global ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSymbol Scope . LOCAL Ġ-> ĠOp Get Local ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSymbol Scope . BUIL TIN Ġ-> ĠOp Get Builtin ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSymbol Scope . FREE Ġ-> ĠOp Get Free ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSymbol Scope . FUNCTION Ġ-> ĠOp Current Closure ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( opcode Ġ!= ĠOp Current Closure ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( opcode , Ġsymbol . index ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit ( opcode ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġleave Scope (): ĠInstructions Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinstructions Ġ= Ġcurrent Instructions () ĊĠĠĠĠĠĠĠ Ġscopes . remove Last () ĊĠĠĠĠĠĠĠ Ġscope Index -- ĊĠĠĠĠĠĠĠ Ġsymbol Table Ġ= Ġsymbol Table . outer !! ĊĠĠĠĠĠĠĠ Ġreturn Ġinstructions ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreplace Last Pop With Return () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlas Pos Ġ= Ġcurrent Scope (). last Instruction . position ĊĠĠĠĠĠĠĠ Ġreplace Instruction ( las Pos , Ġmake ( Op ReturnValue )) ĊĠĠĠĠĠĠĠ Ġcurrent Scope (). last Instruction . op Ġ= ĠOp ReturnValue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġenter Scope () Ġ{ ĊĠĠĠĠĠĠĠ Ġscopes Ġ+= ĠCompilation Scope () ĊĠĠĠĠĠĠĠ Ġsymbol Table Ġ= ĠSymbol Table ( outer Ġ= Ġsymbol Table ) ĊĠĠĠĠĠĠĠ Ġscope Index ++ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchange Operand ( op Pos : ĠInt , Ġoperand : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġop Ġ= Ġcurrent Instructions ()[ op Pos ] ĊĠĠĠĠĠĠĠ Ġval Ġnew Instruction Ġ= Ġmake ( op , Ġoperand ) ĊĠĠĠĠĠĠĠ Ġreplace Instruction ( op Pos , Ġnew Instruction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreplace Instruction ( pos : ĠInt , Ġnew Instruction : ĠInstructions ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġnew Instruction . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Instructions ()[ pos Ġ+ Ġi ] Ġ= Ġnew Instruction [ i ] ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġremove Last Pop () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġwith ( current Scope ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Ġ= Ġlast Instruction ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprevious Ġ= Ġprevious Instruction ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġold Ġ= Ġcurrent Instructions () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Instruction Ġ= Ġold . on set ( last . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinstructions Ġ= Ġnew Instruction ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Instruction Ġ= Ġprevious ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Last Instruction Pop (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġlast Instruction Is ( Op Pop ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlast Instruction Is ( op : ĠOpcode ) Ġ= Ġcurrent Scope (). last Instruction . op Ġ== Ġop ĊĊĠĠĠ Ġprivate Ġfun Ġadd Constant ( obj : ĠM Object ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġconstants Ġ+= Ġobj ĊĠĠĠĠĠĠĠ Ġreturn Ġconstants . size Ġ- Ġ 1 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Instruction ( ins : ĠInstructions ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpos New Instruction Ġ= Ġcurrent Instructions (). size ĊĠĠĠĠĠĠĠ Ġcurrent Scope (). instructions Ġ+= Ġins ĊĠĠĠĠĠĠĠ Ġreturn Ġpos New Instruction ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġemit ( op : ĠOpcode , Ġvar arg Ġoperands : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġins Ġ= Ġmake ( op , Ġ* operands ) ĊĠĠĠĠĠĠĠ Ġval Ġpos Ġ= Ġadd Instruction ( ins ) ĊĠĠĠĠĠĠĠ Ġset Last Instruction ( op , Ġpos ) ĊĠĠĠĠĠĠĠ Ġreturn Ġpos ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Last Instruction ( op : ĠOpcode , Ġposition : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith ( current Scope ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprevious Ġ= Ġlast Instruction ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Ġ= ĠE mitted Instruction ( op , Ġposition ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprevious Instruction Ġ= Ġprevious ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Instruction Ġ= Ġlast ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbytecode (): ĠByte code Ġ= ĠByte code ( current Instructions (), Ġconstants ) ĊĊĠĠĠ Ġprivate Ġfun Ġcurrent Instructions (): ĠInstructions Ġ= Ġcurrent Scope (). instructions ĊĊĠĠĠ Ġfun Ġcurrent Scope (): ĠCompilation Scope Ġ= Ġscopes [ scope Index ] Ċ } Ċ Ċ data Ġclass ĠByte code ( val Ġinstructions : ĠInstructions , Ġval Ġconstants : ĠList < M Object >) Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġ=== Ġother ) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( other Ġ! is ĠByte code ) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! instructions . content Equals ( other . instructions )) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( constants Ġ!= Ġother . constants ) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġinstructions . content HashCode () ĊĠĠĠĠĠĠĠ Ġresult Ġ= Ġ 3 1 Ġ* Ġresult Ġ+ Ġconstants . hashCode () ĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠM Compiler Exception ( message : ĠString ) Ġ: ĠException ( message )