Brainiac is a user-friendly and feature-rich Brainfuck runtime. It runs interactively in the terminal and includes an optimizing interpreter and native code compiler for riscv64 and x86_64. For complete files a profiler and a transpiler for C and Zig are available. It's fast, memory safe, and colorful!
- Status
- What is Brainfuck?
- Installation
- Optimizations
- Features and usage
- Memory Safety
- Performance
- License
- Contributing
- Acknowledgments
Supported platforms:
Linux | Yes | Yes |
Windows | Yes | ?! |
Builds tested for: Zig 0.13, Zig 0.15.
Brainfuck is a minimalist esoteric programming language designed to challenge and amuse programmers with its extreme simplicity yet Turing-completeness. The language consists of eight commands and an infinite memory tape.
+ | Increment the value at the current cell |
- | Decrement the value at the current cell |
> | Move the pointer to the next cell |
< | Move the pointer to the previous cell |
. | Output the value at the current cell as an ASCII character |
, | Read one character from input and store it in the current cell |
[ | Jump to the matching ] if the current cell is zero |
] | Jump back to the matching [ if the current cell is not zero |
Other characters are ignored, allowing for creative code layouts and comment styling.
Despite its minimalism, Brainfuck is Turing-complete, allowing it to compute any computable function given enough time and memory.
Check out the releases page for prebuilt binaries for Linux and Windows.
You'll need the Zig compiler to build Brainiac.
If you have Zig installed, clone the repository and build it:
The final executable will be located in zig-out/bin. You can run it with:
Optionally, copy the executable to install it system-wide:
Brainiac supports multiple optimization levels that produce more powerful internal opcodes:
- -O1: Constant folding: Replace consecutive add/move operations with add/move immediate instructions
- -O2: Set loop optimizations: Replace patterns like [-]+++ with set immediate instructions
- -O3: Multiply-accumulate: Replace loops like [>+>++>---<<<-] with multiply-accumulate instructions
- -O4: Move elimination: Fold moves into other operations in the form of a relative cell offset
The optimization level affects all runtime features: Both interpreted and compiled code runs significantly faster, and the transpiler produces better code as well.
Performed optimizations can be seen in the profiler report, as in the following example of a modified "Hello World" program:
Hello World program without any optimizations (-O0), 125 instructions:
After constant folding (-O1), 67 instructions:
After set loop optimizations (-O2), 64 instructions:
After multiply-accumulate (-O3), 57 instructions:
After move elimination (-O4), 46 instructions:
Brainiac can run Brainfuck programs interactively in the terminal, or from a file, or from stdin (pipe). When a file is given as input, piped input will be treated as program inputs. Files can also be profiled and transpiled.
Supported cell sizes are 8, 16, 32, and 64 bit. Memory size and EOF character are configurable.
Omit the input file to start the interactive mode or pass --interactive if you want to execute a given file first.
The interpreter is pretty slow but most versatile. It can stop programs after a fixed number of instructions or profile them while they are running. The HTML report generated by the profiler can be opened in a web browser to visualize the execution count of each instruction.
Interpret a file:
Interpret piped source code:
If you'd like to play the Brainfuck text adventure "Lost Kingdom" by Jon Ripley but keep getting killed by evil magicians or rotten fish, pipe in the solution file instead:
Profile execution and memory use during interpretation of the program and generate an interactive HTML report afterward:
Example reports can be seen in the Optimizations section and are useful to identify hotspots or dead code.
Compiles Brainfuck to native code and executes it immediately:
The compiled native code runs ~10x faster than the interpreter.
The compiler works interactively, too, and supports all optimization levels, cell and memory sizes but neither profiling nor limiting the execution.
Compilation is only implemented for x86_64 and riscv64.
Optimize Brainfuck program and generate C and Zig programs:
Brainiac uses OS page protection to create danger zones on both sides of the "infinite" memory tape. If a program attempts to access cells beyond the allocated memory, it will trigger a segmentation violation, which Brainiac catches with a user-friendly error message instead of randomly crashing or corrupting process memory.
The size of these danger zones is adjusted based on static analysis of the maximum possible memory access offset.
What would be the point of optimizations without benchmarks? Let's see some numbers!
The following benchmarks were performed using Erik Bosman's Mandelbrot.b, which is both interesting and computationally intensive. Each measurement represents the fastest of three runs.
Transpiled C files were compiled with gcc -O3 and clang -O3, Brainiac with zig build -Doptimize=ReleaseFast.
Some notes on the results:
- Native compilation provides approximately a 10x speedup over the interpreter on both architectures.
- Brainiac at higher optimization levels is competitive with GCC/Clang transpilation on x86_64, while on RISC-V, compiling transpiled C code with GCC or Clang yields better results.
Comparing compiled results only:
Comparing compiled results only:
The following charts show the speedup relative to the unoptimized (-O0) baseline:
This project is licensed under the AGPL license - see the LICENSE text for details.
All files in the bf/ directory belong to their respective authors and may have varying licenses - see the Acknowledgments below.
All contributions are welcome, whether it's about typos, Zig code style, bugs, or ideas.
If you are somehow inclined to spend your valuable time on improving the execution of Brainfuck, feel free to create an issue or submit a pull request even 😉
The project is pretty modular, and new optimization passes or compiler backends should be easy to add without changing much unrelated code.
- Urban Müller for creating the Brainfuck language
- The Zig ⚡ programming language and community
- All authors of the packaged Brainfuck programs:
- Daniel B. Cristofani
- Jon Ripley et al.
- Linus Akesson
- Tim Alex Jacobs
- Erik Bosman