Added all opcodes as constants

This commit is contained in:
Sasha Koshka 2022-08-28 18:34:23 -04:00
parent 045bd2ef6d
commit 287d23fe36
2 changed files with 49 additions and 45 deletions

View File

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

View File

@ -16,7 +16,7 @@ func runMachineTest(program []int, test *testing.T) (machine *Machine) {
func TestPush(test *testing.T) { func TestPush(test *testing.T) {
machine := runMachineTest ([]int { machine := runMachineTest ([]int {
0x0, 654, PUSH, 654,
}, test) }, test)
result := machine.Pop() result := machine.Pop()
@ -30,21 +30,21 @@ func TestPush(test *testing.T) {
func TestArithmetic(test *testing.T) { func TestArithmetic(test *testing.T) {
machine := runMachineTest([]int { machine := runMachineTest([]int {
0x0, 2, PUSH, 2,
0x0, 3, PUSH, 3,
0x4, ADD,
0x0, 10, PUSH, 10,
0x0, 4, PUSH, 4,
0x5, SUB,
0x0, 7, PUSH, 7,
0x0, 2, PUSH, 2,
0x6, MUL,
0x0, 12, PUSH, 12,
0x0, 3, PUSH, 3,
0x7, DIV,
}, test) }, test)
addResult := machine.Pop() addResult := machine.Pop()