* fixed _unix_random bug * add custom instruction "random" * update to spec 1.12 * more cli options
89 lines
2.1 KiB
Rust
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);
|
|
} |