Skip to content

An optimizing brainfuck compiler

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

vstroebel/cranefack

Repository files navigation

Cranefack

docs.rs badge crates.io badge Rust

A cranelift powered optimizing brainfuck compiler suite.

Commandline interface

Cranefack provides a command line utility to run, compile and benchmark programs.

cargo install cranefack-cli

Run

Run a program with interpreter or jit.
Passing the -v option prints some statistics and execution time.

USAGE:
    cranefack run [FLAGS] [OPTIONS] <FILE>

FLAGS:
        --debug-optimizations    Print statistics for optimization passes
    -j, --jit                    Use JIT compiler
    -v, --verbose                
        --wrapping-is-ub         Wrapping overflows are undefined behavior during optimization
    -h, --help                   Prints help information
    -V, --version                Prints version information

OPTIONS:
        --jit-level <level>    Optimization level for JIT [possible values: none, speed, speed_and_size]
    -O <mode>                  Optimization mode [default: 2]  [possible values: 0, 1, 2, 3, s, wtf]

ARGS:
    <FILE>    Brainfuck source file. Use - to read from stdin

Compile

Compile the program.
As of now this will create an assembly like representation by default that is only useful for debugging.
In case you need something to compile into a native binary you can use the rust output format to get ugly rust code that can be compiled with rustc:

cranefack compile -f=rust some_app.bf > some_app.rs
rustc -O some_app.rs
./some_app
USAGE:
    cranefack compile [FLAGS] [OPTIONS] <FILE>

FLAGS:
        --debug-optimizations    Print statistics for optimization passes
    -v, --verbose                
        --wrapping-is-ub         Wrapping overflows are undefined behavior during optimization
    -h, --help                   Prints help information
    -V, --version                Prints version information

OPTIONS:
    -f, --format <format>      Format of compiled code [default: dump]  [possible values: dump, clir, rust]
        --jit-level <level>    Optimization level for JIT [possible values: none, speed, speed_and_size]
    -O <mode>                  Optimization mode [default: 2]  [possible values: 0, 1, 2, 3, s, wtf]

ARGS:
    <FILE>    Brainfuck source file. Use - to read from stdin

Benchmark

Runs a program with different optimization settings and returns a table this the time for each program run.

USAGE:
    cranefack benchmark [FLAGS] [OPTIONS] <FILE>

FLAGS:
    -j, --jit               Only benchmark jit
    -o, --optimized-only    Don't benchmark O0
    -h, --help              Prints help information
    -V, --version           Prints version information

OPTIONS:
    -i, --iterations <ITERATIONS>    Number of benchmarking iterations [default: 2]
    -r, --runs <RUNS>                Number of runs per optimization in each round [default: 4]

ARGS:
    <FILE>    Brainfuck source file. Use - to read from stdin

Use cranefack as a library

To use cranefack as a library add the following to your Cargo.toml dependencies:

cranefack = "0.4"

To run a program with jit compilation:

use std::error::Error;
use cranefack::{parse, optimize_with_config, OptimizeConfig, CompiledJitModule};

fn main() -> Result<(), Box<dyn Error>> {

    // Parse program
    let mut program = parse("++[<].")?;

    // Create optimization config for level 2
    let opt_level = OptimizeConfig::o2();

    // Optimize with optimization level 2
    optimize_with_config(&mut program, &opt_level);

    // Compile program into module
    let module = CompiledJitModule::new(&program, &opt_level)?;

    // Execute compiled module reading from stdin and writing to stdout
    module.execute(std::io::stdin(), std::io::stdout());

    Ok(())
}

License

This project is licensed under either of

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in cranefack by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.