//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 = 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); }