/*! * Expression Processing Module * * Extracted from core.rs lines 408-787 (~380 lines) * Handles expression evaluation, binary operations, method calls, and field access * Core philosophy: "Everything is Box" with clean expression evaluation */ use super::*; use crate::ast::UnaryOperator; use crate::boxes::{buffer::BufferBox, JSONBox, HttpClientBox, StreamBox, RegexBox, IntentBox, SocketBox, HTTPServerBox, HTTPRequestBox, HTTPResponseBox}; use crate::boxes::{FloatBox, MathBox, ConsoleBox, TimeBox, DateTimeBox, RandomBox, SoundBox, DebugBox, file::FileBox, MapBox}; use crate::box_trait::{BoolBox, SharedNyashBox}; // Direct implementation approach to avoid import issues use crate::operator_traits::{DynamicAdd, DynamicSub, DynamicMul, DynamicDiv, OperatorError}; // Local helper functions to bypass import issues fn try_add_operation(left: &dyn NyashBox, right: &dyn NyashBox) -> Option> { // IntegerBox + IntegerBox if let (Some(left_int), Some(right_int)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { return Some(Box::new(IntegerBox::new(left_int.value + right_int.value))); } // StringBox + anything -> concatenation if let Some(left_str) = left.as_any().downcast_ref::() { let right_str = right.to_string_box(); return Some(Box::new(StringBox::new(format!("{}{}", left_str.value, right_str.value)))); } // BoolBox + BoolBox -> IntegerBox if let (Some(left_bool), Some(right_bool)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { return Some(Box::new(IntegerBox::new((left_bool.value as i64) + (right_bool.value as i64)))); } None } fn try_sub_operation(left: &dyn NyashBox, right: &dyn NyashBox) -> Option> { // IntegerBox - IntegerBox if let (Some(left_int), Some(right_int)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { return Some(Box::new(IntegerBox::new(left_int.value - right_int.value))); } None } fn try_mul_operation(left: &dyn NyashBox, right: &dyn NyashBox) -> Option> { // IntegerBox * IntegerBox if let (Some(left_int), Some(right_int)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { return Some(Box::new(IntegerBox::new(left_int.value * right_int.value))); } // StringBox * IntegerBox -> repetition if let (Some(str_box), Some(count_int)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { return Some(Box::new(StringBox::new(str_box.value.repeat(count_int.value as usize)))); } None } fn try_div_operation(left: &dyn NyashBox, right: &dyn NyashBox) -> Result, String> { // IntegerBox / IntegerBox if let (Some(left_int), Some(right_int)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { if right_int.value == 0 { return Err("Division by zero".to_string()); } return Ok(Box::new(IntegerBox::new(left_int.value / right_int.value))); } Err(format!("Division not supported between {} and {}", left.type_name(), right.type_name())) } use std::sync::Arc; // TODO: Fix NullBox import issue later // use crate::NullBox; impl NyashInterpreter { /// 式を実行 - Expression evaluation engine pub(super) fn execute_expression(&mut self, expression: &ASTNode) -> Result, RuntimeError> { match expression { ASTNode::Literal { value, .. } => { Ok(value.to_nyash_box()) } ASTNode::Variable { name, .. } => { // 🌍 革命的変数解決:local変数 → GlobalBoxフィールド → エラー let shared_var = self.resolve_variable(name) .map_err(|_| RuntimeError::UndefinedVariableAt { name: name.clone(), span: expression.span() })?; Ok((*shared_var).share_box()) // 🎯 State-sharing instead of cloning } ASTNode::BinaryOp { operator, left, right, .. } => { self.execute_binary_op(operator, left, right) } ASTNode::UnaryOp { operator, operand, .. } => { self.execute_unary_op(operator, operand) } ASTNode::AwaitExpression { expression, .. } => { self.execute_await(expression) } ASTNode::MethodCall { object, method, arguments, .. } => { let result = self.execute_method_call(object, method, arguments); result } ASTNode::FieldAccess { object, field, .. } => { let shared_result = self.execute_field_access(object, field)?; Ok((*shared_result).clone_box()) // Convert Arc to Box for external interface } ASTNode::New { class, arguments, type_arguments, .. } => { self.execute_new(class, arguments, type_arguments) } ASTNode::This { .. } => { // 🌍 革命的this解決:local変数から取得 let shared_this = self.resolve_variable("me") .map_err(|_| RuntimeError::InvalidOperation { message: "'this' is only available inside methods".to_string(), })?; Ok((*shared_this).clone_box()) // Convert for external interface } ASTNode::Me { .. } => { // 🌍 革命的me解決:local変数から取得(thisと同じ) let shared_me = self.resolve_variable("me") .map_err(|_| RuntimeError::InvalidOperation { message: "'me' is only available inside methods".to_string(), })?; Ok((*shared_me).clone_box()) // Convert for external interface } ASTNode::ThisField { field, .. } => { // 🌍 革命的this.fieldアクセス:local変数から取得 let this_value = self.resolve_variable("me") .map_err(|_| RuntimeError::InvalidOperation { message: "'this' is not bound in the current context".to_string(), })?; if let Some(instance) = (*this_value).as_any().downcast_ref::() { let shared_field = instance.get_field(field) .ok_or_else(|| RuntimeError::InvalidOperation { message: format!("Field '{}' not found on this", field) })?; Ok((*shared_field).clone_box()) // Convert for external interface } else { Err(RuntimeError::TypeError { message: "'this' is not an instance".to_string(), }) } } ASTNode::MeField { field, .. } => { // 🌍 革命的me.fieldアクセス:local変数から取得 let me_value = self.resolve_variable("me") .map_err(|_| RuntimeError::InvalidOperation { message: "'this' is not bound in the current context".to_string(), })?; if let Some(instance) = (*me_value).as_any().downcast_ref::() { let shared_field = instance.get_field(field) .ok_or_else(|| RuntimeError::InvalidOperation { message: format!("Field '{}' not found on me", field) })?; Ok((*shared_field).clone_box()) // Convert for external interface } else { Err(RuntimeError::TypeError { message: "'this' is not an instance".to_string(), }) } } ASTNode::FunctionCall { name, arguments, .. } => { self.execute_function_call(name, arguments) } ASTNode::Arrow { sender, receiver, .. } => { self.execute_arrow(sender, receiver) } ASTNode::Include { filename, .. } => { self.execute_include(filename)?; Ok(Box::new(VoidBox::new())) } ASTNode::FromCall { parent, method, arguments, .. } => { self.execute_from_call(parent, method, arguments) } _ => Err(RuntimeError::InvalidOperation { message: format!("Cannot execute {:?} as expression", expression.node_type()), }), } } /// 二項演算を実行 - Binary operation processing pub(super) fn execute_binary_op(&mut self, op: &BinaryOperator, left: &ASTNode, right: &ASTNode) -> Result, RuntimeError> { let left_val = self.execute_expression(left)?; let right_val = self.execute_expression(right)?; match op { BinaryOperator::Add => { // 🚀 Direct trait-based operator resolution (temporary workaround) // Use helper function instead of trait methods if let Some(result) = try_add_operation(left_val.as_ref(), right_val.as_ref()) { return Ok(result); } Err(RuntimeError::InvalidOperation { message: format!("Addition not supported between {} and {}", left_val.type_name(), right_val.type_name()) }) } BinaryOperator::Equal => { let result = left_val.equals(right_val.as_ref()); Ok(Box::new(result)) } BinaryOperator::NotEqual => { let result = left_val.equals(right_val.as_ref()); Ok(Box::new(BoolBox::new(!result.value))) } BinaryOperator::And => { let left_bool = self.is_truthy(&left_val); if !left_bool { Ok(Box::new(BoolBox::new(false))) } else { let right_bool = self.is_truthy(&right_val); Ok(Box::new(BoolBox::new(right_bool))) } } BinaryOperator::Or => { let left_bool = self.is_truthy(&left_val); if left_bool { Ok(Box::new(BoolBox::new(true))) } else { let right_bool = self.is_truthy(&right_val); Ok(Box::new(BoolBox::new(right_bool))) } } BinaryOperator::Subtract => { // Use helper function instead of trait methods if let Some(result) = try_sub_operation(left_val.as_ref(), right_val.as_ref()) { return Ok(result); } Err(RuntimeError::InvalidOperation { message: format!("Subtraction not supported between {} and {}", left_val.type_name(), right_val.type_name()) }) } BinaryOperator::Multiply => { // Use helper function instead of trait methods if let Some(result) = try_mul_operation(left_val.as_ref(), right_val.as_ref()) { return Ok(result); } Err(RuntimeError::InvalidOperation { message: format!("Multiplication not supported between {} and {}", left_val.type_name(), right_val.type_name()) }) } BinaryOperator::Divide => { // Use helper function instead of trait methods match try_div_operation(left_val.as_ref(), right_val.as_ref()) { Ok(result) => Ok(result), Err(error_msg) => Err(RuntimeError::InvalidOperation { message: error_msg }) } } BinaryOperator::Less => { let result = CompareBox::less(left_val.as_ref(), right_val.as_ref()); Ok(Box::new(result)) } BinaryOperator::Greater => { let result = CompareBox::greater(left_val.as_ref(), right_val.as_ref()); Ok(Box::new(result)) } BinaryOperator::LessEqual => { let result = CompareBox::less_equal(left_val.as_ref(), right_val.as_ref()); Ok(Box::new(result)) } BinaryOperator::GreaterEqual => { let result = CompareBox::greater_equal(left_val.as_ref(), right_val.as_ref()); Ok(Box::new(result)) } } } /// 単項演算を実行 - Unary operation processing pub(super) fn execute_unary_op(&mut self, operator: &UnaryOperator, operand: &ASTNode) -> Result, RuntimeError> { let operand_val = self.execute_expression(operand)?; match operator { UnaryOperator::Minus => { // 数値の符号反転 if let Some(int_box) = operand_val.as_any().downcast_ref::() { Ok(Box::new(IntegerBox::new(-int_box.value))) } else if let Some(float_box) = operand_val.as_any().downcast_ref::() { Ok(Box::new(FloatBox::new(-float_box.value))) } else { Err(RuntimeError::TypeError { message: "Unary minus can only be applied to Integer or Float".to_string(), }) } } UnaryOperator::Not => { // 論理否定 if let Some(bool_box) = operand_val.as_any().downcast_ref::() { Ok(Box::new(BoolBox::new(!bool_box.value))) } else { // どんな値でもtruthyness判定してnot演算を適用 let is_truthy = self.is_truthy(&operand_val); Ok(Box::new(BoolBox::new(!is_truthy))) } } } } /// メソッド呼び出しを実行 - Method call processing pub(super) fn execute_method_call(&mut self, object: &ASTNode, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 🔥 static関数のチェック if let ASTNode::Variable { name, .. } = object { // static関数が存在するかチェック let static_func = { let static_funcs = self.shared.static_functions.read().unwrap(); if let Some(box_statics) = static_funcs.get(name) { if let Some(func) = box_statics.get(method) { Some(func.clone()) } else { None } } else { None } }; if let Some(static_func) = static_func { // static関数を実行 if let ASTNode::FunctionDeclaration { params, body, .. } = static_func { // 引数を評価 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!("Static method {}.{} expects {} arguments, got {}", name, method, params.len(), arg_values.len()), }); } // 🌍 local変数スタックを保存・クリア(static関数呼び出し開始) let saved_locals = self.save_local_vars(); self.local_vars.clear(); // 📤 outbox変数スタックも保存・クリア(static関数専用) let saved_outbox = self.save_outbox_vars(); self.outbox_vars.clear(); // 引数をlocal変数として設定 for (param, value) in params.iter().zip(arg_values.iter()) { self.declare_local_variable(param, value.clone_box()); } // static関数の本体を実行 let mut result = Box::new(VoidBox::new()) as Box; for statement in &body { result = self.execute_statement(statement)?; // return文チェック if let super::ControlFlow::Return(return_val) = &self.control_flow { result = return_val.clone_box(); self.control_flow = super::ControlFlow::None; break; } } // local変数スタックを復元 self.restore_local_vars(saved_locals); // outbox変数スタックを復元 self.restore_outbox_vars(saved_outbox); return Ok(result); } } } // オブジェクトを評価(通常のメソッド呼び出し) let obj_value = self.execute_expression(object)?; // StringBox method calls if let Some(string_box) = obj_value.as_any().downcast_ref::() { return self.execute_string_method(string_box, method, arguments); } // IntegerBox method calls if let Some(integer_box) = obj_value.as_any().downcast_ref::() { return self.execute_integer_method(integer_box, method, arguments); } // FloatBox method calls if let Some(float_box) = obj_value.as_any().downcast_ref::() { return self.execute_float_method(float_box, method, arguments); } // BoolBox method calls if let Some(bool_box) = obj_value.as_any().downcast_ref::() { return self.execute_bool_method(bool_box, method, arguments); } // ArrayBox method calls if let Some(array_box) = obj_value.as_any().downcast_ref::() { return self.execute_array_method(array_box, method, arguments); } // BufferBox method calls if let Some(buffer_box) = obj_value.as_any().downcast_ref::() { return self.execute_buffer_method(buffer_box, method, arguments); } // FileBox method calls if let Some(file_box) = obj_value.as_any().downcast_ref::() { return self.execute_file_method(file_box, method, arguments); } // ResultBox method calls if let Some(result_box) = obj_value.as_any().downcast_ref::() { return self.execute_result_method(result_box, method, arguments); } // FutureBox method calls if let Some(future_box) = obj_value.as_any().downcast_ref::() { return self.execute_future_method(future_box, method, arguments); } // ChannelBox method calls if let Some(channel_box) = obj_value.as_any().downcast_ref::() { return self.execute_channel_method(channel_box, method, arguments); } // JSONBox method calls if let Some(json_box) = obj_value.as_any().downcast_ref::() { return self.execute_json_method(json_box, method, arguments); } // HttpClientBox method calls if let Some(http_box) = obj_value.as_any().downcast_ref::() { return self.execute_http_method(http_box, method, arguments); } // StreamBox method calls if let Some(stream_box) = obj_value.as_any().downcast_ref::() { return self.execute_stream_method(stream_box, method, arguments); } // RegexBox method calls if let Some(regex_box) = obj_value.as_any().downcast_ref::() { return self.execute_regex_method(regex_box, method, arguments); } // MathBox method calls if let Some(math_box) = obj_value.as_any().downcast_ref::() { return self.execute_math_method(math_box, method, arguments); } // NullBox method calls if let Some(null_box) = obj_value.as_any().downcast_ref::() { return self.execute_null_method(null_box, method, arguments); } // TimeBox method calls if let Some(time_box) = obj_value.as_any().downcast_ref::() { return self.execute_time_method(time_box, method, arguments); } // DateTimeBox method calls if let Some(datetime_box) = obj_value.as_any().downcast_ref::() { return self.execute_datetime_method(datetime_box, method, arguments); } // TimerBox method calls if let Some(timer_box) = obj_value.as_any().downcast_ref::() { return self.execute_timer_method(timer_box, method, arguments); } // MapBox method calls if let Some(map_box) = obj_value.as_any().downcast_ref::() { return self.execute_map_method(map_box, method, arguments); } // RandomBox method calls if let Some(random_box) = obj_value.as_any().downcast_ref::() { return self.execute_random_method(random_box, method, arguments); } // SoundBox method calls if let Some(sound_box) = obj_value.as_any().downcast_ref::() { return self.execute_sound_method(sound_box, method, arguments); } // DebugBox method calls if let Some(debug_box) = obj_value.as_any().downcast_ref::() { return self.execute_debug_method(debug_box, method, arguments); } // ConsoleBox method calls if let Some(console_box) = obj_value.as_any().downcast_ref::() { return self.execute_console_method(console_box, method, arguments); } // IntentBox method calls if let Some(intent_box) = obj_value.as_any().downcast_ref::() { return self.execute_intent_box_method(intent_box, method, arguments); } // SocketBox method calls if let Some(socket_box) = obj_value.as_any().downcast_ref::() { let result = self.execute_socket_method(socket_box, method, arguments)?; // 🔧 FIX: Update stored variable for stateful SocketBox methods // These methods modify the SocketBox internal state, so we need to update // the stored variable/field to ensure subsequent accesses get the updated state if matches!(method, "bind" | "connect" | "close") { eprintln!("🔧 DEBUG: Stateful method '{}' called, updating stored instance", method); let updated_instance = socket_box.clone(); eprintln!("🔧 DEBUG: Updated instance created with ID={}", updated_instance.box_id()); match object { ASTNode::Variable { name, .. } => { eprintln!("🔧 DEBUG: Updating local variable '{}'", name); // Handle local variables if let Some(stored_var) = self.local_vars.get_mut(name) { eprintln!("🔧 DEBUG: Found local variable '{}', updating from id={} to id={}", name, stored_var.box_id(), updated_instance.box_id()); *stored_var = Arc::new(updated_instance); } else { eprintln!("🔧 DEBUG: Local variable '{}' not found", name); } }, ASTNode::FieldAccess { object: field_obj, field, .. } => { eprintln!("🔧 DEBUG: Updating field access '{}'", field); // Handle StaticBox fields like me.server match field_obj.as_ref() { ASTNode::Variable { name, .. } => { eprintln!("🔧 DEBUG: Field object is variable '{}'", name); if name == "me" { eprintln!("🔧 DEBUG: Updating me.{} (via variable)", field); if let Ok(me_instance) = self.resolve_variable("me") { eprintln!("🔧 DEBUG: Resolved 'me' instance id={}", me_instance.box_id()); if let Some(instance) = (*me_instance).as_any().downcast_ref::() { eprintln!("🔧 DEBUG: me is InstanceBox, setting field '{}' to updated instance id={}", field, updated_instance.box_id()); let result = instance.set_field(field, Arc::new(updated_instance)); eprintln!("🔧 DEBUG: set_field result: {:?}", result); } else { eprintln!("🔧 DEBUG: me is not an InstanceBox, type: {}", me_instance.type_name()); } } else { eprintln!("🔧 DEBUG: Failed to resolve 'me'"); } } else { eprintln!("🔧 DEBUG: Field object is not 'me', it's '{}'", name); } }, ASTNode::Me { .. } => { eprintln!("🔧 DEBUG: Field object is Me node, updating me.{}", field); if let Ok(me_instance) = self.resolve_variable("me") { eprintln!("🔧 DEBUG: Resolved 'me' instance id={}", me_instance.box_id()); if let Some(instance) = (*me_instance).as_any().downcast_ref::() { eprintln!("🔧 DEBUG: me is InstanceBox, setting field '{}' to updated instance id={}", field, updated_instance.box_id()); let result = instance.set_field(field, Arc::new(updated_instance)); eprintln!("🔧 DEBUG: set_field result: {:?}", result); } else { eprintln!("🔧 DEBUG: me is not an InstanceBox, type: {}", me_instance.type_name()); } } else { eprintln!("🔧 DEBUG: Failed to resolve 'me'"); } }, _ => { eprintln!("🔧 DEBUG: Field object is not a variable or me, type: {:?}", field_obj); } } }, _ => { eprintln!("🔧 DEBUG: Object type not handled: {:?}", object); } } } return Ok(result); } // HTTPServerBox method calls if let Some(http_server_box) = obj_value.as_any().downcast_ref::() { return self.execute_http_server_method(http_server_box, method, arguments); } // HTTPRequestBox method calls if let Some(http_request_box) = obj_value.as_any().downcast_ref::() { return self.execute_http_request_method(http_request_box, method, arguments); } // HTTPResponseBox method calls if let Some(http_response_box) = obj_value.as_any().downcast_ref::() { return self.execute_http_response_method(http_response_box, method, arguments); } // P2PBox method calls - Temporarily disabled // if let Some(p2p_box) = obj_value.as_any().downcast_ref::() { // return self.execute_p2p_box_method(p2p_box, method, arguments); // } // EguiBox method calls (非WASM環境のみ) #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] if let Some(egui_box) = obj_value.as_any().downcast_ref::() { return self.execute_egui_method(egui_box, method, arguments); } // WebDisplayBox method calls (WASM環境のみ) #[cfg(target_arch = "wasm32")] if let Some(web_display_box) = obj_value.as_any().downcast_ref::() { return self.execute_web_display_method(web_display_box, method, arguments); } // WebConsoleBox method calls (WASM環境のみ) #[cfg(target_arch = "wasm32")] if let Some(web_console_box) = obj_value.as_any().downcast_ref::() { return self.execute_web_console_method(web_console_box, method, arguments); } // WebCanvasBox method calls (WASM環境のみ) #[cfg(target_arch = "wasm32")] if let Some(web_canvas_box) = obj_value.as_any().downcast_ref::() { return self.execute_web_canvas_method(web_canvas_box, method, arguments); } // MethodBox method calls if let Some(method_box) = obj_value.as_any().downcast_ref::() { return self.execute_method_box_method(method_box, method, arguments); } // IntegerBox method calls if let Some(integer_box) = obj_value.as_any().downcast_ref::() { return self.execute_integer_method(integer_box, method, arguments); } // FloatBox method calls (将来的に追加予定) // RangeBox method calls (将来的に追加予定) // InstanceBox method calls if let Some(instance) = obj_value.as_any().downcast_ref::() { // 🔥 Usage prohibition guard - check if instance is finalized if instance.is_finalized() { return Err(RuntimeError::InvalidOperation { message: "Instance was finalized; further use is prohibited".to_string(), }); } // fini()は特別処理 if method == "fini" { // 🔥 weak-fini prohibition check - prevent fini() on weak fields if let ASTNode::FieldAccess { object: field_object, field, .. } = object { // Check if this is me..fini() pattern if let ASTNode::Variable { name, .. } = field_object.as_ref() { if name == "me" { // Get current instance to check if field is weak if let Ok(current_me) = self.resolve_variable("me") { if let Some(current_instance) = (*current_me).as_any().downcast_ref::() { if current_instance.is_weak_field(field) { return Err(RuntimeError::InvalidOperation { message: format!( "Cannot finalize weak field '{}' (non-owning reference)", field ), }); } } } } } } // 既に解放済みの場合は何もしない(二重fini()対策) if instance.is_finalized() { return Ok(Box::new(VoidBox::new())); } // まず、Box内で定義されたfini()メソッドがあれば実行 if let Some(fini_method) = instance.get_method("fini") { if let ASTNode::FunctionDeclaration { body, .. } = fini_method.clone() { // 🌍 革命的メソッド実行:local変数スタックを使用 let saved_locals = self.save_local_vars(); self.local_vars.clear(); // thisをlocal変数として設定 self.declare_local_variable("me", obj_value.clone_box()); // fini()メソッドの本体を実行 let mut _result = Box::new(VoidBox::new()) as Box; for statement in &body { _result = self.execute_statement(statement)?; // return文チェック if let super::ControlFlow::Return(_) = &self.control_flow { self.control_flow = super::ControlFlow::None; break; } } // local変数スタックを復元 self.restore_local_vars(saved_locals); } } // インスタンスの内部的な解放処理 instance.fini().map_err(|e| RuntimeError::InvalidOperation { message: e, })?; finalization::mark_as_finalized(instance.box_id()); return Ok(Box::new(VoidBox::new())); } // メソッドを取得 let method_ast = instance.get_method(method) .ok_or(RuntimeError::InvalidOperation { message: format!("Method '{}' not found in {}", method, instance.class_name), })? .clone(); // メソッドが関数宣言の形式であることを確認 if let ASTNode::FunctionDeclaration { params, body, .. } = method_ast { // 🚨 FIX: 引数評価を完全に現在のコンテキストで完了させる let mut arg_values = Vec::new(); for (i, arg) in arguments.iter().enumerate() { let arg_value = self.execute_expression(arg)?; arg_values.push(arg_value); } // パラメータ数チェック if arg_values.len() != params.len() { return Err(RuntimeError::InvalidOperation { message: format!("Method {} expects {} arguments, got {}", method, params.len(), arg_values.len()), }); } // 🌍 NOW SAFE: すべての引数評価完了後にコンテキスト切り替え let saved_locals = self.save_local_vars(); self.local_vars.clear(); // thisをlocal変数として設定 self.declare_local_variable("me", obj_value.clone_box()); // パラメータをlocal変数として設定 for (param, value) in params.iter().zip(arg_values.iter()) { self.declare_local_variable(param, value.clone_box()); } // メソッド本体を実行 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 { result = return_val.clone_box(); self.control_flow = super::ControlFlow::None; break; } } // local変数スタックを復元 self.restore_local_vars(saved_locals); Ok(result) } else { Err(RuntimeError::InvalidOperation { message: format!("Method '{}' is not a valid function declaration", method), }) } } else { Err(RuntimeError::TypeError { message: format!("Cannot call method '{}' on non-instance type", method), }) } } /// フィールドアクセスを実行 - Field access processing with weak reference support pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str) -> Result { // 🔥 Static Boxアクセスチェック if let ASTNode::Variable { name, .. } = object { // Static boxの可能性をチェック if self.is_static_box(name) { let static_result = self.execute_static_field_access(name, field)?; return Ok(Arc::from(static_result)); } } // オブジェクトを評価(通常のフィールドアクセス) let obj_value = self.execute_expression(object); let obj_value = obj_value?; // InstanceBoxにキャスト if let Some(instance) = obj_value.as_any().downcast_ref::() { // 🔥 Usage prohibition guard - check if instance is finalized if instance.is_finalized() { return Err(RuntimeError::InvalidOperation { message: "Instance was finalized; further use is prohibited".to_string(), }); } // フィールドの値を取得 let field_value = instance.get_field(field) .ok_or(RuntimeError::InvalidOperation { message: format!("Field '{}' not found in {}", field, instance.class_name), })?; eprintln!("✅ FIELD ACCESS: Returning shared reference id={}", field_value.box_id()); // 🔗 Weak Reference Check: Use unified accessor for weak fields let box_decls = self.shared.box_declarations.read().unwrap(); if let Some(box_decl) = box_decls.get(&instance.class_name) { if box_decl.weak_fields.contains(&field.to_string()) { eprintln!("🔗 DEBUG: Accessing weak field '{}' in class '{}'", field, instance.class_name); // 🎯 PHASE 2: Use unified accessor for auto-nil weak reference handling if let Some(weak_value) = instance.get_weak_field(field, self) { // Pass self match &weak_value { crate::value::NyashValue::Null => { eprintln!("🔗 DEBUG: Weak field '{}' is null (reference dropped)", field); // Return null box for compatibility return Ok(Arc::new(crate::boxes::null_box::NullBox::new())); } _ => { eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field); // Convert back to Box for now if let Ok(box_value) = weak_value.to_box() { if let Ok(inner_box) = box_value.try_lock() { return Ok(Arc::from(inner_box.clone_box())); } } } } } // If weak field access failed, fall through to normal access } } // Return the shared Arc reference directly Ok(field_value) } else { Err(RuntimeError::TypeError { message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()), }) } } /// 🔥 Static Box名前空間のフィールドアクセス fn execute_static_field_access(&mut self, static_box_name: &str, field: &str) -> Result, RuntimeError> { // 1. Static Boxの初期化を確実に実行 self.ensure_static_box_initialized(static_box_name)?; // 2. GlobalBox.statics.{static_box_name} からインスタンスを取得 let global_box = self.shared.global_box.lock() .map_err(|_| RuntimeError::RuntimeFailure { message: "Failed to acquire global box lock".to_string() })?; let statics_box = global_box.get_field("statics") .ok_or(RuntimeError::RuntimeFailure { message: "statics namespace not found in GlobalBox".to_string() })?; let statics_instance = statics_box.as_any() .downcast_ref::() .ok_or(RuntimeError::TypeError { message: "statics field is not an InstanceBox".to_string() })?; let static_box_instance = statics_instance.get_field(static_box_name) .ok_or(RuntimeError::RuntimeFailure { message: format!("Static box '{}' instance not found in statics namespace", static_box_name) })?; let instance = static_box_instance.as_any() .downcast_ref::() .ok_or(RuntimeError::TypeError { message: format!("Static box '{}' is not an InstanceBox", static_box_name) })?; // 3. フィールドアクセス let shared_field = instance.get_field(field) .ok_or(RuntimeError::InvalidOperation { message: format!("Field '{}' not found in static box '{}'", field, static_box_name), })?; // Convert Arc to Box for compatibility Ok((*shared_field).clone_box()) } /// await式を実行 - Execute await expression pub(super) fn execute_await(&mut self, expression: &ASTNode) -> Result, RuntimeError> { let value = self.execute_expression(expression)?; // FutureBoxなら待機して結果を取得 if let Some(future) = value.as_any().downcast_ref::() { future.wait_and_get() .map_err(|msg| RuntimeError::InvalidOperation { message: msg }) } else { // FutureBoxでなければそのまま返す Ok(value) } } /// 🔄 循環参照検出: オブジェクトの一意IDを取得 fn get_object_id(&self, node: &ASTNode) -> Option { match node { ASTNode::Variable { name, .. } => { // 変数名のハッシュをIDとして使用 Some(self.hash_string(name)) } ASTNode::Me { .. } => { // 'me'参照の特別なID Some(usize::MAX) } ASTNode::This { .. } => { // 'this'参照の特別なID Some(usize::MAX - 1) } _ => None, // 他のノードタイプはID追跡しない } } /// 🔄 文字列のシンプルなハッシュ関数 fn hash_string(&self, s: &str) -> usize { let mut hash = 0usize; for byte in s.bytes() { hash = hash.wrapping_mul(31).wrapping_add(byte as usize); } hash } /// 🔗 Convert NyashBox to NyashValue for weak reference operations // fn box_to_nyash_value(&self, box_val: &Box) -> Option { // // Try to convert the box back to NyashValue for weak reference operations // // This is a simplified conversion - in reality we might need more sophisticated logic // use nyash_rust::value::NyashValue; // use crate::box_trait::{StringBox, IntegerBox, BoolBox, VoidBox}; // // if let Some(string_box) = box_val.as_any().downcast_ref::() { // Some(NyashValue::String(string_box.value.clone())) // } else if let Some(int_box) = box_val.as_any().downcast_ref::() { // Some(NyashValue::Integer(int_box.value)) // } else if let Some(bool_box) = box_val.as_any().downcast_ref::() { // Some(NyashValue::Bool(bool_box.value)) // } else if box_val.as_any().downcast_ref::().is_some() { // Some(NyashValue::Void) // } else if box_val.as_any().downcast_ref::().is_some() { // Some(NyashValue::Null) // } else { // // For complex types, create a Box variant // // Note: This is where we'd store the weak reference // None // Simplified for now // } // } /// 🔥 FromCall実行処理 - from Parent.method(arguments) or from Parent.constructor(arguments) pub(super) fn execute_from_call(&mut self, parent: &str, method: &str, arguments: &[ASTNode]) -> Result, RuntimeError> { // 1. 現在のコンテキストで'me'変数を取得(現在のインスタンス) let current_instance_val = self.resolve_variable("me") .map_err(|_| RuntimeError::InvalidOperation { message: "'from' can only be used inside methods".to_string(), })?; let current_instance = (*current_instance_val).as_any().downcast_ref::() .ok_or(RuntimeError::TypeError { message: "'from' requires current instance to be InstanceBox".to_string(), })?; // 2. 現在のクラスのデリゲーション関係を検証 let current_class = ¤t_instance.class_name; let box_declarations = self.shared.box_declarations.read().unwrap(); let current_box_decl = box_declarations.get(current_class) .ok_or(RuntimeError::UndefinedClass { name: current_class.clone() })?; // extendsまたはimplementsでparentが指定されているか確認 (Multi-delegation) 🚀 let is_valid_delegation = current_box_decl.extends.contains(&parent.to_string()) || current_box_decl.implements.contains(&parent.to_string()); if !is_valid_delegation { return Err(RuntimeError::InvalidOperation { message: format!("Class '{}' does not delegate to '{}'. Use 'box {} from {}' to establish delegation.", current_class, parent, current_class, parent), }); } // 🔥 ビルトインBoxかチェック let mut builtin_boxes = vec![ "IntegerBox", "StringBox", "BoolBox", "ArrayBox", "MapBox", "FileBox", "ResultBox", "FutureBox", "ChannelBox", "MathBox", "TimeBox", "DateTimeBox", "TimerBox", "RandomBox", "SoundBox", "DebugBox", "MethodBox", "NullBox", "ConsoleBox", "FloatBox", "BufferBox", "RegexBox", "JSONBox", "StreamBox", "HTTPClientBox", "IntentBox", "P2PBox", "SocketBox", "HTTPServerBox", "HTTPRequestBox", "HTTPResponseBox" ]; #[cfg(all(feature = "gui", not(target_arch = "wasm32")))] builtin_boxes.push("EguiBox"); let is_builtin = builtin_boxes.contains(&parent); if is_builtin { // ビルトインBoxの場合、ロックを解放してからメソッド呼び出し drop(box_declarations); return self.execute_builtin_box_method(parent, method, current_instance_val.clone_box(), arguments); } // 3. 親クラスのBox宣言を取得(ユーザー定義Boxの場合) let parent_box_decl = box_declarations.get(parent) .ok_or(RuntimeError::UndefinedClass { name: parent.to_string() })? .clone(); drop(box_declarations); // ロック早期解放 // 4. constructorまたはinitまたはpackの場合の特別処理 if method == "constructor" || method == "init" || method == "pack" || method == parent { return self.execute_from_parent_constructor(parent, &parent_box_decl, current_instance_val.clone_box(), arguments); } // 5. 親クラスのメソッドを取得 let parent_method = parent_box_decl.methods.get(method) .ok_or(RuntimeError::InvalidOperation { message: format!("Method '{}' not found in parent class '{}'", method, parent), })? .clone(); // 6. 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // 7. 親メソッドを実行 if let ASTNode::FunctionDeclaration { params, body, .. } = parent_method { // パラメータ数チェック if arg_values.len() != params.len() { return Err(RuntimeError::InvalidOperation { message: format!("Parent method {}.{} expects {} arguments, got {}", parent, method, params.len(), arg_values.len()), }); } // 🌍 local変数スタックを保存・クリア(親メソッド実行開始) let saved_locals = self.save_local_vars(); self.local_vars.clear(); // 'me'を現在のインスタンスに設定(重要:現在のインスタンスを維持) self.declare_local_variable("me", current_instance_val.clone_box()); // 引数をlocal変数として設定 for (param, value) in params.iter().zip(arg_values.iter()) { self.declare_local_variable(param, value.clone_box()); } // 親メソッドの本体を実行 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 { result = return_val.clone_box(); self.control_flow = super::ControlFlow::None; break; } } // 🔍 DEBUG: FromCall実行結果をログ出力 eprintln!("🔍 DEBUG: FromCall {}.{} result: {}", parent, method, result.to_string_box().value); // local変数スタックを復元 self.restore_local_vars(saved_locals); Ok(result) } else { Err(RuntimeError::InvalidOperation { message: format!("Parent method '{}' is not a valid function declaration", method), }) } } /// 🔥 fromCall専用親コンストラクタ実行処理 - from Parent.constructor(arguments) fn execute_from_parent_constructor(&mut self, parent: &str, parent_box_decl: &super::BoxDeclaration, current_instance: Box, arguments: &[ASTNode]) -> Result, RuntimeError> { // 1. 親クラスのコンストラクタを取得(引数の数でキーを作成) // "pack/引数数"、"init/引数数"、"Box名/引数数" の順で試す let pack_key = format!("pack/{}", arguments.len()); let init_key = format!("init/{}", arguments.len()); let box_name_key = format!("{}/{}", parent, arguments.len()); let parent_constructor = parent_box_decl.constructors.get(&pack_key) .or_else(|| parent_box_decl.constructors.get(&init_key)) .or_else(|| parent_box_decl.constructors.get(&box_name_key)) .ok_or(RuntimeError::InvalidOperation { message: format!("No constructor found for parent class '{}' with {} arguments", parent, arguments.len()), })? .clone(); // 2. 引数を評価 let mut arg_values = Vec::new(); for arg in arguments { arg_values.push(self.execute_expression(arg)?); } // 3. 親コンストラクタを実行 if let ASTNode::FunctionDeclaration { params, body, .. } = parent_constructor { // パラメータ数チェック if arg_values.len() != params.len() { return Err(RuntimeError::InvalidOperation { message: format!("Parent constructor {} expects {} arguments, got {}", parent, params.len(), arg_values.len()), }); } // 🌍 local変数スタックを保存・クリア(親コンストラクタ実行開始) let saved_locals = self.save_local_vars(); self.local_vars.clear(); // 'me'を現在のインスタンスに設定 self.declare_local_variable("me", current_instance.clone_box()); // 引数をlocal変数として設定 for (param, value) in params.iter().zip(arg_values.iter()) { self.declare_local_variable(param, value.clone_box()); } // 親コンストラクタの本体を実行 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 { result = return_val.clone_box(); self.control_flow = super::ControlFlow::None; break; } } // local変数スタックを復元 self.restore_local_vars(saved_locals); // 親コンストラクタは通常現在のインスタンスを返す Ok(current_instance) } else { Err(RuntimeError::InvalidOperation { message: format!("Parent constructor is not a valid function declaration"), }) } } /// 🔥 ビルトインBoxのメソッド呼び出し fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box, arguments: &[ASTNode]) -> Result, RuntimeError> { // ビルトインBoxのインスタンスを作成または取得 // 現在のインスタンスからビルトインBoxのデータを取得し、ビルトインBoxとしてメソッド実行 match parent { "StringBox" => { // StringBoxのインスタンスを作成(デフォルト値) let string_box = StringBox::new(""); self.execute_string_method(&string_box, method, arguments) } "IntegerBox" => { // IntegerBoxのインスタンスを作成(デフォルト値) let integer_box = IntegerBox::new(0); self.execute_integer_method(&integer_box, method, arguments) } "ArrayBox" => { let array_box = ArrayBox::new(); self.execute_array_method(&array_box, method, arguments) } "MapBox" => { let map_box = MapBox::new(); self.execute_map_method(&map_box, method, arguments) } "MathBox" => { let math_box = MathBox::new(); self.execute_math_method(&math_box, method, arguments) } "P2PBox" => { // P2PBoxの場合、現在のインスタンスからP2PBoxインスタンスを取得する必要がある // TODO: 現在のインスタンスのフィールドからP2PBoxを取得 return Err(RuntimeError::InvalidOperation { message: format!("P2PBox delegation not yet fully implemented: {}.{}", parent, method), }); } "FileBox" => { let file_box = crate::boxes::file::FileBox::new(); self.execute_file_method(&file_box, method, arguments) } "ConsoleBox" => { let console_box = ConsoleBox::new(); self.execute_console_method(&console_box, method, arguments) } "TimeBox" => { let time_box = TimeBox::new(); self.execute_time_method(&time_box, method, arguments) } "RandomBox" => { let random_box = RandomBox::new(); self.execute_random_method(&random_box, method, arguments) } "DebugBox" => { let debug_box = DebugBox::new(); self.execute_debug_method(&debug_box, method, arguments) } "SoundBox" => { let sound_box = SoundBox::new(); self.execute_sound_method(&sound_box, method, arguments) } "SocketBox" => { let socket_box = SocketBox::new(); self.execute_socket_method(&socket_box, method, arguments) } "HTTPServerBox" => { let http_server_box = HTTPServerBox::new(); self.execute_http_server_method(&http_server_box, method, arguments) } "HTTPRequestBox" => { let http_request_box = HTTPRequestBox::new(); self.execute_http_request_method(&http_request_box, method, arguments) } "HTTPResponseBox" => { let http_response_box = HTTPResponseBox::new(); self.execute_http_response_method(&http_response_box, method, arguments) } _ => { Err(RuntimeError::InvalidOperation { message: format!("Unknown built-in Box type for delegation: {}", parent), }) } } } }