Compare commits

2 Commits

Author SHA1 Message Date
cfae69c0c2 Updated readme accordingly 2022-08-29 20:20:46 -04:00
d7d5be6949 Reversed order of comparison and arithmetic operations 2022-08-29 20:15:46 -04:00
3 changed files with 56 additions and 61 deletions

View File

@@ -16,6 +16,11 @@ Each documented instruction has a list of what is pushed, and what is popped.
the items are listed in chronological order, from first pushed/popped to last the items are listed in chronological order, from first pushed/popped to last
pushed/popped. pushed/popped.
You'll notice that words specifying an address are always at the top of the
stack. This helps increse security and reduce the likelihood of bugs. When
writing functions to extend creature, it is highly advised that you follow this
principle when deciding on an order to pop arguments off of the stack in.
### 0x0 PUSH ### 0x0 PUSH
Pushes the next word in program memory onto the stack. Pushes the next word in program memory onto the stack.
@@ -53,8 +58,8 @@ Pops:
Adds two words. Tip: this can be used as a logical OR. Adds two words. Tip: this can be used as a logical OR.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand + right operand 1. left operand + right operand
@@ -64,8 +69,8 @@ Pushes:
Subtracts two words. Subtracts two words.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand - right operand 1. left operand - right operand
@@ -75,8 +80,8 @@ Pushes:
Multiplies two words. Multiplies two words.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand * right operand 1. left operand * right operand
@@ -86,8 +91,8 @@ Pushes:
Divides two words. Divides two words.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand / right operand 1. left operand / right operand
@@ -97,8 +102,8 @@ Pushes:
Checks if two words are equal. Pushes 1 if true, zero if false. Checks if two words are equal. Pushes 1 if true, zero if false.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand == right operand 1. left operand == right operand
@@ -108,8 +113,8 @@ Pushes:
Checks if a word is greater than another word. Pushes 1 if true, zero if false. Checks if a word is greater than another word. Pushes 1 if true, zero if false.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand > right operand 1. left operand > right operand
@@ -119,8 +124,8 @@ Pushes:
Checks if a word is less than another word. Pushes 1 if true, zero if false. Checks if a word is less than another word. Pushes 1 if true, zero if false.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand < right operand 1. left operand < right operand
@@ -130,8 +135,8 @@ Pushes:
Checks if two words are *not* equal. Pushes 1 if true, zero if false. Checks if two words are *not* equal. Pushes 1 if true, zero if false.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand != right operand 1. left operand != right operand
@@ -142,8 +147,8 @@ Performs a modulo operation on two words. Tip: this can be used as a logical
AND. AND.
Pops: Pops:
1. left operand 1. right operand
2. right operand 2. left operand
Pushes: Pushes:
1. left operand % right operand 1. left operand % right operand

View File

@@ -90,42 +90,38 @@ func (machine *Machine[WORD]) Execute(offset WORD) (err error) {
for int(machine.counter) < len(machine.Program) { for int(machine.counter) < len(machine.Program) {
switch machine.instruction() { switch machine.instruction() {
case PUSH: case PUSH:
// push the next word in program memory onto the stack
machine.counter++ machine.counter++
machine.Push(machine.instruction()) machine.Push(machine.instruction())
case POP: case POP:
// pop the top word off of the stack, and discard it
machine.Pop() machine.Pop()
case PEEK: case PEEK:
// push the word at an address onto the stack
machine.Push(machine.Peek(machine.Pop())) machine.Push(machine.Peek(machine.Pop()))
case POKE: case POKE:
// store a word at an address
address := machine.Pop() address := machine.Pop()
word := machine.Pop() word := machine.Pop()
machine.Poke(address, word) machine.Poke(address, word)
case ADD: case ADD:
// adds the last two words on the stack right := machine.Pop()
machine.Push(machine.Pop() + machine.Pop()) left := machine.Pop()
machine.Push(left + right)
case SUB: case SUB:
// subtracts the second to last word on the stack from right := machine.Pop()
// the last word on the stack left := machine.Pop()
machine.Push(machine.Pop() - machine.Pop()) machine.Push(left - right)
case MUL: case MUL:
// multiplies the last two words on the stack right := machine.Pop()
machine.Push(machine.Pop() * machine.Pop()) left := machine.Pop()
machine.Push(left * right)
case DIV: case DIV:
// divides the last word on the stack by the second to
// last word on the stack
left := machine.Pop()
right := machine.Pop() right := machine.Pop()
left := machine.Pop()
if right == 0 { if right == 0 {
err = ErrorDivideByZero err = ErrorDivideByZero
return return
@@ -133,62 +129,56 @@ func (machine *Machine[WORD]) Execute(offset WORD) (err error) {
machine.Push(left / right) machine.Push(left / right)
case EQ: case EQ:
// checks if the last two words on the stack are equal right := machine.Pop()
left := machine.Pop()
equal := 0 equal := 0
if machine.Pop() == machine.Pop() { if left == right {
equal = 1 equal = 1
} }
machine.Push(WORD(equal)) machine.Push(WORD(equal))
case GT: case GT:
// checks if the last word on the stack is greater than right := machine.Pop()
// the second to last word on the stack left := machine.Pop()
greater := 0 greater := 0
if machine.Pop() > machine.Pop() { if left > right {
greater = 1 greater = 1
} }
machine.Push(WORD(greater)) machine.Push(WORD(greater))
case LT: case LT:
// checks if the last word on the stack is less than the right := machine.Pop()
// second to last word on the stack left := machine.Pop()
less := 0 less := 0
if machine.Pop() < machine.Pop() { if left < right {
less = 1 less = 1
} }
machine.Push(WORD(less)) machine.Push(WORD(less))
case NEQ: case NEQ:
// checks if the last two words on the stack are not right := machine.Pop()
// equal left := machine.Pop()
notEqual := 0 notEqual := 0
if machine.Pop() != machine.Pop() { if left != right {
notEqual = 1 notEqual = 1
} }
machine.Push(WORD(notEqual)) machine.Push(WORD(notEqual))
case MOD: case MOD:
// performs a modulo operation of the second to last right := machine.Pop()
// word on the stack to the last word on the stack left := machine.Pop()
machine.Push(machine.Pop() % machine.Pop()) machine.Push(left % right)
case HALT: case HALT:
// stops execution
return return
case 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
jumpTo := machine.Pop() jumpTo := machine.Pop()
if machine.Pop() != 0 { if machine.Pop() != 0 {
machine.counter = jumpTo - 1 machine.counter = jumpTo - 1
} }
case 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
id := machine.Pop() id := machine.Pop()
if machine.functions == nil { if machine.functions == nil {
break break

View File

@@ -41,24 +41,24 @@ func TestPush(test *testing.T) {
func TestArithmetic(test *testing.T) { func TestArithmetic(test *testing.T) {
machine := runMachineTest([]int { machine := runMachineTest([]int {
PUSH, 2,
PUSH, 3, PUSH, 3,
PUSH, 2,
ADD, ADD,
PUSH, 4,
PUSH, 10, PUSH, 10,
PUSH, 4,
SUB, SUB,
PUSH, 7,
PUSH, 2, PUSH, 2,
PUSH, 7,
MUL, MUL,
PUSH, 3,
PUSH, 12, PUSH, 12,
PUSH, 3,
DIV, DIV,
PUSH, 6,
PUSH, 8, PUSH, 8,
PUSH, 6,
MOD, MOD,
}, nil, test) }, nil, test)
@@ -106,16 +106,16 @@ func TestComparison(test *testing.T) {
PUSH, 6, PUSH, 6,
EQ, EQ,
PUSH, 4,
PUSH, 324, PUSH, 324,
PUSH, 4,
GT, GT,
PUSH, 324,
PUSH, 4, PUSH, 4,
PUSH, 324,
LT, LT,
PUSH, 6,
PUSH, 54, PUSH, 54,
PUSH, 6,
NEQ, NEQ,
}, nil, test) }, nil, test)