SHRUB

From Esolang
Jump to navigation Jump to search
SHRUB
Paradigm(s) imperative
Designed by User:ZM
Appeared in 2022
Computational class see text
Reference implementation
Influenced by Subleq
File extension(s)

SHRUB (SHift Right, set Uppermost bit and Branch on discarded bit) is an OISC found by User:ZM in late 2022.

Overview

in general SHRUB systems operate on a number of memory cells each holding a string of bits with a fixed identical length, and a sequence of instructions. each instruction specifies a memory cell, a pair of boolean values R and S and two instructions as jump targets. when executing an instruction, the bitstring contained in the memory cell pointed to is shifted one step to the right and the leftmost bit in the string set to the bit that was shifted out, ANDed with R then XORed with S (thus, setting R to true rotates the string by one step to the right with S inverting the new leftmost bit, while setting R to false sets the highest bit to S). execution then continues at one of the two specified instructions, depending on the value that was shifted out.

specific implementations of SHRUB may specify a memory cell size, map instructions into regular memory and/or use a less general control flow system, like specifying only a single instruction that is jumped to if the discarded bit had one of the two possible values, with execution continuing at the next instruction in the list otherwise.

Examples

the following examples specify instructions using the format [label:] mem R S [target0 [target1]]. both jump targets are specified if necessary, one if both are identical and none if execution continues with the next instruction in both cases. memory cell size is left unspecified and memory cells assumed to be zero-initialized; instructions are not memory-mapped.

nearly all computation in SHRUB involves rotating multiple input values by one bit at a time and writing a result bit by bit. to keep track of the current location within such a loop, a counter can be used, initialized to zero except for the highest bit, which is set to one. this approach also allows the program to function regardless of memory cell size. to reach this state from an all-zero register the register in question needs to be shifted right once with S set:

counter 0 1

copying a value into another register requires rotating the first register and writing each bit into the second, using the counter to keep track of the number of rotations that have been carried out:

start: a 1 0 a0 a1
a0: out 0 0 checkIter
a1: out 0 1 checkIter
checkIter: counter 1 0 start exit

bitwise operations can be handled in a similar manner, using AND as an example:

start: a 1 0 a0 a1
a0: b 1 0 false
a1: b 1 0 false true
false: out 0 0 checkIter
true: out 0 1 checkIter
checkIter: counter 1 0 start exit

incrementing a value in register a:

start: a 1 1 carry noCarry
finish: a 1 0 noCarry
noCarry: counter 1 0 finish exit
carry: counter 1 0 start exitOverflow

subtracting one value from another:

start: a 1 0 a0 a1
carry: a 1 0 a-1 a0
a-1: b 1 0 b-1 b-2
a0: b 1 0 b0 b-1
a1: b 1 0 b1 b0
b-2: out 0 0 checkCarry
b-1: out 0 1 checkCarry
b0: out 0 0 check
b1: out 0 1 check
checkCarry: counter 1 0 carry exitCarry
check: counter 1 0 start exit

replacing the jumps to exit and exitCarry with jumps to the starts of other subtractions allows compiling SBN programs into SHRUB.

Computational class

SHRUB is capable of performing complex operations on arbitrary memory values and features arbitrary control flow, thus making it very likely capable of emulating a bounded-storage machine whose tape length is proportional to the amount of memory the program has access to. however, SHRUB programs can only ever access a predetermined finite amount of memory: if its memory cells were infinitely large, it would take infinitely long to read a previously written value, and the number of accessible memory cells is finite and constant in the case that instructions aren't memory-mapped, and (at best) bounded exponentially by their size if they are (depending on the instruction encoding); SHRUB therefore isn't Turing-complete.

if the size of each memory cell is proportional to the size of the input, SHRUB without instruction memory mapping is (probably) equivalent to a linear bounded automaton, while SHRUB with memory mapping (again, potentially) has access to an amount of memory exponentially bounded by its input size.

Implementations

SHRUB is currently unimplemented.