Brainfuckn't

From Esolang
Jump to navigation Jump to search

Brainfuckn't is a tape-based esolang created by user:4gboframram. The goal of the language was to make a language that is more frustrating to use than brainfuck, but at the same time to have a just as simple instruction set. Like brainfuck, this language's name should be written in all lowercase unless at the start of a sentence.

Brief Specification

Brainfuckn't is a tape-based esolang where there are two tapes with binary cells. Each tape has 2 pointers that can be cast to different sizes and when doing so, the pointer expands or contracts from the right (the lower bits, higher position value). The state of a pointer for a specific tape can thus be defined as a 2-tuple of unsigned integers, (size, pos). The state of a tape can be defined as a 3-tuple containing the elements of the pointer and a single n-bit unsigned integer, where n is the length of the tape, which may or may not be unbounded. Since the pointers have the same size at all times, the entire program state can therefore be stored as a 5-tuple of unsigned integers (s, p1, d1, p2, d2), where s is the size of the pointers. pn is the position of the nth tape's pointer, and dn is the contents of the nth tape. The initial state of the program is then (1, 0, 0, 0, 0).

Bit-wise operations can be applied between the contents of the two pointers. The result of the operation overrides the content of the first pointer. The list of all instructions is as follows:

Instruction Description
> Move the first tape's pointer to the right (increment its position)
< Move the first tape's pointer to the left (decrement its position)
} Move the second tape's pointer to the right (increment its position)
{ Move the second tape's pointer to the left (decrement its position)
+ Increment the pointer size
- Decrement the pointer size
. Output the character signified by the contents of the first tape's pointer interpreted as a base-10 integer, with the bits at the lowest position interpreted as the highest bits. This should be accurate to at least 32 bits.
* Get a single byte of input from standard input and set the contents of the first tape's pointer to be the value of that byte interpreted as an integer. If the byte is too large for the pointer, then truncate the bytes so that the lowest value bytes are put into the pointer first.
, Output the value of contents of the first tape's pointer interpreted as an (unsigned) integer, with the bits at the lowest position interpreted as the highest bits.
~ Flip each bit in the contents of the first tape's pointer
| Apply a bit-wise or operation between the contents of both pointers and override the contents of the first tape's pointer with the result of the operation
& Apply a bit-wise and operation between the contents of both pointers and override the contents of the first tape's pointer with the result of the operation
^ Apply a bit-wise xor operation between the contents of both pointers and override the contents of the first tape's pointer with the result of the operation
@ Swap the tapes (The pointers are attached to their tape)
[ Jump past the matching ] if the contents of the first tape's pointer are all zeroes or the pointer size is zero
] Jump back to the matching [ if the value of the contents of the first tape's pointer are non-zero and the pointer size is non-zero
_ Print the binary representation of both tapes to standard output and provide an indication of the position and size of the pointer. Bits with a lower position should be printed first. The actual indication may vary depending on implementation. Should be used for debugging purposes.

All other characters are treated as comments and are to be ignored.

Examples

Feel free to add more examples (with commented and uncommented versions).

Cat (12 characters)

(Commented)

+++++++ Set size to 8
~ Invert the byte so that the loop can start
[*.] Keep printing each character in the input

(Uncommented)

+++++++~[*.]

Truth Machine (29 characters)

(Commented)


>>+~++++++<< Put ascii of 0 onto first tape
@* Get input character into second tape
^ Check if the character is 0
If the character is 0 then a zero is put onto the tape otherwise there will be a non zero value on the first tape
[@ If that value is not zero switch tapes
>>[-]+[,] Move to the first 1 in the binary of 0 and decrease the pointer size to 1 and continuously print the 1 as a digit 
] End of loop
@. Otherwise switch tapes and print the 0 once

(Uncommented)


>>+~++++++<<@*^[@>>[-]+[,]]@.

Hello World! (104 characters)

The shortest known program that prints Hello, World! with the comma and trailing newline was created by the author of the language. There is too much to comment on, so there are no comments. It's a lot of character by character "bit fuckery," as phrased by the author. They also believe that it is possible to create such a program with less than 80 characters.

++++++~>~>>~>~<<<<.@^>^>>^<<<.@>>>>^..<<<<@|.-@>>>>>.[>]<.+^<.@.[>]<^<<<.>>^<<<<<.>>&<<.[>-]~++~++<.--@.

Computational Class

If the length of the tapes are unbounded, brainfuckn't is Turing complete due to its instruction set being a superset of the instruction set of a brainfuck with binary cells, which has been proven to be Turing complete by user:Keymaker. If the size of the pointer is always 1 and the instruction set is reduced to []~><, then brainfuckn't is equivalent to brainfuck with binary cells with a 1-to-1 instruction substitution. Since Ørjan Johansen proved that said version of brainfuck is Turing complete even with the added restriction of loops being nested only 2 levels deep, that same restriction applies to brainfuckn't.

External Resources