package vm type OpHandler func(*State, *Instruction) var OpHandlers = map[OpCodeType]OpHandler{ OpNoOp: (*State).NoOp, OpCall: (*State).Call, OpReturn: (*State).Return, OpMove: (*State).Move, OpAdd: (*State).Add, OpSubtract: (*State).Subtract, OpMultiply: (*State).Multiply, OpDivideUnsigned: (*State).DivideUnsigned, OpDivideSigned: (*State).DivideSigned, OpIsEqual: (*State).IsEqual, OpIsLessThanUnsigned: (*State).IsLessThanUnsigned, OpIsLessThanSigned: (*State).IsLessThanSigned, OpIsGreaterThanUnsigned: (*State).IsGreaterThanUnsigned, OpIsGreaterThanSigned: (*State).IsGreaterThanSigned, OpIsLessThanOrEqualUnsigned: (*State).IsLessThanOrEqualUnsigned, OpIsLessThanOrEqualSigned: (*State).IsLessThanOrEqualSigned, OpIsGreaterThanOrEqualUnsigned: (*State).IsGreaterThanOrEqualUnsigned, OpIsGreaterThanOrEqualSigned: (*State).IsGreaterThanOrEqualSigned, OpJump: (*State).Jump, OpJumpIfTrue: (*State).JumpIfTrue, OpJumpIfFalse: (*State).JumpIfFalse, } func (state *State) NoOp(instr *Instruction) { } func (state *State) Call(instr *Instruction) { in := state.ReadSigned(&instr.Operand1) state.call(in) } func (state *State) Return(instr *Instruction) { state.ret() } func (state *State) Move(instr *Instruction) { in := state.ReadUnsigned(&instr.Operand2) state.WriteUnsigned(&instr.Operand1, in) } func (state *State) Add(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.WriteUnsigned(&instr.Operand1, in1+in2) } func (state *State) Subtract(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.WriteUnsigned(&instr.Operand1, in1-in2) } func (state *State) Multiply(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.WriteUnsigned(&instr.Operand1, in1*in2) } func (state *State) DivideUnsigned(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.WriteUnsigned(&instr.Operand1, in1/in2) } func (state *State) DivideSigned(instr *Instruction) { in1 := state.ReadSigned(&instr.Operand1) in2 := state.ReadSigned(&instr.Operand2) state.WriteSigned(&instr.Operand1, in1/in2) } func (state *State) IsEqual(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.ComparisonResult = (in1 == in2) } func (state *State) IsLessThanUnsigned(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.ComparisonResult = (in1 < in2) } func (state *State) IsLessThanSigned(instr *Instruction) { in1 := state.ReadSigned(&instr.Operand1) in2 := state.ReadSigned(&instr.Operand2) state.ComparisonResult = (in1 < in2) } func (state *State) IsGreaterThanUnsigned(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.ComparisonResult = (in1 > in2) } func (state *State) IsGreaterThanSigned(instr *Instruction) { in1 := state.ReadSigned(&instr.Operand1) in2 := state.ReadSigned(&instr.Operand2) state.ComparisonResult = (in1 > in2) } func (state *State) IsLessThanOrEqualUnsigned(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.ComparisonResult = (in1 <= in2) } func (state *State) IsLessThanOrEqualSigned(instr *Instruction) { in1 := state.ReadSigned(&instr.Operand1) in2 := state.ReadSigned(&instr.Operand2) state.ComparisonResult = (in1 <= in2) } func (state *State) IsGreaterThanOrEqualUnsigned(instr *Instruction) { in1 := state.ReadUnsigned(&instr.Operand1) in2 := state.ReadUnsigned(&instr.Operand2) state.ComparisonResult = (in1 >= in2) } func (state *State) IsGreaterThanOrEqualSigned(instr *Instruction) { in1 := state.ReadSigned(&instr.Operand1) in2 := state.ReadSigned(&instr.Operand2) state.ComparisonResult = (in1 >= in2) } func (state *State) Jump(instr *Instruction) { in := state.ReadSigned(&instr.Operand1) state.InstructionIndex += in - 1 } func (state *State) JumpIfTrue(instr *Instruction) { if state.ComparisonResult == true { state.Jump(instr) } } func (state *State) JumpIfFalse(instr *Instruction) { if state.ComparisonResult == false { state.Jump(instr) } }