package vm type opHandler func(*State, *Instruction) var opHandlers = map[OpCodeType]opHandler{ OpNoOp: (*State).handleNoOp, OpMove: (*State).handleMove, OpAdd: (*State).handleAdd, OpSubtract: (*State).handleSubtract, OpMultiply: (*State).handleMultiply, OpDivideUnsigned: (*State).handleDivideUnsigned, OpDivideSigned: (*State).handleDivideSigned, OpNot: (*State).handleNot, OpAnd: (*State).handleAnd, OpOr: (*State).handleOr, OpXor: (*State).handleXor, OpShiftRight: (*State).handleShiftRight, OpShiftLeft: (*State).handleShiftLeft, OpIsEqual: (*State).handleIsEqual, OpIsLessThanUnsigned: (*State).handleIsLessThanUnsigned, OpIsLessThanSigned: (*State).handleIsLessThanSigned, OpIsGreaterThanUnsigned: (*State).handleIsGreaterThanUnsigned, OpIsGreaterThanSigned: (*State).handleIsGreaterThanSigned, OpIsLessThanOrEqualUnsigned: (*State).handleIsLessThanOrEqualUnsigned, OpIsLessThanOrEqualSigned: (*State).handleIsLessThanOrEqualSigned, OpIsGreaterThanOrEqualUnsigned: (*State).handleIsGreaterThanOrEqualUnsigned, OpIsGreaterThanOrEqualSigned: (*State).handleIsGreaterThanOrEqualSigned, OpJump: (*State).handleJump, OpJumpIfTrue: (*State).handleJumpIfTrue, OpJumpIfFalse: (*State).handleJumpIfFalse, OpCall: (*State).handleCall, OpCallIfTrue: (*State).handleCallIfTrue, OpCallIfFalse: (*State).handleCallIfFalse, OpReturn: (*State).handleReturn, OpReturnIfTrue: (*State).handleReturnIfTrue, OpReturnIfFalse: (*State).handleReturnIfFalse, } func (state *State) handleNoOp(instr *Instruction) { } func (state *State) handleMove(instr *Instruction) { in := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in) } func (state *State) handleAdd(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1+in2) } func (state *State) handleSubtract(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1-in2) } func (state *State) handleMultiply(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1*in2) } func (state *State) handleDivideUnsigned(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1/in2) } func (state *State) handleDivideSigned(instr *Instruction) { in1 := state.readSigned(&instr.Operand1) in2 := state.readSigned(&instr.Operand2) state.writeSigned(&instr.Operand1, in1/in2) } func (state *State) handleNot(instr *Instruction) { in := state.readUnsigned(&instr.Operand1) state.writeUnsigned(&instr.Operand1, ^in) } func (state *State) handleAnd(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1&in2) } func (state *State) handleOr(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1|in2) } func (state *State) handleXor(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1^in2) } func (state *State) handleShiftRight(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1>>in2) } func (state *State) handleShiftLeft(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.writeUnsigned(&instr.Operand1, in1< in2) } func (state *State) handleIsGreaterThanSigned(instr *Instruction) { in1 := state.readSigned(&instr.Operand1) in2 := state.readSigned(&instr.Operand2) state.comparisonResult = (in1 > in2) } func (state *State) handleIsLessThanOrEqualUnsigned(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.comparisonResult = (in1 <= in2) } func (state *State) handleIsLessThanOrEqualSigned(instr *Instruction) { in1 := state.readSigned(&instr.Operand1) in2 := state.readSigned(&instr.Operand2) state.comparisonResult = (in1 <= in2) } func (state *State) handleIsGreaterThanOrEqualUnsigned(instr *Instruction) { in1 := state.readUnsigned(&instr.Operand1) in2 := state.readUnsigned(&instr.Operand2) state.comparisonResult = (in1 >= in2) } func (state *State) handleIsGreaterThanOrEqualSigned(instr *Instruction) { in1 := state.readSigned(&instr.Operand1) in2 := state.readSigned(&instr.Operand2) state.comparisonResult = (in1 >= in2) } func (state *State) handleJump(instr *Instruction) { in := state.readSigned(&instr.Operand1) state.jump(in) } func (state *State) handleJumpIfTrue(instr *Instruction) { if state.comparisonResult == true { state.handleJump(instr) } } func (state *State) handleJumpIfFalse(instr *Instruction) { if state.comparisonResult == false { state.handleJump(instr) } } func (state *State) handleCall(instr *Instruction) { in := state.readSigned(&instr.Operand1) state.call(in) } func (state *State) handleCallIfTrue(instr *Instruction) { if state.comparisonResult == true { state.handleCall(instr) } } func (state *State) handleCallIfFalse(instr *Instruction) { if state.comparisonResult == false { state.handleCall(instr) } } func (state *State) handleReturn(instr *Instruction) { state.ret() } func (state *State) handleReturnIfTrue(instr *Instruction) { if state.comparisonResult == true { state.handleReturn(instr) } } func (state *State) handleReturnIfFalse(instr *Instruction) { if state.comparisonResult == false { state.handleReturn(instr) } }