diff --git a/src/box_trait.rs b/src/box_trait.rs index 98916a37..cebba74d 100644 --- a/src/box_trait.rs +++ b/src/box_trait.rs @@ -13,6 +13,9 @@ use std::sync::atomic::{AtomicU64, Ordering}; use std::fs; use std::path::Path; +// 🔥 新しい型エイリアス - 将来的にBoxを全て置き換える +pub type SharedNyashBox = Arc; + /// 🔥 BoxBase + BoxCore革命 - 統一ID生成システム /// CharmFlow教訓を活かした互換性保証の基盤 pub fn next_box_id() -> u64 { @@ -84,6 +87,11 @@ pub trait NyashBox: BoxCore + Debug { /// Clone this box (equivalent to Python's copy()) fn clone_box(&self) -> Box; + /// Arc参照を返す新しいcloneメソッド(参照共有) + fn clone_arc(&self) -> SharedNyashBox { + Arc::from(self.clone_box()) + } + // 🌟 TypeBox革命: Get type information as a Box // Everything is Box極限実現 - 型情報もBoxとして取得! // TODO: 次のステップで完全実装 diff --git a/src/instance.rs b/src/instance.rs index 0fe438ad..538f5317 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -5,7 +5,7 @@ * Everything is Box哲学に基づくオブジェクト指向システム */ -use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase}; +use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase, SharedNyashBox}; use crate::ast::ASTNode; use crate::value::NyashValue; use crate::interpreter::NyashInterpreter; @@ -20,8 +20,8 @@ pub struct InstanceBox { /// クラス名 pub class_name: String, - /// フィールド値 (Legacy compatibility) - pub fields: Arc>>>, + /// フィールド値 (Updated to use Arc for reference sharing) + pub fields: Arc>>, /// 🔗 Next-generation fields (weak reference capable) pub fields_ng: Arc>>, @@ -49,9 +49,9 @@ pub struct InstanceBox { impl InstanceBox { pub fn new(class_name: String, fields: Vec, methods: HashMap) -> Self { // フィールドをVoidBoxで初期化 - let mut field_map = HashMap::new(); + let mut field_map: HashMap = HashMap::new(); for field in &fields { - field_map.insert(field.clone(), Box::new(VoidBox::new()) as Box); + field_map.insert(field.clone(), Arc::new(VoidBox::new())); } Self { @@ -270,14 +270,24 @@ impl InstanceBox { } /// フィールドの値を取得 - pub fn get_field(&self, field_name: &str) -> Option> { - self.fields.lock().unwrap().get(field_name).map(|v| v.clone_box()) + pub fn get_field(&self, field_name: &str) -> Option { + eprintln!("✅ FIX: get_field('{}') returning shared Arc reference", field_name); + + // 🔧 修正:v.clone_box() → Arc::clone(v) で参照共有 + self.fields.lock().unwrap().get(field_name).map(Arc::clone) } /// フィールドに値を設定 - pub fn set_field(&self, field_name: &str, value: Box) -> Result<(), String> { + pub fn set_field(&self, field_name: &str, value: SharedNyashBox) -> Result<(), String> { + eprintln!("🔧 INSTANCE: set_field('{}') with shared Arc reference id={}", + field_name, value.box_id()); + let mut fields = self.fields.lock().unwrap(); if fields.contains_key(field_name) { + if let Some(old_value) = fields.get(field_name) { + eprintln!("🔧 INSTANCE: Replacing field '{}': old_id={} -> new_id={}", + field_name, old_value.box_id(), value.box_id()); + } fields.insert(field_name.to_string(), value); Ok(()) } else { @@ -286,7 +296,7 @@ impl InstanceBox { } /// 🌍 GlobalBox用:フィールドを動的に追加・設定 - pub fn set_field_dynamic(&mut self, field_name: String, value: Box) { + pub fn set_field_dynamic(&mut self, field_name: String, value: SharedNyashBox) { let mut fields = self.fields.lock().unwrap(); fields.insert(field_name, value); } diff --git a/src/interpreter/core.rs b/src/interpreter/core.rs index 3a5dba15..72ab0407 100644 --- a/src/interpreter/core.rs +++ b/src/interpreter/core.rs @@ -6,7 +6,7 @@ */ use crate::ast::{ASTNode, Span}; -use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox}; +use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, SharedNyashBox}; use crate::instance::InstanceBox; use crate::parser::ParseError; use std::sync::{Arc, Mutex, RwLock}; @@ -192,10 +192,10 @@ pub struct NyashInterpreter { pub(super) shared: SharedState, /// 📦 local変数スタック(関数呼び出し時の一時変数) - pub(super) local_vars: HashMap>, + pub(super) local_vars: HashMap, /// 📤 outbox変数スタック(static関数内の所有権移転変数) - pub(super) outbox_vars: HashMap>, + pub(super) outbox_vars: HashMap, /// 制御フロー状態 pub(super) control_flow: ControlFlow, @@ -322,7 +322,7 @@ impl NyashInterpreter { // ========== 🌍 GlobalBox変数解決システム ========== /// 革命的変数解決: local変数 → GlobalBoxフィールド → エラー - pub(super) fn resolve_variable(&self, name: &str) -> Result, RuntimeError> { + pub(super) fn resolve_variable(&self, name: &str) -> Result { let log_msg = format!("resolve_variable: name='{}', local_vars={:?}", name, self.local_vars.keys().collect::>()); debug_log(&log_msg); @@ -331,13 +331,27 @@ impl NyashInterpreter { // 1. outbox変数を最初にチェック(static関数内で優先) if let Some(outbox_value) = self.outbox_vars.get(name) { eprintln!("🔍 DEBUG: Found '{}' in outbox_vars", name); - return Ok(outbox_value.clone_box()); + + // 🔧 修正:clone_box() → Arc::clone() で参照共有 + let shared_value = Arc::clone(outbox_value); + + eprintln!("✅ RESOLVE_VARIABLE shared reference: {} id={}", + name, shared_value.box_id()); + + return Ok(shared_value); } // 2. local変数をチェック if let Some(local_value) = self.local_vars.get(name) { eprintln!("🔍 DEBUG: Found '{}' in local_vars", name); - return Ok(local_value.clone_box()); + + // 🔧 修正:clone_box() → Arc::clone() で参照共有 + let shared_value = Arc::clone(local_value); + + eprintln!("✅ RESOLVE_VARIABLE shared reference: {} id={}", + name, shared_value.box_id()); + + return Ok(shared_value); } // 3. GlobalBoxのフィールドをチェック @@ -357,15 +371,17 @@ impl NyashInterpreter { /// 🔥 厳密変数設定: 明示的宣言のみ許可 - Everything is Box哲学 pub(super) fn set_variable(&mut self, name: &str, value: Box) -> Result<(), RuntimeError> { + let shared_value = Arc::from(value); // Convert Box to Arc + // 1. outbox変数が存在する場合は更新 if self.outbox_vars.contains_key(name) { - self.outbox_vars.insert(name.to_string(), value); + self.outbox_vars.insert(name.to_string(), shared_value); return Ok(()); } // 2. local変数が存在する場合は更新 if self.local_vars.contains_key(name) { - self.local_vars.insert(name.to_string(), value); + self.local_vars.insert(name.to_string(), shared_value); return Ok(()); } @@ -375,7 +391,7 @@ impl NyashInterpreter { if global_box.get_field(name).is_some() { drop(global_box); // lockを解放 let mut global_box = self.shared.global_box.lock().unwrap(); - global_box.set_field_dynamic(name.to_string(), value); + global_box.set_field_dynamic(name.to_string(), shared_value); return Ok(()); } } @@ -391,34 +407,38 @@ impl NyashInterpreter { /// local変数を宣言(関数内でのみ有効) pub(super) fn declare_local_variable(&mut self, name: &str, value: Box) { - self.local_vars.insert(name.to_string(), value); + self.local_vars.insert(name.to_string(), Arc::from(value)); } /// outbox変数を宣言(static関数内で所有権移転) pub(super) fn declare_outbox_variable(&mut self, name: &str, value: Box) { - self.outbox_vars.insert(name.to_string(), value); + self.outbox_vars.insert(name.to_string(), Arc::from(value)); } /// local変数スタックを保存・復元(関数呼び出し時) pub(super) fn save_local_vars(&self) -> HashMap> { self.local_vars.iter() - .map(|(k, v)| (k.clone(), v.clone_box())) + .map(|(k, v)| (k.clone(), (**v).clone_box())) // Deref Arc to get the Box .collect() } pub(super) fn restore_local_vars(&mut self, saved: HashMap>) { - self.local_vars = saved; + self.local_vars = saved.into_iter() + .map(|(k, v)| (k, Arc::from(v))) // Convert Box to Arc + .collect(); } /// outbox変数スタックを保存・復元(static関数呼び出し時) pub(super) fn save_outbox_vars(&self) -> HashMap> { self.outbox_vars.iter() - .map(|(k, v)| (k.clone(), v.clone_box())) + .map(|(k, v)| (k.clone(), (**v).clone_box())) // Deref Arc to get the Box .collect() } pub(super) fn restore_outbox_vars(&mut self, saved: HashMap>) { - self.outbox_vars = saved; + self.outbox_vars = saved.into_iter() + .map(|(k, v)| (k, Arc::from(v))) // Convert Box to Arc + .collect(); } /// トップレベル関数をGlobalBoxのメソッドとして登録 - 🔥 暗黙オーバーライド禁止対応 @@ -453,7 +473,8 @@ impl NyashInterpreter { /// 🌍 革命的変数取得(テスト用):GlobalBoxのフィールドから取得 pub fn get_variable(&self, name: &str) -> Result, RuntimeError> { - self.resolve_variable(name) + let shared_var = self.resolve_variable(name)?; + Ok((*shared_var).clone_box()) // Convert Arc back to Box for external interface } } diff --git a/src/interpreter/expressions.rs b/src/interpreter/expressions.rs index d004299a..cc240ea9 100644 --- a/src/interpreter/expressions.rs +++ b/src/interpreter/expressions.rs @@ -25,11 +25,12 @@ impl NyashInterpreter { ASTNode::Variable { name, .. } => { // 🌍 革命的変数解決:local変数 → GlobalBoxフィールド → エラー - self.resolve_variable(name) + let shared_var = self.resolve_variable(name) .map_err(|_| RuntimeError::UndefinedVariableAt { name: name.clone(), span: expression.span() - }) + })?; + Ok((*shared_var).clone_box()) // Convert for external interface } ASTNode::BinaryOp { operator, left, right, .. } => { @@ -702,6 +703,8 @@ impl NyashInterpreter { 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) { @@ -731,8 +734,8 @@ impl NyashInterpreter { } } - // Normal field access for now - Ok(field_value) + // Normal field access - convert Arc back to Box for compatibility + Ok((*field_value).clone_box()) } else { Err(RuntimeError::TypeError { message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),