命令行界面

虚拟机已经完成,剩下的就是把它包装成命令行界面 (CLI) 了。

我们使用 clap 库,用结构体定义命令行参数解析。

https://github.com/clap-rs/clap

cargo add clap --features derive

这就是 main.rs 的全部代码。

mod bfir;
mod bfjit;
mod error;

use crate::bfjit::BfVM;

use std::io::{stdin, stdout};
use std::path::PathBuf;

use clap::Parser;

#[derive(Debug, clap::Parser)]
#[clap(version)]
struct Opt {
    #[clap(name = "FILE")]
    file_path: PathBuf,

    #[clap(short = 'o', long = "optimize", help = "Optimize code")]
    optimize: bool,
}

fn main() {
    let opt = Opt::parse();

    let stdin = stdin();
    let stdout = stdout();

    let ret = BfVM::new(
        &opt.file_path,
        Box::new(stdin.lock()),
        Box::new(stdout.lock()),
        opt.optimize,
    )
    .and_then(|mut vm| vm.run());

    if let Err(e) = &ret {
        eprintln!("bfjit: {}", e);
    }

    std::process::exit(ret.is_err() as i32)
}

把写好的命令行应用安装到系统。

$ cargo install --path .
$ bfjit --help
Usage: bfjit [OPTIONS] <FILE>

Arguments:
  <FILE>  

Options:
  -o, --optimize  Optimize code
  -h, --help      Print help
  -V, --version   Print version

从 github 上找一些 brainfuck 程序运行,观察 JIT 与解释器的效率差别。

$ bfjit bf/hello.bf
Hello World!

观察折叠操作对速度的影响。

$ time bfjit bf/mendelbrot.bf > m.txt

real    0m5.858s
user    0m5.840s
sys     0m0.012s

$ time bfjit bf/mendelbrot.bf -o > m.txt

real    0m1.921s
user    0m1.903s
sys     0m0.010s

甚至可以运行一层 brainfuck 自解释器。

注意:多层自解释器的效率会严重下降,短时间内无法得出结果。

https://github.com/cagataycali/awesome-brainfuck

http://homepages.xnet.co.nz/~clive/eigenratios/cgbfi2.b