This is a pet project.
Brainfuck and Brainfork are well-known esoteric programming languages. While both are fully turing complete, they are not intened to practical use. 😉
But each of them is an ideal candidate to learn how to write by yourself an interpreter, REPL, compiler or virtual machine and in overall - play by doing it. It is also an interesting place to learn and verify various concepts like e.g. property based testing (with manopapad/proper) or working with an amazing tracing support in Erlang (and equally terrific ferd/recon library with facilities for analyzing/detecting common problems in the systems built on top of Erlang VM).
- Grab
rebar3
binaries from here. rebar3 compile
rebar3 shell
- Invoke following commands in the Erlang shell:
application:ensure_all_started(bferl).
bferl_app:attach_console().
- Now you can play with all kind of Brainfuck / Brainfork programs!
- See the documentation for more examples.
- During development, you will probably need:
- To run tests, by invoking command:
rebar3 ct
- To perform a Dialyzer analysis, by invoking command:
rebar3 dialyzer
Supported and tested on:
- Erlang 17.5
- Erlang 18.0, 18.1, 18.2, 18.2.1 and 18.3
- Erlang 19.0
If you want to start playing without any hassle, here you have an example program which adds two digits (represented as ASCII
characters) and display result of that operation:
1> bferl_app:run_code(",>++++++[<-------->-],[<+>-]<.").
> 2
> 3
5
{interpreter,...}
As a result of the invocation we returned the internal state of the interpreter after the program execution.
Note: You have probably noticed that it will not produce proper results if the result will be greater than '9'. 😉
Interested in more? Dive into one of those pages:
- Architecture - General overview and architecture documentation.
- REPL - Description of REPL and Interpreter subsystems.
- Compiler - Description of the Compiler subsystem (compilation to Core Erlang representation).
- Virtual Machine - Description of the Virtual Machine subsystem.
- Further improvements:
- REPL and Interpreter - Detecting infinite loop based on IC observation (increasing trend).
- Compiler - Safe pointer operations in
debug
mode. - Compiler - Dump pretty printed Core Erlang to a file.
- Compiler - Additional stage for various optimizations.
- Removing unused code (scan generated code and remove implementation of unused instructions).
- Rolling up increments, decrements and pointer movements.
- Virtual Machine - Additional stage for instructions rewrite optimizations (
optimize
).- Rolling up increments / decrements.
- Rolling up pointer movements.
- Replacing reading from input with constant loading when tape provided.
- Virtual Machine - Additional stage for JIT optimizations (
jit
).- Using
jnze
instead of plainjmp
andjze
.- How? We have to remove
jze
, insertjnze
with the same index and rewrite jump table prepared at the beginning. It should be optimized after several rounds (e.g. at least 5 iterations).
- How? We have to remove
- Using
- Adding support for
Y
instruction (Brainfork) - it make sense only in the Compiler and Virtual Machine.- For Virtual Machine - fork uses new
bferl_vm_thread
process with cloned state. - For Compiler - fork should
spawn_link
a new process with logic and its own memory.
- For Virtual Machine - fork uses new