/*! * Execution Runner Module - Nyash File and Mode Execution Coordinator * * This module handles all execution logic, backend selection, and mode coordination, * separated from CLI parsing and the main entry point. */ use crate::cli::CliConfig; use crate::{ box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, AddBox, BoxCore}, tokenizer::{NyashTokenizer}, ast::ASTNode, parser::NyashParser, interpreter::NyashInterpreter, mir::{MirCompiler, MirPrinter}, backend::{VM, wasm::WasmBackend, aot::AotBackend}, }; use std::{fs, process}; // BID prototype imports use crate::bid::{PluginRegistry, PluginBoxInstance}; /// Main execution coordinator pub struct NyashRunner { config: CliConfig, } impl NyashRunner { /// Create a new runner with the given configuration pub fn new(config: CliConfig) -> Self { Self { config } } /// Run Nyash based on the configuration pub fn run(&self) { // Try to initialize BID plugins from nyash.toml (best-effort) self.init_bid_plugins(); // Benchmark mode - can run without a file if self.config.benchmark { println!("๐Ÿ“Š Nyash Performance Benchmark Suite"); println!("===================================="); println!("Running {} iterations per test...", self.config.iterations); println!(); self.execute_benchmark_mode(); return; } if let Some(ref filename) = self.config.file { self.execute_file_mode(filename); } else { self.execute_demo_mode(); } } fn init_bid_plugins(&self) { // Best-effort init; do not fail the program if missing if let Ok(()) = crate::bid::registry::init_global_from_config("nyash.toml") { let reg = crate::bid::registry::global().unwrap(); // If FileBox plugin is present, try a birth/fini cycle as a smoke test if let Some(plugin) = reg.get_by_name("FileBox") { if let Ok(inst) = PluginBoxInstance::birth(plugin) { println!("๐Ÿ”Œ BID plugin loaded: FileBox (instance_id={})", inst.instance_id); // Drop will call fini return; } } println!("๐Ÿ”Œ BID registry initialized"); } } /// Execute file-based mode with backend selection fn execute_file_mode(&self, filename: &str) { if self.config.dump_mir || self.config.verify_mir { println!("๐Ÿš€ Nyash MIR Compiler - Processing file: {} ๐Ÿš€", filename); self.execute_mir_mode(filename); } else if self.config.compile_wasm { println!("๐ŸŒ Nyash WASM Compiler - Processing file: {} ๐ŸŒ", filename); self.execute_wasm_mode(filename); } else if self.config.compile_native { println!("๐Ÿš€ Nyash AOT Compiler - Processing file: {} ๐Ÿš€", filename); self.execute_aot_mode(filename); } else if self.config.backend == "vm" { println!("๐Ÿš€ Nyash VM Backend - Executing file: {} ๐Ÿš€", filename); self.execute_vm_mode(filename); } else { println!("๐Ÿฆ€ Nyash Rust Implementation - Executing file: {} ๐Ÿฆ€", filename); if let Some(fuel) = self.config.debug_fuel { println!("๐Ÿ”ฅ Debug fuel limit: {} iterations", fuel); } else { println!("๐Ÿ”ฅ Debug fuel limit: unlimited"); } println!("===================================================="); self.execute_nyash_file(filename); } } /// Execute demo mode with all demonstrations fn execute_demo_mode(&self) { println!("๐Ÿฆ€ Nyash Rust Implementation - Everything is Box! ๐Ÿฆ€"); println!("===================================================="); // Demonstrate basic Box creation and operations demo_basic_boxes(); // Demonstrate Box operations demo_box_operations(); // Demonstrate Box collections demo_box_collections(); // Demonstrate Environment & Scope management demo_environment_system(); // Demonstrate Tokenizer system demo_tokenizer_system(); // Demonstrate Parser system demo_parser_system(); // Demonstrate Interpreter system demo_interpreter_system(); println!("\n๐ŸŽ‰ All Box operations completed successfully!"); println!("Memory safety guaranteed by Rust's borrow checker! ๐Ÿ›ก๏ธ"); } /// Execute Nyash file with interpreter fn execute_nyash_file(&self, filename: &str) { // Read the file let code = match fs::read_to_string(filename) { Ok(content) => content, Err(e) => { eprintln!("โŒ Error reading file {}: {}", filename, e); process::exit(1); } }; println!("๐Ÿ“ File contents:\n{}", code); println!("\n๐Ÿš€ Parsing and executing...\n"); // Test: immediate file creation (use relative path to avoid sandbox issues) std::fs::create_dir_all("development/debug_hang_issue").ok(); std::fs::write("development/debug_hang_issue/test.txt", "START").ok(); // Parse the code with debug fuel limit eprintln!("๐Ÿ” DEBUG: Starting parse with fuel: {:?}...", self.config.debug_fuel); let ast = match NyashParser::parse_from_string_with_fuel(&code, self.config.debug_fuel) { Ok(ast) => { eprintln!("๐Ÿ” DEBUG: Parse completed, AST created"); ast }, Err(e) => { eprintln!("โŒ Parse error: {}", e); process::exit(1); } }; eprintln!("๐Ÿ” DEBUG: About to print parse success message..."); println!("โœ… Parse successful!"); eprintln!("๐Ÿ” DEBUG: Parse success message printed"); // Debug log file write if let Ok(mut file) = std::fs::OpenOptions::new() .create(true) .append(true) .open("development/debug_hang_issue/debug_trace.log") { use std::io::Write; let _ = writeln!(file, "=== MAIN: Parse successful ==="); let _ = file.flush(); } eprintln!("๐Ÿ” DEBUG: Creating interpreter..."); // Execute the AST let mut interpreter = NyashInterpreter::new(); eprintln!("๐Ÿ” DEBUG: Starting execution..."); match interpreter.execute(ast) { Ok(result) => { println!("โœ… Execution completed successfully!"); println!("Result: {}", result.to_string_box().value); }, Err(e) => { // Use enhanced error reporting with source context eprintln!("โŒ Runtime error:\n{}", e.detailed_message(Some(&code))); process::exit(1); } } } /// Execute MIR compilation and processing mode fn execute_mir_mode(&self, filename: &str) { // Read the file let code = match fs::read_to_string(filename) { Ok(content) => content, Err(e) => { eprintln!("โŒ Error reading file {}: {}", filename, e); process::exit(1); } }; // Parse to AST let ast = match NyashParser::parse_from_string(&code) { Ok(ast) => ast, Err(e) => { eprintln!("โŒ Parse error: {}", e); process::exit(1); } }; // Compile to MIR let mut mir_compiler = MirCompiler::new(); let compile_result = match mir_compiler.compile(ast) { Ok(result) => result, Err(e) => { eprintln!("โŒ MIR compilation error: {}", e); process::exit(1); } }; // Verify MIR if requested if self.config.verify_mir { println!("๐Ÿ” Verifying MIR..."); match &compile_result.verification_result { Ok(()) => println!("โœ… MIR verification passed!"), Err(errors) => { eprintln!("โŒ MIR verification failed:"); for error in errors { eprintln!(" โ€ข {}", error); } process::exit(1); } } } // Dump MIR if requested if self.config.dump_mir { let mut printer = if self.config.mir_verbose { MirPrinter::verbose() } else { MirPrinter::new() }; println!("๐Ÿš€ MIR Output for {}:", filename); println!("{}", printer.print_module(&compile_result.module)); } } /// Execute VM mode fn execute_vm_mode(&self, filename: &str) { // Read the file let code = match fs::read_to_string(filename) { Ok(content) => content, Err(e) => { eprintln!("โŒ Error reading file {}: {}", filename, e); process::exit(1); } }; // Parse to AST let ast = match NyashParser::parse_from_string(&code) { Ok(ast) => ast, Err(e) => { eprintln!("โŒ Parse error: {}", e); process::exit(1); } }; // Compile to MIR let mut mir_compiler = MirCompiler::new(); let compile_result = match mir_compiler.compile(ast) { Ok(result) => result, Err(e) => { eprintln!("โŒ MIR compilation error: {}", e); process::exit(1); } }; // Execute with VM let mut vm = VM::new(); match vm.execute_module(&compile_result.module) { Ok(result) => { println!("โœ… VM execution completed successfully!"); println!("Result: {:?}", result); }, Err(e) => { eprintln!("โŒ VM execution error: {}", e); process::exit(1); } } } /// Execute WASM compilation mode fn execute_wasm_mode(&self, filename: &str) { // Read the file let code = match fs::read_to_string(filename) { Ok(content) => content, Err(e) => { eprintln!("โŒ Error reading file {}: {}", filename, e); process::exit(1); } }; // Parse to AST let ast = match NyashParser::parse_from_string(&code) { Ok(ast) => ast, Err(e) => { eprintln!("โŒ Parse error: {}", e); process::exit(1); } }; // Compile to MIR let mut mir_compiler = MirCompiler::new(); let compile_result = match mir_compiler.compile(ast) { Ok(result) => result, Err(e) => { eprintln!("โŒ MIR compilation error: {}", e); process::exit(1); } }; // Compile to WASM (Phase 9.77a fix: use compile_to_wat instead of compile_module) let mut wasm_backend = WasmBackend::new(); let wat_text = match wasm_backend.compile_to_wat(compile_result.module) { Ok(wat) => wat, Err(e) => { eprintln!("โŒ WASM compilation error: {}", e); process::exit(1); } }; // Determine output file let output = self.config.output_file.as_deref() .unwrap_or_else(|| { if filename.ends_with(".nyash") { filename.strip_suffix(".nyash").unwrap_or(filename) } else { filename } }); let output_file = format!("{}.wat", output); // Write WAT output (already a string) let output_str = wat_text; match fs::write(&output_file, output_str) { Ok(()) => { println!("โœ… WASM compilation successful!"); println!("Output written to: {}", output_file); }, Err(e) => { eprintln!("โŒ Error writing WASM file {}: {}", output_file, e); process::exit(1); } } } /// Execute AOT compilation mode fn execute_aot_mode(&self, filename: &str) { // Read the file let code = match fs::read_to_string(filename) { Ok(content) => content, Err(e) => { eprintln!("โŒ Error reading file {}: {}", filename, e); process::exit(1); } }; // Parse to AST let ast = match NyashParser::parse_from_string(&code) { Ok(ast) => ast, Err(e) => { eprintln!("โŒ Parse error: {}", e); process::exit(1); } }; // Compile to MIR let mut mir_compiler = MirCompiler::new(); let compile_result = match mir_compiler.compile(ast) { Ok(result) => result, Err(e) => { eprintln!("โŒ MIR compilation error: {}", e); process::exit(1); } }; // Compile via AOT backend let mut aot_backend = match AotBackend::new() { Ok(backend) => backend, Err(e) => { eprintln!("โŒ Failed to create AOT backend: {}", e); process::exit(1); } }; let output = self.config.output_file.as_deref() .unwrap_or_else(|| { if filename.ends_with(".nyash") { filename.strip_suffix(".nyash").unwrap_or(filename) } else { filename } }); match aot_backend.compile_to_executable(compile_result.module, output) { Ok(()) => { println!("โœ… AOT compilation successful!"); println!("Executable written to: {}", output); }, Err(e) => { eprintln!("โŒ AOT compilation error: {}", e); process::exit(1); } } } /// Execute benchmark mode fn execute_benchmark_mode(&self) { println!("๐Ÿ Running benchmark mode with {} iterations", self.config.iterations); // Simple benchmark test file let test_code = r#" local x x = 42 local y y = x + 58 return y "#; println!("\n๐Ÿงช Test code:"); println!("{}", test_code); // Benchmark interpreter println!("\nโšก Interpreter Backend:"); let start = std::time::Instant::now(); for _ in 0..self.config.iterations { if let Ok(ast) = NyashParser::parse_from_string(test_code) { let mut interpreter = NyashInterpreter::new(); let _ = interpreter.execute(ast); } } let interpreter_time = start.elapsed(); println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, interpreter_time, self.config.iterations as f64 / interpreter_time.as_secs_f64()); // Benchmark VM if available println!("\n๐Ÿš€ VM Backend:"); let start = std::time::Instant::now(); for _ in 0..self.config.iterations { if let Ok(ast) = NyashParser::parse_from_string(test_code) { let mut mir_compiler = MirCompiler::new(); if let Ok(compile_result) = mir_compiler.compile(ast) { let mut vm = VM::new(); let _ = vm.execute_module(&compile_result.module); } } } let vm_time = start.elapsed(); println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, vm_time, self.config.iterations as f64 / vm_time.as_secs_f64()); // Performance comparison let speedup = interpreter_time.as_secs_f64() / vm_time.as_secs_f64(); println!("\n๐Ÿ“Š Performance Summary:"); println!(" VM is {:.2}x {} than Interpreter", if speedup > 1.0 { speedup } else { 1.0 / speedup }, if speedup > 1.0 { "faster" } else { "slower" }); } } // Demo functions (moved from main.rs) fn demo_basic_boxes() { println!("\n๐Ÿ“ฆ 1. Basic Box Creation:"); // Create different types of boxes let string_box = StringBox::new("Hello, Nyash!".to_string()); let int_box = IntegerBox::new(42); let bool_box = BoolBox::new(true); let void_box = VoidBox::new(); println!(" StringBox: {}", string_box.to_string_box().value); println!(" IntegerBox: {}", int_box.to_string_box().value); println!(" BoolBox: {}", bool_box.to_string_box().value); println!(" VoidBox: {}", void_box.to_string_box().value); // Show unique IDs println!(" Box IDs: String={}, Integer={}, Bool={}, Void={}", string_box.box_id(), int_box.box_id(), bool_box.box_id(), void_box.box_id()); } fn demo_box_operations() { println!("\n๐Ÿ”„ 2. Box Operations:"); // Addition between boxes let left = IntegerBox::new(10); let right = IntegerBox::new(32); let add_box = AddBox::new(Box::new(left), Box::new(right)); println!(" 10 + 32 = {}", add_box.to_string_box().value); // String concatenation let str1 = StringBox::new("Hello, ".to_string()); let str2 = StringBox::new("World!".to_string()); let concat_box = AddBox::new(Box::new(str1), Box::new(str2)); println!(" \"Hello, \" + \"World!\" = {}", concat_box.to_string_box().value); } fn demo_box_collections() { println!("\n๐Ÿ“š 3. Box Collections:"); // This would be expanded when ArrayBox is implemented println!(" Box collections functionality placeholder"); println!(" (ArrayBox and other collection types will be demonstrated here)"); } fn demo_environment_system() { println!("\n๐ŸŒ 4. Environment & Scope Management:"); println!(" Environment demo placeholder - full testing done in interpreter"); } fn demo_tokenizer_system() { println!("\n๐Ÿ”ค 5. Tokenizer System:"); // Test code to tokenize let test_code = "x = 42 + y"; println!(" Input: {}", test_code); // Tokenize the code let mut tokenizer = NyashTokenizer::new(test_code); match tokenizer.tokenize() { Ok(tokens) => { println!(" Tokenized {} tokens successfully", tokens.len()); }, Err(e) => println!(" Tokenization error: {}", e), } } fn demo_parser_system() { println!("\n๐ŸŒณ 6. Parser & AST System:"); // Test simple box declaration println!(" ๐Ÿ“ Simple Box Declaration Test:"); let simple_code = r#" box TestBox { value getValue() { return this.value } } "#; match NyashParser::parse_from_string(simple_code) { Ok(ast) => { println!(" Input: {}", simple_code.trim()); println!(" AST: {}", ast); if let ASTNode::Program { statements, .. } = &ast { println!(" Program has {} statements", statements.len()); for (i, stmt) in statements.iter().enumerate() { println!(" [{}] {}", i, stmt.info()); } } } Err(e) => println!(" Error: {}", e), } // Test assignment and method call println!("\n ๐Ÿš€ Assignment & Method Call Test:"); let assignment_code = r#" obj = new TestBox() obj.value = "test123" print("Direct field: " + obj.value) print("Method call: " + obj.getValue()) "#; match NyashParser::parse_from_string(assignment_code) { Ok(ast) => { println!(" Successfully parsed assignment & method call code"); if let ASTNode::Program { statements, .. } = &ast { println!(" Parsed {} statements:", statements.len()); for (i, stmt) in statements.iter().enumerate() { println!(" [{}] {} ({})", i, stmt.info(), stmt.node_type()); } } } Err(e) => println!(" Error: {}", e), } // Test expression parsing println!("\n โšก Expression Parsing Test:"); let expr_code = r#" result = x + y * z condition = a == b && c < d "#; match NyashParser::parse_from_string(expr_code) { Ok(ast) => { println!(" Successfully parsed complex expressions"); if let ASTNode::Program { statements, .. } = &ast { for (i, stmt) in statements.iter().enumerate() { if let ASTNode::Assignment { target, value, .. } = stmt { println!(" Assignment [{}]: {} = {}", i, target.info(), value.info()); } } } } Err(e) => println!(" Error: {}", e), } // Test control structures println!("\n ๐Ÿ”„ Control Structure Test:"); let control_code = r#" if condition { print("True branch") } else { print("False branch") } loop { print("Loop body") return } "#; match NyashParser::parse_from_string(control_code) { Ok(ast) => { println!(" Successfully parsed control structures"); if let ASTNode::Program { statements, .. } = &ast { for (i, stmt) in statements.iter().enumerate() { println!(" [{}] {} ({})", i, stmt.info(), stmt.node_type()); } } } Err(e) => println!(" Error: {}", e), } } fn demo_interpreter_system() { println!("\n๐ŸŽญ 7. Interpreter System:"); // Simple execution test let simple_code = r#" local x x = 42 return x "#; println!(" ๐Ÿ“ Simple Variable Test:"); println!(" Code: {}", simple_code.trim()); match NyashParser::parse_from_string(simple_code) { Ok(ast) => { let mut interpreter = NyashInterpreter::new(); match interpreter.execute(ast) { Ok(result) => { println!(" โœ… Result: {}", result.to_string_box().value); }, Err(e) => { println!(" โŒ Execution error: {}", e); } } } Err(e) => println!(" โŒ Parse error: {}", e), } // Expression evaluation test let expr_code = r#" local result result = 10 + 32 return result "#; println!("\n โšก Expression Evaluation Test:"); println!(" Code: {}", expr_code.trim()); match NyashParser::parse_from_string(expr_code) { Ok(ast) => { let mut interpreter = NyashInterpreter::new(); match interpreter.execute(ast) { Ok(result) => { println!(" โœ… Result: {}", result.to_string_box().value); }, Err(e) => { println!(" โŒ Execution error: {}", e); } } } Err(e) => println!(" โŒ Parse error: {}", e), } } #[cfg(test)] mod tests { use super::*; #[test] fn test_runner_creation() { let config = CliConfig { file: None, debug_fuel: Some(100000), dump_mir: false, verify_mir: false, mir_verbose: false, backend: "interpreter".to_string(), compile_wasm: false, compile_native: false, output_file: None, benchmark: false, iterations: 10, }; let runner = NyashRunner::new(config); assert_eq!(runner.config.backend, "interpreter"); } }