less_retarded_wiki/brainfuck.md
2024-02-04 07:54:26 +01:00

114 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Brainfuck
Brainfuck is an extremely simple, untyped [esoteric programming language](esoland.md); simple by its specification (consisting only of 8 commands) but intentionally very hard to program in. It works similarly to a pure [Turing machine](turing_machine.md). In a way it is kind of [beautiful](beauty.md) by its [simplicity](minimalism.md). It is very easy to write your own brainfuck [interpreter](interpreter.md).
There exist [self-hosted](self_hosting.md) brainfuck interpreters and compilers (i.e. themselves written in brainfuck) which is pretty fucked up. The smallest one is probably the one called [dbfi](dbfi.md) which has only slightly above 400 characters, that's incredible!!! (Esolang wiki states that it's one of the smallest self interpreters among imperative languages).
The language is based on a 1964 language P´´ which was published in a mathematical paper; it is very similar to brainfuck except for having no [I/O](io.md).
Brainfuck has seen tremendous success in the [esolang](esolang.md) community as the **lowest common denominator language**: just as mathematicians use [Turing machines](turing_machine.md) in proofs, esolang programmers use brainfuck in similar ways -- many esolangs just compile to brainfuck or use brainfuck in proofs of [Turing completeness](turing_complete.md) etc. This is thanks to brainfuck being an actual, implemented and working language reflecting real computers, not just a highly abstract mathematical model with many different variants. For example if one wants to encode a program as an integer number, we can simply take the binary representation of the program's brainfuck implementation.
In [LRS](lrs.md) programs brainfuck may be seriously used as a super simple [scripting language](script.md).
Brainfuck can be trivially translated to [comun](comun.md) like this: remove all comments from brainfuck program, then replace `+`, `-`, `>`, `<`, `.`, `,`, `[` and `]` with `++ ` , `-- `, `$>0 `, `$<0 `, `->' `, `$<0 <- `, `@' ` and `. `, respectively, and prepend `$>0 `.
## Specification
The "vanilla" brainfuck operates as follows:
We have a linear memory of **cells** and a **data pointer** which initially points to the 0th cell. The size and count of the cells is implementation-defined, but usually a cell is 8 bits wide and there is at least 30000 cells.
A program consists of these possible commands:
- `+`: increment the data cell under data pointer
- `-`: decrement the data cell under data pointer
- `>`: move the data pointer to the right
- `<`: move the data pointer to the left
- `[`: jump after corresponding `]` if value under data pointer is zero
- `]`: jump after corresponding `[` if value under data pointer is not zero
- `.`: output value under data pointer as an ASCII character
- `,`: read value and store it to the cell under data pointer
## Implementation
This is a very simple [C](c.md) implementation of brainfuck:
```
#include <stdio.h>
#define CELLS 30000
const char program[] = ",[.-]"; // your program here
int main(void)
{
char tape[CELLS];
unsigned int cell = 0;
const char *i = program;
int bDir, bCount;
while (*i != 0)
{
switch (*i)
{
case '>': cell++; break;
case '<': cell--; break;
case '+': tape[cell]++; break;
case '-': tape[cell]--; break;
case '.': putchar(tape[cell]); fflush(stdout); break;
case ',': scanf("%c",tape + cell); break;
case '[':
case ']':
if ((tape[cell] == 0) == (*i == ']'))
break;
bDir = (*i == '[') ? 1 : -1;
bCount = 0;
while (1)
{
if (*i == '[')
bCount += bDir;
else if (*i == ']')
bCount -= bDir;
if (bCount == 0)
break;
i += bDir;
}
break;
default: break;
}
i++;
}
}
```
TODO: comun implementation
## Programs
Here are some simple programs in brainfuck.
Print `HI`:
```
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ . + .
```
Read two 0-9 numbers (as ASCII digits) and add them:
```
,>,[<+>-]<------------------------------------------------.
```
TODO: more
## Variants
TODO