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.
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

View File

@ -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()