diff --git a/Cargo.lock b/Cargo.lock index 2501596..9bd056b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,64 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "gumdrop" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc700f989d2f6f0248546222d9b4258f5b02a171a431f8285a81c08142629e3" +dependencies = [ + "gumdrop_derive", +] + +[[package]] +name = "gumdrop_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "matcha" version = "0.1.0" +dependencies = [ + "gumdrop", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/Cargo.toml b/Cargo.toml index 7528f71..fedc1fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +gumdrop = "0.8.1" diff --git a/src/main.rs b/src/main.rs index 0e99de8..efd73f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ use std::env::args; +use std::fs::read_to_string; + +use gumdrop::Options; #[macro_use] mod lex; @@ -9,10 +12,34 @@ use parse::parse; mod interpret; use interpret::interpret; +#[derive(Debug, Options)] +struct Opts { + #[options(help = "print help message")] + help: bool, + + #[options(free, help = "matcha file")] + filename: Option, + + #[options(help = "raw matcha code to execute")] + execute: Option, +} + fn main() { - println!("\n"); // makes output easier to visually parse when run with cargo run - let args: String = args().skip(1).collect::>().join(" "); - let k = match lex_tokens(&args) { + let opt = Opts::parse_args_default_or_exit(); + let code = if let Some(code) = opt.execute { + code + } else { + let args: Vec<_> = args().collect(); + let filename = opt.filename.unwrap_or_else(|| { + eprintln!("{}: filename or -e option required", args[0]); + std::process::exit(1); + }); + read_to_string(&filename).unwrap_or_else(|e| { + eprintln!("{}: unable to read file {filename}\n{e}", args[0]); + std::process::exit(1); + }) + }; + let k = match lex_tokens(&code) { Ok(a) => a, Err((_, a)) => panic!("{a:?}"), }; @@ -20,9 +47,9 @@ fn main() { Ok(a) => a, Err(a) => panic!("{:?}", a.description), }; - let stack = match interpret(p) { + let _ = match interpret(p) { Ok(a) => a, Err(a) => panic!("{:?}", a.description), }; - println!("\nreturn: {stack:?}\n"); + //println!("\nreturn: {stack:?}"); }