Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kneelian/bfntp
a brainfuck interpreter/transpiler
https://github.com/kneelian/bfntp
brainfuck brainfuck-interpreter brainfuck-transpiler transpiler
Last synced: about 1 month ago
JSON representation
a brainfuck interpreter/transpiler
- Host: GitHub
- URL: https://github.com/kneelian/bfntp
- Owner: kneelian
- License: bsd-3-clause
- Created: 2023-12-15T21:11:53.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2023-12-16T13:56:08.000Z (about 1 year ago)
- Last Synced: 2024-02-22T05:25:48.532Z (11 months ago)
- Topics: brainfuck, brainfuck-interpreter, brainfuck-transpiler, transpiler
- Language: C++
- Homepage:
- Size: 137 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# bfntp
A simple Brainfuck/bf interpreter and transpiler
## About Brainfuck
The programming language [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) is a Turing-complete minimalistic esoteric language (esolang) by Urban Müller. It isn't the smallest possible such language (for a more minimal example, check out the Wiki page on [OISC](https://en.wikipedia.org/wiki/One-instruction_set_computer)s), but it did inspire a lot of modern interest in esolangs. It is also very dear to me: it was, unfortunately, the first programming language I actually used, and the one I learned programming with.
## About bfntp
This repository contains the code to a relatively simple interpreter/compiler for Brainfuck that I call **bfntp** (short for **B**rain**f**uck i**nt**er**p**reter) that I wrote in a few evenings. It's not particularly clean or serious code, and the resulting interpreter is *not* particularly efficient or fast: on my machine, it takes it ~7.25 seconds on my machine to run the sample `mandelbrot.bf` program, whereas [rdebath's tritium](https://github.com/rdebath/Brainfuck/tree/master/tritium) blazes through it in ~0.4 seconds using the option `-b16`. Nevertheless, it *does* perform some optimisations, enabled with the flag `-o`, and without them it takes it ~22.5 seconds to print the Mandelbrot set. It's also got a tiny Brainfuck analysis toolset, currently only counting the number of executed instructions from start to finish (with the `-c` flag).
Apart from just interpreting Brainfuck code directly, `bfntp` has the ability to transpile it to C++ code that uses a `std::vector` as its memory tape, which (with Brainfuck optimisations and using `-O3` with your C++ compiler of choice) provides a reasonably performant binary that is, for example, only ~2x slower than the `tritium` JIT interpreter for `mandelbrot.bf`.
`bfntp` uses 16-bit cells in a `std::vector<>` tape, though any numeric type that implements `{ ++, --, +=, -= }` comparisons with integers and overflow wraparound can be substituted with minimal changes (for example, if you want to use floating point cells, it's not going to be a simple edit because they don't wrap from highest to lowest). Larger cell types can sometimes increase runtime significantly, due to how Brainfuck programs use wraparound, though this completely depends on the program in question. By default, it provides a tape that is 32768 cells long and accessing beyond the end of tape *on either end* will probably give you a segfault; in safe mode (enabled by the `-s` flag; has not been fully tested with optimisations), the interpreter checks for out-of-bounds accesses and grows the tape every time it runs out, and makes sure you can't read before the beginning of the tape (so a program that starts with `<+` will not segfault in safe mode). An unfortunate drawback of safe mode is that it can be slower than regular mode, since it will perform a large number of checks every time the data pointer is adjusted (basically, whenever the program encounters `<` or `>`, which is *frequently*).
There are many obvious clean-up areas and optimisation tactics that aren't used: `bfntp` was put together in the span of a few evenings and is not an exceptionally powerful tool, but it does fully support all vanilla Brainfuck features. Physical limitations aside, it provides a full Turing-complete environment (though not a particularly fast one).
Currently, `bfntp` has the following optimisations implemented and planned:
- [x] clear-loop elimination (`[-]` and `[+]` alone)
- [x] run-length encoding (folding e.g. `>>>>` into the struct `{4, RIGHT}`)
- [ ] folding of elementary arithmetic (e.g. `[->>>+<<<]` into `{3, ADD_RIGHT}`)
- [ ] fusing of moves into operations in general (e.g. `>>>+++<<<` into `{3, 3, RIGHT, ADD}`)?
- [ ] dead loop elimination (e.g. elision of `[-][>+++<-]`)?
- [ ] folding of zero-add into assignment (e.g. `[-]+++++` into `{5, ASSIGN}`)?## Usage
`bfntp` is a bit finnicky to use. It takes the filepath of the brainfuck input file as its first argument, and all other command-line options always follow it. It will complain if the first argument isn't a file path. You can use the option `-h` to see the full set of options provided by `bfntp` and commentary on each of them (obviously, you don't need to provide a file path for the usage notes).
## Building
There is one external dependency, [fmt](https://github.com/fmtlib/fmt), and `bfntp` was built against v10.0.0 of the library; it expects its headers in `./include/fmt`, and its shared library object in `./lib`. There is a `build.sh` script in the root directory, the contents of which are simply `g++ *.cpp -o main.a -O3 -Iinclude -L./lib -lfmt`. The `fmt` library can be relatively easily replaced with `printf()`, though I haven't taken the time to do so as I wanted to experiment a little with it. `bfntp` should build with any compiler compatible with C++11, as the `fmt` header uses type traits, and `bfntp` itself uses fixed-width integer types. Rewriting it to comply with C++03 would probably be an easy job (replace `fmt`, and either add `#include ` or just use the regular types), but it's more hassle than I feel is worth (I don't see myself using a compiler that's stuck on C++03 any time soon).
## Changelog
- v0.2c: changed the way the input functionality works, to conform to expectations of Lost Kingdom
- v0.2b: fixed the segfault when trying to use safe-mode with optimisations
- v0.2a: code clean-up, separating monolith into files; no functional changes
- v0.1a: initial release