Added documentation of all the opcodes in README

This commit is contained in:
Sasha Koshka 2022-08-28 23:24:43 -04:00
parent 975de37927
commit dba858307d
2 changed files with 219 additions and 0 deletions

170
README.md
View File

@ -1,3 +1,173 @@
# creature
A simple, extendable, 16 instruction stack machine.
It has two portions of memory: the stack and the block. I hesitate to call the
block a heap because it is not a data structure, it is a continuous block of
memory.
Both the stack and the block are as infinite, as computing resources and integer
limits allow, in the positive direction. They are automatically expanded
when written to.
## Instruction Set
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
pushed/popped.
### 0x0 PUSH
Pushes the next word in program memory onto the stack.
Pushes:
1. next word in program memory
### 0x1 POP
Pops the top word off of the stack, and discards it.
Pops:
1. word
### 0x2 PEEK
Reads a memory address from the block and places it atop the stack.
Pops:
1. address
Pushes:
1. word found at address
### 0x3 POKE
Sets a memory address in the block.
Pops:
1. address
2. value to store
### 0x4 ADD
Adds two words. Tip: this can be used as a logical OR.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand + right operand
### 0x5 SUB
Subtracts two words.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand - right operand
### 0x6 MUL
Multiplies two words.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand * right operand
### 0x7 DIV
Divides two words.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand / right operand
### 0x8 EQ
Checks if two words are equal. Pushes 1 if true, zero if false.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand == right operand
### 0x9 GT
Checks if a word is greater than another word. Pushes 1 if true, zero if false.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand > right operand
### 0xA LT
Checks if a word is less than another word. Pushes 1 if true, zero if false.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand < right operand
### 0xB NEQ
Checks if two words are *not* equal. Pushes 1 if true, zero if false.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand != right operand
### 0xC MOD
Performs a modulo operation on two words.
Pops:
1. left operand
2. right operand
Pushes:
1. left operand % right operand
### 0xD HALT
Halts execution of the machine.
### 0xE JMP
Jumps to the specified address if a word is non-zero.
Pops:
1. address
2. condition
### 0xF CAL
Call a function that can be registered using the Machine.Register method.
Functions are allowed to push and pop whatever they want to and from the stack,
as well as read and write to and from the block.
Pops:
1. function ID
2. ...other stuff, it depends on the function.
Pushes:
1. ...again, depends on the function.

View File

@ -227,3 +227,52 @@ func TestJump(test *testing.T) {
test.Fail()
}
}
func TestRegister(test *testing.T) {
output := ""
machine := &Machine { Program: []int {
PUSH, int('h'),
PUSH, 4,
CAL,
PUSH, int('e'),
PUSH, 4,
CAL,
PUSH, int('l'),
PUSH, 4,
CAL,
PUSH, int('l'),
PUSH, 4,
CAL,
PUSH, int('o'),
PUSH, 4,
CAL,
PUSH, int('r'),
PUSH, 4,
CAL,
PUSH, int('l'),
PUSH, 4,
CAL,
PUSH, int('d'),
PUSH, 4,
CAL,
PUSH, int('!'),
PUSH, 4,
CAL,
}}
machine.Register(4, func(machine *Machine) (stop bool) {
output += string(rune(machine.Pop()))
return
})
err := machine.Execute(0)
if err != nil {
test.Log("machine exited with error:", err)
test.Fail()
}
test.Log("printed:", output)
if output != "hellorld!" {
test.Log("result should be", "hellorld!")
test.Fail()
}
}