# 🌟 Nyash アーキテクチャ再設計提案 *by Codex exec (2025-08-21)* ## 🎯 核心的洞察 **「実装詳細共有」から「モデル共有・実行時共有」への転換** 現在の問題の本質は、InterpreterとVMが「実装詳細」を共有しようとしていること。正しいアプローチは「モデル(宣言)」と「ランタイム(実行環境)」を共有し、実行戦略だけを分離すること。 ## 🏗️ 新アーキテクチャ層構造 ``` ┌─────────────┐ │ AST/Model │ ← 純粋なデータモデル(依存なし) └──────┬──────┘ │ ┌──────▼──────┐ │ Runtime │ ← 型システム・クラス管理・インスタンス生成 └──────┬──────┘ │ ┌──────┴──────┬──────────┬────────────┐ │ Interpreter │ VM │ Plugins │ └─────────────┴──────────┴────────────┘ ``` ### 各層の責務 **AST/Model層** - 言語の純データモデル - BoxDeclaration、ASTNode、型シグネチャ - 実行時情報を含まない **Runtime層** - BoxClass/BoxFactoryによる型システム - インスタンス生成とライフサイクル管理 - メソッドディスパッチと呼び出し規約 **Backend層** - Interpreter: AST直接実行 - VM: MIR/Bytecode実行 - 両者ともRuntimeを通じてBoxを操作 ## 🔧 具体的な設計 ### 1. BoxDeclarationの移動 ```rust // core::model::box_declaration.rs pub struct BoxDeclaration { pub name: String, pub type_params: Vec, pub fields: Vec, pub methods: Vec, pub static_methods: Vec, pub attrs: AttrSet, pub source_span: Option, } pub struct FieldDecl { pub name: String, pub ty: TypeRef, pub attrs: AttrSet, } pub struct MethodDecl { pub name: String, pub sig: FnSig, pub body: FnBodyRef, // AST or MIR reference } ``` ### 2. NyashRuntimeの導入 ```rust // runtime::mod.rs pub struct NyashRuntime { box_registry: BoxRegistry, type_space: TypeSpace, fn_space: FnSpace, } pub struct ExecutionSession { runtime: Arc, root_box: SharedBox, frames: Vec, env: Environment, } // SharedBox = Arc pub type SharedBox = Arc; ``` ### 3. BoxClass/Factoryシステム ```rust // runtime::box_class.rs pub trait BoxClass: Send + Sync { fn name(&self) -> &str; fn instantiate( &self, args: &[SharedBox], sess: &mut ExecutionSession ) -> Result; fn lookup_method(&self, name: &str) -> Option; fn lifecycle(&self) -> Option<&dyn BoxLifecycle>; } pub trait BoxFactory: Send + Sync { fn can_build(&self, decl: &BoxDeclaration) -> bool; fn build_class( &self, decl: &BoxDeclaration, rt: &NyashRuntime ) -> Result>; } pub trait BoxLifecycle { fn on_birth(&self, ctx: &mut InstanceCtx) -> Result<()>; fn on_fini(&self, ctx: &mut InstanceCtx); } ``` ### 4. 統一されたBox管理 ```rust // runtime::registry.rs pub struct BoxRegistry { classes: RwLock>>, factories: RwLock>>, } impl BoxRegistry { pub fn register_class(&self, class: Arc) { // 登録処理 } pub fn get_class(&self, name: &str) -> Option> { // クラス取得 } pub fn create_instance( &self, class_name: &str, args: &[SharedBox], sess: &mut ExecutionSession ) -> Result { let class = self.get_class(class_name)?; class.instantiate(args, sess) } } ``` ## 📋 実装手順(最小破壊的移行) ### Step 1: BoxDeclarationの移動 ```rust // 1. core::model モジュールを作成 // 2. BoxDeclarationを移動 // 3. インタープリターで一時的に別名を使用 use core::model::BoxDeclaration as InterpreterBoxDecl; ``` ### Step 2: NyashRuntimeの骨組み作成 ```rust // 最初は空の実装から始める pub struct NyashRuntime { // 段階的に追加 } pub struct NyashRuntimeBuilder { // SharedStateからの移行を支援 } ``` ### Step 3: BoxFactoryのdyn化 ```rust // 現在の trait BoxFactory を使用 // すべて Arc として扱う ``` ### Step 4: グローバル登録の排除 ```rust // 削除: register_user_defined_factory(...) // 追加: NyashRuntimeBuilder::with_factory(...) ``` ### Step 5: SharedStateの段階的分解 ```rust // 一時的なシム pub struct SharedStateShim { runtime: Arc, session: ExecutionSession, } // 互換性のためのFrom実装 impl From for SharedStateShim { // 移行ロジック } ``` ### Step 6-8: 統一と最適化 - Interpreter/VMのコンストラクタ統一 - birth/finiライフサイクルの一元化 - 最終的なSharedState削除 ## 🎯 得られる利点 1. **依存関係の明確化** - VM→Interpreter依存が完全に解消 - 両者はRuntimeのみに依存 2. **テスタビリティ向上** - グローバル状態なし - 並行テスト可能 3. **保守性向上** - 責務が明確に分離 - 新しいBackend追加が容易 4. **Everything is Box哲学の貫徹** - 統一的なBox管理 - birth/finiライフサイクルの一元化 ## ⚠️ 実装上の注意点 1. **trait objectは必ず`Arc`** - `Arc`は使わない - dynキーワードを忘れない 2. **段階的移行** - 各ステップでテストが通ることを確認 - 互換性レイヤーを活用 3. **ロックの最小化** - Runtimeは基本的に不変 - 必要最小限のRwLock使用 --- この設計により、Nyashはよりシンプルでエレガントなアーキテクチャとなり、InterpreterとVMの統合が自然に実現されます。