diff --git a/Cargo.lock b/Cargo.lock index 84d09b1a8..faac1413f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -196,6 +196,11 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "arg" +version = "1.0.0" +source = "git+https://github.com/parazyd/arg#bad0beb83e9df6d9037aa68d4624c77708c8c957" + [[package]] name = "arrayref" version = "0.3.7" @@ -7204,6 +7209,6 @@ dependencies = [ name = "zkas" version = "0.4.1" dependencies = [ - "clap 4.3.23", + "arg", "darkfi", ] diff --git a/bin/zkas/Cargo.toml b/bin/zkas/Cargo.toml index 27b79501d..d43132218 100644 --- a/bin/zkas/Cargo.toml +++ b/bin/zkas/Cargo.toml @@ -9,5 +9,5 @@ license = "AGPL-3.0-only" edition = "2021" [dependencies] -clap = {version = "4.3.22", features = ["derive"]} +arg = {git = "https://github.com/parazyd/arg"} darkfi = {path = "../../", features = ["zkas"]} diff --git a/bin/zkas/src/main.rs b/bin/zkas/src/main.rs index 5268135a6..05afe09fa 100644 --- a/bin/zkas/src/main.rs +++ b/bin/zkas/src/main.rs @@ -19,52 +19,71 @@ use std::{ fs::{read_to_string, File}, io::Write, - process::exit, + process::ExitCode, }; -use clap::Parser as ClapParser; +use arg::Args; use darkfi::{ - cli_desc, zkas::{Analyzer, Compiler, Lexer, Parser, ZkBinary}, + ANSI_LOGO, }; -#[derive(clap::Parser)] -#[clap(name = "zkas", about = cli_desc!(), version)] -struct Args { - /// Place the output into `` - #[clap(short = 'o', value_name = "FILE")] - output: Option, +const ABOUT: &str = + concat!("zkas ", env!("CARGO_PKG_VERSION"), '\n', env!("CARGO_PKG_DESCRIPTION")); - /// Strip debug symbols - #[clap(short = 's')] - strip: bool, +const USAGE: &str = r#" +Usage: zkas [OPTIONS] - /// Preprocess only; do not compile - #[clap(short = 'E')] - evaluate: bool, +Arguments: + ZK script to compile - /// Interactive semantic analysis - #[clap(short = 'i')] - interactive: bool, +Options: + -o Place the output into + -s Strip debug symbols + -p Preprocess only; do not compile + -i Interactive semantic analysis + -e Examine decoded bytecode + -h Print this help +"#; - /// Examine decoded bytecode - #[clap(short = 'e')] - examine: bool, - - /// ZK script to compile - input: String, +fn usage() { + print!("{}{}\n{}", ANSI_LOGO, ABOUT, USAGE); } -fn main() { - let args = Args::parse(); +fn main() -> ExitCode { + let argv; + let mut pflag = false; + let mut iflag = false; + let mut eflag = false; + let mut sflag = false; + let mut hflag = false; + let mut output = String::new(); - let filename = args.input.as_str(); + { + let mut args = Args::new().with_cb(|args, flag| match flag { + 'p' => pflag = true, + 'i' => iflag = true, + 'e' => eflag = true, + 's' => sflag = true, + 'o' => output = args.eargf().to_string(), + _ => hflag = true, + }); + + argv = args.parse(); + } + + if hflag || argv.is_empty() { + usage(); + return ExitCode::FAILURE + } + + let filename = argv[0].as_str(); let source = match read_to_string(filename) { Ok(v) => v, Err(e) => { eprintln!("Error: Failed reading from \"{}\". {}", filename, e); - exit(1); + return ExitCode::FAILURE } }; @@ -89,16 +108,16 @@ fn main() { let mut analyzer = Analyzer::new(filename, source.chars(), constants, witnesses, statements); analyzer.analyze_types(); - if args.interactive { + if iflag { analyzer.analyze_semantic(); } - if args.evaluate { + if pflag { println!("{:#?}", analyzer.constants); println!("{:#?}", analyzer.witnesses); println!("{:#?}", analyzer.statements); println!("{:#?}", analyzer.heap); - exit(0); + return ExitCode::SUCCESS } let compiler = Compiler::new( @@ -110,34 +129,33 @@ fn main() { analyzer.witnesses, analyzer.statements, analyzer.literals, - !args.strip, + !sflag, ); let bincode = compiler.compile(); // ANCHOR_END: zkas - let output = match args.output { - Some(o) => o, - None => format!("{}.bin", args.input), - }; + let output = if output.is_empty() { format!("{}.bin", filename) } else { output }; let mut file = match File::create(&output) { Ok(v) => v, Err(e) => { eprintln!("Error: Failed to create \"{}\". {}", output, e); - exit(1); + return ExitCode::FAILURE } }; if let Err(e) = file.write_all(&bincode) { eprintln!("Error: Failed to write bincode to \"{}\". {}", output, e); - exit(1); + return ExitCode::FAILURE }; println!("Wrote output to {}", &output); - if args.examine { + if eflag { let zkbin = ZkBinary::decode(&bincode).unwrap(); println!("{:#?}", zkbin); } + + ExitCode::SUCCESS }