/*! * Function Processing Module * * Extracted from core.rs - function call and definition handling * Handles function declarations, calls, and function-related operations * Core philosophy: "Everything is Box" with structured function processing */ use super::*; impl NyashInterpreter { /// 関数呼び出しを実行 - 🌍 革命的実装:GlobalBoxのメソッド呼び出し pub(super) fn execute_function_call( &mut self, name: &str, arguments: &[ASTNode], ) -> Result, RuntimeError> { // Fallback: built-in type ops as global functions: isType(value, "Type"), asType(value, "Type") if (name == "isType" || name == "asType") && arguments.len() == 2 { // Evaluate args let val = self.execute_expression(&arguments[0])?; let ty_box = self.execute_expression(&arguments[1])?; // Get type name string let type_name = if let Some(s) = ty_box .as_any() .downcast_ref::() { s.value.clone() } else { return Err(RuntimeError::InvalidOperation { message: "Type name must be a string".to_string(), }); }; if name == "isType" { let matched = Self::matches_type_name(&val, &type_name); return Ok(Box::new(crate::box_trait::BoolBox::new(matched))); } else { // asType: minimal safe cast (int<->float), otherwise identity return Self::cast_to_type(val, &type_name); } } // コンストラクタ内での親コンストラクタ呼び出しチェック if let Some(context) = self.current_constructor_context.clone() { if let Some(parent_class) = context.parent_class { if name == parent_class { // 親コンストラクタ呼び出し return self.execute_parent_constructor(&parent_class, arguments); } } } // 🌍 GlobalBoxのメソッドとして実行 let global_box = self.shared.global_box.lock().unwrap(); let method_ast = global_box .get_method(name) .ok_or(RuntimeError::UndefinedFunction { name: name.to_string(), })? .clone(); drop(global_box); // メソッド呼び出しとして実行(GlobalBoxインスタンス上で) if let ASTNode::FunctionDeclaration { params, body, .. } = method_ast { // 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // パラメータ数チェック if arg_values.len() != params.len() { return Err(RuntimeError::InvalidOperation { message: format!( "Function {} expects {} arguments, got {}", name, params.len(), arg_values.len() ), }); } // 🌍 local変数スタックを保存・クリア(関数呼び出し開始) let saved_locals = self.save_local_vars(); self.local_vars.clear(); // パラメータをlocal変数として設定 for (param, value) in params.iter().zip(arg_values.iter()) { self.declare_local_variable(param, value.clone_or_share()); } // 関数本体を実行(TaskGroupスコープをプッシュ) crate::runtime::global_hooks::push_task_scope(); let mut result: Box = Box::new(VoidBox::new()); for statement in &body { result = self.execute_statement(statement)?; // return文チェック if let super::ControlFlow::Return(return_val) = &self.control_flow { if std::env::var("NYASH_INT_RET_TRACE").ok().as_deref() == Some("1") { let ty = return_val.type_name(); let sv = return_val.to_string_box().value; eprintln!("[INT-RET] epilogue capture: type={} value={}", ty, sv); } result = return_val.clone_box(); self.control_flow = super::ControlFlow::None; break; } } // 🌍 local変数スタックを復元(関数呼び出し終了) crate::runtime::global_hooks::pop_task_scope(); self.restore_local_vars(saved_locals); Ok(result) } else { Err(RuntimeError::InvalidOperation { message: format!("Function '{}' is not a valid function declaration", name), }) } } /// 関数宣言を登録 - 🌍 革命的実装:GlobalBoxのメソッドとして登録 pub(super) fn register_function_declaration( &mut self, name: String, params: Vec, body: Vec, ) { // 🌍 GlobalBoxのメソッドとして登録 let func_ast = ASTNode::FunctionDeclaration { name: name.clone(), params, body, is_static: false, // 通常の関数は静的でない is_override: false, // 🔥 通常の関数はオーバーライドでない span: crate::ast::Span::unknown(), // デフォルトspan }; self.register_global_function(name, func_ast) .unwrap_or_else(|err| { eprintln!("Warning: Failed to register global function: {}", err); }); } /// Helper: match a NyashBox value against a simple type name fn matches_type_name(val: &Box, type_name: &str) -> bool { let tn = val.type_name(); match type_name { "Integer" | "Int" | "I64" => tn == "IntegerBox", "Float" | "F64" => tn == "FloatBox", "Bool" | "Boolean" => tn == "BoolBox", "String" => tn == "StringBox", "Void" | "Unit" => tn == "VoidBox", other => tn == other || tn == format!("{}Box", other), } } /// Helper: cast box to a target type name (minimal support) fn cast_to_type( val: Box, type_name: &str, ) -> Result, RuntimeError> { match type_name { "Integer" | "Int" | "I64" => { // Float -> Integer (truncate), Integer -> Integer, else error if let Some(i) = val.as_any().downcast_ref::() { Ok(Box::new(crate::box_trait::IntegerBox::new(i.value))) } else if let Some(f) = val.as_any().downcast_ref::() { Ok(Box::new(crate::box_trait::IntegerBox::new(f.value as i64))) } else { Ok(val) // identity fallback for now } } "Float" | "F64" => { if let Some(f) = val.as_any().downcast_ref::() { Ok(Box::new(crate::boxes::FloatBox::new(f.value))) } else if let Some(i) = val.as_any().downcast_ref::() { Ok(Box::new(crate::boxes::FloatBox::new(i.value as f64))) } else { Ok(val) } } _ => Ok(val), } } }