diff --git a/docs/CURRENT_TASK.md b/docs/CURRENT_TASK.md index 66aabed4..3942f344 100644 --- a/docs/CURRENT_TASK.md +++ b/docs/CURRENT_TASK.md @@ -1,20 +1,24 @@ # 🎯 現在のタスク (2025-08-19 更新) -## ✅ 完了: ビルド時間劇的改善成功! +## ✅ 完了: Phase 9.78 統合BoxFactory革命達成! -### 🎉 達成結果 -**ビルド時間: 4分 → 43秒 (5.6倍高速化!)** +### 🎉 Phase 9.78a/9.78b 達成結果 +**統合FactoryによるBox生成フロー統一成功!** -#### 実装内容 -1. **✅ wasmtime分離完了** - `wasm-backend` feature flag実装 - - `Cargo.toml`: wasmtime/wabtをoptional化 - - `src/backend/mod.rs`: 条件付きコンパイル追加 - - `src/runner.rs`: feature未有効時の適切なエラー表示 - - `src/benchmarks.rs`: WASM関連を条件付き化 +#### 🏭 実装完了内容 +1. **✅ Phase 9.78a: BoxFactory基盤実装** + - `BoxFactory`トレイト+`UnifiedBoxRegistry`統一アーキテクチャ + - `src/box_factory/`: builtin, plugin, user_defined Factory分離 + - 優先順位制御(builtin > user > plugin)+型キャッシュ -2. **✅ ビルドエラー修正完了** - - benchmarks.rs内の条件付きコンパイル対応 - - すべてのビルドパターンで正常動作確認済み +2. **✅ Phase 9.78b: ビルトインBox統合** + - 600+行match文 → 30行レジストリ呼び出しに削減成功 + - StringBox, IntegerBox, ArrayBox等20+種類統合完了 + - 🏭 統合レジストリ経由での生成を実測確認済み + +3. **✅ ビルド時間劇的改善維持** + - wasmtime分離: `wasm-backend` feature flag + - **ビルド時間: 4分 → 43秒 (5.6倍高速化!)** ### 📊 新しいビルドコマンド ```bash @@ -29,17 +33,47 @@ cargo build --release -j32 --features wasm-backend ## 🎯 次の優先事項 -### 1. 統合Box管理システムの設計(最優先)🆕 -- **目標**: ビルトイン・ユーザー定義・プラグインBoxの統一管理 -- **現状の問題**: - - ビルトインBox: 直接`Box`生成 - - ユーザー定義Box: `InstanceBox`経由 - - プラグインBox: BIDシステム経由 -- **提案**: 統合BoxFactory/BoxRegistryシステム -- **期待効果**: - - フロー簡略化(すべて同じインターフェース) - - WASMビルド時の除外が容易(feature分岐統一) - - 将来の拡張性向上 +### 1. Phase 9.78d: InstanceBox簡素化統一実装(最優先🔥) +**深い分析結果: シンプルで美しい統一戦略確定** + +- **目標**: レガシー削除 + すべてのBox型をInstanceBox統一 +- **確定戦略**: 簡素化InstanceBox + trait object完全統一 +- **現状**: + - ✅ ビルトインBox: 統合レジストリ経由で生成済み + - ✅ InstanceBox設計: 深い分析完了、簡素化戦略確定 + - 📋 実装準備: レガシー削除 + 統一コンストラクタ + +#### 🎯 確定した簡素化InstanceBox設計 +```rust +pub struct InstanceBox { + pub class_name: String, + // ✅ 統一フィールド管理(レガシーfields削除) + pub fields_ng: Arc>>, + // ✅ メソッド(ユーザー定義のみ、ビルトインは空) + pub methods: Arc>, + // 🏭 統一内容 - すべてのBox型を同じように扱う + pub inner_content: Option>, + // ✅ 基底 + 最小限ライフサイクル + base: BoxBase, + finalized: Arc>, +} + +// 🎯 統一コンストラクタ +impl InstanceBox { + // ビルトイン・プラグイン用 + pub fn from_any_box(class_name: String, inner: Box) -> Self; + // ユーザー定義用 + pub fn from_declaration(class_name: String, fields: Vec, methods: HashMap) -> Self; +} +``` + +#### ✨ Rust的美しさ +1. **trait object統一**: すべて`Box`として同じ扱い +2. **Option柔軟性**: `inner_content`でビルトイン/ユーザー分岐 +3. **統一ライフサイクル**: init/finiロジック完全統一 +4. **レガシー削除**: `fields`削除でオーバーヘッド最小化 + +**📚 両AI先生アーカイブ**: [phase_9_78_option_c_consultation_archive.md](docs/archive/phase_9_78_option_c_consultation_archive.md) ### 2. nekocodeでソースコードダイエット - **目標**: 3.3MB → 2MB以下 @@ -60,45 +94,59 @@ cargo build --release -j32 --features wasm-backend --- -## 💡 統合Box管理システム設計案 +## 💡 Phase 9.78d: InstanceBox統一実装戦略 -### 🎯 **深く考えた結果: BoxFactory統一アーキテクチャ** +### 🎯 **両AI先生一致の結論: Option B段階戦略** +#### **段階移行プラン** +``` +フェーズ1: Option B実装 (短期・1-2週間) ← 今ここ +├── UnifiedInstanceBoxFactory作成 +├── InstanceBox拡張 (from_builtin/from_plugin) +└── 統一create_boxフロー + +フェーズ2: パフォーマンス最適化 (中期・1週間) +├── ベンチマーク実行 +├── InstanceBoxフィールド最適化 (Option) +└── オーバーヘッド実測・改善 + +フェーズ3: Option C移行 (長期・必要時) +├── 単純Box(NullBox等)からBoxClass化 +├── ハイブリッド実装 (従来+BoxClass混在) +└── 段階的16種類移行 +``` + +#### **即座実装: InstanceBox拡張** ```rust -// 統合BoxFactoryトレイト -pub trait BoxFactory { - fn create_box(&self, name: &str, args: &[Box]) -> Result, RuntimeError>; - fn is_available(&self) -> bool; - fn box_types(&self) -> Vec<&str>; -} - -// 実装例 -struct BuiltinBoxFactory; // StringBox, IntegerBox等 -struct UserBoxFactory; // InstanceBox経由 -struct PluginBoxFactory; // BID/FFI経由 - -// 統合レジストリ -struct UnifiedBoxRegistry { - factories: Vec>, +impl InstanceBox { + /// ビルトインBoxからInstanceBox作成 + pub fn from_builtin(builtin: Box) -> Self { + Self { + box_type_name: builtin.type_name().to_string(), + inner_value: Some(builtin), // ビルトインを内包 + fields: HashMap::new(), + methods: HashMap::new(), + // ... 既存フィールド + } + } + + /// プラグインBoxからInstanceBox作成 + pub fn from_plugin(plugin: Box) -> Self { + Self { + box_type_name: plugin.type_name().to_string(), + inner_value: Some(plugin), // プラグインを内包 + plugin_wrapped: true, + // ... 既存フィールド + } + } } ``` -### 📊 **利点** -1. **統一インターフェース**: `new StringBox()`も`new MyBox()`も同じ処理フロー -2. **条件付きコンパイル簡単**: - ```rust - #[cfg(not(target_arch = "wasm32"))] - registry.add_factory(Box::new(PluginBoxFactory)); - ``` -3. **優先順位制御**: ビルトイン→ユーザー定義→プラグインの順で検索 -4. **エラーハンドリング統一**: すべて同じエラー型で処理 - -### 🚀 **実装ステップ** -1. BoxFactoryトレイト定義 -2. 各種Factory実装(Builtin/User/Plugin) -3. UnifiedBoxRegistry実装 -4. objects.rsのcreate_object統合 -5. WASM向けfeature分岐追加 +### 📊 **Option B優位性** +1. **🎯 哲学的**: 「Everything is Box」に最も忠実 +2. **🔧 保守性**: 循環参照なし、理解しやすい +3. **🚀 実現性**: 1-2週間で実装可能 +4. **💎 将来性**: Option C移行の完璧な基盤 --- @@ -126,6 +174,48 @@ struct UnifiedBoxRegistry { --- +## ⚠️ 発見されたレガシー問題と修正(2025-08-19) + +### 🐛 重要なレガシー問題: 重複StringBox定義 +**Phase 9.78d実装中に発見された深刻な型システム問題** + +#### 問題の詳細 +- **症状**: 文字列連結演算子 (`+`) が全アプリケーションで動作不可 +- **エラー**: "Addition not supported between StringBox and StringBox" +- **根本原因**: StringBoxが2か所で定義されていた + - `src/box_trait.rs`: 古い定義 + - `src/boxes/string_box.rs`: 新しい正規定義 + +#### 影響範囲 +- 全アプリケーションの文字列演算が破綻 +- 型ダウンキャストの失敗 +- ビルトインBox統合レジストリとの不整合 + +#### 適用された修正 +**ファイル**: `src/interpreter/expressions/operators.rs:8` +```rust +// ❌ 修正前(不正な重複定義を使用) +use crate::box_trait::{NyashBox, IntegerBox, BoolBox, CompareBox, StringBox}; + +// ✅ 修正後(統一レジストリと一致) +use crate::box_trait::{NyashBox, IntegerBox, BoolBox, CompareBox}; +use crate::boxes::StringBox; // 🔧 統一レジストリと一致させる +``` + +#### 検証結果 +```rust +🔍 StringBox downcast SUCCESS! +Test completed WITH concatenation +✅ Execution completed successfully! +``` + +#### 今後の対策 +- 全BoxTypeの重複定義チェック必要 +- 統合レジストリと演算子ハンドラーの一貫性確認 +- 型システム統一の徹底(Phase 9.78d統一戦略の重要性を再確認) + +--- + ## 📋 技術メモ ### wasmtime使用箇所 @@ -154,5 +244,51 @@ time cargo clean && time cargo build --release -j32 --- +--- + +## 🧠 AI先生方との技術相談実績 + +### 📋 相談実績 +- **ChatGPT5先生**: Option C(BoxClass統一戦略)理想形提案 +- **Gemini先生**: Option B → Option C段階移行戦略推奨 +- **共通結論**: Option B実装が現実的かつ哲学に忠実 + +### 💎 重要な技術洞察 +- **循環参照回避**: Context注入パターンで依存関係単方向化 +- **パフォーマンス**: 実測に基づく判断、オーバーヘッド最適化可能 +- **段階移行**: リスク分散しつつ理想形へのパス確保 + +**📚 詳細アーカイブ**: [phase_9_78_option_c_consultation_archive.md](docs/archive/phase_9_78_option_c_consultation_archive.md) + +--- + +--- + +## 🎯 Phase 9.78d実装計画 + +### **Step 1: InstanceBox実装・テスト(最優先)** + +#### 🎯 実装目標コード +```rust +// これが動けばStep 1完了! +let test_string = InstanceBox::from_any_box("StringBox".to_string(), Box::new(StringBox::new("hello"))); +let test_user = InstanceBox::from_declaration("MyBox".to_string(), vec!["field1".to_string()], HashMap::new()); + +// 基本メソッド呼び出しテスト +assert_eq!(test_string.to_string_box().value, "hello"); +``` + +#### 📋 実装タスク +1. `src/instance.rs`: レガシー`fields`削除 +2. `from_any_box`/`from_declaration`コンストラクタ実装 +3. 統一NyashBoxトレイト実装 +4. 上記テストコード動作確認 + +**✅ Step 1完了後**: 段階的置き換え(StringBox等)開始 + +**💎 期待結果**: 完全統一フロー、Everything is Box哲学の完成! + +--- + **最終更新**: 2025年8月19日 -**次回: 統合Box管理システムで革命を!** \ No newline at end of file +**次回: Phase 9.78d簡素化InstanceBox実装開始!** \ No newline at end of file diff --git a/src/instance_v2.rs b/src/instance_v2.rs new file mode 100644 index 00000000..6b38c94a --- /dev/null +++ b/src/instance_v2.rs @@ -0,0 +1,283 @@ +/*! + * Nyash Instance System v2 - Simplified Box Instance Implementation + * + * 🎯 Phase 9.78d: 簡素化InstanceBox統一実装 + * Everything is Box哲学に基づく統一オブジェクト指向システム + * + * 🔄 設計方針: trait objectによる完全統一 + * - すべてのBox型を同じように扱う + * - Optionによる柔軟性 + * - レガシー負債の完全削除 + */ + +use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase}; +use crate::ast::ASTNode; +use crate::value::NyashValue; +use std::collections::HashMap; +use std::fmt::{Debug, Display}; +use std::any::Any; +use std::sync::{Arc, Mutex}; + +/// 🎯 簡素化InstanceBox - すべてのBox型を統一管理 +#[derive(Debug)] +pub struct InstanceBox { + /// クラス名(StringBox, MyUserBox等統一) + pub class_name: String, + + /// 統一フィールド管理(レガシーfields削除) + pub fields_ng: Arc>>, + + /// メソッド定義(ユーザー定義時のみ使用、ビルトインは空) + pub methods: Arc>, + + /// 🏭 統一内容 - すべてのBox型を同じように扱う + pub inner_content: Option>, + + /// Box基底 + ライフサイクル管理 + base: BoxBase, + finalized: Arc>, +} + +impl InstanceBox { + /// 🎯 統一コンストラクタ - すべてのBox型対応 + pub fn from_any_box(class_name: String, inner: Box) -> Self { + Self { + class_name, + fields_ng: Arc::new(Mutex::new(HashMap::new())), + methods: Arc::new(HashMap::new()), // ビルトインは空、ユーザー定義時は設定 + inner_content: Some(inner), // 統一内包 + base: BoxBase::new(), + finalized: Arc::new(Mutex::new(false)), + } + } + + /// ユーザー定義Box専用コンストラクタ + pub fn from_declaration(class_name: String, fields: Vec, methods: HashMap) -> Self { + let mut field_map = HashMap::new(); + for field in fields { + field_map.insert(field, NyashValue::Null); + } + + Self { + class_name, + fields_ng: Arc::new(Mutex::new(field_map)), + methods: Arc::new(methods), + inner_content: None, // ユーザー定義は内包Boxなし + base: BoxBase::new(), + finalized: Arc::new(Mutex::new(false)), + } + } + + /// 🔄 レガシー互換性メソッド - 段階移行用 + pub fn new(class_name: String, fields: Vec, methods: HashMap) -> Self { + Self::from_declaration(class_name, fields, methods) + } + + /// 🔄 レガシー互換性 - 高度なfiniシステムを簡素化して対応 + pub fn new_with_box_info( + class_name: String, + fields: Vec, + methods: HashMap, + _init_field_order: Vec, // 簡素化により無視 + _weak_fields: Vec // 簡素化により無視 + ) -> Self { + eprintln!("⚠️ new_with_box_info: Advanced fini system simplified - init_order and weak_fields ignored"); + Self::from_declaration(class_name, fields, methods) + } + + /// 🎯 統一フィールドアクセス + pub fn get_field(&self, field_name: &str) -> Option { + self.fields_ng.lock().unwrap().get(field_name).cloned() + } + + /// 🎯 統一フィールド設定 + pub fn set_field(&self, field_name: String, value: NyashValue) -> Result<(), String> { + self.fields_ng.lock().unwrap().insert(field_name, value); + Ok(()) + } + + /// 動的フィールド追加(GlobalBox用) + pub fn set_field_dynamic(&self, field_name: String, value: NyashValue) { + self.fields_ng.lock().unwrap().insert(field_name, value); + } + + /// メソッド定義を取得 + pub fn get_method(&self, method_name: &str) -> Option<&ASTNode> { + self.methods.get(method_name) + } + + /// メソッドが存在するかチェック + pub fn has_method(&self, method_name: &str) -> bool { + self.methods.contains_key(method_name) + } + + /// メソッド動的追加(GlobalBox用) + pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) -> Result<(), String> { + let mut new_methods = (*self.methods).clone(); + new_methods.insert(method_name, method_ast); + self.methods = Arc::new(new_methods); + Ok(()) + } + + /// 🎯 統一初期化処理 + pub fn init(&mut self, args: &[Box]) -> Result<(), String> { + match &self.inner_content { + Some(_) => Ok(()), // ビルトイン・プラグインは初期化済み + None => { + // ユーザー定義のinit実行(インタープリター側で実装) + // TODO: インタープリター統合時に実装 + Ok(()) + } + } + } + + /// 🎯 統一解放処理 + pub fn fini(&self) -> Result<(), String> { + let mut finalized = self.finalized.lock().unwrap(); + if *finalized { + return Ok(()); // 既に解放済み + } + + // フィールドクリア + self.fields_ng.lock().unwrap().clear(); + + *finalized = true; + eprintln!("🎯 fini(): Instance {} (ID: {}) finalized", self.class_name, self.base.id); + Ok(()) + } + + /// 解放済みかチェック + pub fn is_finalized(&self) -> bool { + *self.finalized.lock().unwrap() + } +} + +/// 🎯 統一NyashBoxトレイト実装 +impl NyashBox for InstanceBox { + fn to_string_box(&self) -> StringBox { + StringBox::new(format!("<{} instance #{}>", self.class_name, self.base.id)) + } + + fn equals(&self, other: &dyn NyashBox) -> BoolBox { + if let Some(other_instance) = other.as_any().downcast_ref::() { + BoolBox::new(self.base.id == other_instance.base.id) + } else { + BoolBox::new(false) + } + } + + fn type_name(&self) -> &'static str { + "InstanceBox" + } + + fn clone_box(&self) -> Box { + Box::new(InstanceBox { + class_name: self.class_name.clone(), + fields_ng: Arc::clone(&self.fields_ng), + methods: Arc::clone(&self.methods), + inner_content: self.inner_content.as_ref().map(|inner| inner.clone_box()), + base: self.base.clone(), + finalized: Arc::clone(&self.finalized), + }) + } + + fn share_box(&self) -> Box { + // TODO: 正しいshare_boxセマンティクス実装 + self.clone_box() + } + +} + +impl BoxCore for InstanceBox { + fn box_id(&self) -> u64 { + self.base.id + } + + fn parent_type_id(&self) -> Option { + self.base.parent_type_id + } + + fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "<{} instance #{}>", self.class_name, self.base.id) + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } +} + +impl Display for InstanceBox { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.fmt_box(f) + } +} + +// ===== Tests ===== + +#[cfg(test)] +mod tests { + use super::*; + use crate::box_trait::IntegerBox; + + #[test] + fn test_from_any_box_creation() { + let string_box = Box::new(crate::box_trait::StringBox::new("hello")); + let instance = InstanceBox::from_any_box("StringBox".to_string(), string_box); + + assert_eq!(instance.class_name, "StringBox"); + assert!(instance.inner_content.is_some()); + assert!(instance.methods.is_empty()); // ビルトインは空 + } + + #[test] + fn test_from_declaration_creation() { + let fields = vec!["x".to_string(), "y".to_string()]; + let methods = HashMap::new(); + let instance = InstanceBox::from_declaration("Point".to_string(), fields, methods); + + assert_eq!(instance.class_name, "Point"); + assert!(instance.inner_content.is_none()); // ユーザー定義は内包なし + assert_eq!(instance.get_field("x"), Some(NyashValue::Null)); + assert_eq!(instance.get_field("y"), Some(NyashValue::Null)); + } + + #[test] + fn test_field_operations() { + let instance = InstanceBox::from_declaration("TestBox".to_string(), vec!["value".to_string()], HashMap::new()); + + // フィールド設定 + instance.set_field("value".to_string(), NyashValue::Integer(42)).unwrap(); + + // フィールド取得 + assert_eq!(instance.get_field("value"), Some(NyashValue::Integer(42))); + } + + #[test] + fn test_unified_approach() { + // ビルトインBox + let string_instance = InstanceBox::from_any_box( + "StringBox".to_string(), + Box::new(crate::box_trait::StringBox::new("test")) + ); + + // ユーザー定義Box + let user_instance = InstanceBox::from_declaration( + "MyBox".to_string(), + vec!["field1".to_string()], + HashMap::new() + ); + + // どちらも同じ型として扱える! + let instances: Vec = vec![string_instance, user_instance]; + + for instance in instances { + println!("Instance: {}", instance.class_name); + // すべて Box として統一処理可能 + let _box_ref: &dyn NyashBox = &instance; + } + } +} \ No newline at end of file diff --git a/src/interpreter/expressions/operators.rs b/src/interpreter/expressions/operators.rs index 9c800fce..1f5434b9 100644 --- a/src/interpreter/expressions/operators.rs +++ b/src/interpreter/expressions/operators.rs @@ -4,24 +4,33 @@ // Removed super::* import - specific imports below use crate::ast::{ASTNode, BinaryOperator, UnaryOperator}; -use crate::box_trait::{NyashBox, IntegerBox, StringBox, BoolBox, CompareBox}; +use crate::box_trait::{NyashBox, IntegerBox, BoolBox, CompareBox}; +use crate::boxes::StringBox; // 🔧 統一レジストリと一致させる use crate::boxes::FloatBox; use crate::interpreter::core::{NyashInterpreter, RuntimeError}; // Local helper functions to bypass import issues pub(super) fn try_add_operation(left: &dyn NyashBox, right: &dyn NyashBox) -> Option> { + // 🔍 デバッグ出力追加 + eprintln!("🔍 try_add_operation: left={}, right={}", left.type_name(), right.type_name()); + // IntegerBox + IntegerBox if let (Some(left_int), Some(right_int)) = ( left.as_any().downcast_ref::(), right.as_any().downcast_ref::() ) { + eprintln!("🔍 IntegerBox + IntegerBox detected"); return Some(Box::new(IntegerBox::new(left_int.value + right_int.value))); } // StringBox + anything -> concatenation + eprintln!("🔍 Checking StringBox downcast..."); if let Some(left_str) = left.as_any().downcast_ref::() { + eprintln!("🔍 StringBox downcast SUCCESS!"); let right_str = right.to_string_box(); return Some(Box::new(StringBox::new(format!("{}{}", left_str.value, right_str.value)))); + } else { + eprintln!("🔍 StringBox downcast FAILED!"); } // BoolBox + BoolBox -> IntegerBox diff --git a/src/lib.rs b/src/lib.rs index b48b1fdf..1aa48b4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ pub mod ast; // Using old ast.rs for now pub mod parser; // Using old parser.rs for now pub mod interpreter; pub mod instance; +pub mod instance_v2; // 🎯 Phase 9.78d: Simplified InstanceBox implementation pub mod channel_box; pub mod finalization; pub mod exception_box; @@ -70,7 +71,8 @@ pub use type_box::{TypeBox, TypeRegistry, MethodSignature}; // 🌟 TypeBox exp pub use ast::{ASTNode, BinaryOperator, LiteralValue}; pub use parser::{NyashParser, ParseError}; pub use interpreter::{NyashInterpreter, RuntimeError}; -pub use instance::InstanceBox; +// pub use instance::InstanceBox; // 旧実装 +pub use instance_v2::InstanceBox; // 🎯 新実装テスト pub use channel_box::{ChannelBox, MessageBox}; pub use boxes::math_box::{MathBox, FloatBox, RangeBox}; pub use boxes::time_box::{TimeBox, DateTimeBox, TimerBox};