Brainfuck

 back   


Introduction  -   Program 1  -   Program 2  -   Program 3  -   To go further  -   Links


Introduction

Brainfuck (aka Brainf*ck, brainf*** or even BF for the more constipated) is a minimalist computer programming language created by Urban Müller around 1993. Müller's goal was to create a simple Turing-complete programming language which could be implemented with the smallest possible compiler. It is also a Turing tarpit, ie a programming language designed to be Turing-complete while minimizing the number of distinct instructions (8 commands in that case, all with 0 operands).

A programming language is said to be Turing-complete if it has computational power equivalent to a universal Turing machine.

A Turing machine is made of a read/write head going forward or backward along an infinite-length tape divided into cells, a stats register that stores the current state, and an actions table that tells what to do in a defined state, or rather given a state-symbol combination. Well, indeed, the tape is finite at any time but new cells are added whenever the read/write head reaches one end, for it was important to Turing that the machine would be possible to build in reality. Nevertheless, it remains an ideal, imaginary and abstract machine, refined model of the actual computers.

Speaking Code: Coding as Aesthetic and Political Expression Speaking Code: Coding as Aesthetic and Political Expression
Geoff Cox
The MIT Press
Software Studies: A Lexicon Software Studies: A Lexicon
Matthew Fuller
The MIT Press

The eight Brainfuck statements, each consisting of a single character, are the following:
+  increment the cell value
-  decrement the cell value
>  move the read/write head on the right cell (next one)
<  move the read/write head on the left cell (previous one)
[  start a loop (like a while)
]  end a loop
.  write an ASCII character on the standard output
,  read an ASCII character from the standard input

Unlike a Turing machine, brainfuck doesn't have a read/write head or a tape. Instead it has a pointer and an array of at least 30,000 cells. The < and > instructions thus move the pointer within that array. The Turing machine metaphor is therefore kept for convenience only.

There are many interpreters for that language, among them is Daniel Lorch's one, written in PHP and used there (see http://daniel.lorch.cc/projects/brainfuck/).

I'm going to use there Daniel Lorch's PHP interpreter to make my first steps (and yours) in Brainfuck (a local copy is available too, but can be not up-to-date).
To use that tool, the PHP script will look like that:

<?php
	include "brainfuck.php";
	echo brainfuck("_Brainfuck_source_code_");
?>

Let's go now to the Brainfuck programming through a series of short programs that will go beyond your wildest expectations.


The first stage will display the digits from 0 to 9.

We will use an incremental counter (initialisation and units), one cell for the units and one for the space character. The @number notation is used to describe the cell number number of the tape (recall the Turing machine...), ie the content of the cell number number of the array (if you prefer to stick to arrays and pointers).

@0: counter
@1: character '0' (ASCII 48)
@2: character space (ASCII 32)
The commented program is:
'0' (ASCII 48)
+++++[->++++++++++<]>--
<
' ' (ASCII 32)
+++[->>++++++++++<<]>>++

<<
----------[+>.>.<+<]
And runs in three steps:
  • 48 (= 5*10-2) is set in @1
  • 32 (= 3*10+2) is set in @2
  • we display the content of @1, then of @2, and we increment @1, the whole of it 10 times

The second stage will display the numbers from 10 to 19.

We will use an incremental counter (initialisation and units), one cell for the tens (fixed), one for the units and one for the space character.

@0: counter
@1: character '1' (ASCII 49)
@2: character '0' (ASCII 48)
@3: character espace (ASCII 32)
The commented program is:
'0' (ASCII 48)
+++++[->++++++++++<]>--
<
'1' (ASCII 49)
+++++[->>++++++++++<<]>>-
<<
' ' (ASCII 32)
+++[->>>++++++++++<<<]>>>++
<<<
----------[+>>.<.>>.<<+<]

And runs in four steps:
  • 48 (= 5*10-2) is set in @1
  • 49 (= 5*10-1) is set in @2
  • 32 (= 3*10+2) is set in @3
  • we display the content of @2 (ten), then of @1 (unit), then of @3 (space), and we increment @1, the whole of it 10 times

The third (and last) stage will display the numbers from 0 to 99.

We will use two counters: a global one (initialisation, then main loop) and one for the units, and three cells: one for the units, one for the tens and one for the space character.

@0: updating main counter
@1: units counter
@2: units, initialised to character '0' (ASCII 48)
@3: tens, initialised to character '0' (ASCII 48)
@4: character space (ASCII 32)
The commented program is:
initialisation
'0' (ASCII 48)
+++++[->>++++++++++<<]>>--
<<
'0' (ASCII 48)
+++++[->>>++++++++++<<<]>>>--
<<<
' ' (ASCII 32)
+++[->>>>++++++++++<<<<]>>>>++

<<<

main loop: set the number of loops in @0
<
++++++++++[->

display loop
----------[+>>.<.+>>.<<<]
reset units cell to '0'
>
----------
add 1 to the tens cell
>+

<<<]
And runs in four steps:
  • initialisation: 48 (= 5*10-2) is set in @2 ('0' unit)
  • initialisation: 48 (= 5*10-2) is set in @3 ('0' ten)
  • initialisation: 32 (= 3*10+2) is set in @4 (' ' space)
  • main loop: main counter @0 set to 10
    • we display the content of @3 (tens), then of @2 (units), and then of @4 (space), then we increment the units counter @1, the whole of it 10 times
    • we reset the units cell @2 to '0'
    • and we increment the tens cell @3 of 1

We have now reached the end of that short tutorial that has maybe make you feel eager to program a Turing machine with the Brainfuck language.


To go further:

Programming is a matter of taste and habits, but furthermore, this is a matter of improvement and feedback. This part is a free speech area opened to those who want to add some information to this tutorial.

Daniel Cristofani shows us how to initialize both @1 (character '0' aka ASCII 48) and @2 (character space aka ASCII 32) in the same loop in the first program (digits from 0 to 9), as 48=8*6 and 32=8*4. It spells out as: ++++++++[>++++++>++++<<-]
Besides, positive numbers are slightly more portable than negative ones, so the displaying part (----------[+>.>.<+<]) can be rewritten as: ++++++++++[>.+>.<<-] (the decrementing loop is now an incrementing one).
And the whole can be further combined as: ++++++++[>+>++++++>++++<<<-]>++[>.+>.<<-]
In the same way, program 2 (numbers from 10 to 19) can be rewritten as:
++++++++[>+>++++++>++++++>++++<<<<-]>>+<++[>.>.+>.<<<-]
and program 3 (numbers from 0 to 99) as:
>++++++++[<+>>++++++>++++++>++++<<<-]
<++[>++++++++++[>.>.+>.<<<-]>+>----------<<<-]


Links:

Daniel Lorch's PHP interpreter (and some good documentation for a beginner)
Introduction to Brainfuck
Daniel Cristofani's brainfuck page (with a collection of programs)

Books:


 back