EBFC(1)
π EBFC(1) β like, the ELF Brainfuck compiler bestie π
okay so bestie, sit DOWN, because this is the ebfc manual page from section 1 of the General Commands Manual and it's genuinely iconic. it's the ELF Brainfuck compiler, and yes, that is exactly as powerful as it sounds. π§β¨
β¨ NAME β¨
ebfc β the ELF Brainfuck compiler. that's it, that's the whole name, no cap. π
πΈ SYNOPSIS πΈ
ebfc [OPTIONS] SRCFILE
like, options first, then your source file. simple. gorgeous. periodt. π
π DESCRIPTION π
ebfc is a compiler for the Brainfuck programming language, and the way that it creates 64-bit ELF files targeted for the Intel x86-64 architecture? it's giving main character energy, fr fr. ππ
and it's not a one-trick pony either β ebfc can create:
- standalone executables
- shared libraries
- object files
and those object files can themselves be targeted for a standalone executable, a shared library, or a module in a larger program. versatility! we love to see it. π¦
π― COMPILATION TARGET OPTIONS π―
these options control what type of source file gets created. for all of these, the manpage assumes your source file is named foo.b. (yes, foo.b, iconic name, no notes. π)
-xβ compiles the source code into a standalone executable file, namedfoo.-lβ compiles the source code into a shared library file, namedlibfoo.so. the program gets exported as a function namedfoo().-cβ compiles the source code into a function, namedfoo(), inside an object file namedfoo.o. this object file is targeted for a module in an executable.-xcβ compiles the source code into an object file, namedfoo.o, that can then be linked as a standalone executable.-lcβ compiles the source code into a function, namedfoo(), inside an object file namedfoo.o, that can then be linked as a shared library.
β οΈ okay important bit: if theSRCFILEargument doesn't have a.bor.bfsuffix, then the entire filename gets used when creating the name of the target file and function. and for-xspecifically? the target file is nameda.outinstead. slay but make sure you know which one you're getting. π
π οΈ OTHER OPTIONS π οΈ
-a,--argβ compiles the function so it takes an argument, namely a pointer to the byte array. by default,ebfccompiles its code to a function that takes no arguments, and that one uses an internal byte array. when this option is used, there's no difference between the object file created by-cand the one created by-lc. (also β this option is not applicable to a standalone executable.) π«Ά-f,--function=FUNCTIONβ usesFUNCTIONas the name of the function that contains the compiled program. if you don't pass this argument, the function's name gets taken from the source filename, exactly like described in the previous section. β¨-i,--input=FILEβ usesFILEas the name of the source file to place in the target file. heads up: this option does not supersede theSRCFILEargument β it just changes what name gets stored in the object file. (and it's not meaningful if the target isn't an object file, or if the--stripoption is used.) π-o,--output=FILEβ usesFILEas the target filename. skip it and the output filename gets generated from the source filename, same as described in the previous section. π-s,--stripβ suppresses inclusion of unnecessary data in the target file. by defaultebfcincludes a.commentsection and includes a symbol in the symbol table for the source filename. this option removes both of those from the output. additionally, if the output is a standalone executable, this option suppresses inclusion of the section header table. π-z,--compressedβ reads the source file in compressed Brainfuck format (see below, bestie, it's a whole thing). π¦--helpβ displays help and exits. π--versionβ displays the version number and exits. β
π LINKING π
when you're calling a compiled Brainfuck program from inside a C program, the C prototype for the function should look like this:
extern void foo(void);
or, if you used the --arg option, it should look like this instead:
extern void foo(char *buffer);
in that latter case, the buffer pointed to by the function parameter gets used as the initial state of the Brainfuck buffer when the function is invoked, and upon return it'll contain the final state of the buffer. it's giving give-and-take. iykyk. π«Άβ¨
π§ THE BRAINFUCK PROGRAMMING LANGUAGE π§
a Brainfuck program has an implicit byte pointer, called "the pointer", and that pointer is free to move around within an array of bytes that are initially all set to zero. the pointer itself is initialized to point to the beginning of this array.
π side note: the size of the array isn't constrained by the language, but it's typically 30000 bytes or more. ebfc programs get an array of 32768 bytes. no cap.
the Brainfuck programming language consists of eight commands, each represented as a single character:
>β increment the pointer.<β decrement the pointer.+β increment the byte at the pointer.-β decrement the byte at the pointer..β output the byte at the pointer.,β input a byte and store it in the byte at the pointer.[β jump to the matching]if the byte at the pointer is zero.]β jump to the matching[.
any other characters in the source code are treated as comments or whitespace and ignored. so go ahead, write a whole essay in there, it's fine. π
the semantics of the Brainfuck commands can also be expressed succinctly in terms of C, like this (assuming p has previously been defined as a char*):
> becomes ++p;
< becomes --p;
+ becomes ++*p;
- becomes --*p;
. becomes putchar(*p);
, becomes *p = getchar();
[ becomes while (*p) {
] becomes }
β οΈ and just like with C, the generated program's behavior is undefined if the pointer is moved outside of the byte array. do not do this. i am begging. π
ποΈ COMPRESSED BRAINFUCK ποΈ
there's a compressed format for storing and transmitting Brainfuck programs, and ebfc can read it natively by using the --compressed option. it's giving zip file but for vibes. π
in compressed Brainfuck, the eight commands are encoded in three bits, like this:
+ 000
- 001
< 010
> 011
[ 100
] 101
, 110
. 111
each byte in a compressed Brainfuck file contains one or more commands. the top two bits select between one of four possible readings of the lower six bits, like this:
- singleton β bits
00 abc abcβ translation:abc - pair β bits
00 abc defβ translation:abcfollowed bydef - triplet β bits
10 ab cd efβ translation:0abthen0cdthen0ef - repetition β bits
01 abc defβ translation:defrepeated2 + abctimes (2-9) - repetition β bits
11 abcd efβ translation:0efrepeated2 + abcdtimes (2-17)
look at that compression. she's efficient. she's compact. she ate. π
π¨ ERRORS π¨
the compiler will issue an error message, and the compilation will fail, if:
- the program contains unbalanced bracket commands, or
- the level of nested brackets exceeds the compiler's maximum capacity β which is arbitrarily set at 256.
so like, nest responsibly bestie. ππ
π COPYRIGHT π
Copyright Β© 1999, 2001, 2021 Brian Raiter <breadbox@muppetlabs.com>.
License GPLv2+: GNU GPL version 2 or later. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
and that's the whole page, bestie!! π this was ELF kickers 3.2, dated May 2021, and you just read the EBFC(1) manpage. go compile something unhinged. i'm obsessed with you. πβ¨π
π¦ where this page comes from
- arch rolling: elfkickers 3.2-6 Β· GPL-2.0-or-later
- debian trixie: elfkickers 0+git20240221+ds-5
- nixos 26.05: elfkickers 3.2
- nixpkgs unstable: elfkickers 3.2
- ubuntu resolute: elfkickers 3.2+ds-1
- ubuntu stonking: elfkickers 3.2+ds-1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms