Troels' Brainfuck Page

Contents

  1. Introduction
  2. abf
  3. Braintwist
  4. Brainfork
  5. Resources

Introduction

Image of a gnu

Brainfuck is a programming language devised by Urban Muller during an attempt to write the smallest possible compiler for a Turing-complete language. The result of his attempt is not relevant here, what is relevant, however, is the fact that he designed a new, syntactically and semantically simple, yet Turing-complete, language. That language is what we know as Brainfuck. Brainfuck is a simple language, with a syntax devised of one-character tokens, where each token may stand for either one of 8 operators, or a comment. Everything which is not an operator is a comment, and every piece of ASCII-text can thus be considered a Brainfuck-program (given that it doesn't crash the compiler or interpreter). Of course, while this language is Turing-complete, and thus able to perform any computation that has ever been performed on any computer in the history of mankind, it is extremely complicated to do so. Writing even trivial Brainfuck-programs can often be an exercise in futility, and understanding Brainfuck-code written by other hackers is almost impossible, except for simple or well-commented programs. Of course, some consider Brainfuck an extremely interesting language exactly due to these qualities. I am not going to provide a full introduction to the Brainfuck programming language (see here for that, and further down for a list of operators), but instead focus on the work I have done with, and on, the language.

I assume the few of you who haven't left this page in utter disgust at the notion of actually writing programs in a language such as Brainfuck, are as fascinated as I am by the fact that such a simple language is actually able to perform such great feats of computation. In fact, Brainfuck rather effectively demonstrates that simplicity and elegance, which the language has in abundance, is not equal to practicality, which Brainfuck has an utter lack of. Brainfuck's 8 operators are semantically simpler than most other programming languages multitude of keywords and data types, and almost any programmer can learn the language in a few minutes. In many areas, simplicity and ease-of-learning are paramount qualities when developing software, but Brainfuck shows very clearly that these concepts, when taken to the extreme, results in something close to unusable.

Still, Brainfuck is a fascinating toy to a lot of hackers, and on this page I will try to describe some of the stuff I've made with it.

abf

abf is Athas Brainfuck, a Brainfuck-interpreter implemented in standard C++, designed as an extremely flexible interpreter, with a bias towards implementing the various dialects of the Brainfuck language. Currently, it implements Brainfork as well as Braintwist. The abf distribution also contains a number of other small tools that I find useful when writing Brainfuck: cleanbf, a source-code-cleaner, str2bf (instead of the str2bf in the abf distribution, you might want to use the somewhat more cleverly written str2bf by Craig St. Jean), a string-to-Brainfuck-code-generator and a number of utilities written in Braintwist. At this point, the documentation consists of the source code, and figuring out how to use the tools may be considered an exercise for the reader.

abf is very simple to use. It takes a filename as argument, and executes whatever code it finds in the file. Alternatively, if no file is provided, it will read code from standard input (terminated by end-of-file). The ,-operator will read from standard input in either case. If there is a mismatch of []-operators, abf will throw an exception, which may be picked up, and generate a helpful error message, at your local C++ implementations leisure. It should be noted that abf is by no means a fast interpreter. Numerically intensive production-code should be run on a faster interpreter, or perhaps even compiled to native machine code. See the resources list for links. abf is useful for testing dialects of Brainfuck, however.

abf operator reference list

This is a reference list of operators in abf
Operator Description
< Move the data pointer a single step to the left.
> Move the data pointer a single step to the right.
+ Increment the cell at the data pointer by 1.
- Decrement the cell at the data pointer by 1.
, Read a single character from standard input, and save its value in the cell at the data pointer.
. Write the character presented as an ASCII-value in the cell at the data pointer to standard output.
[ Jumps to the intruction following the matching ] if the value in the cell at the data pointer is 0, jumps to the next instruction otherwise.
] Jumps to the matching [ if the value in the cell at the data pointer is not 0, jumps to the next instruction otherwise.
Y Brainfork-feature: Splits the current execution thread into two seperate threads, with seperate execution contexts (data and code pointers). The value of the data cell following the cell pointed to by the data pointer will be set to the value of the current cell plus one, while the value of the current cell will be set to 0. One thread will continue with the data pointer pointing at the current cell, while the others data pointer will point at the next cell.
X Braintwist-feature: Swap data and code pointers in the current thread.

Tutorial

This will be a very short and simple tutorial, since part of the joy of Brainfuck is figuring stuff out for yourself. This tutorial will show how to invoke abf with an example program included in the standard distribution (look at the resources list for download links). The following operation should be identical on any Unix-system with a relatively modern shell.

      ~/code/bf++ $ ./abf eval.bf
      >+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>+
      +++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.++
      +.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.
      ^D
      ^D
      Hello World!
      ~/code/bf++ $

The eval.bf program reads from standard input until end-of-file, and executes the read characters as code. Two end-of-file characters are, due to a rather esoteric condition in the interpreter, required in this case. When using tools such as cat to pipe input, this is done automagically.

Braintwist

Braintwist is the sick child of too many energy-drinks and too little sleep. Of course, I was rather clear-headed when I implemented it, so I can't shift all the blame to various caffeinated sodas. Basically, Braintwist is a Brainfuck-dialect that permits self-modifying code. There, I said it. Braintwist defines the X-operator, which swaps the code and code pointer, and data and data pointer sets. What was code becomes data, and what was data becomes code. The two respective pointers will still point to the same positions as they did before the switch, but their use will be swapped. That means means that execution will continue from whereever the data pointer was pointing before the switch, with the data array being executed as plain Braintwist-code. Of course, later down the execution path, X-operator may be used again to perform another swap. It is important to put some code in the data array before performing the swap, as the program will otherwise just terminate without further ado (as if you ran a Brainfuck-program with nothing but comments).

Brainfork

Basically, Brainfork is multithreaded Brainfuck. I'm not going to introduce how exactly it works (look at the resources list for the official website), but merely how it is integrated into Braintwist and abf. Originally, the X-operator swapped the data and code arrays globally, but the final implementation performs per-thread switches. That means, that after a fork, one thread may invoke the X-operator, which means that what one thread sees as the data array, may be iterated through as code. This requires the programmer to be extremely careful (and a bit of a masochist) when programming with both dialects.

Resources

This section contains links to Brainfuck resources on the Internet.


Troels Henriksen athas@sigkill.dk Back to index