Brainfuck is a minimalist esoteric programming language created by Urban Müller in 1993. It operates on a tape of memory cells using a data pointer, with only 8 commands. Despite its simplicity, it is Turing complete.
All data is stored as unsigned 8-bit integers (u8, range 0–255)
with wrapping arithmetic. Incrementing 255 gives 0; decrementing 0 gives 255.
A Brainfuck program consists of the 8 command characters listed below. All other characters are ignored and can be used as comments.
| Command | Description | Effect |
|---|---|---|
> | Move right | Increment the data pointer by one |
< | Move left | Decrement the data pointer by one |
+ | Increment | Increment the byte at the data pointer (wraps 255 → 0) |
- | Decrement | Decrement the byte at the data pointer (wraps 0 → 255) |
. | Output | Output the byte at the data pointer as an ASCII character |
, | Input | Read one byte of input into the cell at the data pointer (0 if no input) |
[ | Jump forward | If the byte at the data pointer is 0, jump to the matching ] |
] | Jump back | If the byte at the data pointer is nonzero, jump to the matching [ |
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-] >>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
,[.,]
++ Set cell 0 to 2 >+++ Set cell 1 to 3 <[->+<] Move cell 0 into cell 1 (addition) > Move to cell 1 (now 5) ++++++++++++++++++++++++++++++++++++++++++++++++. Add 48 for ASCII '5'
+++++++ Set cell 0 to 7
[>+++++++<-] Multiply into cell 1: 7×7 = 49 (ASCII '1')
Cell 0 is now 0
< (already at cell 0)
+++++ Set cell 0 to 5 (loop counter)
[ While cell 0 is nonzero
>.+ Print cell 1, then increment it
<- Decrement counter
]
Brainfuck supports HTTP requests, KV storage, and environment variable access via memory-mapped I/O. The tape is extended to 33,000 cells, with cells 30,000–32,004 reserved for I/O control. Programs write parameters into designated cells and trigger execution by writing a non-zero value to the trigger cell.
| Cells | Purpose | Size |
|---|---|---|
| 0–29,999 | Normal workspace | 30,000 bytes |
| 30,000–30,499 | URL / Key buffer (null-terminated) | 500 bytes |
| 30,500–30,999 | Body / Value buffer (null-terminated) | 500 bytes |
| 31,000–31,999 | Response buffer (written on resume) | 1,000 bytes |
| 32,000 | IO_STATUS (0=idle, 1=success, 2=error) | 1 byte |
| 32,001 | IO_METHOD (see table below) | 1 byte |
| 32,002 | IO_RESP_LEN_LO (response length & 0xFF) | 1 byte |
| 32,003 | IO_RESP_LEN_HI (response length >> 8) | 1 byte |
| 32,004 | IO_EXEC (write non-zero to trigger) | 1 byte |
| IO_METHOD | Operation | URL/Key Buffer | Body/Value Buffer |
|---|---|---|---|
| 1 | HTTP GET | URL | (unused) |
| 2 | HTTP POST | URL | Request body |
| 3 | KV GET | Key | (unused) |
| 4 | KV SET | Key | Value |
| 5 | KV DELETE | Key | (unused) |
| 6 | ENV | Variable name | (unused) |
After the trigger, execution suspends. The runtime fulfills the I/O request and writes the response into cells 31,000+, sets IO_STATUS to 1 (success) or 2 (error), writes the response length into IO_RESP_LEN_LO/HI, and resets IO_EXEC to 0. ENV (method 6) is resolved locally without suspending.
This annotated program fetches https://httpbin.org/ip and
prints the response. The full program is ~35,000 characters.
Phase 1: Navigate to URL buffer (cell 30,000)
>>>>>...>>>>> 30,000 > characters
Phase 2: Write URL byte-by-byte
++++...++++++ > 104 +'s = 'h' (ASCII 104), advance
++++...++++++ > 116 +'s = 't' (ASCII 116), advance
... (22 bytes for "https://httpbin.org/ip")
Phase 3: Navigate to IO_METHOD (cell 32,001)
>>>>>...>>>>> + 1,979 >'s (skip past remaining URL + body buffers)
+ sets method = 1 (HTTP GET)
Phase 4: Trigger I/O (cell 32,004)
>>>+ 3 >'s to reach IO_EXEC, + triggers
Execution suspends here
Phase 5: Navigate to response buffer (cell 31,000)
<<<<<...<<<<< 1,004 < characters (32,004 → 31,000)
Phase 6: Print response
[.>] Loop: print byte, advance, until null
u8 (0–255, wrapping)