diff --git a/docs/development/roadmap/phases/phase-9/phase_9_78h_mir_pipeline_stabilization.md b/docs/development/roadmap/phases/phase-9/phase_9_78h_mir_pipeline_stabilization.md index 7be5384b..0e15b018 100644 --- a/docs/development/roadmap/phases/phase-9/phase_9_78h_mir_pipeline_stabilization.md +++ b/docs/development/roadmap/phases/phase-9/phase_9_78h_mir_pipeline_stabilization.md @@ -48,7 +48,7 @@ P2PBox(Phase 9.79)に着手する前に、MIRパイプライン(Builder/SS - [ ] 軽量スナップショット緑(TypeOp/extern_call/loop/await/boxcall) - [ ] VM未実装の解消(And/Or・BoxRef演算) - [ ] CLI分離テスト導線(`cargo test -p core`)安定 -- [ ] ResultBox移行完了(旧参照なし) +- [x] ResultBox移行完了(旧参照なし) - [ ] 命令セットの単一出典化(INSTRUCTION_SET.md)と総数26のテストがCIで緑 ## 🪜 タスク分解(実行順) diff --git a/docs/ideas/new-features/2025-08-25-box-converter-system.md b/docs/ideas/new-features/2025-08-25-box-converter-system.md new file mode 100644 index 00000000..4a49be7a --- /dev/null +++ b/docs/ideas/new-features/2025-08-25-box-converter-system.md @@ -0,0 +1,248 @@ +# ビルトイン⇔プラグインBox相互変換システム +Status: Proposal +Created: 2025-08-25 +Priority: High +Related: Everything is Box哲学の現実的実装 + +## 概要 + +ビルトインBoxとプラグインBoxを自由に相互変換できるシステムの提案。 +同一ソースコードから両形態を自動生成し、用途に応じて使い分ける。 + +## 基本アーキテクチャ + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Box定義 │ ──→ │ 変換層 │ ──→ │ 生成物 │ +│ (単一ソース)│ │ (自動生成) │ │ (両形態) │ +└─────────────┘ └─────────────┘ └─────────────┘ + ↓ ↓ ↓ + #[nyash_box] nyash-box-gen .rlib + .so +``` + +## 実装設計 + +### 1. 統一Box定義フォーマット + +```rust +// boxes/string_box/src/lib.rs +#[nyash_box( + id = "string", + version = "1.0.0", + capabilities = ["core", "serializable"] +)] +pub struct StringBox { + value: String, +} + +#[nyash_box_impl] +impl StringBox { + #[nyash_constructor] + pub fn new(s: &str) -> Self { + Self { value: s.to_string() } + } + + #[nyash_method] + pub fn length(&self) -> i64 { + self.value.len() as i64 + } + + #[nyash_method(name = "toString")] + pub fn to_string(&self) -> String { + self.value.clone() + } +} +``` + +### 2. 自動生成される形態 + +#### ビルトイン版(静的リンク用) +```rust +// 自動生成: target/builtin/string_box.rs +use crate::box_trait::{NyashBox, BoxCore}; + +impl BoxCore for StringBox { + fn box_id(&self) -> u64 { /* 自動生成 */ } + fn fmt_box(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "StringBox({})", self.value) + } +} + +impl NyashBox for StringBox { + fn type_name(&self) -> &'static str { "StringBox" } + + fn to_string_box(&self) -> StringBox { + StringBox::new(&self.value) + } + + // メソッドディスパッチ + fn call_method(&self, method: &str, args: Vec>) + -> Result, String> { + match method { + "length" => Ok(Box::new(IntegerBox::new(self.length()))), + "toString" => Ok(Box::new(StringBox::new(&self.to_string()))), + _ => Err(format!("Unknown method: {}", method)) + } + } +} +``` + +#### プラグイン版(動的ロード用) +```rust +// 自動生成: target/plugin/string_box_plugin.rs +use std::ffi::{c_char, c_void}; + +#[repr(C)] +pub struct StringBoxFFI { + handle: u64, +} + +#[no_mangle] +pub extern "C" fn nyash_box_register(host: *const NyHostV1) -> *const NyBoxV1 { + // ホストAPIの保存とBox登録 +} + +#[no_mangle] +pub extern "C" fn string_new(s: *const c_char) -> StringBoxFFI { + let s = unsafe { CStr::from_ptr(s).to_string_lossy() }; + let box_instance = StringBox::new(&s); + // ハンドル管理に登録して返す +} + +#[no_mangle] +pub extern "C" fn string_length(handle: StringBoxFFI) -> i64 { + // ハンドルから実体を取得してメソッド呼び出し +} +``` + +### 3. ビルドシステム + +#### nyash-box-gen ツール +```toml +# nyash-box-gen/Cargo.toml +[package] +name = "nyash-box-gen" +version = "0.1.0" + +[dependencies] +syn = { version = "2.0", features = ["full"] } +quote = "1.0" +proc-macro2 = "1.0" +``` + +#### 使用方法 +```bash +# 両形態を生成 +nyash-box-gen generate \ + --input boxes/string_box/src/lib.rs \ + --builtin-out target/builtin/string_box.rs \ + --plugin-out target/plugin/string_box_plugin.rs + +# ディレクトリ一括処理 +nyash-box-gen batch \ + --input-dir boxes/ \ + --builtin-dir target/builtin/ \ + --plugin-dir target/plugin/ +``` + +### 4. ビルド設定 + +```toml +# Nyash本体のCargo.toml +[features] +# 個別Box制御 +static-string-box = [] +static-integer-box = [] +static-console-box = [] + +# 一括制御 +all-static = ["static-string-box", "static-integer-box", ...] +all-dynamic = [] +hybrid-performance = ["static-string-box", "static-integer-box"] # よく使うものだけ静的 +``` + +### 5. ランタイムでの透過的利用 + +```rust +// src/runtime/box_loader.rs +pub struct BoxLoader { + static_boxes: HashMap<&'static str, fn() -> Box>, + plugin_loader: PluginLoaderV2, +} + +impl BoxLoader { + pub fn load_box(&self, name: &str) -> Result, Error> { + // 静的版が有効なら優先 + #[cfg(feature = "static-string-box")] + if name == "StringBox" { + return Ok(Box::new(StringBox::new(""))); + } + + // なければプラグインから + self.plugin_loader.load_box(name) + } +} +``` + +## 高度な機能 + +### 1. ホットスワップ開発モード +```rust +// 開発時のみ有効 +#[cfg(feature = "dev-mode")] +impl BoxLoader { + pub fn reload_box(&mut self, name: &str) -> Result<(), Error> { + // プラグインを再ロード(ビルトインは不可) + self.plugin_loader.reload(name) + } +} +``` + +### 2. パフォーマンスプロファイリング +```rust +// 両形態の性能を比較 +nyash-box-gen benchmark \ + --box string \ + --iterations 1000000 \ + --compare static vs dynamic +``` + +### 3. 移行ツール +```rust +// 既存ビルトインBoxをプラグイン化 +nyash-box-gen migrate \ + --from src/boxes/old_string_box.rs \ + --to boxes/string_box/src/lib.rs \ + --infer-annotations +``` + +## 利点 + +1. **柔軟性**: 同一コードで両形態を維持 +2. **パフォーマンス**: 必要に応じて静的リンク選択可 +3. **開発効率**: プラグインでホットリロード開発 +4. **互換性**: 既存コードへの影響最小 +5. **段階的移行**: Boxごとに個別に移行可能 + +## 実装ロードマップ + +### Phase 1: 基礎実装(1週間) +- [ ] nyash-box-genの基本実装 +- [ ] マクロ(#[nyash_box]等)の定義 +- [ ] 単純なBoxでのプロトタイプ + +### Phase 2: 統合(2週間) +- [ ] BoxLoaderの実装 +- [ ] ビルドシステムとの統合 +- [ ] 既存Boxの移行 + +### Phase 3: 最適化(1週間) +- [ ] ベンチマークシステム +- [ ] ホットリロード機能 +- [ ] デバッグサポート + +## まとめ + +このシステムにより、「Everything is Box」の理想を保ちながら、 +現実的なパフォーマンスと開発効率を両立できる。 +純粋主義と実用主義の最適なバランスを実現する。 \ No newline at end of file diff --git a/src/box_trait.rs b/src/box_trait.rs index f162fc65..391b2bac 100644 --- a/src/box_trait.rs +++ b/src/box_trait.rs @@ -719,159 +719,6 @@ impl Display for ErrorBox { } } -/// Result values in Nyash - represents success or error results -#[deprecated(note = "Use boxes::result::NyashResultBox (aka boxes::ResultBox) instead")] -#[derive(Debug)] -pub struct ResultBox { - pub is_success: bool, - pub value: Option>, - pub error: Option, - base: BoxBase, -} - -#[allow(deprecated)] -impl ResultBox { - pub fn new_success(value: Box) -> Self { - Self { - is_success: true, - value: Some(value), - error: None, - base: BoxBase::new(), - } - } - - pub fn new_error(error: ErrorBox) -> Self { - Self { - is_success: false, - value: None, - error: Some(error), - base: BoxBase::new(), - } - } - - // ===== Result Methods for Nyash ===== - - /// Check if result is successful - pub fn is_ok(&self) -> Box { - Box::new(BoolBox::new(self.is_success)) - } - - /// Get success value (returns void if error) - pub fn get_value(&self) -> Box { - match &self.value { - Some(val) => val.clone_box(), - None => Box::new(VoidBox::new()), - } - } - - /// Get error (returns void if success) - pub fn get_error(&self) -> Box { - match &self.error { - Some(err) => Box::new(err.clone()), - None => Box::new(VoidBox::new()), - } - } -} - -#[allow(deprecated)] -impl BoxCore for ResultBox { - 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, "{}", self.to_string_box().value) - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } -} - -#[allow(deprecated)] -impl NyashBox for ResultBox { - fn to_string_box(&self) -> StringBox { - if self.is_success { - if let Some(value) = &self.value { - StringBox::new(format!("Result(OK: {})", value.to_string_box().value)) - } else { - StringBox::new("Result(OK: void)".to_string()) - } - } else { - if let Some(error) = &self.error { - StringBox::new(format!("Result(Error: {})", error.to_string_box().value)) - } else { - StringBox::new("Result(Error: unknown)".to_string()) - } - } - } - - fn equals(&self, other: &dyn NyashBox) -> BoolBox { - if let Some(other_result) = other.as_any().downcast_ref::() { - if self.is_success != other_result.is_success { - return BoolBox::new(false); - } - - if self.is_success { - // Compare success values - match (&self.value, &other_result.value) { - (Some(a), Some(b)) => a.equals(b.as_ref()), - (None, None) => BoolBox::new(true), - _ => BoolBox::new(false), - } - } else { - // Compare errors - match (&self.error, &other_result.error) { - (Some(a), Some(b)) => a.equals(b), - (None, None) => BoolBox::new(true), - _ => BoolBox::new(false), - } - } - } else { - BoolBox::new(false) - } - } - - fn type_name(&self) -> &'static str { - "ResultBox" - } - - fn clone_box(&self) -> Box { - if self.is_success { - if let Some(value) = &self.value { - Box::new(ResultBox::new_success(value.clone_box())) - } else { - Box::new(ResultBox::new_success(Box::new(VoidBox::new()))) - } - } else { - if let Some(error) = &self.error { - Box::new(ResultBox::new_error(error.clone())) - } else { - Box::new(ResultBox::new_error(ErrorBox::new("Unknown", "Unknown error"))) - } - } - } - - /// 仮実装: clone_boxと同じ(後で修正) - fn share_box(&self) -> Box { - self.clone_box() - } -} - -#[allow(deprecated)] -impl Display for ResultBox { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.fmt_box(f) - } -} // FutureBox is now implemented in src/boxes/future/mod.rs using RwLock pattern // and re-exported from src/boxes/mod.rs as both NyashFutureBox and FutureBox