class RegisterMachine ( maxMem : Int, maxRegs : Int ) { assert ( maxMem > 0 && maxRegs > 0 ) private val mem = Array.fill ( maxMem ) ( 0 ) private val reg = Array.fill ( maxRegs ) ( 0 ) private var pc = 0 private var ir = 0 private var sp = 0 private def incSP () = { sp = ( sp + 1 ) % maxMem } private def decSP () = { sp = ( sp - 1 ) % maxMem } private def incPC () = { pc = ( pc + 1 ) % maxMem } def load ( code : Array [ Int ], startAddress : Int ) : Unit = { throw new Exception ( "[RegisterMachine::load] not implemented yet" ) } def run () : Unit = { while ( true ) { ir = mem ( pc ) incPC () ir match { case 0 => {} // I_Nop case 1 => { // I_Pop val i = mem ( pc ) incPC () reg ( i ) = mem ( sp ) decSP () } case 2 => { // I_Push val i = mem ( pc ) incPC () incSP () mem ( sp ) = reg ( i ) } case 3 => { // I_Load val i = mem ( pc ) incPC () val x = mem ( pc ) incPC () reg ( i ) = mem ( x ) } case 4 => { // I_LoadImm val i = mem ( pc ) incPC () val n = mem ( pc ) incPC () reg ( i ) = n } case 5 => { // I_Store val i = mem ( pc ) incPC () val x = mem ( pc ) incPC () mem ( i ) = reg ( x ) } case 6 => { // I_CompGreaterThan val i = mem ( pc ) incPC () val j = mem ( pc ) incPC () if ( reg ( i ) > reg ( j ) ) reg ( i ) = 1 else reg ( i ) = 0 } case 7 => { // I_CompEq val i = mem ( pc ) incPC () val j = mem ( pc ) incPC () if ( reg ( i ) == reg ( j ) ) reg ( i ) = 1 else reg ( i ) = 0 } case 8 => { // I_Jump pc = mem ( pc ) } case 9 => { // I_JumpTrue val i = mem ( pc ) incPC () val adr = mem ( pc ) incPC () if ( reg ( i ) != 0 ) pc = adr } case 10 => { // I_JumpFalse val i = mem ( pc ) incPC () val adr = mem ( pc ) incPC () if ( reg ( i ) == 0 ) pc = adr } case 11 => { // I_Plus val i = mem ( pc ) incPC () val j = mem ( pc ) incPC () reg ( i ) = reg ( i ) + reg ( j ) } case 12 => { // I_Minus val i = mem ( pc ) incPC () val j = mem ( pc ) incPC () reg ( i ) = reg ( i ) - reg ( j ) } case 13 => { // I_Times val i = mem ( pc ) incPC () val j = mem ( pc ) incPC () reg ( i ) = reg ( i ) * reg ( j ) } case 14 => { // I_Divide val i = mem ( pc ) incPC () val j = mem ( pc ) incPC () reg ( i ) = reg ( i ) / reg ( j ) } case 15 => { // I_Negate val i = mem ( pc ) incPC () reg ( i ) = reg ( i ) * ( -1 ) } case 16 => { // I_PlusStack val i = mem ( pc ) incPC () val arg = mem ( sp ) decSP () reg ( i ) = reg ( i ) + arg } case 17 => { // I_MinusStack val i = mem ( pc ) incPC () val arg = mem ( sp ) decSP () reg ( i ) = reg ( i ) - arg } case 18 => { // I_TimesStack val i = mem ( pc ) incPC () val arg = mem ( sp ) decSP () reg ( i ) = reg ( i ) * arg } case 19 => { // I_DivideStack val i = mem ( pc ) incPC () val arg = mem ( sp ) decSP () reg ( i ) = reg ( i ) / arg } case _ => throw new Exception ( "[RegisterMachine:run] illegal opcode" ) } } } }