labast/src/main.rs
n3taeli 4fb06f8f34
update v1.0.3
* fixed _unix_random bug
* add custom instruction "random"
* update to spec 1.12
* more cli options
2024-02-06 19:59:43 +02:00

89 lines
2.1 KiB
Rust

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<std::path::PathBuf>,
}
fn parse_args() -> Result<AppArgs, pico_args::Error> {
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);
}