//use std::{env, fs};
use std::{env, fs, process::exit};
use kabel::{debug::{debug_ast, debug_bytecode, debug_stack, debug_token_array}, run_codegen, run_lexer, run_parser, run_semantic_analysis};
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
println!("Must provide kabel file to run");
exit(1);
}
let program =
fs::read_to_string(args[1].clone()).unwrap();
let mut output = "".to_string();
let lexer = run_lexer(program.to_string());
for error in lexer.errors.clone() {
output += &error.to_string();
output += "\n";
}
//output += &format!("{:?}", lexer.output);
if lexer.errors.len() != 0 || lexer.output.len() == 0 {
println!("{}", output);
return;
}
//output += &debug_token_array(lexer.output.clone());
let (ast, parser) = run_parser(program.to_string(), lexer.output);
for error in parser.errors.clone() {
output += &error.to_string();
output += "\n";
}
if parser.errors.len() != 0 {
println!("{}", output);
return;
}
output += &debug_ast(ast.clone(), 0);
output += "\n\n";
//output += &format!("{:#?}", ast);
let (ast, analyzer) = run_semantic_analysis(program.to_string(), ast.clone());
for error in analyzer.errors.clone() {
output += &error.to_string();
output += "\n";
}
if analyzer.errors.len() != 0 {
println!("{}", output);
return;
}
output += &debug_ast(ast.clone(), 0);
output += "\n";
let codegen = run_codegen(program.to_string(), ast);
let mut vm = codegen.vm;
for (index, _) in vm.units.iter().enumerate() {
vm.unit_ptr = index;
output += &format!("{:?}", vm.units[vm.unit_ptr].pool);
output += "unit ptr: ";
output += &vm.unit_ptr.to_string();
output += "\n";
output += &debug_bytecode(&vm);
output += "\n";
}
vm.unit_ptr = 0;
println!("{}", output);
println!("{:?}", vm.variables);
output += "\n";
match vm.run(&mut output) {
Ok(()) => {}
Err(e) => output += &e.to_string(),
}
//output += &debug_stack(&vm.units[0].stack);
println!("{}", output);
}