use mumu::{Interpreter, Value};
use mumu::modules::compose::register_compose_and_pipe;
use mumu::modules::slog::register_slog;
use mumu::modules::sput::register_sput;
use mumu::modules::r#type::register_type;
use mumu::modules::ink::register_ink;
use mumu::modules::check::register_check;
use mumu::modules::include::register_include;
use mumu::parser::lexer::tokenize;
use mumu::parser::core::driver::parse_tokens;
use mumu::parser::ast::Stmt;
fn print_help() {
println!("af [OPTIONS] <path-to-file>");
println!(" -h, --help Print this help message");
println!(" --version Print version & debug info");
println!("Examples:");
println!(" af script.af");
}
fn main() {
if let Err(e) = try_main() {
println!("Error: {}", e);
}
}
fn try_main() -> Result<(), String> {
let args: Vec<String> = std::env::args().collect();
let mut debug_verbose = false;
let mut file_path: Option<String> = None;
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"-h" | "--help" => {
print_help();
return Ok(());
}
"--version" => {
println!("mumu version 0.9.1");
println!("Environment: REPL + file-run example");
return Ok(());
}
"-v" | "--verbose" => {
debug_verbose = true;
i += 1;
continue;
}
other => {
file_path = Some(other.to_string());
}
}
i += 1;
}
if file_path.is_none() {
return mumu::modules::repl::run_repl_mode(debug_verbose);
}
let file_path = file_path.unwrap();
let code = std::fs::read_to_string(&file_path)
.map_err(|e| format!("Failed to read '{}': {}", file_path, e))?;
let tokens = tokenize(&code, debug_verbose)
.map_err(|lex_err| format!("Lex error: {}", lex_err))?;
let ast = parse_tokens(&tokens, debug_verbose)
.map_err(|parse_err| format!("Parse error: {}", parse_err))?;
let mut interp = Interpreter::new();
interp.set_verbose(debug_verbose);
interp.set_repl_mode(false);
register_compose_and_pipe(&mut interp);
register_sput(&mut interp);
register_slog(&mut interp);
register_type(&mut interp);
register_ink(&mut interp);
register_check(&mut interp);
register_include(&mut interp);
let mut _last_val = Value::Int(0);
let mut idx = 0;
while idx < ast.len() {
let stmt = &ast[idx];
match stmt {
Stmt::ImportSo { .. } => {
let val = interp
.exec_statement(stmt)
.map_err(|e| format!("Statement {} error: {}", idx + 1, e))?;
_last_val = val;
idx += 1;
}
_ => {
break;
}
}
}
for (stmt_index, stmt) in ast[idx..].iter().enumerate() {
let val = interp
.exec_statement(stmt)
.map_err(|e| format!("Statement {} error: {}", idx + stmt_index + 1, e))?;
_last_val = val;
}
loop {
if let Some(poll_fn) = interp.get_dynamic_function("poll_events") {
let _ = poll_fn.lock().unwrap()(&mut interp, vec![]);
}
let total_tasks = interp.poll_all();
if total_tasks == 0 {
break;
}
}
interp.remove_all_pollers();
Ok(())
}