less_retarded_wiki

main page, file list, single page HTML, source, report, wiki last updated on 02/04/23

Brainfuck

Brainfuck is an extremely simple, untyped esoteric programming language; simple by its specification (consisting only of 8 commands) but intentionally very hard to program in. It works similarly to a pure Turing machine. In a way it is kind of beautiful by its simplicity. It is very easy to write your own brainfuck interpreter.

There exist self-hosted brainfuck interpreters which is pretty fucked up.

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.

Brainfuck has seen tremendous success in the esolang community as the lowest common denominator language: just as mathematicians use Turing machines in proofs, esolang programmers use brainfuck in similar ways -- many esolangs just compile to brainfuck or use brainfuck in proofs of Turing completeness 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 programs brainfuck may be seriously used as a super simple scripting language.

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:

Implementation

This is a very simple C 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++;
  }
}

Variants

TODO


All content available under CC0 1.0 (public domain). Send comments and corrections to drummyfish at disroot dot org.