use std::{fs, io::{BufRead, Write}}; use errors::RunError; use execute::execute; use parse::parse; use stack::Stack; mod stack; mod parse; mod execute; mod instructions; mod errors; const HELP: &str = "\ labast - Labaski interpreter written in Rust. usage: labast [options] [ file.lb ] options: -h, --help prints help information -v, --version prints version "; fn main() { let args = match parse_args() { Ok(v) => v, Err(e) => { eprintln!("Error: {}.", e); std::process::exit(1); } }; let mut stack = Stack::new(); if args.input.is_none() { let mut line = String::new(); loop { line.clear(); stack.program.clear(); let stdin = std::io::stdin(); print!("> "); std::io::stdout().flush().expect("Cannot flush the buffer."); stdin.lock().read_line(&mut line).unwrap(); parse(&mut stack, &line.trim()); execute(&mut stack, None, &"inline".to_string()); } } else { let input = &args.input.expect("error: no input file"); let lines = fs::read_to_string(&input).expect(&format!("{}", RunError::FailToReadFile)); parse(&mut stack, &lines); execute(&mut stack, None, &String::from(input.file_name().expect("Failed to read file name.").to_str().expect("Failed to convert file name to string"))); } } #[derive(Debug)] struct AppArgs { input: Option, } fn parse_args() -> Result { let mut pargs = pico_args::Arguments::from_env(); if pargs.contains(["-h", "--help"]) { print!("{}", HELP); std::process::exit(0); } if pargs.contains(["-v", "--version"]) { println!("labast version {}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")); std::process::exit(0); } let args = AppArgs { input: pargs.opt_free_from_str()?, }; let remaining = pargs.finish(); if !remaining.is_empty() { eprintln!("Warning: unused arguments left: {:?}.", remaining); } return Ok(args); }