# Cranefack [![docs.rs badge](https://docs.rs/cranefack/badge.svg)](https://docs.rs/cranefack/) [![crates.io badge](https://img.shields.io/crates/v/cranefack.svg)](https://crates.io/crates/cranefack/) [![Rust](https://github.com/vstroebel/cranefack/actions/workflows/rust.yml/badge.svg)](https://github.com/vstroebel/cranefack/actions/workflows/rust.yml) A cranelift powered optimizing brainfuck compiler suite. ## Commandline interface Cranefack provides a command line utility to run, compile and benchmark programs. ```shell cargo install cranefack-cli ``` ### Run Run a program with interpreter or jit.
Passing the `-v` option prints some statistics and execution time. ```text USAGE: cranefack run [FLAGS] [OPTIONS] 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 Optimization level for JIT [possible values: none, speed, speed_and_size] -O Optimization mode [default: 2] [possible values: 0, 1, 2, 3, s, wtf] ARGS: 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: ```shell cranefack compile -f=rust some_app.bf > some_app.rs rustc -O some_app.rs ./some_app ``` ```text USAGE: cranefack compile [FLAGS] [OPTIONS] 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 of compiled code [default: dump] [possible values: dump, clir, rust] --jit-level Optimization level for JIT [possible values: none, speed, speed_and_size] -O Optimization mode [default: 2] [possible values: 0, 1, 2, 3, s, wtf] ARGS: 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. ```text USAGE: cranefack benchmark [FLAGS] [OPTIONS] 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 Number of benchmarking iterations [default: 2] -r, --runs Number of runs per optimization in each round [default: 4] ARGS: 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: ```toml cranefack = "0.4" ``` To run a program with jit compilation: ```rust use std::error::Error; use cranefack::{parse, optimize_with_config, OptimizeConfig, CompiledJitModule}; fn main() -> Result<(), Box> { // 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 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) ## 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.