Added all opcodes as constants
This commit is contained in:
parent
045bd2ef6d
commit
287d23fe36
68
creature.go
68
creature.go
@ -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
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user