Ever since I first encountered esoteric programming languages, Brainfuck stood out. Its extreme minimalism was fascinating, but also intimidating. It’s Turing complete, meaning theoretically you can compute anything with it, but practically, writing or reading anything beyond simple examples is incredibly difficult. The idea of simplifying this process got stuck in my head.
This led me to create BFScript: a compiler that takes code written in a simpler, C-like syntax and translates it into functional Brainfuck code.
My initial attempt was a different project, the Brainfuck Transpiler. However, I soon realized that approach had fundamental limitations and wasn’t truly Turing complete. It couldn’t handle the complexity I envisioned. So, I decided to start over with a more robust compiler approach, which became BFScript.
Primarily, this is a passion project born out of curiosity. It’s for me, for the fun of tackling a weird challenge, and maybe for anyone else intrigued by the intersection of conventional programming and esoteric languages.
What is Brainfuck, Anyway?
Before diving into BFScript, it helps to understand the target language. Brainfuck uses only eight simple commands to manipulate a tape of memory cells:
Command | Description |
---|---|
> |
Increment the data pointer. |
< |
Decrement the data pointer. |
+ |
Increment the byte at the pointer. |
- |
Decrement the byte at the pointer. |
. |
Output the byte at the pointer. |
, |
Input a byte to the pointer. |
[ |
Jump forward if byte is zero. |
] |
Jump backward if byte is non-zero. |
A simple “Hello World!” in Brainfuck looks like this:
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
As you can see, readability isn’t its strong suit. BFScript aims to fix that!
After hitting the limits with the simple transpiler, I knew I needed a more structured approach for BFScript. I decided to build a proper compiler using Python.
The key technology choices were:
The compilation process generally involves:
.bfs
file) and validates its syntax, creating an AST.while
loop, output
call), it generates the corresponding sequence of Brainfuck commands. This involves figuring out how to manage Brainfuck’s memory tape to represent variables and control flow.The BFScript language itself evolved to include features essential for non-trivial programs:
size_t name = value;
)+
, -
)while (condition) { ... }
)output('A');
, output(variable);
)Here’s an example of BFScript code that prints a pyramid, showcasing its readability compared to raw Brainfuck:
// --- Pyramid Printer ---
// Prints a pyramid of '*' characters using nested loops.
size_t height = 7; // Declare and initialize a variable
size_t current_row = 1;
size_t chars_for_this_row = 1;
// Loop for each row
while (current_row <= height) {
// --- Print leading spaces ---
size_t spaces_needed = height - current_row;
size_t spaces_printed = 0;
while (spaces_printed < spaces_needed) {
output(' '); // Output a character literal
spaces_printed = spaces_printed + 1;
}
// --- Print the characters ('*') ---
size_t chars_printed = 0;
while (chars_printed < chars_for_this_row) {
output('*');
chars_printed = chars_printed + 1;
}
// --- Print a newline character ---
output('\n');
// --- Prepare for the next row ---
current_row = current_row + 1;
// Add 2 characters for the next row (1 -> 3 -> 5 -> ...)
chars_for_this_row = chars_for_this_row + 2;
}
This is much easier to understand and maintain!
This project was definitely challenging, pushing me to learn quite a bit.
Technical Challenges:
while
loops or arithmetic efficiently using only +
, -
, <
, >
, [
, ]
? This required studying Brainfuck programming techniques and designing specific Brainfuck “subroutines” for common operations. Managing the data pointer (<
, >
) effectively to avoid unnecessary movement was also tricky.Non-Technical Challenges: Mostly time management and staying motivated on a project that’s complex and doesn’t have an immediate practical application outside of the learning experience itself.
Solutions:
BFScript is currently functional and usable. You can write programs like the pyramid example above and compile them into working Brainfuck code. While there’s always room for improvement and more features, I’m happy with its current state as a proof-of-concept and a learning tool.