SplitFuck

From Esolang
Jump to navigation Jump to search

SplitFuck is a derivative of Brainfuck whose commands make use of a byte split into two four-bit nibbles, which denote a command and the behavior of that command. This functionality is adapted from the 3-bit/5-bit command/behavior split of Brainfuck Assembly Language (BAL). Like BAL, it is meant to make hardware implementation of Brainfuck easier. However, it is also split in a sense that a portion of the 16 possible commands are directly inherited from Brainfuck (with the added functionality of BAL), while another portion are adapted to manipulate the memory pointer beyond incrementing and decrementing, and a few are adapted to manipulate the instruction pointer beyond loops. This is roughly adapted from and inspired by the additional commands of BrainGuck, and is also meant to make the language easier to use.

Language Overview

Commands are ran directly off of RAM, with the program loaded at the beginning of memory. The memory contains both the executable program and the brainfuck memory array. The program may edit itself during executing, similar to BAL. It makes use of three registers, one to keep track of the instruction pointer, another to keep track of the memory pointer, and another to keep track of loop start/end counting and traversal. The instruction set is as follows, adapted from the combined instruction sets and goals of Brainfuck, Brainfuck Assembly Language, and BrainGuck, as well as a bit of originality:

Command Behavior (based on argument n)
+n
n 0 Terminate program
n 1-15 Add n to the memory value
-n
Subtract n from the memory value
^n
Pull the memory value into a byte of the memory pointer, starting at a bit index of n*8
~n
Swap memory value with a byte of the memory pointer, starting at a bit index of n*8
.n
Take the byte of memory value as output. Pass n as additional info to peripherals, which specify behavior.
,n
Take a byte of input and store it as the memory value. Pass n as additional info to peripherals, which specify behavior.
[n
n 0 Skip instruction pointer to loop end if memory value is zero
n 1-15 Add n to instruction pointer if memory value is zero
]n
n 0 Return instruction pointer to loop start if memory value is not zero
n 1-15 Subtract n from instruction pointer if memory value is not zero
>n
Add n to the memory address
<n
Subtract n from the memory address
vn
Pull the memory value into a byte of the instruction pointer, starting at a bit index of n*8
xn
Swap memory value with a byte of the instruction pointer, starting at a bit index of n*8
/n
Pull a byte of the instruction pointer into a byte of the memory pointer, both bytes starting at a bit index of n*8
\n
Pull a byte of the memory pointer into a byte of the instruction pointer, both bytes starting at a bit index of n*8
{n
n 0 Skip instruction pointer to loop end if memory address is zero
n 1-15 Add n to instruction pointer if memory address is zero
}n
n 0 Return instruction pointer to loop start if memory address is not zero
n 1-15 Subtract n from instruction pointer if memory address is not zero


To explain why the ^, v, /, and \ commands appear the way they do, it is necessary to visualize the memory stack as a horizontal array of data values with the memory pointer placed above it and the instruction pointer placed below it. ^ denotes moving from the memory stack into the memory pointer, v denotes moving from the memory stack into the instruction pointer, / indicates a sort of rightward "slide" from the instruction pointer into the memory pointer, and \ indicates a similar rightward "slide" from the memory pointer into the instruction pointer. I would include a visual here, but I do not know how to do it justice.


It is worth noting that the code to terminate any program is 00000000, the combined Byte code for adding 0.


"A byte of the _ pointer, starting at a bit index" denotes where the read/written byte is located within the bits of the specified address, treating the address as an essential array of bits with indices. In circumstances where a byte would overflow anywhere past the edge of the address, it should wrap back around to the front and continue from there, even if the whole pointer byte effectively takes place past the limits of the memory address. Due to the limitations of the Nibble-based "pointer address byte start index," only up to 128-bit pointer addresses are able to be fully supported by related commands (^, ~, v, x, /, and \).

Similar to Brainfuck Assembly Language, an implicit argument n is applied to any commands lacking an argument: 1 for +, -, [, and ] as well as their address equivalents, >, <, {, and }, and 0 for ,, ., ^, ~, v, x, /, and \.

Similar to BAL and other Brainfuck derivatives, addition and subtraction of addresses and values are subject to wrapping, and such is considered a feature. This is true even in the case of loop counting through the instruction pointer, where ][ or }{ could be considered valid command formatting, for whatever reason that may be. Whether or not the loop counting index can wrap (essentially guaranteeing an infinite loop or some otherwise unsightly behavior) is up to the specification. It should be assumed that this is not the case, however, since that would essentially be pointless.

Any characters besides the listed commands are treated as comments, in the circumstance of a compiler.


The commands +, -, >, <, ., ,, [, and ] are sourced from Brainfuck.

The commands ^, {, and } are sourced from BrainGuck.

The commands ~, v, x, /, and \ are original to SplitFuck.

Implementations

Similar to Brainfuck Assembly Language, SplitFuck leaves room for differentiation in its specifications. Variations include the memory word size (usually 8 bit, like BrainFuck), memory size (recommended 256 B to retain single byte addresses), interpretation of arguments passed into inputs and outputs, and starting values of the memory and instruction pointers (for possible ease of use in certain circumstances). Implementations, their values, and instructions:

Logic World
Information
Author User:TechieOpsoss
Status Abandoned
Word Size 8-bit
Memory Size 64 kiB
Initial Memory Address 0
Initial Instruction Address 0
Arguments for input
n 0 Read when held
n 1 Read when pressed
n 2 Read when released
n 3 Read when pressed or released
n 4 Read random input
n 5-15 No-op
Arguments for output
n 0 Output as ASCII
n 1 Output to screen as color
n 2-15 No-op

Credit where it's due

I heavily based the content of this article off of the article for Brainfuck Assembly Language.