use log::info;
use std::{
env,
fs::File,
io::{self, Read, Write},
path::Path,
process::exit,
};
use umpl::{cli, error, eval::Eval, lexer::Lexer, parser::Parser};
fn main() {
let args: Vec<String> = env::args().collect(); let (index, mut parsed_args): (usize, cli::ParsedArgs) = cli::get_string_args(&args); if index != 0 {
cli::get_dash_args(&args, index, &mut parsed_args);
}
if parsed_args.log {
simple_file_logger::init_logger!("UMPL", simple_file_logger::LogLevel::Debug)
.expect("couldn't initialize logger");
}
let mut full_repl: Vec<String> = Vec::new(); if parsed_args.repl {
let mut current_repl: String = String::new(); 'l: loop {
let mut input = String::new();
print!(">> "); io::stdout()
.flush()
.unwrap_or_else(|_| panic!("Failed to flush stdout"));
io::stdin()
.read_line(&mut input)
.unwrap_or_else(|_| panic!("Failed to read stdin"));
if input.trim() == "exit" {
info!("Exiting...");
if !parsed_args.file.is_empty() {
if Path::new(&parsed_args.file).exists() && !parsed_args.force {
print!("Do you want to overwrite the {}? (y/n): ", parsed_args.file); io::stdout()
.flush()
.unwrap_or_else(|_| panic!("Failed to flush stdout"));
let mut y_or_n: String = String::new();
io::stdin()
.read_line(&mut y_or_n)
.unwrap_or_else(|_| panic!("Failed to read stdin")); if y_or_n == "n" {
exit(0);
}
}
let mut file: File = File::create(parsed_args.file)
.expect("Error encountered while creating file!"); for line in full_repl {
file.write_all(line.as_bytes())
.expect("Error encountered while writing to file!");
}
}
break 'l;
} else if input.trim() == "run" {
run(current_repl.to_string()); input.clear();
} else {
current_repl.push_str(&input); full_repl.push(input.to_string());
}
}
} else {
let mut file: File = File::open(&parsed_args.file).unwrap_or_else(|_| {
error::error(0, "Error encountered while opening file!");
}); let mut contents: String = String::new(); match file.read_to_string(&mut contents) {
Ok(contents) => contents,
Err(_) => {
error::error(0, "could not read file");
}
}; run(contents); }
}
fn run(line: String) {
let lexer: Lexer = Lexer::new(line);
let mut parsed: Parser = Parser::new(lexer.scan_tokens());
Eval::new(parsed.parse());
}