EBFC(1) General Commands Manual EBFC(1)

ebfc - ELF Brainfuck compiler

ebfc [OPTIONS] SRCFILE

ebfc is a compiler for the Brainfuck programming language, creating 64-bit ELF files targeted for the Intel x86-64 architecture.

ebfc can create standalone executables, shared libraries, or object files. Object files can themselves be targeted for a standalone executable, a shared library, or a module in a larger program.

The following options control what type of source file is created. It is assumed here that the name of the source file is foo.b.
-x
Compile the source code into a standalone executable file, named foo.
-l
Compile the source code into a shared library file, named libfoo.so. The program will be exported as a function named foo().
-c
Compile the source code into a function, named foo(), in an object file, named foo.o. The object file will be targeted for a module in an executable.
-xc
Compile the source code into an object file, named foo.o, that can then be linked as a standalone executable.
-lc
Compile the source code into a function, named foo(), in an object file, named foo.o, that can then be linked as a shared library.

If the SRCFILE argument lacks a .b or .bf suffix, then the entire filename will be used when creating the name of the target file and function. (In the case of -x, the name of the target file will be a.out instead.)

-a, --arg
Compile the function to take an argument, namely a pointer to the byte array. By default, ebfc will compile its code to a function that takes no arguments, which will use an internal byte array. When this option is used, there is no difference in the object file created by -c and -lc. (This option is not applicable to a standalone executable.)
-f, --function=FUNCTION
Use FUNCTION as the name of the function to contain the compiled program. If this argument is omitted, then the function's name will be taken from the source filename, as described in the previous section.
-i, --input=FILE
Use FILE as the name of the source file to place in the target file. This option does not supersede the SRCFILE argument; it merely changes what name is stored in the object file. (This option is not meaningful if the target is not an object file, or if the --strip option is used.)
-o, --output=FILE
Use FILE as the target filename. If this option is omitted, the output filename will be generated from the source filename, as described in the previous section.
-s, --strip
Suppress inclusion of unnecessary data in the target file. By default, ebfc includes a .comment section, and includes a symbol in the symbol table for the source filename. These items will be removed from the output when this option is used. Additionally, if the output is a standalone executable, this option will suppress inclusion of the section header table.
-z, --compressed
Read the source file in compressed Brainfuck format (see below).
--help
Display help and exit.
--version
Display version number and exit.

When calling a compiled Brainfuck program from within a C program, the C prototype for the function should have the form:

extern void foo(void);

or, if the --arg option is specified:

extern void foo(char *buffer);

In the latter case, the buffer pointed to by the function parameter will be used as the initial state of the Brainfuck buffer when the function is invoked, and upon return will contain the final state of the buffer.

A Brainfuck program has an implicit byte pointer, called "the pointer", which is free to move around within an array of bytes, initially all set to zero. The pointer itself is initialized to point to the beginning of this array. (The size of the array is not constrained by the language, but is typically 30000 bytes or more. ebfc programs are given an array of 32768 bytes.)

The Brainfuck programming language consists of eight commands, each of which is 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.

The semantics of the Brainfuck commands can also be succinctly expressed in terms of C, as follows (assuming that p has been previously defined as a char*):

>
becomes  ++p;
<
becomes  --p;
+
becomes  ++*p;
-
becomes  --*p;
.
becomes  putchar(*p);
,
becomes  *p = getchar();
[
becomes  while (*p) {
]
becomes  }

As with C, the generated program's behavior is undefined if the pointer is moved outside of the byte array.

There is a compressed format for storing and transmitting Brainfuck programs, which ebfc can read natively by using the --compressed option.

In compressed Brainfuck, the eight commands are encoded in three bits as follows:

+
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, as follows:

Encoding    Bits
 Translation
singleton   00 abc abc
 abc
pair        00 abc def
 abc followed by def
triplet     10 ab cd ef
 0ab then 0cd then 0ef
repetition  01 abc def
 def repeated 2 + abc times (2-9)
repetition  11 abcd ef
 0ef repeated 2 + abcd times (2-17)

The compiler will issue an error message, and the compilation will fail, if the program contains unbalanced bracket commands, or if the level of nested brackets exceeds the compiler's maximum capacity (which is arbitrarily set at 256).

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.

May 2021 ELF kickers 3.2