# 組み込みnyashstd名前空間アーキテクチャ設計 ## 🏗️ 技術的実装アーキテクチャ ### 📊 現在のインタープリター構造分析 #### **NyashInterpreter構造** ```rust pub struct NyashInterpreter { pub(super) shared: SharedState, // 共有状態 pub(super) local_vars: HashMap, pub(super) outbox_vars: HashMap, // その他の制御フロー状態... } ``` #### **設計判断:SharedStateに組み込み** - **理由**: 標準ライブラリは不変・全インタープリターで共有可能 - **利点**: メモリ効率、パフォーマンス向上 - **実装**: SharedStateに`builtin_stdlib`フィールド追加 ## 🌟 最適化されたアーキテクチャ設計 ### 1. SharedState拡張 #### **src/interpreter/core.rs** ```rust #[derive(Clone)] pub struct SharedState { // 既存フィールド... pub global_vars: Arc>>, pub functions: Arc>>, pub box_definitions: Arc>>>, pub loop_counter: Arc, pub included_files: Arc>>, // 🌟 新規追加: 組み込み標準ライブラリ pub builtin_stdlib: Arc, pub using_imports: Arc>>, // ファイル別インポート管理 } #[derive(Debug, Clone)] pub struct UsingContext { pub imported_namespaces: Vec, // ["nyashstd"] pub file_id: String, // インポート元ファイル識別 } ``` ### 2. BuiltinStdlib効率化設計 #### **新ファイル: src/stdlib/builtin.rs** ```rust //! 🚀 高性能組み込み標準ライブラリ //! //! 設計方針: //! - Zero-allocation関数実行 //! - 高速名前解決 //! - 既存Box実装の最大活用 use crate::boxes::*; use std::collections::HashMap; /// 組み込み標準ライブラリのメイン構造体 #[derive(Debug)] pub struct BuiltinStdlib { /// 高速アクセス用:フラットな関数マップ /// "string.upper" -> BuiltinFunction pub flat_functions: HashMap, /// IDE補完用:階層構造 /// "nyashstd" -> { "string" -> ["upper", "lower", ...] } pub hierarchical_map: HashMap>>, } /// 組み込み関数の実装 pub struct BuiltinFunction { pub namespace: &'static str, // "nyashstd" pub box_name: &'static str, // "string" pub method_name: &'static str, // "upper" pub implementation: BuiltinMethodImpl, pub arg_count: Option, // None = 可変長 pub description: &'static str, // エラーメッセージ・ヘルプ用 } /// 高性能関数実装 pub type BuiltinMethodImpl = fn(&[Box]) -> Result, RuntimeError>; impl BuiltinStdlib { /// 🚀 標準ライブラリ初期化(起動時1回のみ) pub fn new() -> Self { let mut stdlib = BuiltinStdlib { flat_functions: HashMap::new(), hierarchical_map: HashMap::new(), }; // 標準関数登録 stdlib.register_all_functions(); stdlib } /// ⚡ 高速関数解決 pub fn get_function(&self, qualified_name: &str) -> Option<&BuiltinFunction> { // "string.upper" で直接アクセス self.flat_functions.get(qualified_name) } /// 🔍 IDE補完用:利用可能関数一覧取得 pub fn get_available_methods(&self, namespace: &str, box_name: &str) -> Option<&Vec> { self.hierarchical_map.get(namespace)?.get(box_name) } /// 📋 全名前空間取得(IDE補完用) pub fn get_all_namespaces(&self) -> Vec<&String> { self.hierarchical_map.keys().collect() } } ``` ### 3. 標準関数実装(高性能版) #### **文字列関数実装** ```rust impl BuiltinStdlib { fn register_all_functions(&mut self) { // === nyashstd.string.* === self.register_function("string.upper", BuiltinFunction { namespace: "nyashstd", box_name: "string", method_name: "upper", implementation: |args| { if args.len() != 1 { return Err(RuntimeError::InvalidArguments( "string.upper(str) takes exactly 1 argument".to_string() )); } // 🚀 既存StringBox実装活用 let input_str = args[0].to_string_box().value; let result = StringBox::new(&input_str.to_uppercase()); Ok(Box::new(result)) }, arg_count: Some(1), description: "Convert string to uppercase", }); self.register_function("string.lower", BuiltinFunction { namespace: "nyashstd", box_name: "string", method_name: "lower", implementation: |args| { if args.len() != 1 { return Err(RuntimeError::InvalidArguments( "string.lower(str) takes exactly 1 argument".to_string() )); } let input_str = args[0].to_string_box().value; let result = StringBox::new(&input_str.to_lowercase()); Ok(Box::new(result)) }, arg_count: Some(1), description: "Convert string to lowercase", }); self.register_function("string.split", BuiltinFunction { namespace: "nyashstd", box_name: "string", method_name: "split", implementation: |args| { if args.len() != 2 { return Err(RuntimeError::InvalidArguments( "string.split(str, separator) takes exactly 2 arguments".to_string() )); } // 🚀 既存StringBox.split()メソッド活用 let string_box = StringBox::new(&args[0].to_string_box().value); let separator = &args[1].to_string_box().value; string_box.split(separator) }, arg_count: Some(2), description: "Split string by separator into array", }); // === nyashstd.math.* === self.register_function("math.sin", BuiltinFunction { namespace: "nyashstd", box_name: "math", method_name: "sin", implementation: |args| { if args.len() != 1 { return Err(RuntimeError::InvalidArguments( "math.sin(x) takes exactly 1 argument".to_string() )); } // 🚀 既存MathBox実装活用 let math_box = MathBox::new(); let x = args[0].to_integer_box().value as f64; let result = math_box.sin(x)?; Ok(result) }, arg_count: Some(1), description: "Calculate sine of x (in radians)", }); // 階層マップも同時構築 self.build_hierarchical_map(); } fn register_function(&mut self, qualified_name: &str, function: BuiltinFunction) { self.flat_functions.insert(qualified_name.to_string(), function); } fn build_hierarchical_map(&mut self) { for (qualified_name, function) in &self.flat_functions { let namespace_map = self.hierarchical_map .entry(function.namespace.to_string()) .or_insert_with(HashMap::new); let method_list = namespace_map .entry(function.box_name.to_string()) .or_insert_with(Vec::new); method_list.push(function.method_name.to_string()); } // ソートして一貫性確保 for namespace_map in self.hierarchical_map.values_mut() { for method_list in namespace_map.values_mut() { method_list.sort(); } } } } ``` ### 4. インタープリター統合 #### **NyashInterpreter拡張** ```rust impl NyashInterpreter { /// using文実行 pub fn execute_using(&mut self, namespace_name: &str) -> Result<(), RuntimeError> { // 組み込み名前空間存在チェック if !self.shared.builtin_stdlib.hierarchical_map.contains_key(namespace_name) { return Err(RuntimeError::UndefinedNamespace(namespace_name.to_string())); } // 現在ファイルのusingコンテキスト更新 let file_id = self.get_current_file_id(); let mut using_imports = self.shared.using_imports.write().unwrap(); let context = using_imports.entry(file_id.clone()).or_insert(UsingContext { imported_namespaces: Vec::new(), file_id: file_id.clone(), }); if !context.imported_namespaces.contains(&namespace_name.to_string()) { context.imported_namespaces.push(namespace_name.to_string()); } Ok(()) } /// ⚡ 高速名前解決:string.upper() → nyashstd.string.upper() pub fn resolve_qualified_call(&self, path: &[String]) -> Option { if path.len() != 2 { return None; // Phase 0では2段階のみ対応 } let box_name = &path[0]; let method_name = &path[1]; let file_id = self.get_current_file_id(); // 現在ファイルのusingインポート確認 if let Ok(using_imports) = self.shared.using_imports.read() { if let Some(context) = using_imports.get(&file_id) { for namespace in &context.imported_namespaces { let qualified_name = format!("{}.{}", box_name, method_name); // 実際に関数が存在するかチェック if self.shared.builtin_stdlib.get_function(&qualified_name).is_some() { return Some(qualified_name); } } } } None } /// 🚀 組み込み関数実行 pub fn call_builtin_function(&self, qualified_name: &str, args: Vec>) -> Result, RuntimeError> { if let Some(function) = self.shared.builtin_stdlib.get_function(qualified_name) { // 引数数チェック if let Some(expected_count) = function.arg_count { if args.len() != expected_count { return Err(RuntimeError::InvalidArguments( format!("{}.{}() takes exactly {} arguments, got {}", function.box_name, function.method_name, expected_count, args.len()) )); } } // 関数実行 (function.implementation)(&args) } else { Err(RuntimeError::UndefinedMethod(qualified_name.to_string())) } } } ``` ### 5. 式実行統合 #### **src/interpreter/expressions.rs修正** ```rust impl NyashInterpreter { pub fn execute_expression(&mut self, node: &ASTNode) -> Result, RuntimeError> { match node { // 既存のケース... // メソッド呼び出し処理修正 ASTNode::MethodCall { object, method, args, .. } => { // オブジェクトが単純な識別子かチェック if let ASTNode::Variable { name: box_name, .. } = object.as_ref() { // using経由での短縮呼び出しチェック let path = vec![box_name.clone(), method.clone()]; if let Some(qualified_name) = self.resolve_qualified_call(&path) { // 引数評価 let evaluated_args = self.evaluate_arguments(args)?; // 組み込み関数実行 return self.call_builtin_function(&qualified_name, evaluated_args); } } // 既存のメソッド呼び出し処理 // ... } // using文実行 ASTNode::UsingStatement { namespace_name, .. } => { self.execute_using(namespace_name)?; Ok(Box::new(VoidBox::new())) } // 他の既存ケース... } } } ``` ## 📊 パフォーマンス特性 ### ⚡ 最適化ポイント #### **1. Zero-Allocation関数解決** ```rust // ❌ 遅い:毎回文字列生成 let qualified = format!("{}.{}", box_name, method_name); // ✅ 高速:事前計算済みマップ if let Some(func) = stdlib.flat_functions.get(&qualified_name) { ... } ``` #### **2. 高速名前解決** ```rust // O(1)アクセス:HashMap直接ルックアップ // "string.upper" -> BuiltinFunction ``` #### **3. 既存Box実装活用** ```rust // 既存の最適化済みStringBox.split()を直接使用 string_box.split(separator) // 新規実装不要 ``` ## 🧪 テストカバレッジ ### Phase 0必須テスト #### **基本機能テスト** ```nyash # test_builtin_stdlib_basic.hako using nyashstd # 文字列操作 assert(string.upper("hello") == "HELLO") assert(string.lower("WORLD") == "world") assert(string.split("a,b,c", ",").length() == 3) # 数学関数 assert(math.sin(0) == 0) assert(math.cos(0) == 1) # 配列操作 local arr = [1, 2, 3] assert(array.length(arr) == 3) assert(array.get(arr, 1) == 2) ``` #### **エラーハンドリング** ```nyash # test_builtin_stdlib_errors.hako using nyashstd # 引数数エラー try { string.upper("hello", "extra") # 2引数でエラー assert(false, "Should have thrown error") } catch e { assert(e.contains("takes exactly 1 argument")) } # 未定義名前空間 try { using nonexistent assert(false, "Should have thrown error") } catch e { assert(e.contains("UndefinedNamespace")) } ``` #### **IDE補完サポート** ```rust // テスト:補完候補取得 let methods = stdlib.get_available_methods("nyashstd", "string"); assert!(methods.unwrap().contains(&"upper".to_string())); assert!(methods.unwrap().contains(&"lower".to_string())); ``` ## 🎯 実装順序 ### 🚨 Critical(即時実装) 1. **BuiltinStdlib基盤** - src/stdlib/builtin.rs作成 2. **SharedState統合** - builtin_stdlibフィールド追加 3. **using文パーサー** - ASTNode::UsingStatement ### ⚡ High(今週中) 4. **string関数4種** - upper, lower, split, join 5. **基本テスト** - using nyashstd動作確認 6. **エラーハンドリング** - 適切なエラーメッセージ ### 📝 Medium(来週) 7. **math関数5種** - sin, cos, sqrt, floor, random 8. **array関数4種** - length, get, push, slice 9. **io関数3種** - print, println, debug --- **⚡ この高性能アーキテクチャで、複雑なファイル依存関係なしに即座に実用的なnamespace/usingが実現できるにゃ!🚀**