diff --git a/creature.go b/creature.go index 72b2e68..719f25e 100644 --- a/creature.go +++ b/creature.go @@ -20,6 +20,26 @@ type Machine struct { // machine will halt execution if true is returned. type MachineFunction func(machine *Machine) (stop bool) +// All supported opcodes +const ( + PUSH = 0x0 + POP = 0x1 + LOAD = 0x2 + STOR = 0x3 + ADD = 0x4 + SUB = 0x5 + MUL = 0x6 + DIV = 0x7 + EQ = 0x8 + GT = 0x9 + LT = 0xa + NEQ = 0xb + MOD = 0xc + HALT = 0xd + JMP = 0xe + CAL = 0xf +) + // Error is an error type that can be returned from the machine's methods if // they experience problems. type Error int @@ -62,45 +82,37 @@ func (machine *Machine) Execute(offset int) (err error) { for machine.counter < len(machine.Program) { switch machine.instruction() { - case 0x0: - // PUSH + case PUSH: // push the next word in program memory onto the stack machine.counter++ machine.Push(machine.instruction()) - case 0x1: - // POP + case POP: // pop the top word off of the stack, and discard it machine.Pop() - case 0x2: - // LOAD + case LOAD: // push the word at an address onto the stack machine.Push(machine.Peek(machine.Pop())) - case 0x3: - // STOR + case STOR: // store a word at an address machine.Poke(machine.Pop(), machine.Pop()) - case 0x4: - // ADD + case ADD: // adds the last two words on the stack machine.Push(machine.Pop() + machine.Pop()) - case 0x5: - // SUB + case SUB: // subtracts the second to last word on the stack from // the last word on the stack machine.Push(machine.Pop() - machine.Pop()) - case 0x6: - // MUL + case MUL: // multiplies the last two words on the stack machine.Push(machine.Pop() * machine.Pop()) - case 0x7: - // DIV + case DIV: // divides the last word on the stack by the second to // last word on the stack left := machine.Pop() @@ -111,8 +123,7 @@ func (machine *Machine) Execute(offset int) (err error) { } machine.Push(left / right) - case 0x8: - // EQ + case EQ: // checks if the last two words on the stack are equal equal := 0 if machine.Pop() == machine.Pop() { @@ -120,8 +131,7 @@ func (machine *Machine) Execute(offset int) (err error) { } machine.Push(equal) - case 0x9: - // GT + case GT: // checks if the last word on the stack is greater than // the second to last word on the stack greater := 0 @@ -130,8 +140,7 @@ func (machine *Machine) Execute(offset int) (err error) { } machine.Push(greater) - case 0xa: - // LT + case LT: // checks if the last word on the stack is less than the // second to last word on the stack less := 0 @@ -140,8 +149,7 @@ func (machine *Machine) Execute(offset int) (err error) { } machine.Push(less) - case 0xb: - // NEQ + case NEQ: // checks if the last two words on the stack are not // equal notEqual := 0 @@ -150,19 +158,16 @@ func (machine *Machine) Execute(offset int) (err error) { } machine.Push(notEqual) - case 0xc: - // MOD + case MOD: // performs a modulo operation of the second to last // word on the stack to the last word on the stack machine.Push(machine.Pop() % machine.Pop()) - case 0xd: - // HALT + case HALT: // stops execution return - case 0xe: - // JMP + case JMP: // jump to the address specified by the last word on the // stack if the second to last word on the stack is // nonzero @@ -171,8 +176,7 @@ func (machine *Machine) Execute(offset int) (err error) { machine.counter = jumpTo - 1 } - case 0xf: - // CAL + case CAL: // call an implementation-defined subroutine, with the // id specified by the last word on the stack. this may // push and pop various things from the stack diff --git a/creature_test.go b/creature_test.go index a7055f9..a3cb62d 100644 --- a/creature_test.go +++ b/creature_test.go @@ -16,7 +16,7 @@ func runMachineTest(program []int, test *testing.T) (machine *Machine) { func TestPush(test *testing.T) { machine := runMachineTest ([]int { - 0x0, 654, + PUSH, 654, }, test) result := machine.Pop() @@ -30,21 +30,21 @@ func TestPush(test *testing.T) { func TestArithmetic(test *testing.T) { machine := runMachineTest([]int { - 0x0, 2, - 0x0, 3, - 0x4, + PUSH, 2, + PUSH, 3, + ADD, - 0x0, 10, - 0x0, 4, - 0x5, + PUSH, 10, + PUSH, 4, + SUB, - 0x0, 7, - 0x0, 2, - 0x6, + PUSH, 7, + PUSH, 2, + MUL, - 0x0, 12, - 0x0, 3, - 0x7, + PUSH, 12, + PUSH, 3, + DIV, }, test) addResult := machine.Pop()