-
Notifications
You must be signed in to change notification settings - Fork 30
streaming byte-string Stack-based Assembly draft #6
Description
streaming byte-string Stack-based Assembly
The goal of this language is to design a minimal stack assembly that is meant to work with byte string.
interestingly, using context based addressing for "modules" means that recursion is not possible using call
the atomic value in this language is a byte-string.
byte string as defined as:
[length][value]
length is a bit fiddly. If the length can be encoded in 1 byte, then it is
otherwise that byte is set to 255 (max) and the next 2 bytes describe the length
if this is insufficient length, those bits are set to max value and the next 2n bytes describe the length.
this means lengths are encoded in O(log(n)) bytes (the same as another other number), but potentially twice as many bytes as a normal number in computer science.
A length of 0 indicates all remaining bytes in a block/object
Better schemes for encoding arbitrary lengths are welcome.
memory management:
"contexts" are key-value memories stored in a stack
by default values are stored on the top context of the stack
keys that are read seek down the stack until a match is found
In general methods receive arguments and return results via the stack
basic statement:
[command code byte-string] [args]
basic command codes are:
command | code | args | results
output | 0 | byte-string | outputs byte-string
put | 1 | byte-string | puts byte string on top of stack
pop | 2 | none | discards the current top of stack
store | 4 | key | stores top of stack in memory[value]
get | 5 | key | puts value at key on top of stack
context | 6 | none | starts a new memory context stack
untext | 7 | none | discards the current top context
cmp | 8 | signed-integer | if stack value is not 0, skips the indicated number of bytes. negative skips allow loops
call | 9 | hash location | fetches and runs indicated block, perpending it to the "todo" buffer.
cmp should only work in context of the current block of code. You cannot skip back before this block began and can skip past the end.
This way only the source of the current block and your location in it is required to "rewind"
NEEDS byte-string operations (concat, lshift, rshift) and MATH (add, subtract). Everything else can be implemented in-language
this method of encoding opcodes allows for infinitely many, however it is suggested call be used to implement basic functions. The performance hit of retrieving them goes away very quickly as they should be cached. it might be worth chucking the variable length for opcodes entirely, but I like the future proofing it offers.
a "raw data" block would be:
output DATA
or
put DATA