Files
subcoding/ophandler.go
2021-11-16 15:27:30 -10:00

150 lines
4.4 KiB
Go

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)
}
}