diff --git a/src/interpreter/expressions/access.rs b/src/interpreter/expressions/access.rs index f52de15b..c639ad9a 100644 --- a/src/interpreter/expressions/access.rs +++ b/src/interpreter/expressions/access.rs @@ -2,4 +2,145 @@ * Field access operations */ -use super::*; \ No newline at end of file +use super::*; +use crate::ast::ASTNode; +use crate::box_trait::{NyashBox, SharedNyashBox}; +use crate::boxes::FutureBox; +use crate::{InstanceBox}; +use crate::interpreter::core::{NyashInterpreter, RuntimeError}; +use std::sync::Arc; + +impl NyashInterpreter { + /// フィールドアクセスを実行 - 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) + } + } +} \ No newline at end of file diff --git a/src/interpreter/expressions/builtins.rs b/src/interpreter/expressions/builtins.rs index 05a18c6e..6ef1ed75 100644 --- a/src/interpreter/expressions/builtins.rs +++ b/src/interpreter/expressions/builtins.rs @@ -2,4 +2,179 @@ * Builtin box methods and birth methods */ -use super::*; \ No newline at end of file +use super::*; +use crate::ast::ASTNode; +use crate::box_trait::{NyashBox, StringBox, IntegerBox, VoidBox}; +use crate::boxes::{ArrayBox, MapBox, MathBox, ConsoleBox, TimeBox, RandomBox, DebugBox, SoundBox, SocketBox}; +use crate::boxes::{HTTPServerBox, HTTPRequestBox, HTTPResponseBox}; +use crate::boxes::file::FileBox; +use crate::interpreter::core::{NyashInterpreter, RuntimeError}; + +impl NyashInterpreter { + /// 🔥 ビルトインBoxのメソッド呼び出し + pub(super) fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box, arguments: &[ASTNode]) + -> Result, RuntimeError> { + + // 🌟 Phase 8.9: birth method support for builtin boxes + if method == "birth" { + return self.execute_builtin_birth_method(parent, current_instance, arguments); + } + + // ビルトイン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), + }) + } + } + } + + /// 🌟 Phase 8.9: Execute birth method for builtin boxes + /// Provides constructor functionality for builtin boxes through explicit birth() calls + pub(super) fn execute_builtin_birth_method(&mut self, builtin_name: &str, current_instance: Box, arguments: &[ASTNode]) + -> Result, RuntimeError> { + + // 引数を評価 + let mut arg_values = Vec::new(); + for arg in arguments { + arg_values.push(self.execute_expression(arg)?); + } + + // ビルトインBoxの種類に応じて適切なインスタンスを作成して返す + match builtin_name { + "StringBox" => { + if arg_values.len() != 1 { + return Err(RuntimeError::InvalidOperation { + message: format!("StringBox.birth() expects 1 argument, got {}", arg_values.len()), + }); + } + + let content = arg_values[0].to_string_box().value; + eprintln!("🌟 DEBUG: StringBox.birth() created with content: '{}'", content); + let string_box = StringBox::new(content); + Ok(Box::new(VoidBox::new())) // Return void to indicate successful initialization + } + "IntegerBox" => { + if arg_values.len() != 1 { + return Err(RuntimeError::InvalidOperation { + message: format!("IntegerBox.birth() expects 1 argument, got {}", arg_values.len()), + }); + } + + let value = if let Ok(int_val) = arg_values[0].to_string_box().value.parse::() { + int_val + } else { + return Err(RuntimeError::TypeError { + message: format!("Cannot convert '{}' to integer", arg_values[0].to_string_box().value), + }); + }; + + let integer_box = IntegerBox::new(value); + eprintln!("🌟 DEBUG: IntegerBox.birth() created with value: {}", value); + Ok(Box::new(VoidBox::new())) + } + "MathBox" => { + // MathBoxは引数なしのコンストラクタ + if arg_values.len() != 0 { + return Err(RuntimeError::InvalidOperation { + message: format!("MathBox.birth() expects 0 arguments, got {}", arg_values.len()), + }); + } + + let math_box = MathBox::new(); + eprintln!("🌟 DEBUG: MathBox.birth() created"); + Ok(Box::new(VoidBox::new())) + } + "ArrayBox" => { + // ArrayBoxも引数なしのコンストラクタ + if arg_values.len() != 0 { + return Err(RuntimeError::InvalidOperation { + message: format!("ArrayBox.birth() expects 0 arguments, got {}", arg_values.len()), + }); + } + + let array_box = ArrayBox::new(); + eprintln!("🌟 DEBUG: ArrayBox.birth() created"); + Ok(Box::new(VoidBox::new())) + } + _ => { + // 他のビルトインBoxは今後追加 + Err(RuntimeError::InvalidOperation { + message: format!("birth() method not yet implemented for builtin box '{}'", builtin_name), + }) + } + } + } +} \ No newline at end of file diff --git a/src/interpreter/expressions/mod.rs b/src/interpreter/expressions/mod.rs index 4c36dee9..f8de55f1 100644 --- a/src/interpreter/expressions/mod.rs +++ b/src/interpreter/expressions/mod.rs @@ -153,138 +153,6 @@ impl NyashInterpreter { - /// フィールドアクセスを実行 - 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 { @@ -314,7 +182,6 @@ impl NyashInterpreter { 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 @@ -339,170 +206,4 @@ impl NyashInterpreter { // } - /// 🔥 ビルトインBoxのメソッド呼び出し - fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box, arguments: &[ASTNode]) - -> Result, RuntimeError> { - - // 🌟 Phase 8.9: birth method support for builtin boxes - if method == "birth" { - return self.execute_builtin_birth_method(parent, current_instance, arguments); - } - - // ビルトイン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), - }) - } - } - } - - /// 🌟 Phase 8.9: Execute birth method for builtin boxes - /// Provides constructor functionality for builtin boxes through explicit birth() calls - fn execute_builtin_birth_method(&mut self, builtin_name: &str, current_instance: Box, arguments: &[ASTNode]) - -> Result, RuntimeError> { - - // 引数を評価 - let mut arg_values = Vec::new(); - for arg in arguments { - arg_values.push(self.execute_expression(arg)?); - } - - // ビルトインBoxの種類に応じて適切なインスタンスを作成して返す - match builtin_name { - "StringBox" => { - if arg_values.len() != 1 { - return Err(RuntimeError::InvalidOperation { - message: format!("StringBox.birth() expects 1 argument, got {}", arg_values.len()), - }); - } - - let content = arg_values[0].to_string_box().value; - eprintln!("🌟 DEBUG: StringBox.birth() created with content: '{}'", content); - let string_box = StringBox::new(content); - Ok(Box::new(VoidBox::new())) // Return void to indicate successful initialization - } - "IntegerBox" => { - if arg_values.len() != 1 { - return Err(RuntimeError::InvalidOperation { - message: format!("IntegerBox.birth() expects 1 argument, got {}", arg_values.len()), - }); - } - - let value = if let Ok(int_val) = arg_values[0].to_string_box().value.parse::() { - int_val - } else { - return Err(RuntimeError::TypeError { - message: format!("Cannot convert '{}' to integer", arg_values[0].to_string_box().value), - }); - }; - - let integer_box = IntegerBox::new(value); - eprintln!("🌟 DEBUG: IntegerBox.birth() created with value: {}", value); - Ok(Box::new(VoidBox::new())) - } - "MathBox" => { - // MathBoxは引数なしのコンストラクタ - if arg_values.len() != 0 { - return Err(RuntimeError::InvalidOperation { - message: format!("MathBox.birth() expects 0 arguments, got {}", arg_values.len()), - }); - } - - let math_box = MathBox::new(); - eprintln!("🌟 DEBUG: MathBox.birth() created"); - Ok(Box::new(VoidBox::new())) - } - "ArrayBox" => { - // ArrayBoxも引数なしのコンストラクタ - if arg_values.len() != 0 { - return Err(RuntimeError::InvalidOperation { - message: format!("ArrayBox.birth() expects 0 arguments, got {}", arg_values.len()), - }); - } - - let array_box = ArrayBox::new(); - eprintln!("🌟 DEBUG: ArrayBox.birth() created"); - Ok(Box::new(VoidBox::new())) - } - _ => { - // 他のビルトインBoxは今後追加 - Err(RuntimeError::InvalidOperation { - message: format!("birth() method not yet implemented for builtin box '{}'", builtin_name), - }) - } - } - } } \ No newline at end of file