Reversed order of comparison and arithmetic operations

This commit is contained in:
Sasha Koshka 2022-08-29 20:15:46 -04:00
parent e342d9b254
commit d7d5be6949
2 changed files with 33 additions and 43 deletions

View File

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

View File

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