//! Evaluation entry points: execute program and nodes use crate::ast::ASTNode; use crate::box_trait::{NyashBox, VoidBox, StringBox}; use super::{NyashInterpreter, RuntimeError, ControlFlow}; impl NyashInterpreter { /// ASTを実行 pub fn execute(&mut self, ast: ASTNode) -> Result, RuntimeError> { super::core::debug_log("=== NYASH EXECUTION START ==="); let result = self.execute_node(&ast); if let Err(ref e) = result { eprintln!("❌ Interpreter error: {}", e); } super::core::debug_log("=== NYASH EXECUTION END ==="); result } /// ノードを実行 fn execute_node(&mut self, node: &ASTNode) -> Result, RuntimeError> { match node { ASTNode::Program { statements, .. } => { let mut result: Box = Box::new(VoidBox::new()); let last = statements.len().saturating_sub(1); for (i, statement) in statements.iter().enumerate() { let prev = self.discard_context; self.discard_context = i != last; // 最終文以外は値が破棄される result = self.execute_statement(statement)?; self.discard_context = prev; // 制御フローチェック match &self.control_flow { ControlFlow::Break => { return Err(RuntimeError::BreakOutsideLoop); } ControlFlow::Return(_) => { return Err(RuntimeError::ReturnOutsideFunction); } ControlFlow::Throw(_) => { return Err(RuntimeError::UncaughtException); } ControlFlow::None => {} } } // 🎯 Static Box Main パターン - main()メソッドの自動実行 let has_main_method = { if let Ok(definitions) = self.shared.static_box_definitions.read() { if let Some(main_definition) = definitions.get("Main") { main_definition.methods.contains_key("main") } else { false } } else { false } }; if has_main_method { // Main static boxを初期化 self.ensure_static_box_initialized("Main")?; // Main.main(args?) を呼び出し(引数が1つなら空配列をデフォルト注入) let mut default_args: Vec = Vec::new(); if let Ok(defs) = self.shared.static_box_definitions.read() { if let Some(main_def) = defs.get("Main") { if let Some(m) = main_def.methods.get("main") { if let ASTNode::FunctionDeclaration { params, .. } = m { if params.len() == 1 { default_args.push(ASTNode::New { class: "ArrayBox".to_string(), arguments: vec![], type_arguments: vec![], span: crate::ast::Span::unknown() }); } } } } } let main_call_ast = ASTNode::MethodCall { object: Box::new(ASTNode::FieldAccess { object: Box::new(ASTNode::Variable { name: "statics".to_string(), span: crate::ast::Span::unknown() }), field: "Main".to_string(), span: crate::ast::Span::unknown(), }), method: "main".to_string(), arguments: default_args, span: crate::ast::Span::unknown(), }; // main()の戻り値を最終結果として使用 result = self.execute_statement(&main_call_ast)?; } Ok(result) } _ => self.execute_statement(node), } } }