Skip to content

brainfsck/c++ interop and compile-time brainfsck embedding/compilation

License

Notifications You must be signed in to change notification settings

khemritolya/libbrain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libbrain

Build Status LICENSE help please

A header-only library providing brainfsck/C++ interoperability and compile-time brainfsck compilation and embedding. To use, simply point your compiler to the libbrain.h header, or paste it into your project.

Author: Luis Hoderlein

Quick Start

#include <cstdio>
#include "libbrain.h"

int main() {
    // allocate some amount of memory for our program to work with
    auto* data = BRAIN_ALLOC_TAPE(10000);

    // compiles a program which prints "hello world!"
    // thank you KSab https://codegolf.stackexchange.com/questions/55422/hello-world/163590#163590
    BRAIN_PROGRAM hello_bf = BRAIN_COMPILE(+[>>>->-[>->----<<<]>>]>.---.>+..+++.>>.<.>>---.<<<.+++.------.<-.>>+.);

    // run the program
    // identical to `hello_bf.exec(data, 0, stout, stdin);`
    int status_code = hello_bf.exec(data, 0);
    
    delete[] data;
    
    return status_code;
}

Building

Requires:
  • C++17 or later
  • g++-7 or later

Note: libbrain currently uses a GCC exclusive feature (though I've heard clang might also have it) called a "literal operator template" in order to turn string literals into brainfsck programs. I have tried to come up with alternatives to this, but have not succeeded. If you have please submit a pull request.

Also, opening libbrain.h causes CLion's syntax highlighter to fail due to the complexity of the templates/macros involved. I'm sorry. If you have a fix please submit a pull request.

Building tests and examples
cmake CMakeLists.txt
cmake  --build .
Help my brainfsck is not working?

Enable build with debug by commenting the line in libbrain.h:

#undef LIBBRAIN_BUILD_WITH_DEBUG
Help my brainfsck is not compiling?

It takes a bit to compile. Blame the fact that I can't index into a parameter pack in faster than O(n). Enabling build with debug gives you a heuristic for how much prograss has been made.

The How

The short answer:

A mixture of C++ Constexprs and Template Metaprogramming.

The longer answer:

The BRAIN_COMPILE(...) macro expands to a literal representing a program, using the aforementioned literal operator template. A program is a templated struct which is generic over its state. This struct has an inline function to be expanded at compile time by gcc, which corresponds to a brainfsck operation. Partial template specialization is then used to allow gcc compile the current instruction and to then repeat this process for subsequent instructions.

The long answer:

For now, just look in libbrain.h. Pay attention to op_at<...>, scan_forward<...> and scan_backward<...>.

File IO with libbrain

libbrain uses c-style IO. Sorry about that. This means that when executing a program, you can specify FILE*s for whatever input and output method you want to use. By default (i.e. when not specified), libbrain runs programs using c stdout and stdin. See the example and test directories if you are particularly curious.

A Warning

libbrain offers no compile time safety for pointers. If you move the data pointer outside of the range of the tape that you have specified, that is UNDEFINED BEHAVIOR and you will suffer the same consequences (e.g. SIGSEGV) that you would in regular C++.