feat(plugin): Fix plugin BoxRef return and Box argument support

- Fixed deadlock in FileBox plugin copyFrom implementation (single lock)
- Added TLV Handle (tag=8) parsing in calls.rs for returned BoxRefs
- Improved plugin loader with config path consistency and detailed logging
- Fixed loader routing for proper Handle type_id/fini_method_id resolution
- Added detailed logging for TLV encoding/decoding in plugin_loader_v2

Test docs/examples/plugin_boxref_return.nyash now works correctly:
- cloneSelf() returns FileBox Handle properly
- copyFrom(Box) accepts plugin Box arguments
- Both FileBox instances close and fini correctly

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-21 00:41:26 +09:00
parent af32896574
commit cc2a820af7
274 changed files with 7244 additions and 4608 deletions

View File

@ -0,0 +1,241 @@
# 🌟 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<TypeParam>,
pub fields: Vec<FieldDecl>,
pub methods: Vec<MethodDecl>,
pub static_methods: Vec<StaticDecl>,
pub attrs: AttrSet,
pub source_span: Option<Span>,
}
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<NyashRuntime>,
root_box: SharedBox,
frames: Vec<Frame>,
env: Environment,
}
// SharedBox = Arc<dyn NyashBox>
pub type SharedBox = Arc<dyn NyashBox>;
```
### 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<SharedBox>;
fn lookup_method(&self, name: &str) -> Option<MethodHandle>;
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<Arc<dyn BoxClass>>;
}
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<HashMap<String, Arc<dyn BoxClass>>>,
factories: RwLock<Vec<Arc<dyn BoxFactory>>>,
}
impl BoxRegistry {
pub fn register_class(&self, class: Arc<dyn BoxClass>) {
// 登録処理
}
pub fn get_class(&self, name: &str) -> Option<Arc<dyn BoxClass>> {
// クラス取得
}
pub fn create_instance(
&self,
class_name: &str,
args: &[SharedBox],
sess: &mut ExecutionSession
) -> Result<SharedBox> {
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<dyn BoxFactory> として扱う
```
### Step 4: グローバル登録の排除
```rust
// 削除: register_user_defined_factory(...)
// 追加: NyashRuntimeBuilder::with_factory(...)
```
### Step 5: SharedStateの段階的分解
```rust
// 一時的なシム
pub struct SharedStateShim {
runtime: Arc<NyashRuntime>,
session: ExecutionSession,
}
// 互換性のためのFrom実装
impl From<SharedState> 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<dyn Trait>`**
- `Arc<Trait>`は使わない
- dynキーワードを忘れない
2. **段階的移行**
- 各ステップでテストが通ることを確認
- 互換性レイヤーを活用
3. **ロックの最小化**
- Runtimeは基本的に不変
- 必要最小限のRwLock使用
---
この設計により、Nyashはよりシンプルでエレガントなアーキテクチャとなり、InterpreterとVMの統合が自然に実現されます。

View File

@ -0,0 +1,123 @@
# Instance v2 統一レジストリ設計メモ(提案)
目的: ユーザー定義 / ビルトイン / プラグインの3系統を instance_v2 で一元管理し、同一の生成birth/破棄finiライフサイクルで扱えるようにする。また、wasm-bindgen ターゲットでプラグイン機構を安全に無効化できる切替を用意する。
---
## 現状の整理(実装済み)
- ユーザー定義Box
- インタプリタの AST → InstanceBox 生成で対応済み。
- `execute_new` は最初に統一レジストリを呼び、ユーザー定義については最終的に `InstanceBox` を構築し、birth 相当のコンストラクタ実行を行う。
- ビルトインBox
- 統一レジストリ経由で生成可能。ユーザー定義と同じ呼び出し経路に乗る。
- プラグインBoxv2
- `nyash.toml v2``PluginLoaderV2` が読み込み、`nyash_plugin_invoke` の birth 呼び出しでインスタンスを生成。
- 現状、`PluginBoxV2``clone_box=新birth``share_box=同一 instance_id` を実装済み。
---
## 目標
1. 3系統ユーザー定義/ビルトイン/プラグインを「統一レジストリ→instance_v2」で一元管理。
2. birth/fini ライフサイクルの整合をとる。
3. wasm-bindgen ターゲット(`wasm32-unknown-unknown`)ではプラグイン機構をコンパイル時に無効化し、ビルド可能にする。
---
## 設計方針
### 1) 統一レジストリの責務
- 名前(クラス名)と引数(`Box<dyn NyashBox>` の配列)を入力に、ユーザー定義/ビルトイン/プラグインの順で解決・生成を試みる。
- 生成に成功したら `Box<dyn NyashBox>` を返す。
- ユーザー定義: `InstanceBox` とし、インタプリタがコンストラクタbirthを実行。
- ビルトイン: 直接生成必要なら簡易birth相当の初期化
- プラグイン: `PluginLoaderV2``invoke_fn(type_id, method_id=0=birth, ...)` を呼ぶ。
### 2) birth / fini ライフサイクル
- birth:
- ユーザー定義: 既存通り AST 上のコンストラクタbirthを呼ぶ。
- プラグイン: `nyash.toml``methods.birth` の method_id=0 を使い、`invoke_fn` 呼び出しで instance_id を取得済み。
- fini:
- InstanceBox のフィールド差し替え時、旧値が InstanceBox なら `fini()` を呼んで finalize 済みIDとしてマーキング実装済み
- プラグインBoxについても `nyash.toml``methods.fini`(例: 0xFFFFを定義し、差し替えやスコープ終端で `invoke_fn(type_id, method_id=fini, instance_id, ...)` を呼ぶ。エラーは握りつぶさずログ化。
### 3) wasm-bindgen ターゲットでの切り替え
- Cargo features によるコンパイル時ガードを導入:
- `plugins`デフォルトON`wasm-backend`WASMビルド用の2フラグを用意。
- `#[cfg(all(feature = "plugins", not(target_arch = "wasm32")))]` のときのみ `plugin_loader_v2` 実体を有効化。
- それ以外では `plugin_loader_v2` のスタブ実装を使う(常に `Err(BidError::PluginError)` を返すなど)。
- 統一レジストリはプラグインFactoryの登録を `#[cfg(feature="plugins")]` でガードし、WASMビルドでもユーザー定義/ビルトインは動かせる。
- `nyash.toml` のファイルI/O`from_file`)も `cfg` で握り、WASMではロードしない。
---
## nyash.toml v2 との整合
- 既存:
- `libraries.<libname>.boxes = ["FileBox"]`
- `libraries.<libname>.<BoxType>.methods.birth = { method_id = 0 }`
- `... .fini = { method_id = 4294967295 }` など
- 追加検討:
- 将来、ユーザー定義Boxをプラグインで置換したい場合
- クラス名→プラグインBox型の上書きマップを `nyash.toml` に追加(例:`overrides = { "DataBox" = "libX::RemoteDataBox" }`)。
- 統一レジストリがこのマップを見て、ユーザー定義をスキップしてプラグインへ委譲。
---
## API/コード上の具体案(抜粋)
- features`Cargo.toml`:
```toml
[features]
default = ["plugins"]
plugins = []
wasm-backend = []
```
- プラグインローダ(`src/runtime/plugin_loader_v2.rs`:
```rust
#[cfg(all(feature = "plugins", not(target_arch = "wasm32")))]
pub mod real_loader { /* 現在の実装 */ }
#[cfg(any(not(feature = "plugins"), target_arch = "wasm32"))]
pub mod stub_loader {
use crate::bid::{BidResult, BidError};
use crate::box_trait::NyashBox;
pub struct PluginLoaderV2; // ダミー
impl PluginLoaderV2 { pub fn new() -> Self { Self } }
impl PluginLoaderV2 {
pub fn load_config(&mut self, _p: &str) -> BidResult<()> { Ok(()) }
pub fn load_all_plugins(&self) -> BidResult<()> { Ok(()) }
pub fn create_box(&self, _t: &str, _a: &[Box<dyn NyashBox>]) -> BidResult<Box<dyn NyashBox>> {
Err(BidError::PluginError)
}
}
}
```
- 統一レジストリのFactory登録部は `#[cfg(feature = "plugins")]` でプラグインFactoryの登録を条件化。
---
## マイグレーション手順(段階)
1. Cargo features と cfg ガードの導入(プラグイン機構のスタブ化を含む)。
2. 統一レジストリのプラグインFactory登録の条件化。
3. プラグインBoxの `fini` 呼び出し用メソッドを InstanceBox 置換/破棄パスへ組み込む。
4. 必要に応じて `nyash.toml` の `methods.fini` を明記。
5. 追加要件(ユーザー定義のプラグイン置換)を `overrides` マップで設計 → 実装。
---
## テスト観点
- ユニット:
- birth/fini の呼び出し順と複数回置換時の `fini` 呼び出し保証。
- `plugins` ON/OFF、`wasm-backend` ON の3軸でビルド/テストが通ること。
- 統合テスト:
- `nyash.toml` によるビルトイン→プラグインの透過切替。
- ユーザー定義→ビルトイン→プラグインの優先順位が想定通り。
---
## メモ
- すでに `execute_new` は統一レジストリ優先の実装になっており、この設計と整合が良い。
- WASM ターゲットでは `libloading` が使えないため、コンパイル時に完全にプラグインコードを外す方針cfg/featureは自然。
- `nyash.toml` のロードはネイティブ時のみで十分WASM は将来、バンドルまたは JS 側から供給する計画があるなら別途)。
---
以上。必要であれば、この方針でPRを小さく分割features→レジストリ→fini→overridesして入れていきます。

View File

@ -0,0 +1,80 @@
# Issue 62 Update Proposal: Enable String Constants in WASM Backend First
This is a concrete request to implement minimal string support in the WASM backend so that Issue #62 can proceed. It reflects the current repo state.
## Background
- As noted in Issue #61, the current WASM backend does not support string constants yet.
- Issue #62 depends on string support and cannot be completed without it.
- Current state:
- `src/backend/wasm/codegen.rs``generate_const` handles only Integer/Bool/Void; String is not implemented.
- `src/backend/wasm/memory.rs` already defines a basic layout for `StringBox`:
- Header: `[type_id:i32][ref_count:i32][field_count:i32]`
- Fields: `[data_ptr:i32][length:i32]`
- `StringBox` type_id = `0x1001`.
## Goal
Add minimal string constant support to the WASM backend:
- Allow `ConstValue::String` in codegen by embedding UTF-8 string bytes and constructing a `StringBox` with `[data_ptr,length]`.
- Provide a minimal debugging import `env.print_str(ptr,len)` to verify strings at runtime.
- Unblock Issue #62 implementation and tests that require strings.
## Scope
Minimal features required:
1) Data segments for string literals
- Extend `WasmModule` (in `codegen.rs`) with a `data_segments: Vec<String>` field.
- Update `to_wat()` to emit `(data ...)` after memory/globals and before functions/exports.
- For each string constant, create a unique offset and emit a `(data (i32.const <offset>) "...bytes...")` entry.
2) Codegen for `ConstValue::String`
- In `generate_const`, when encountering `ConstValue::String(s)`,
- Allocate a data segment for `s` (UTF-8 bytes) and get its offset and length.
- Allocate a `StringBox` using existing helpers (see `MemoryManager`),
then set its fields: `data_ptr` and `length`.
- Return the `StringBox` pointer (i32) in the destination local.
3) Helper for `StringBox` allocation
- Either:
- Provide a dedicated WAT helper function `$alloc_stringbox` that calls `$malloc`, writes header (`type_id=0x1001`, `ref_count=1`, `field_count=2`), and returns the box pointer, then inline store `data_ptr`/`length`.
- Or:
- Use `$box_alloc` with `(type_id=0x1001, field_count=2)` and then store `data_ptr`/`length` via generated `i32.store` sequences.
4) Runtime import for string output (for verification)
- Extend `RuntimeImports` (`src/backend/wasm/runtime.rs`) with:
- `(import "env" "print_str" (func $print_str (param i32 i32)))`
- In host (Node/Browser), implement `importObject.env.print_str = (ptr,len) => { decode UTF-8 from memory; console.log(...) }`.
5) E2E test
- Add a tiny program that produces/prints a string (e.g., Const String → call `env.print_str(ptr,len)` via a minimal MIR program) and verify it logs the correct text.
- Option: update `test_runner.js` to include `print_str` and decode from memory using `TextDecoder('utf-8')`.
## Out of Scope (for this change)
- String operations (concat/substr/compare), normalization, encoding conversions.
- GC/RC or freeing memory (current allocator is bump-only).
- Returning StringBox directly from `main` (keep verification via `print_str`).
## Acceptance Criteria
- Generated WAT includes `(data ...)` segments for string literals and correct offsets.
- `ConstValue::String` codegen constructs a valid `StringBox` with proper `[data_ptr,length]`.
- `env.print_str` correctly prints UTF-8 strings in both Browser and Node runners.
- Issue #62 tasks that rely on strings can proceed.
## References (repo paths)
- String unsupported path: `src/backend/wasm/codegen.rs` (`generate_const`)
- Memory/layout: `src/backend/wasm/memory.rs` (StringBox, type_id=0x1001)
- Runtime imports: `src/backend/wasm/runtime.rs` (currently only `env.print(i32)`)
- Node runner: `test_runner.js` (has `env.print`; extend with `print_str`)
## Notes
- Data segment approach is the simplest for initial support; future work may add constant pooling and deduplication.
- Keeping verification via `print_str(ptr,len)` avoids complicating function return types for now.
- UTF-8 decoding is available in hosts via `TextDecoder('utf-8')`.

View File

@ -0,0 +1,361 @@
# MIR 35→26命令削減: 詳細分析・移行戦略
*実装ベース完全マッピング - 2025年8月17日版*
## 🔍 **現在実装35命令 vs ChatGPT5仕様26命令の完全マッピング**
### **維持する命令 (既存実装 → 26命令仕様)**
| 現在実装 | 26命令仕様 | 効果 | 変更 |
|----------|------------|------|------|
| `Const` | `Const` | pure | ✅ 維持 |
| `BinOp` | `BinOp` | pure | ✅ 維持 |
| `Compare` | `Compare` | pure | ✅ 維持 |
| `Branch` | `Branch` | control | ✅ 維持 |
| `Jump` | `Jump` | control | ✅ 維持 |
| `Phi` | `Phi` | pure | ✅ 維持 |
| `Call` | `Call` | context | ✅ 維持 |
| `Return` | `Return` | control | ✅ 維持 |
| `NewBox` | `NewBox` | mut | ✅ 維持 |
| `BoxCall` | `BoxCall` | context | ✅ 維持 |
| `ExternCall` | `ExternCall` | context | ✅ 維持 |
| `Safepoint` | `Safepoint` | io | ✅ 維持 |
| `RefGet` | `RefGet` | pure | ✅ 維持 |
| `RefSet` | `RefSet` | mut | ✅ 維持 |
| `WeakNew` | `WeakNew` | pure | ✅ 維持 |
| `WeakLoad` | `WeakLoad` | pure | ✅ 維持 |
**小計**: 16命令維持
### **削除する命令 (17命令)**
#### **グループ1: BinOp統合 (1命令)**
| 削除命令 | 置換方法 | 実装例 |
|----------|----------|--------|
| `UnaryOp` | `BinOp`統合 | `not %a``%a xor true`<br>`neg %a``0 sub %a` |
#### **グループ2: BoxField操作統合 (4命令)**
| 削除命令 | 置換方法 | 実装例 |
|----------|----------|--------|
| `Load` | `BoxFieldLoad` | `load %ptr``%ptr.value` |
| `Store` | `BoxFieldStore` | `store %val -> %ptr``%ptr.value = %val` |
| `ArrayGet` | `BoxFieldLoad` | `%arr[%idx]``%arr.elements[%idx]` |
| `ArraySet` | `BoxFieldStore` | `%arr[%idx] = %val``%arr.elements[%idx] = %val` |
#### **グループ3: intrinsic化 (6命令)**
| 削除命令 | intrinsic名 | 実装例 |
|----------|-------------|--------|
| `Print` | `@print` | `print %val``call @print, %val` |
| `Debug` | `@debug` | `debug %val "msg"``call @debug, %val, "msg"` |
| `TypeCheck` | `@type_check` | `type_check %val "Type"``call @type_check, %val, "Type"` |
| `Cast` | `@cast` | `cast %val Type``call @cast, %val, Type` |
| `Throw` | `@throw` | `throw %exc``call @throw, %exc` |
| `Catch` | `@catch` | `catch Type -> %bb``call @catch, Type, %bb` |
#### **グループ4: 完全削除 (3命令)**
| 削除命令 | 削除理由 | 代替方法 |
|----------|----------|----------|
| `Copy` | 最適化パス専用 | 最適化段階でのみ使用 |
| `Nop` | 不要 | 削除(プレースホルダー不要) |
| `RefNew` | 冗長 | `RefGet`で代用可能 |
#### **グループ5: 統合・置換 (3命令)**
| 削除命令 | 統合先 | 実装例 |
|----------|--------|--------|
| `BarrierRead` | `AtomicFence` | `barrier_read %ptr``atomic_fence acquire` |
| `BarrierWrite` | `AtomicFence` | `barrier_write %ptr``atomic_fence release` |
| `FutureNew` | `NewBox + BoxCall` | `future_new %val``%f = new_box "Future"(%val)` |
| `FutureSet` | `BoxCall` | `future_set %f = %val``%f.set(%val)` |
| `Await` | `BoxCall` | `await %f``%f.await()` |
### **追加する命令 (10命令)**
| 新命令 | 効果 | 目的 | 実装必要度 |
|--------|------|------|------------|
| `BoxFieldLoad` | pure | Everything is Box核心 | 🔥 Critical |
| `BoxFieldStore` | mut | Everything is Box核心 | 🔥 Critical |
| `WeakCheck` | pure | weak参照完全対応 | ⚡ High |
| `Send` | io | Bus操作一次市民化 | ⚡ High |
| `Recv` | io | Bus操作一次市民化 | ⚡ High |
| `TailCall` | control | JIT最適化基盤 | 📝 Medium |
| `Adopt` | mut | 所有権移管明示 | 📝 Medium |
| `Release` | mut | 所有権移管明示 | 📝 Medium |
| `MemCopy` | mut | 最適化基盤 | 📝 Medium |
| `AtomicFence` | io | 並行制御統一 | 📝 Medium |
## 🛠️ **具体的実装戦略**
### **Phase 1: 新命令実装**
#### **BoxFieldLoad/BoxFieldStore実装**
```rust
// src/mir/instruction.rs
pub enum MirInstruction {
// 新規追加
BoxFieldLoad {
dst: ValueId,
box_val: ValueId,
field: String,
},
BoxFieldStore {
box_val: ValueId,
field: String,
value: ValueId,
},
// ...
}
```
#### **WeakCheck実装**
```rust
WeakCheck {
dst: ValueId,
weak_ref: ValueId,
}
```
#### **Send/Recv実装**
```rust
Send {
data: ValueId,
target: ValueId,
},
Recv {
dst: ValueId,
source: ValueId,
},
```
### **Phase 2: intrinsic関数システム実装**
#### **intrinsic レジストリ**
```rust
// src/interpreter/intrinsics.rs
pub struct IntrinsicRegistry {
functions: HashMap<String, IntrinsicFunction>,
}
impl IntrinsicRegistry {
pub fn new() -> Self {
let mut registry = Self { functions: HashMap::new() };
registry.register("@print", intrinsic_print);
registry.register("@debug", intrinsic_debug);
registry.register("@type_check", intrinsic_type_check);
registry.register("@cast", intrinsic_cast);
registry.register("@array_get", intrinsic_array_get);
registry.register("@array_set", intrinsic_array_set);
registry
}
}
```
#### **intrinsic関数実装例**
```rust
fn intrinsic_print(args: &[Value]) -> Result<Value, RuntimeError> {
println!("{}", args[0]);
Ok(Value::Void)
}
fn intrinsic_array_get(args: &[Value]) -> Result<Value, RuntimeError> {
let array = args[0].as_array_box()?;
let index = args[1].as_integer()?;
array.get_element(index as usize)
}
fn intrinsic_array_set(args: &[Value]) -> Result<Value, RuntimeError> {
let array = args[0].as_array_box_mut()?;
let index = args[1].as_integer()?;
let value = args[2].clone();
array.set_element(index as usize, value)
}
```
### **Phase 3: AST→MIR生成更新**
#### **Load/Store → BoxFieldLoad/BoxFieldStore変換**
```rust
// src/mir/builder.rs
impl MirBuilder {
fn visit_field_access(&mut self, node: &FieldAccessNode) -> Result<ValueId, BuildError> {
let box_val = self.visit_expression(&node.object)?;
let dst = self.new_temp_var();
// 旧: Load命令生成
// self.emit(MirInstruction::Load { dst, ptr: box_val });
// 新: BoxFieldLoad命令生成
self.emit(MirInstruction::BoxFieldLoad {
dst,
box_val,
field: node.field.clone(),
});
Ok(dst)
}
fn visit_field_assignment(&mut self, node: &FieldAssignmentNode) -> Result<(), BuildError> {
let box_val = self.visit_expression(&node.object)?;
let value = self.visit_expression(&node.value)?;
// 旧: Store命令生成
// self.emit(MirInstruction::Store { value, ptr: box_val });
// 新: BoxFieldStore命令生成
self.emit(MirInstruction::BoxFieldStore {
box_val,
field: node.field.clone(),
value,
});
Ok(())
}
}
```
#### **配列操作 → BoxField + intrinsic変換**
```rust
fn visit_array_access(&mut self, node: &ArrayAccessNode) -> Result<ValueId, BuildError> {
let array = self.visit_expression(&node.array)?;
let index = self.visit_expression(&node.index)?;
let dst = self.new_temp_var();
// intrinsic化
self.emit(MirInstruction::Call {
dst: Some(dst),
func: self.get_intrinsic_id("@array_get"),
args: vec![array, index],
effects: EffectMask::PURE,
});
Ok(dst)
}
```
### **Phase 4: バックエンド対応**
#### **Interpreter実装**
```rust
// src/backend/interpreter.rs
impl Interpreter {
fn execute_box_field_load(&mut self, dst: ValueId, box_val: ValueId, field: &str) -> Result<(), RuntimeError> {
let box_obj = self.get_value(box_val)?;
let field_value = box_obj.get_field(field)?;
self.set_value(dst, field_value);
Ok(())
}
fn execute_box_field_store(&mut self, box_val: ValueId, field: &str, value: ValueId) -> Result<(), RuntimeError> {
let mut box_obj = self.get_value_mut(box_val)?;
let field_value = self.get_value(value)?;
box_obj.set_field(field, field_value)?;
Ok(())
}
}
```
#### **VM実装**
```rust
// src/backend/vm.rs
impl VM {
fn exec_box_field_load(&mut self, dst: RegId, box_val: RegId, field_id: FieldId) -> VMResult<()> {
let box_ptr = self.registers[box_val as usize];
let field_value = unsafe {
self.load_field(box_ptr, field_id)
};
self.registers[dst as usize] = field_value;
Ok(())
}
}
```
#### **WASM実装**
```rust
// src/backend/wasm/codegen.rs
impl WasmCodegen {
fn generate_box_field_load(&mut self, dst: ValueId, box_val: ValueId, field: &str) -> Result<(), CodegenError> {
let box_addr = self.get_value_address(box_val)?;
let field_offset = self.get_field_offset(field)?;
// WASM: i32.load offset=field_offset
self.emit_wasm(&format!("i32.load offset={}", field_offset));
self.set_value_register(dst);
Ok(())
}
}
```
## 📊 **移行スケジュール詳細**
### **Week 1: 基盤実装 (8/18-8/24)**
- [ ] 新命令構造体定義
- [ ] intrinsicレジストリ実装
- [ ] パーサー拡張(新旧両対応)
### **Week 2: フロントエンド移行 (8/25-8/31)**
- [ ] AST→MIR変換更新
- [ ] 配列操作intrinsic化
- [ ] Load/Store→BoxField変換
### **Week 3: 最適化パス移行 (9/1-9/7)**
- [ ] Effect分類実装
- [ ] 所有権森検証
- [ ] BoxFieldLoad/Store最適化
### **Week 4: バックエンド移行 (9/8-9/14)**
- [ ] Interpreter新命令実装
- [ ] VM新命令実装
- [ ] WASM新命令実装
### **Week 5: クリーンアップ (9/15-9/21)**
- [ ] 旧命令完全削除
- [ ] テスト更新
- [ ] ドキュメント整備
## 🧪 **テスト・検証計画**
### **段階的テスト**
```bash
# Week 1終了時
./scripts/test_mir_parsing_26.sh
# Week 2終了時
./scripts/test_frontend_migration.sh
# Week 3終了時
./scripts/test_optimization_passes.sh
# Week 4終了時
./scripts/test_all_backends.sh
# Week 5終了時
./scripts/test_golden_mir_final.sh
```
### **性能回帰テスト**
```bash
# 削減前後性能比較
./scripts/benchmark_mir_reduction.sh
```
## 🎯 **リスク対策**
### **高リスク箇所**
1. **配列操作intrinsic化**: パフォーマンス影響大
2. **BoxField統合**: Box型システムとの整合性
3. **Effect分類変更**: 最適化ロジック全面見直し
### **対策**
- **プロトタイプ実装**: 高リスク箇所の事前検証
- **性能測定**: 各段階での性能チェック
- **ロールバック**: 問題発生時の迅速復旧
---
**分析完了**: 2025年8月17日
**実装開始**: 2025年8月18日
**完了予定**: 2025年9月21日

View File

@ -0,0 +1,267 @@
# nyash.linkシステム設計 - モジュール・依存関係管理革命
## 🎯 設計背景
### 📊 現状調査結果
- **include使用状況**: 主にexamples/text_adventureで10件程度、実用性は限定的
- **usingキーワード**: **未実装**(トークナイザーにも存在しない)
- **namespace設計**: Phase 9.75eで仕様完成、実装待ち
### 🌟 Gemini先生の推奨
> 「技術的に非常に妥当であり、現代的なプログラミング言語の設計として強く推奨される」
**結論**: includeほぼ未使用 + using未実装 = 完全に新設計で進められる!🎉
## 🚀 設計方針
### 💡 基本コンセプト
```
依存関係管理nyash.link + モジュールインポートusing = 完璧な統合
```
### 🎯 他言語成功モデル
- **Rust**: `Cargo.toml + mod/use` - 厳格で分かりやすい
- **Node.js**: `package.json + import/export` - エコシステム成功
- **Python**: `pyproject.toml + import` - 依存関係分離
## 📋 nyash.linkファイル仕様
### 基本フォーマット
```toml
# nyash.link (プロジェクトルート)
[project]
name = "my-nyash-project"
version = "0.1.0"
description = "素晴らしいNyashプロジェクト"
[dependencies]
# 標準ライブラリ
nyashstd = { path = "./stdlib/nyashstd.nyash" }
# ユーザーライブラリ
mylib = { path = "./libs/mylib.nyash" }
utils = { path = "./src/utils.nyash" }
# 将来の外部パッケージ(例)
# http_client = { version = "1.0.0", registry = "nyash-pkg" }
[search_paths]
stdlib = "./stdlib/"
libs = "./libs/"
src = "./src/"
[build]
entry_point = "./src/main.nyash"
```
### 依存関係タイプ
#### 1. **ローカル依存**
```toml
[dependencies]
my_module = { path = "./src/my_module.nyash" }
```
#### 2. **標準ライブラリ**
```toml
[dependencies]
nyashstd = { stdlib = true } # 特別扱い
```
#### 3. **将来の外部パッケージ**
```toml
[dependencies]
awesome_lib = { version = "^1.2.0", registry = "nyash-pkg" }
```
## 🔧 usingシステム設計
### 1. トークナイザー拡張
```rust
// src/tokenizer.rs に追加
pub enum TokenType {
// 既存...
USING, // using (モジュールインポート)
NAMESPACE, // namespace (名前空間宣言)
}
```
### 2. パーサー拡張
```rust
// AST拡張
pub enum Statement {
// 既存...
UsingStatement {
module_path: Vec<String>, // ["nyashstd", "string"]
alias: Option<String>, // using nyashstd.string as str
},
NamespaceDeclaration {
name: String,
body: Vec<Statement>,
},
}
```
### 3. 基本構文
```nyash
// ===== using構文パターン =====
// パターンA: 名前空間全体
using nyashstd
string.upper("hello") // nyashstd.string.upper
math.sin(3.14) // nyashstd.math.sin
// パターンB: 特定機能(将来拡張)
using nyashstd.string
upper("hello") // string.upperを直接
// パターンC: エイリアス(将来拡張)
using nyashstd.string as str
str.upper("hello")
// パターンD: 完全修飾名(常時利用可能)
nyashstd.string.upper("hello") // using不要
```
## 📁 推奨ディレクトリ構造
### 基本プロジェクト構造
```
my-nyash-project/
├── nyash.link # 依存関係定義
├── src/
│ ├── main.nyash # エントリーポイント
│ ├── utils.nyash # ユーティリティモジュール
│ └── models/
│ └── user.nyash # モデル定義
├── libs/ # プロジェクト固有ライブラリ
│ └── mylib.nyash
├── stdlib/ # 標準ライブラリ(システム配布)
│ └── nyashstd.nyash
└── tests/ # テストファイル
└── test_main.nyash
```
### 標準ライブラリ構造
```
stdlib/
├── nyashstd.nyash # メインエントリー
├── string/
│ └── mod.nyash # string関連機能
├── math/
│ └── mod.nyash # 数学関数
├── http/
│ └── mod.nyash # HTTP関連
└── io/
└── mod.nyash # I/O関連
```
## 🔄 動作フロー
### 1. プロジェクト初期化
```bash
# 将来のCLI例
nyash init my-project # nyash.linkテンプレート生成
cd my-project
```
### 2. 実行時解決
```
main.nyash実行
nyash.link読み込み
using nyashstd解析
./stdlib/nyashstd.nyash読み込み
namespace nyashstd解析・登録
string.upper()利用可能
```
### 3. 名前解決アルゴリズム
```
string.upper() 呼び出し
1. ローカルスコープ検索
2. usingでインポートされた名前空間検索
3. 完全修飾名として解釈
4. エラー(未定義)
```
## 🧪 実装段階
### Phase 1: 最小実装
```nyash
// ✅ 実装目標
using mylib // 単純パス解決
mylib.hello() // 関数呼び出し
// nyash.link
[dependencies]
mylib = { path = "./mylib.nyash" }
```
### Phase 2: 名前空間サポート
```nyash
// ✅ 実装目標
using nyashstd
string.upper("hello")
// nyashstd.nyash
namespace nyashstd {
static box string {
static upper(str) { ... }
}
}
```
### Phase 3: 高度機能
- エイリアス(`using ... as ...`
- 選択インポート(`using nyashstd.string`
- 循環依存検出
- パッケージレジストリ連携
## ⚡ 実装優先順位
### 🚨 Critical即時
1. **UsingTokenizer実装** - Token::USINGを追加
2. **基本パーサー** - using文AST構築
3. **nyash.link解析** - TOML読み込み機能
### ⚡ High今週
4. **名前解決エンジン** - モジュール→ファイル解決
5. **基本テスト** - using mylib動作確認
6. **エラー処理** - 未定義モジュール等
### 📝 Medium来週
7. **namespace構文** - static box解析
8. **標準ライブラリ設計** - nyashstd.nyash作成
9. **完全修飾名** - nyashstd.string.upper()
### 🔮 Future今後
10. **IDE連携** - Language Server補完
11. **パッケージマネージャー** - 外部レジストリ
12. **循環依存検出** - 高度エラー処理
## 🎉 期待効果
### 📈 開発体験向上
- **IDE補完**: `ny`→全標準機能表示
- **探索可能性**: モジュール構造が明確
- **エラー削減**: 名前衝突・未定義の事前検出
### 🏗️ プロジェクト管理
- **依存関係明確化**: nyash.linkで一元管理
- **ビルド再現性**: 他環境での確実な動作
- **スケーラビリティ**: 大規模プロジェクト対応
### 🌍 エコシステム発展
- **ライブラリ共有**: 標準化されたモジュール形式
- **コミュニティ成長**: パッケージレジストリ基盤
- **言語成熟度**: モダンな言語仕様
---
**🐾 この設計でNyashが真にモダンなプログラミング言語になるにゃ**

View File

@ -0,0 +1,654 @@
# BID×usingシステム統合技術実装詳細
## 🎯 統合設計の核心
### 📊 既存システムとの整合性
-**MIR ExternCall**: 既にFFI-ABI対応実装済み
-**WASM RuntimeImports**: BID→WASM自動生成基盤あり
-**VM ExternStub**: スタブ実行環境実装済み
- 🔧 **統合課題**: usingシステムとBIDの橋渡し実装
### 🚀 統合アーキテクチャ概要
```
User Code (using statements)
UniversalNamespaceRegistry
CallTarget Resolution
↓ ↓ ↓
Builtin FFI-ABI NyashModule
↓ ↓ ↓
MIR Generation (BuiltinCall/ExternCall/ModuleCall)
Backend Execution (VM/WASM/AOT)
```
## 🏗️ 詳細技術実装
### 1. BID定義システム
#### **BIDファイル構造拡張**
```yaml
# apis/enhanced_canvas.yaml
version: 1
metadata:
name: "Enhanced Canvas API"
description: "Extended Canvas API with batch operations"
target_environments: ["browser", "node-canvas", "skia"]
nyash_namespace: "canvas_api" # usingで使用する名前空間
interfaces:
- name: canvas_api.canvas
box: Canvas
methods:
# 基本描画
- name: fillRect
params:
- {string: canvas_id, description: "Canvas element ID"}
- {i32: x, description: "X coordinate"}
- {i32: y, description: "Y coordinate"}
- {i32: width, description: "Rectangle width"}
- {i32: height, description: "Rectangle height"}
- {string: color, description: "Fill color (CSS format)"}
returns: void
effect: io
optimization_hints:
batch_compatible: true # バッチ処理可能
gpu_accelerated: true # GPU加速対応
# バッチ描画(最適化版)
- name: fillRectBatch
params:
- {string: canvas_id}
- {array_of_rect: rects, element_type: "CanvasRect"}
returns: void
effect: io
optimization_hints:
prefer_over: ["fillRect"] # 複数fillRectの代替
min_batch_size: 3
# テキスト描画
- name: fillText
params:
- {string: canvas_id}
- {string: text}
- {i32: x}
- {i32: y}
- {string: font}
- {string: color}
returns: void
effect: io
# カスタム型定義
custom_types:
- name: CanvasRect
fields:
- {i32: x}
- {i32: y}
- {i32: width}
- {i32: height}
- {string: color}
```
#### **BID読み込み・検証システム**
```rust
// 新ファイル: src/bid/mod.rs
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BidDefinition {
pub version: u32,
pub metadata: BidMetadata,
pub interfaces: Vec<BidInterface>,
pub custom_types: Option<Vec<BidCustomType>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BidMetadata {
pub name: String,
pub description: String,
pub target_environments: Vec<String>,
pub nyash_namespace: String, // using文で使用する名前空間名
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BidInterface {
pub name: String, // "canvas_api.canvas"
pub box_name: String, // "Canvas"
pub methods: Vec<BidMethod>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BidMethod {
pub name: String,
pub params: Vec<BidParam>,
pub returns: BidType,
pub effect: BidEffect,
pub optimization_hints: Option<BidOptimizationHints>,
pub description: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BidOptimizationHints {
pub batch_compatible: Option<bool>,
pub gpu_accelerated: Option<bool>,
pub prefer_over: Option<Vec<String>>,
pub min_batch_size: Option<usize>,
}
impl BidDefinition {
pub fn load_from_file(path: &Path) -> Result<Self, BidError> {
let content = std::fs::read_to_string(path)?;
let bid: BidDefinition = serde_yaml::from_str(&content)?;
// バリデーション
bid.validate()?;
Ok(bid)
}
pub fn validate(&self) -> Result<(), BidError> {
// バージョン確認
if self.version > 1 {
return Err(BidError::UnsupportedVersion(self.version));
}
// 名前空間重複チェック
let mut interface_names = HashSet::new();
for interface in &self.interfaces {
if interface_names.contains(&interface.name) {
return Err(BidError::DuplicateInterface(interface.name.clone()));
}
interface_names.insert(interface.name.clone());
}
// パラメータ型確認
for interface in &self.interfaces {
for method in &interface.methods {
for param in &method.params {
self.validate_type(&param.param_type)?;
}
self.validate_type(&method.returns)?;
}
}
Ok(())
}
pub fn resolve_method(&self, box_name: &str, method_name: &str)
-> Option<&BidMethod> {
for interface in &self.interfaces {
// インターフェース名から最後の部分を取得
// "canvas_api.canvas" → "canvas"
let interface_box_name = interface.name.split('.').last().unwrap_or(&interface.name);
if interface_box_name == box_name {
for method in &interface.methods {
if method.name == method_name {
return Some(method);
}
}
}
}
None
}
}
```
### 2. 統合名前空間レジストリ詳細
#### **UniversalNamespaceRegistry実装**
```rust
// src/registry/universal.rs
use crate::stdlib::BuiltinStdlib;
use crate::bid::BidDefinition;
use crate::module::ExternalModule;
use crate::mir::Effect;
pub struct UniversalNamespaceRegistry {
/// 組み込み標準ライブラリ
builtin_stdlib: Arc<BuiltinStdlib>,
/// FFI-ABI定義BID
bid_definitions: HashMap<String, Arc<BidDefinition>>,
/// Nyashモジュール従来
nyash_modules: HashMap<String, Arc<ExternalModule>>,
/// ファイル別usingコンテキスト
using_contexts: Arc<RwLock<HashMap<String, UsingContext>>>,
/// 最適化情報キャッシュ
optimization_cache: Arc<RwLock<OptimizationCache>>,
}
#[derive(Debug, Clone)]
pub struct UsingContext {
pub file_id: String,
pub builtin_namespaces: Vec<String>, // ["nyashstd"]
pub bid_namespaces: Vec<String>, // ["canvas_api", "console_api"]
pub module_namespaces: Vec<String>, // ["mylib", "utils"]
}
impl UniversalNamespaceRegistry {
pub fn new() -> Self {
UniversalNamespaceRegistry {
builtin_stdlib: Arc::new(BuiltinStdlib::new()),
bid_definitions: HashMap::new(),
nyash_modules: HashMap::new(),
using_contexts: Arc::new(RwLock::new(HashMap::new())),
optimization_cache: Arc::new(RwLock::new(OptimizationCache::new())),
}
}
pub fn load_from_nyash_link(&mut self, nyash_link: &NyashLink)
-> Result<(), RegistryError> {
// BID依存関係読み込み
for (namespace_name, dependency) in &nyash_link.dependencies {
match dependency {
Dependency::Bid { bid_path, .. } => {
let bid = BidDefinition::load_from_file(Path::new(bid_path))?;
self.bid_definitions.insert(namespace_name.clone(), Arc::new(bid));
},
Dependency::Path { path } => {
let module = ExternalModule::load_from_file(Path::new(path))?;
self.nyash_modules.insert(namespace_name.clone(), Arc::new(module));
},
Dependency::Builtin { .. } => {
// 組み込みライブラリは既に初期化済み
},
}
}
Ok(())
}
/// 統合using処理
pub fn process_using(&mut self, namespace_name: &str, file_id: &str)
-> Result<(), RuntimeError> {
let mut contexts = self.using_contexts.write().unwrap();
let context = contexts.entry(file_id.to_string()).or_insert_with(|| {
UsingContext {
file_id: file_id.to_string(),
builtin_namespaces: Vec::new(),
bid_namespaces: Vec::new(),
module_namespaces: Vec::new(),
}
});
// 組み込み標準ライブラリチェック
if self.builtin_stdlib.has_namespace(namespace_name) {
if !context.builtin_namespaces.contains(&namespace_name.to_string()) {
context.builtin_namespaces.push(namespace_name.to_string());
}
return Ok(());
}
// BID定義チェック
if let Some(bid) = self.bid_definitions.get(namespace_name) {
if !context.bid_namespaces.contains(&namespace_name.to_string()) {
context.bid_namespaces.push(namespace_name.to_string());
}
return Ok(());
}
// Nyashモジュールチェック
if let Some(_module) = self.nyash_modules.get(namespace_name) {
if !context.module_namespaces.contains(&namespace_name.to_string()) {
context.module_namespaces.push(namespace_name.to_string());
}
return Ok(());
}
Err(RuntimeError::UndefinedNamespace(namespace_name.to_string()))
}
/// 統合関数解決
pub fn resolve_call(&self, file_id: &str, call_path: &[String])
-> Result<ResolvedCall, RuntimeError> {
if call_path.len() != 2 {
return Err(RuntimeError::InvalidCallPath(call_path.join(".")));
}
let box_name = &call_path[0];
let method_name = &call_path[1];
let contexts = self.using_contexts.read().unwrap();
if let Some(context) = contexts.get(file_id) {
// 1. 組み込み標準ライブラリ解決
for namespace in &context.builtin_namespaces {
if let Some(method) = self.builtin_stdlib.resolve_method(namespace, box_name, method_name) {
return Ok(ResolvedCall::Builtin {
namespace: namespace.clone(),
box_name: box_name.clone(),
method_name: method_name.clone(),
method_info: method,
});
}
}
// 2. BID定義解決
for namespace in &context.bid_namespaces {
if let Some(bid) = self.bid_definitions.get(namespace) {
if let Some(method) = bid.resolve_method(box_name, method_name) {
return Ok(ResolvedCall::BidCall {
namespace: namespace.clone(),
interface_name: format!("{}.{}", namespace, box_name),
method_name: method_name.clone(),
method_info: method.clone(),
bid_definition: bid.clone(),
});
}
}
}
// 3. Nyashモジュール解決
for namespace in &context.module_namespaces {
if let Some(module) = self.nyash_modules.get(namespace) {
if let Some(function) = module.resolve_function(box_name, method_name) {
return Ok(ResolvedCall::ModuleCall {
namespace: namespace.clone(),
module_name: namespace.clone(),
function_name: format!("{}.{}", box_name, method_name),
function_info: function,
});
}
}
}
}
Err(RuntimeError::UndefinedMethod(format!("{}.{}", box_name, method_name)))
}
}
#[derive(Debug, Clone)]
pub enum ResolvedCall {
Builtin {
namespace: String,
box_name: String,
method_name: String,
method_info: BuiltinMethodInfo,
},
BidCall {
namespace: String,
interface_name: String,
method_name: String,
method_info: BidMethod,
bid_definition: Arc<BidDefinition>,
},
ModuleCall {
namespace: String,
module_name: String,
function_name: String,
function_info: ModuleFunctionInfo,
},
}
```
### 3. MIR生成統合
#### **統合MIR Builder**
```rust
// src/mir/builder.rs拡張
impl MirBuilder {
pub fn build_unified_method_call(&mut self, resolved_call: ResolvedCall, args: Vec<ValueId>)
-> Result<Option<ValueId>, MirError> {
match resolved_call {
ResolvedCall::Builtin { method_info, .. } => {
let result = self.new_value_id();
self.emit(MirInstruction::BuiltinCall {
qualified_name: method_info.qualified_name(),
args,
result,
effect: method_info.effect(),
});
Ok(Some(result))
},
ResolvedCall::BidCall { interface_name, method_name, method_info, .. } => {
let result = if method_info.returns == BidType::Void {
None
} else {
Some(self.new_value_id())
};
self.emit(MirInstruction::ExternCall {
interface: interface_name,
method: method_name,
args,
result,
effect: self.bid_effect_to_mir_effect(&method_info.effect),
bid_signature: BidSignature::from_method(&method_info),
});
Ok(result)
},
ResolvedCall::ModuleCall { module_name, function_name, function_info, .. } => {
let result = self.new_value_id();
self.emit(MirInstruction::ModuleCall {
module: module_name,
function: function_name,
args,
result,
effect: Effect::Io, // Nyashモジュールはデフォルトでio
});
Ok(Some(result))
},
}
}
fn bid_effect_to_mir_effect(&self, bid_effect: &BidEffect) -> Effect {
match bid_effect {
BidEffect::Pure => Effect::Pure,
BidEffect::Mut => Effect::Mut,
BidEffect::Io => Effect::Io,
BidEffect::Control => Effect::Control,
}
}
}
```
### 4. バックエンド統合
#### **WASM生成統合**
```rust
// src/backend/wasm/codegen.rs拡張
impl WasmCodegen {
pub fn generate_unified_call(&mut self, instruction: &MirInstruction)
-> Result<(), WasmError> {
match instruction {
MirInstruction::ExternCall { interface, method, args, bid_signature, .. } => {
// BIDから自動生成されたWASM import名
let wasm_import_name = self.bid_to_wasm_import_name(interface, method);
// 引数の型変換・マーシャリング
let marshalled_args = self.marshal_args_for_wasm(args, &bid_signature.params)?;
// WASM関数呼び出し生成
self.emit_call(&wasm_import_name, &marshalled_args)?;
// 戻り値のアンマーシャリング
if bid_signature.returns != BidType::Void {
self.unmarshal_return_value(&bid_signature.returns)?;
}
Ok(())
},
// 他の命令は既存実装
_ => self.generate_instruction_legacy(instruction),
}
}
fn bid_to_wasm_import_name(&self, interface: &str, method: &str) -> String {
// "canvas_api.canvas" + "fillRect" → "canvas_api_canvas_fillRect"
format!("{}_{}", interface.replace(".", "_"), method)
}
fn marshal_args_for_wasm(&mut self, args: &[ValueId], params: &[BidParam])
-> Result<Vec<WasmValue>, WasmError> {
let mut marshalled = Vec::new();
for (i, param) in params.iter().enumerate() {
let arg_value = self.get_value(args[i])?;
match &param.param_type {
BidType::String => {
// 文字列を (ptr, len) にマーシャル
let (ptr, len) = self.string_to_wasm_memory(&arg_value)?;
marshalled.push(WasmValue::I32(ptr));
marshalled.push(WasmValue::I32(len));
},
BidType::I32 => {
marshalled.push(WasmValue::I32(arg_value.to_i32()?));
},
BidType::F64 => {
marshalled.push(WasmValue::F64(arg_value.to_f64()?));
},
// その他の型...
}
}
Ok(marshalled)
}
}
```
#### **VM実行統合**
```rust
// src/backend/vm.rs拡張
impl VmBackend {
pub fn execute_unified_instruction(&mut self, instruction: &MirInstruction)
-> Result<(), VmError> {
match instruction {
MirInstruction::ExternCall { interface, method, args, bid_signature, .. } => {
// VM環境ではスタブまたはネイティブ呼び出し
let evaluated_args = self.evaluate_args(args)?;
if let Some(native_impl) = self.find_native_implementation(interface, method) {
// ネイティブ実装がある場合ファイルI/O
let result = native_impl.call(evaluated_args, bid_signature)?;
if let Some(result_id) = &instruction.result {
self.set_value(*result_id, result);
}
} else {
// スタブ実装(ログ出力等)
self.execute_stub_call(interface, method, evaluated_args, bid_signature)?;
}
Ok(())
},
// 他の命令は既存実装
_ => self.execute_instruction_legacy(instruction),
}
}
fn find_native_implementation(&self, interface: &str, method: &str)
-> Option<&dyn NativeImplementation> {
// VM環境で利用可能なネイティブ実装を検索
match (interface, method) {
("env.console", "log") => Some(&self.console_impl),
("env.filesystem", "read") => Some(&self.filesystem_impl),
("env.filesystem", "write") => Some(&self.filesystem_impl),
_ => None,
}
}
}
```
## 🧪 統合テスト戦略
### Phase別テスト実装
#### **Phase 0: 基本統合テスト**
```nyash
# test_basic_integration.nyash
using nyashstd
# 組み込み標準ライブラリのみ
assert(string.upper("test") == "TEST")
assert(math.sin(0) == 0)
```
#### **Phase 1: BID統合テスト**
```nyash
# test_bid_integration.nyash
using nyashstd
using console_api
# 組み込み + FFI-ABI
string.upper("hello") # 組み込み
console.log("Testing") # FFI-ABI
```
#### **Phase 2: 完全統合テスト**
```nyash
# test_full_integration.nyash
using nyashstd
using console_api
using mylib
# 3種類すべて
string.upper("test") # 組み込み
console.log("Integration") # FFI-ABI
mylib.process("data") # Nyashモジュール
```
### エラーハンドリングテスト
```nyash
# test_error_handling.nyash
try {
using nonexistent_api
} catch error {
assert(error.type == "UndefinedNamespace")
}
try {
console.nonexistent_method("test")
} catch error {
assert(error.type == "UndefinedMethod")
assert(error.message.contains("Available methods:"))
}
```
## 📊 実装マイルストーン
### ✅ Phase 0完了条件
- [ ] UniversalNamespaceRegistry基盤実装
- [ ] 組み込み標準ライブラリ統合
- [ ] 基本using文処理
- [ ] MIR BuiltinCall生成
### ✅ Phase 1完了条件
- [ ] BID定義読み込み・検証
- [ ] BID→MIR ExternCall統合
- [ ] WASM RuntimeImports自動生成
- [ ] VM スタブ実行
### ✅ Phase 2完了条件
- [ ] Nyashモジュール統合
- [ ] 統合エラーハンドリング
- [ ] 最適化キャッシュ
- [ ] 全バックエンド対応
---
**🎯 この詳細実装により、BIDとusingシステムの完全統合が実現でき、「なんでもAPI計画」の技術基盤が完成するにゃ🚀🐱**

View File

@ -0,0 +1,456 @@
# 組み込みnyashstd名前空間アーキテクチャ設計
## 🏗️ 技術的実装アーキテクチャ
### 📊 現在のインタープリター構造分析
#### **NyashInterpreter構造**
```rust
pub struct NyashInterpreter {
pub(super) shared: SharedState, // 共有状態
pub(super) local_vars: HashMap<String, SharedNyashBox>,
pub(super) outbox_vars: HashMap<String, SharedNyashBox>,
// その他の制御フロー状態...
}
```
#### **設計判断SharedStateに組み込み**
- **理由**: 標準ライブラリは不変・全インタープリターで共有可能
- **利点**: メモリ効率、パフォーマンス向上
- **実装**: SharedStateに`builtin_stdlib`フィールド追加
## 🌟 最適化されたアーキテクチャ設計
### 1. SharedState拡張
#### **src/interpreter/core.rs**
```rust
#[derive(Clone)]
pub struct SharedState {
// 既存フィールド...
pub global_vars: Arc<RwLock<HashMap<String, SharedNyashBox>>>,
pub functions: Arc<RwLock<HashMap<String, Function>>>,
pub box_definitions: Arc<RwLock<HashMap<String, Box<UserDefinedBoxDefinition>>>>,
pub loop_counter: Arc<AtomicU64>,
pub included_files: Arc<RwLock<HashSet<String>>>,
// 🌟 新規追加: 組み込み標準ライブラリ
pub builtin_stdlib: Arc<BuiltinStdlib>,
pub using_imports: Arc<RwLock<HashMap<String, UsingContext>>>, // ファイル別インポート管理
}
#[derive(Debug, Clone)]
pub struct UsingContext {
pub imported_namespaces: Vec<String>, // ["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<String, BuiltinFunction>,
/// IDE補完用階層構造
/// "nyashstd" -> { "string" -> ["upper", "lower", ...] }
pub hierarchical_map: HashMap<String, HashMap<String, Vec<String>>>,
}
/// 組み込み関数の実装
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<usize>, // None = 可変長
pub description: &'static str, // エラーメッセージ・ヘルプ用
}
/// 高性能関数実装
pub type BuiltinMethodImpl = fn(&[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, 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<String>> {
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<String> {
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<Box<dyn NyashBox>>)
-> Result<Box<dyn NyashBox>, 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<Box<dyn NyashBox>, 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.nyash
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.nyash
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が実現できるにゃ🚀**

View File

@ -0,0 +1,394 @@
# nyash.linkシステム使用例
## 🎯 基本的な使用例
### 📁 プロジェクト構造例
```
my-awesome-app/
├── nyash.link # 依存関係定義
├── src/
│ ├── main.nyash # メインファイル
│ ├── models/
│ │ └── user.nyash # ユーザーモデル
│ └── utils/
│ └── helpers.nyash # ヘルパー関数
├── libs/
│ └── custom_lib.nyash # カスタムライブラリ
└── stdlib/
└── nyashstd.nyash # 標準ライブラリ
```
### 📋 nyash.linkファイル例
```toml
[project]
name = "my-awesome-app"
version = "1.0.0"
description = "Everything is Box philosophy in action!"
[dependencies]
# 標準ライブラリ
nyashstd = { path = "./stdlib/nyashstd.nyash" }
# プロジェクト内モジュール
user_model = { path = "./src/models/user.nyash" }
helpers = { path = "./src/utils/helpers.nyash" }
# カスタムライブラリ
custom_lib = { path = "./libs/custom_lib.nyash" }
[search_paths]
stdlib = "./stdlib/"
src = "./src/"
libs = "./libs/"
[build]
entry_point = "./src/main.nyash"
```
## 🌟 実用的なコード例
### 1. 基本的なusing使用
```nyash
# ===== src/main.nyash =====
using nyashstd
using helpers
static box Main {
init { console }
main() {
me.console = new ConsoleBox()
# 標準ライブラリ使用
local text = "hello world"
local upper_text = string.upper(text) # nyashstd.string.upper
me.console.log("Upper: " + upper_text)
# ヘルパー関数使用
local processed = helpers.process_data("sample data")
me.console.log("Processed: " + processed)
# 数学関数
local result = math.sin(3.14159)
me.console.log("Sin: " + result.toString())
}
}
```
### 2. 標準ライブラリ定義例
```nyash
# ===== stdlib/nyashstd.nyash =====
namespace nyashstd {
static box string {
static upper(str) {
local string_box = new StringBox(str)
return string_box.upper()
}
static lower(str) {
local string_box = new StringBox(str)
return string_box.lower()
}
static split(str, separator) {
local string_box = new StringBox(str)
return string_box.split(separator)
}
static join(array, separator) {
local sep_box = new StringBox(separator)
return sep_box.join(array)
}
}
static box math {
static sin(x) {
local math_box = new MathBox()
return math_box.sin(x)
}
static cos(x) {
local math_box = new MathBox()
return math_box.cos(x)
}
static random() {
local random_box = new RandomBox()
return random_box.nextFloat()
}
static floor(x) {
local math_box = new MathBox()
return math_box.floor(x)
}
}
static box io {
static read_file(path) {
local file_box = new FileBox()
return file_box.read(path)
}
static write_file(path, content) {
local file_box = new FileBox()
return file_box.write(path, content)
}
}
}
```
### 3. ヘルパーモジュール例
```nyash
# ===== src/utils/helpers.nyash =====
using nyashstd
static function process_data(data) {
# データ処理のヘルパー
local trimmed = string.trim(data)
local upper = string.upper(trimmed)
return "PROCESSED: " + upper
}
static function calculate_score(points, multiplier) {
local result = points * multiplier
return math.floor(result)
}
static function format_user_name(first, last) {
return string.upper(first) + " " + string.upper(last)
}
```
### 4. モデル定義例
```nyash
# ===== src/models/user.nyash =====
using nyashstd
using helpers
box User {
init { name, email, score }
birth(user_name, user_email) {
me.name = user_name
me.email = user_email
me.score = 0
}
add_points(points) {
me.score = me.score + points
return me.score
}
get_formatted_name() {
local parts = string.split(me.name, " ")
if parts.length() >= 2 {
return helpers.format_user_name(parts.get(0), parts.get(1))
} else {
return string.upper(me.name)
}
}
save_to_file() {
local data = "User: " + me.name + ", Email: " + me.email + ", Score: " + me.score.toString()
local filename = "user_" + string.lower(me.name) + ".txt"
io.write_file(filename, data)
}
}
```
## 🎮 実用アプリケーション例
### 1. シンプルなWebサーバー
```nyash
# ===== web_server.nyash =====
using nyashstd
using custom_lib
static box WebServer {
init { server, port }
birth(server_port) {
me.port = server_port
me.server = new HttpServerBox()
}
start() {
me.server.bind("localhost", me.port)
me.server.on("request", me.handle_request)
local console = new ConsoleBox()
console.log("Server started on port " + me.port.toString())
me.server.listen()
}
handle_request(request, response) {
local url = request.getUrl()
if url == "/" {
local html = io.read_file("./public/index.html")
response.setStatus(200)
response.setHeader("Content-Type", "text/html")
response.send(html)
} else {
response.setStatus(404)
response.send("Not Found")
}
}
}
# メイン実行
local server = new WebServer(3000)
server.start()
```
### 2. データ処理パイプライン
```nyash
# ===== data_processor.nyash =====
using nyashstd
using helpers
static box DataProcessor {
init { input_file, output_file }
birth(input_path, output_path) {
me.input_file = input_path
me.output_file = output_path
}
process() {
# データ読み込み
local raw_data = io.read_file(me.input_file)
local lines = string.split(raw_data, "\n")
# 処理済みデータ配列
local processed_lines = new ArrayBox()
# 各行を処理
local i = 0
loop(i < lines.length()) {
local line = lines.get(i)
local processed = helpers.process_data(line)
processed_lines.push(processed)
i = i + 1
}
# 結果をファイルに保存
local result = string.join(processed_lines, "\n")
io.write_file(me.output_file, result)
return processed_lines.length()
}
}
# メイン処理
local processor = new DataProcessor("input.txt", "output.txt")
local count = processor.process()
local console = new ConsoleBox()
console.log("Processed " + count.toString() + " lines")
```
## 🔧 高度な使用パターン
### 1. 条件付きモジュール読み込み(将来拡張)
```nyash
# 開発環境では詳細ログ、本番環境ではシンプルログ
using nyashstd
static function get_logger() {
local env = os.get_env("NYASH_ENV")
if env == "development" {
using dev_logger
return new dev_logger.DetailLogger()
} else {
using prod_logger
return new prod_logger.SimpleLogger()
}
}
```
### 2. エイリアス使用例(将来拡張)
```nyash
# 長い名前空間のエイリアス
using very.long.namespace.name as short
local result = short.helper_function("data")
# 複数の類似ライブラリ
using json_v1 as json1
using json_v2 as json2
local data1 = json1.parse(input)
local data2 = json2.parse(input)
```
### 3. 部分インポート(将来拡張)
```nyash
# 名前空間全体ではなく特定機能のみ
using nyashstd.string
using nyashstd.math
# これで直接呼び出せる
local result = upper("hello") # string.upper不要
local sin_val = sin(3.14) # math.sin不要
```
## 📊 移行例既存includeからusingへ
### Before現在のinclude使用
```nyash
# ===== 既存のtext_adventure例 =====
include "text_adventure/items.nyash"
include "text_adventure/rooms.nyash"
# アイテム作成
local sword = new Weapon("Sword", 10)
```
### After新しいusing使用
```nyash
# ===== nyash.link =====
[dependencies]
game_items = { path = "./text_adventure/items.nyash" }
game_rooms = { path = "./text_adventure/rooms.nyash" }
# ===== main.nyash =====
using game_items
using game_rooms
# アイテム作成(名前空間経由)
local sword = game_items.create_weapon("Sword", 10)
```
## 🎉 期待される開発体験
### IDE補完の改善
```nyash
using nyashstd
# "st" と入力すると...
st → string (補完候補)
# "string." と入力すると...
string. → upper, lower, split, join, trim, ... (全メソッド表示)
```
### エラーメッセージの改善
```nyash
using nyashstd
# 間違った呼び出し
local result = string.uppper("hello") # typo
# エラー:
# Error: Method 'uppper' not found in nyashstd.string
# Did you mean: 'upper'?
# Available methods: upper, lower, split, join, trim
```
---
**🌟 これらの例でnyash.linkシステムの実用性と美しさが伝わるにゃ🐱**

View File

@ -0,0 +1,406 @@
# 最終実装戦略標準関数優先namespace/usingシステム
## 🎯 実装戦略まとめ
### 📋 設計完了項目
-**基本戦略**: nyash.link前の段階的実装
-**アーキテクチャ**: SharedState統合による高性能設計
-**標準関数**: 組み込みnyashstd名前空間
-**実装順序**: Critical → High → Medium
### 🚀 最終実装ロードマップ
## Phase 0: 組み込みnyashstd基盤1-2週間
### 🚨 Critical実装即時
#### **1. トークナイザー拡張**
```rust
// src/tokenizer.rs
pub enum TokenType {
// 既存...
USING, // using キーワード追加
}
// キーワード認識
fn tokenize_keyword(word: &str) -> TokenType {
match word {
// 既存...
"using" => TokenType::USING,
_ => TokenType::IDENTIFIER(word.to_string()),
}
}
```
#### **2. AST最小拡張**
```rust
// src/ast.rs
pub enum ASTNode {
// 既存...
UsingStatement {
namespace_name: String, // Phase 0: "nyashstd"のみ
span: Span,
},
}
```
#### **3. BuiltinStdlib基盤**
```rust
// 新ファイル: src/stdlib/mod.rs
pub mod builtin;
pub use builtin::*;
// 新ファイル: src/stdlib/builtin.rs
// 前回設計したBuiltinStdlib実装
```
#### **4. SharedState統合**
```rust
// src/interpreter/core.rs
#[derive(Clone)]
pub struct SharedState {
// 既存フィールド...
pub builtin_stdlib: Arc<BuiltinStdlib>,
pub using_imports: Arc<RwLock<HashMap<String, UsingContext>>>,
}
impl SharedState {
pub fn new() -> Self {
SharedState {
// 既存初期化...
builtin_stdlib: Arc::new(BuiltinStdlib::new()),
using_imports: Arc::new(RwLock::new(HashMap::new())),
}
}
}
```
### ⚡ High実装今週中
#### **5. using文パーサー**
```rust
// src/parser/statements.rs
impl NyashParser {
pub fn parse_statement(&mut self) -> Result<ASTNode, ParseError> {
match &self.current_token().token_type {
// 既存ケース...
TokenType::USING => self.parse_using(),
// 他の既存ケース...
}
}
fn parse_using(&mut self) -> Result<ASTNode, ParseError> {
let start_span = self.current_token().span.clone();
self.advance(); // consume 'using'
if let TokenType::IDENTIFIER(namespace_name) = &self.current_token().token_type {
let name = namespace_name.clone();
self.advance();
// Phase 0制限nyashstdのみ許可
if name != "nyashstd" {
return Err(ParseError::UnsupportedFeature(
format!("Only 'nyashstd' namespace is supported in Phase 0, got '{}'", name)
));
}
Ok(ASTNode::UsingStatement {
namespace_name: name,
span: start_span,
})
} else {
Err(ParseError::ExpectedIdentifier(
"Expected namespace name after 'using'".to_string()
))
}
}
}
```
#### **6. 基本string関数実装**
```rust
// src/stdlib/builtin.rs拡張
impl BuiltinStdlib {
fn register_string_functions(&mut self) {
// string.upper
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() takes exactly 1 argument".to_string()
));
}
let input = &args[0].to_string_box().value;
let result = StringBox::new(&input.to_uppercase());
Ok(Box::new(result))
},
arg_count: Some(1),
description: "Convert string to uppercase",
});
// string.lower
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() takes exactly 1 argument".to_string()
));
}
let input = &args[0].to_string_box().value;
let result = StringBox::new(&input.to_lowercase());
Ok(Box::new(result))
},
arg_count: Some(1),
description: "Convert string to lowercase",
});
// string.split
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() takes exactly 2 arguments".to_string()
));
}
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",
});
// string.join
self.register_function("string.join", BuiltinFunction {
namespace: "nyashstd",
box_name: "string",
method_name: "join",
implementation: |args| {
if args.len() != 2 {
return Err(RuntimeError::InvalidArguments(
"string.join() takes exactly 2 arguments".to_string()
));
}
let array_arg = &args[0];
let separator = &args[1].to_string_box().value;
let separator_box = StringBox::new(separator);
separator_box.join(array_arg.clone())
},
arg_count: Some(2),
description: "Join array elements with separator",
});
}
}
```
#### **7. インタープリター統合**
```rust
// src/interpreter/expressions.rs
impl NyashInterpreter {
pub fn execute_expression(&mut self, node: &ASTNode) -> Result<Box<dyn NyashBox>, RuntimeError> {
match node {
// using文処理
ASTNode::UsingStatement { namespace_name, .. } => {
self.execute_using(namespace_name)?;
Ok(Box::new(VoidBox::new()))
}
// メソッド呼び出し処理拡張
ASTNode::MethodCall { object, method, args, .. } => {
// 組み込み関数チェック
if let ASTNode::Variable { name: box_name, .. } = object.as_ref() {
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);
}
}
// 既存のメソッド呼び出し処理
// ...
}
// 既存の他のケース...
}
}
}
```
### 📝 Medium実装来週
#### **8. math関数実装**
```rust
// math.sin, cos, sqrt, floor, random
```
#### **9. array関数実装**
```rust
// array.length, get, push, slice
```
#### **10. io関数実装**
```rust
// io.print, println, debug
```
## Phase 1: 拡張機能2-3週間後
### 🌟 完全修飾名対応
```nyash
# using不要でも使える
nyashstd.string.upper("hello")
nyashstd.math.sin(3.14)
```
#### **実装**
```rust
// ASTNode::QualifiedCall追加
ASTNode::QualifiedCall {
path: Vec<String>, // ["nyashstd", "string", "upper"]
args: Vec<ASTNode>,
span: Span,
}
// パーサーで "identifier.identifier.identifier()" 構文解析
```
### 🔧 エラーハンドリング強化
```rust
// より詳細なエラーメッセージ
RuntimeError::UndefinedBuiltinMethod {
namespace: String,
box_name: String,
method_name: String,
available_methods: Vec<String>, // "Did you mean: ..."
span: Span,
}
```
### 📊 IDE補完サポート
```rust
// Language Server連携用API
impl BuiltinStdlib {
pub fn get_completion_candidates(&self, prefix: &str) -> Vec<CompletionItem> {
// "ny" -> ["nyashstd"]
// "nyashstd." -> ["string", "math", "array", "io"]
// "nyashstd.string." -> ["upper", "lower", "split", "join"]
}
}
```
## Phase 2: nyash.link準備1ヶ月後
### 🔗 外部モジュール対応基盤
```rust
// ModuleResolver拡張
pub enum NamespaceSource {
Builtin(Arc<BuiltinStdlib>), // 組み込み
External(PathBuf), // nyash.linkで管理
}
// NamespaceRegistry統合
pub struct NamespaceRegistry {
builtin: Arc<BuiltinStdlib>,
external: HashMap<String, ExternalModule>,
}
```
### 📁 nyash.link対応
```toml
[dependencies]
mylib = { path = "./mylib.nyash" }
# using mylib # Phase 2で対応
```
## 🧪 段階的テスト戦略
### Phase 0テスト
```nyash
# test_phase0_basic.nyash
using nyashstd
# 基本動作
assert(string.upper("hello") == "HELLO")
assert(string.lower("WORLD") == "world")
# エラー処理
try {
using unknown_namespace
} catch e {
assert(e.contains("nyashstd"))
}
```
### Phase 1テスト
```nyash
# test_phase1_qualified.nyash
# using不要のテスト
assert(nyashstd.string.upper("hello") == "HELLO")
assert(nyashstd.math.sin(0) == 0)
```
### Phase 2テスト
```nyash
# test_phase2_external.nyash
using mylib
assert(mylib.custom.process("data") == "processed: data")
```
## 📊 実装マイルストーン
### ✅ Phase 0完了条件
- [ ] USINGトークン認識
- [ ] using nyashstd構文解析
- [ ] 組み込みstring関数4種動作
- [ ] 基本テスト全通過
- [ ] エラーハンドリング適切
### ✅ Phase 1完了条件
- [ ] 完全修飾名 nyashstd.string.upper() 動作
- [ ] math/array/io関数実装
- [ ] IDE補完候補API実装
- [ ] 詳細エラーメッセージ
### ✅ Phase 2完了条件
- [ ] 外部モジュール基盤実装
- [ ] nyash.link基本対応
- [ ] 依存関係解決機能
- [ ] 全機能統合テスト
## 🔥 即座に開始すべき実装
### 今日やること
1. **src/stdlib/mod.rs作成** - モジュール基盤
2. **TokenType::USING追加** - トークナイザー拡張
3. **BuiltinStdlib::new()実装** - 空の基盤作成
### 今週やること
4. **using文パーサー実装** - 基本構文解析
5. **string.upper()実装** - 最初の関数
6. **基本テスト作成** - 動作確認
### 来週やること
7. **string関数完成** - lower, split, join
8. **math関数開始** - sin, cos, sqrt
9. **IDE補完設計** - Language Server準備
---
**🎯 この段階的戦略で、複雑なnyash.linkなしに即座に実用的なnamespace/usingシステムが実現できるにゃ**
**🚀 Phase 0実装を今すぐ開始して、Nyashをモダンなプログラミング言語に進化させよう🐱✨**

View File

@ -0,0 +1,471 @@
# nyash.linkシステム実装計画
## 🎯 実装戦略
### 📊 現状確認
-**include**: 限定的使用text_adventure例のみ→廃止OK
-**using**: 未実装→完全新規作成
-**namespace**: 設計完了→実装のみ
-**Gemini推奨**: 技術的妥当性確認済み
## 📋 段階的実装ロードマップ
### 🚀 **Phase 1: 基盤構築1-2週間**
#### 1.1 トークナイザー拡張
```rust
// src/tokenizer.rs
pub enum TokenType {
// 既存...
USING, // using キーワード
NAMESPACE, // namespace キーワード
AS, // as キーワード(将来のエイリアス用)
}
// キーワード認識追加
fn tokenize_identifier(input: &str) -> TokenType {
match input {
// 既存...
"using" => TokenType::USING,
"namespace" => TokenType::NAMESPACE,
"as" => TokenType::AS,
_ => TokenType::IDENTIFIER(input.to_string()),
}
}
```
#### 1.2 AST拡張
```rust
// src/ast.rs
pub enum ASTNode {
// 既存...
UsingStatement {
module_path: Vec<String>, // ["nyashstd"] or ["mylib"]
alias: Option<String>, // using mylib as lib
span: Span,
},
NamespaceDeclaration {
name: String,
body: Vec<ASTNode>,
span: Span,
},
QualifiedCall {
path: Vec<String>, // ["nyashstd", "string", "upper"]
args: Vec<ASTNode>,
span: Span,
},
}
```
#### 1.3 パーサー基本実装
```rust
// src/parser/statements.rs
impl NyashParser {
pub fn parse_using(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'using'
let module_path = self.parse_module_path()?;
// using mylib → ["mylib"]
// using nyashstd.string → ["nyashstd", "string"]
Ok(ASTNode::UsingStatement {
module_path,
alias: None, // Phase 1では未サポート
span: self.current_span(),
})
}
fn parse_module_path(&mut self) -> Result<Vec<String>, ParseError> {
let mut path = vec![];
// 最初の識別子
if let TokenType::IDENTIFIER(name) = &self.current_token().token_type {
path.push(name.clone());
self.advance();
} else {
return Err(ParseError::ExpectedIdentifier);
}
// ドット区切りで追加パス(将来拡張)
// using nyashstd.string のような構文
Ok(path)
}
}
```
### ⚡ **Phase 2: nyash.link基盤2-3週間**
#### 2.1 nyash.linkパーサー
```rust
// 新ファイル: src/link_file.rs
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Deserialize, Serialize)]
pub struct NyashLink {
pub project: Option<ProjectInfo>,
pub dependencies: HashMap<String, Dependency>,
pub search_paths: Option<HashMap<String, String>>,
pub build: Option<BuildConfig>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ProjectInfo {
pub name: String,
pub version: String,
pub description: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum Dependency {
Path { path: String },
Stdlib { stdlib: bool },
Registry { version: String, registry: String },
}
#[derive(Debug, Deserialize, Serialize)]
pub struct BuildConfig {
pub entry_point: Option<String>,
}
impl NyashLink {
pub fn from_file(path: &Path) -> Result<Self, LinkError> {
let content = std::fs::read_to_string(path)?;
let link: NyashLink = toml::from_str(&content)?;
Ok(link)
}
pub fn resolve_dependency(&self, name: &str) -> Option<PathBuf> {
if let Some(dep) = self.dependencies.get(name) {
match dep {
Dependency::Path { path } => Some(PathBuf::from(path)),
Dependency::Stdlib { .. } => {
// 標準ライブラリパス解決ロジック
self.resolve_stdlib_path(name)
}
_ => None, // Phase 2では未サポート
}
} else {
None
}
}
}
```
#### 2.2 依存関係解決エンジン
```rust
// 新ファイル: src/module_resolver.rs
pub struct ModuleResolver {
nyash_link: NyashLink,
loaded_modules: HashMap<String, Arc<ParsedModule>>,
loading_stack: Vec<String>, // 循環依存検出用
}
impl ModuleResolver {
pub fn new(link_path: &Path) -> Result<Self, ResolverError> {
let nyash_link = NyashLink::from_file(link_path)?;
Ok(ModuleResolver {
nyash_link,
loaded_modules: HashMap::new(),
loading_stack: Vec::new(),
})
}
pub fn resolve_using(&mut self, module_name: &str) -> Result<Arc<ParsedModule>, ResolverError> {
// 既にロード済みかチェック
if let Some(module) = self.loaded_modules.get(module_name) {
return Ok(module.clone());
}
// 循環依存チェック
if self.loading_stack.contains(&module_name.to_string()) {
return Err(ResolverError::CircularDependency(
self.loading_stack.clone()
));
}
// ファイルパス解決
let file_path = self.nyash_link.resolve_dependency(module_name)
.ok_or(ResolverError::ModuleNotFound(module_name.to_string()))?;
// 再帰的読み込み防止
self.loading_stack.push(module_name.to_string());
// ファイル読み込み・パース
let content = std::fs::read_to_string(&file_path)?;
let ast = NyashParser::parse_from_string(&content)?;
// モジュール作成
let module = Arc::new(ParsedModule {
name: module_name.to_string(),
file_path,
ast,
exports: self.extract_exports(&ast)?,
});
// キャッシュに保存
self.loaded_modules.insert(module_name.to_string(), module.clone());
self.loading_stack.pop();
Ok(module)
}
}
```
### 📈 **Phase 3: 名前空間システム3-4週間**
#### 3.1 namespace解析
```rust
impl NyashParser {
pub fn parse_namespace(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'namespace'
let name = self.expect_identifier()?;
self.expect_token(TokenType::LBRACE)?;
let mut body = vec![];
while !self.check_token(&TokenType::RBRACE) {
body.push(self.parse_statement()?);
}
self.expect_token(TokenType::RBRACE)?;
Ok(ASTNode::NamespaceDeclaration {
name,
body,
span: self.current_span(),
})
}
}
```
#### 3.2 名前空間レジストリ
```rust
// 新ファイル: src/namespace_registry.rs
pub struct NamespaceRegistry {
namespaces: HashMap<String, Namespace>,
using_imports: HashMap<String, Vec<String>>, // ファイル別インポート
}
pub struct Namespace {
pub name: String,
pub static_boxes: HashMap<String, StaticBox>,
}
pub struct StaticBox {
pub name: String,
pub static_methods: HashMap<String, MethodSignature>,
}
impl NamespaceRegistry {
pub fn register_namespace(&mut self, name: String, namespace: Namespace) {
self.namespaces.insert(name, namespace);
}
pub fn add_using_import(&mut self, file_id: String, namespace_name: String) {
self.using_imports
.entry(file_id)
.or_insert_with(Vec::new)
.push(namespace_name);
}
pub fn resolve_call(&self, file_id: &str, path: &[String]) -> Option<MethodSignature> {
// 例: string.upper() → nyashstd.string.upper()
if path.len() == 2 {
let box_name = &path[0];
let method_name = &path[1];
// usingでインポートされた名前空間を検索
if let Some(imports) = self.using_imports.get(file_id) {
for namespace_name in imports {
if let Some(namespace) = self.namespaces.get(namespace_name) {
if let Some(static_box) = namespace.static_boxes.get(box_name) {
if let Some(method) = static_box.static_methods.get(method_name) {
return Some(method.clone());
}
}
}
}
}
}
None
}
}
```
### 🎯 **Phase 4: インタープリター統合4-5週間**
#### 4.1 using文実行
```rust
// src/interpreter/core.rs
impl NyashInterpreter {
pub fn execute_using(&mut self, module_path: &[String]) -> Result<(), RuntimeError> {
let module_name = module_path.join(".");
// モジュール解決・読み込み
let module = self.module_resolver.resolve_using(&module_name)?;
// 名前空間登録
if let Some(namespace) = self.extract_namespace_from_module(&module) {
self.namespace_registry.register_namespace(module_name.clone(), namespace);
self.namespace_registry.add_using_import(
self.current_file_id.clone(),
module_name
);
}
Ok(())
}
fn extract_namespace_from_module(&self, module: &ParsedModule) -> Option<Namespace> {
// ASTからnamespace宣言を探して解析
for node in &module.ast {
if let ASTNode::NamespaceDeclaration { name, body, .. } = node {
return Some(self.build_namespace_from_body(name, body));
}
}
None
}
}
```
#### 4.2 qualified call実行
```rust
impl NyashInterpreter {
pub fn execute_qualified_call(&mut self, path: &[String], args: &[ASTNode])
-> Result<Box<dyn NyashBox>, RuntimeError> {
// 名前解決
if let Some(method_sig) = self.namespace_registry.resolve_call(
&self.current_file_id,
path
) {
// 引数評価
let evaluated_args = self.evaluate_args(args)?;
// メソッド実行既存のBox呼び出しシステム活用
return self.call_static_method(&method_sig, evaluated_args);
}
// 完全修飾名として試行
if path.len() >= 3 {
// nyashstd.string.upper() の場合
let namespace_name = &path[0];
let box_name = &path[1];
let method_name = &path[2];
if let Some(namespace) = self.namespace_registry.namespaces.get(namespace_name) {
if let Some(static_box) = namespace.static_boxes.get(box_name) {
if let Some(method) = static_box.static_methods.get(method_name) {
let evaluated_args = self.evaluate_args(args)?;
return self.call_static_method(method, evaluated_args);
}
}
}
}
Err(RuntimeError::UndefinedMethod(path.join(".")))
}
}
```
## 🧪 テスト戦略
### Phase 1テスト
```nyash
# test_basic_using.nyash
# 基本using文テスト
# ファイル: mylib.nyash
static function hello() {
return "Hello from mylib!"
}
# ファイル: main.nyash
using mylib
local result = mylib.hello()
assert(result == "Hello from mylib!")
```
### Phase 2テスト
```nyash
# test_nyash_link.nyash
# nyash.linkファイル連携テスト
# nyash.link内容:
# [dependencies]
# mylib = { path = "./mylib.nyash" }
using mylib
local result = mylib.process("data")
assert(result == "processed: data")
```
### Phase 3テスト
```nyash
# test_namespace.nyash
# 名前空間システムテスト
# nyashstd.nyash:
# namespace nyashstd {
# static box string {
# static upper(str) { ... }
# }
# }
using nyashstd
local result = string.upper("hello")
assert(result == "HELLO")
# 完全修飾名
local result2 = nyashstd.string.upper("world")
assert(result2 == "WORLD")
```
## 📊 実装マイルストーン
### ✅ 完了条件
#### Phase 1
- [ ] USING/NAMESPACE トークン認識
- [ ] using文AST構築
- [ ] 基本パーサーテスト通過
#### Phase 2
- [ ] nyash.linkファイル読み込み
- [ ] 依存関係解決
- [ ] モジュールキャッシュ機能
#### Phase 3
- [ ] namespace宣言解析
- [ ] 名前空間レジストリ動作
- [ ] 静的メソッド解決
#### Phase 4
- [ ] インタープリター統合
- [ ] qualified call実行
- [ ] 全テストケース通過
## 🔮 将来拡張
### Phase 5: 高度機能
- エイリアス(`using mylib as lib`
- 選択インポート(`using nyashstd.string`
- 動的モジュール読み込み
### Phase 6: 標準ライブラリ
- nyashstd.nyash完全実装
- string/math/io/http モジュール
- ドキュメント生成
### Phase 7: エコシステム
- パッケージレジストリ設計
- CLI ツールnyash init/install
- IDE Language Server連携
---
**🎯 この実装計画でnyash.linkシステムを段階的に完成させるにゃ**

View File

@ -0,0 +1,372 @@
# なんでもAPI計画最終統合アーキテクチャ
## 🌟 革命的ビジョンの実現
### 📊 統合設計完了状況
-**nyash.link基盤**: 依存関係管理システム設計完了
-**FFI-ABI統合**: BID×MIR×バックエンド統合設計完了
-**usingシステム**: 3種類API統一インポート設計完了
-**実世界例**: ゲーム・データサイエンス・Web・システムプログラミング実証
- 🎯 **最終統合**: 全システム統合による革命的開発体験実現
### 🚀 完成後の開発体験
```nyash
# === たった一つの構文ですべてが使える ===
using nyashstd # 組み込み標準ライブラリ
using browser_api # ブラウザAPICanvas, DOM, WebAudio...
using system_api # システムAPIlibc, filesystem, network...
using ml_api # 機械学習TensorFlow, PyTorch, OpenCV...
using game_api # ゲーム開発SDL, OpenGL, Vulkan...
using mylib # 自作Nyashモジュール
# 全部同じ記法・同じパフォーマンス・同じエラーハンドリング!
string.upper("hello") # 組み込み標準
browser.canvas.fillRect("game", 10, 10, 100, 100, "red") # ブラウザAPI
system.file.read("/etc/passwd") # システムAPI
ml.opencv.loadImage("photo.jpg") # 機械学習API
game.sdl.createWindow("Game", 800, 600) # ゲームAPI
mylib.processData("input") # 自作モジュール
```
## 🏗️ 最終統合アーキテクチャ
### 1. 全体システム構成
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Nyash Code │ │ nyash.link │ │ BID Files │
│ │ │ │ │ │
│ using browser_api│ │ [dependencies] │ │ browser_api: │
│ using system_api │───▶│ browser_api = │───▶│ canvas.yaml │
│ using mylib │ │ {bid=...} │ │ dom.yaml │
│ canvas.fillRect │ │ system_api = │ │ system_api: │
│ file.read │ │ {bid=...} │ │ libc.yaml │
│ mylib.process │ │ mylib = {path} │ │ filesystem.yaml│
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└────────────────────────┼────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ UniversalNamespaceRegistry │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │BuiltinStdlib│ │BidDefinition│ │ExternalModules │ │
│ │ │ │ │ │ │ │
│ │nyashstd.* │ │browser_api.*│ │mylib.* │ │
│ │string.upper │ │canvas.fill* │ │custom functions │ │
│ │math.sin │ │dom.events │ │ │ │
│ │array.length │ │system.file* │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ MIR Generation │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │BuiltinCall │ │ExternCall │ │ModuleCall │ │
│ │ │ │ │ │ │ │
│ │string.upper │ │canvas.fill* │ │mylib.process │ │
│ │effect:pure │ │effect:io │ │effect:io │ │
│ │optimize:yes │ │gpu_accel:yes│ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Backend Execution │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ VM │ │ WASM │ │ AOT │ │
│ │ │ │ │ │ │ │
│ │Native Impl │ │RuntimeImport│ │LLVM ExternFunc │ │
│ │Stub Calls │ │Auto-generated│ │Native Libraries │ │
│ │ │ │from BID │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### 2. nyash.link統合仕様最終版
```toml
# nyash.link - 全API統一管理設定
[project]
name = "ultimate-nyash-app"
version = "2.0.0"
description = "Everything is accessible through unified APIs"
license = "MIT"
[dependencies]
# === 組み込み標準ライブラリ ===
nyashstd = { builtin = true }
# === ブラウザ・Web API ===
browser_api = {
bid = ["./apis/canvas.yaml", "./apis/dom.yaml", "./apis/webaudio.yaml"],
target_environments = ["browser"]
}
webgl_api = {
bid = "./apis/webgl.yaml",
target_environments = ["browser"]
}
# === システム・OS API ===
system_api = {
bid = ["./apis/libc.yaml", "./apis/filesystem.yaml", "./apis/network.yaml"],
library = "system",
target_environments = ["linux", "macos", "windows"]
}
posix_api = {
bid = "./apis/posix.yaml",
library = "system",
target_environments = ["linux", "macos"]
}
# === 機械学習・データサイエンス ===
ml_api = {
bid = ["./apis/opencv.yaml", "./apis/numpy.yaml"],
library = ["./libs/opencv.so", "./libs/numpy.so"],
target_environments = ["linux", "macos"]
}
tensorflow_api = {
bid = "./apis/tensorflow.yaml",
library = "./libs/tensorflow.so",
optional = true # 環境によってオプション
}
# === ゲーム開発 ===
game_api = {
bid = ["./apis/sdl.yaml", "./apis/opengl.yaml"],
library = ["SDL2", "OpenGL"],
target_environments = ["linux", "macos", "windows"]
}
# === データベース ===
database_api = {
bid = ["./apis/sqlite.yaml", "./apis/postgresql.yaml"],
library = ["sqlite3", "pq"],
}
# === ネットワーク・Web ===
http_api = {
bid = "./apis/http_client.yaml",
library = "curl"
}
# === Nyashモジュール従来通り ===
mylib = { path = "./src/mylib.nyash" }
utils = { path = "./src/utils/" }
models = { path = "./src/models.nyash" }
# === 将来の外部パッケージ ===
awesome_lib = {
version = "^1.2.0",
registry = "nyash-pkg",
bid = "auto" # パッケージレジストリから自動取得
}
[build]
entry_point = "./src/main.nyash"
backends = ["vm", "wasm", "aot"]
optimization_level = "release"
[targets]
browser = ["browser_api", "webgl_api"]
desktop = ["system_api", "game_api", "ml_api"]
server = ["system_api", "database_api", "http_api"]
[optimization]
# MIRレベル最適化設定
enable_effect_optimization = true
enable_batch_optimization = true # FFI-ABI呼び出しバッチ化
enable_gpu_acceleration = true
cache_bid_compilation = true
```
### 3. BIDエコシステム標準API集
```
nyash-std-apis/ # 標準APIライブラリ
├── browser/
│ ├── canvas.yaml # Canvas API
│ ├── dom.yaml # DOM API
│ ├── webaudio.yaml # Web Audio API
│ ├── webgl.yaml # WebGL API
│ └── fetch.yaml # Fetch API
├── system/
│ ├── libc.yaml # C標準ライブラリ
│ ├── filesystem.yaml # ファイルシステム
│ ├── network.yaml # ネットワーク
│ ├── process.yaml # プロセス管理
│ └── threads.yaml # スレッド・並行処理
├── ml/
│ ├── opencv.yaml # コンピューターヴィジョン
│ ├── numpy.yaml # 数値計算
│ ├── tensorflow.yaml # 機械学習
│ └── pytorch.yaml # 深層学習
├── game/
│ ├── sdl.yaml # SDL2ライブラリ
│ ├── opengl.yaml # OpenGL API
│ ├── vulkan.yaml # Vulkan API
│ └── physics.yaml # 物理エンジン
├── database/
│ ├── sqlite.yaml # SQLite
│ ├── postgresql.yaml # PostgreSQL
│ ├── mysql.yaml # MySQL
│ └── redis.yaml # Redis
└── crypto/
├── openssl.yaml # OpenSSL
├── libsodium.yaml # libsodium
└── bcrypt.yaml # bcrypt
```
## 🚀 段階的実装戦略(現実的ロードマップ)
### Phase 0: 基盤構築2-3週間
```rust
// 🎯 最小実装目標
// using nyashstd → 動作
```
#### **実装内容**
1. **USINGトークナイザー** - `TokenType::USING`追加
2. **基本パーサー** - `using nyashstd`構文解析
3. **BuiltinStdlib基盤** - 組み込み標準ライブラリ
4. **基本string関数** - upper, lower, split, join
#### **テスト**
```nyash
using nyashstd
assert(string.upper("hello") == "HELLO")
```
### Phase 1: BID基盤4-6週間
```rust
// 🎯 外部API基盤目標
// using console_api → 動作VM Stub
```
#### **実装内容**
1. **BID読み込み** - YAML解析・検証システム
2. **UniversalNamespaceRegistry** - 統合名前空間管理
3. **MIR ExternCall統合** - BID→MIR変換
4. **VM Stub実装** - console.log等の基本スタブ
#### **テスト**
```nyash
using nyashstd
using console_api
string.upper("test")
console.log("BID integration works!")
```
### Phase 2: WASM統合6-8週間
```rust
// 🎯 WASM動作目標
// ブラウザでCanvas API動作
```
#### **実装内容**
1. **WASM RuntimeImports自動生成** - BID→WASM import
2. **文字列マーシャリング** - UTF-8 (ptr,len)対応
3. **Canvas API完全実装** - fillRect, fillText等
4. **ブラウザテスト環境** - HTML/JS統合
#### **テスト**
```nyash
using browser_api
canvas.fillRect("game-canvas", 10, 10, 100, 100, "red")
```
### Phase 3: システムAPI統合8-12週間
```rust
// 🎯 ネイティブライブラリ動作目標
// ファイルI/O, システムコール等
```
#### **実装内容**
1. **AOTバックエンド統合** - LLVM IR外部関数
2. **システムライブラリ連携** - libc, filesystem等
3. **エラーハンドリング統合** - 統一エラーモデル
4. **パフォーマンス最適化** - バッチ処理・GPU加速
#### **テスト**
```nyash
using system_api
local content = file.read("/etc/passwd")
file.write("./output.txt", content)
```
### Phase 4: 完全エコシステム12-16週間
```rust
// 🎯 実用的アプリケーション開発
// ゲーム・ML・Webアプリ等
```
#### **実装内容**
1. **標準APIライブラリ** - nyash-std-apis完成
2. **パッケージレジストリ** - BID共有システム
3. **IDE Language Server** - 統合補完・エラー検出
4. **最適化エンジン** - Effect System活用
#### **実用例**
```nyash
# 本格的なゲーム開発
using game_api
using audio_api
game.sdl.createWindow("My Game", 1024, 768)
audio.mixer.playMusic("bgm.ogg")
```
## 📊 既存実装との整合性
### Phase 9.75eとの関係
```
Phase 9.75e (既存計画) なんでもAPI計画 (新設計)
↓ ↓
namespace構文 using統一構文
依存関係システム → nyash.link統合管理
外部ファイル読み込み → BID統合システム
完全統合アーキテクチャ
```
### 既存MIR/バックエンドとの統合
-**MIR ExternCall**: 既存実装活用
-**WASM RuntimeImports**: 既存基盤拡張
-**VM Backend**: 既存スタブシステム活用
- 🔧 **統合課題**: usingシステムとの橋渡し
## 🌟 長期ビジョンNyashの未来
### 2025年目標
- **Phase 0-1完了**: 基盤・BID統合
- **実用アプリ**: シンプルなブラウザゲーム・ツール
- **コミュニティ**: 開発者コミュニティ形成
### 2026年目標
- **Phase 2-3完了**: WASM・システムAPI統合
- **本格アプリ**: ゲーム・データサイエンス・Webアプリ
- **エコシステム**: BIDライブラリエコシステム
### 2027年目標
- **Phase 4完了**: 完全エコシステム
- **産業利用**: 企業での実用的活用
- **言語標準化**: BID標準の業界採用
## 🎯 即座に開始すべき実装
### 今日のアクション
1. **src/stdlib/mod.rs作成** - 組み込み標準ライブラリ基盤
2. **TokenType::USING追加** - トークナイザー拡張
3. **Phase 0実装開始** - using nyashstd基本動作
### 今週のアクション
4. **BuiltinStdlib::new()実装** - string関数4種
5. **基本テスト作成** - using動作確認
6. **Phase 1設計** - BID統合詳細設計
### 来週のアクション
7. **BID読み込み基盤** - YAML解析システム
8. **UniversalNamespaceRegistry** - 統合名前空間管理
9. **console.log実装** - 最初のBID統合テスト
---
**🎉 この最終統合アーキテクチャにより、Nyashが真に「なんでもできる」革命的プログラミング言語になるにゃ**
**🚀 今すぐPhase 0実装を開始して、プログラミング言語の未来を創造しよう🐱✨**

View File

@ -0,0 +1,435 @@
# 最小実装標準関数優先namespace/usingシステム
## 🎯 基本戦略nyash.link前の段階的実装
### 📊 現状分析
- **既存Box型**: 25種類以上の豊富なBox実装
- **include使用**: 限定的text_adventure例のみ
- **using実装**: 完全未実装→新規作成可能
- **最優先課題**: 複雑なファイル依存関係システムより、まず標準関数のIDE補完
### 🌟 段階的実装アプローチ
#### **Phase 0: 組み込みnyashstd最小実装**
```
ファイル読み込み一切なし → インタープリターに直接組み込み
```
#### **Phase 1: using構文**
```nyash
using nyashstd
string.upper("hello") # ✅ 動作
```
#### **Phase 2: 将来のnyash.link対応**
```
外部ファイル・依存関係システム(後日実装)
```
## 🏗️ 組み込みnyashstd設計
### 優先順位別Box分類
#### 🚨 **Tier 1: 最優先基本機能**
```rust
// 使用頻度最高・IDE補完必須
- string_box.rs nyashstd.string.*
- math_box.rs nyashstd.math.*
- array/mod.rs nyashstd.array.*
- console_box.rs nyashstd.io.*
```
#### ⚡ **Tier 2: 重要機能**
```rust
// 標準的な機能
- time_box.rs nyashstd.time.*
- random_box.rs nyashstd.random.*
- map_box.rs nyashstd.map.*
```
#### 📝 **Tier 3: 特殊用途**
```rust
// 特定用途・後で追加
- debug_box.rs nyashstd.debug.*
- http_server_box.rs nyashstd.http.*
- p2p_box.rs nyashstd.p2p.*
```
### 最小実装スコープPhase 0
#### **nyashstd.string機能**
```nyash
using nyashstd
string.upper("hello") # "HELLO"
string.lower("WORLD") # "world"
string.split("a,b,c", ",") # ["a", "b", "c"]
string.join(["a","b"], "-") # "a-b"
string.length("test") # 4
```
#### **nyashstd.math機能**
```nyash
using nyashstd
math.sin(3.14159) # 0.0 (approximately)
math.cos(0) # 1.0
math.sqrt(16) # 4.0
math.floor(3.7) # 3
math.random() # 0.0-1.0のランダム値
```
#### **nyashstd.array機能**
```nyash
using nyashstd
array.length([1,2,3]) # 3
array.push([1,2], 3) # [1,2,3]
array.get([1,2,3], 1) # 2
array.slice([1,2,3,4], 1, 3) # [2,3]
```
#### **nyashstd.io機能**
```nyash
using nyashstd
io.print("Hello") # コンソール出力
io.println("World") # 改行付き出力
io.debug("Debug info") # デバッグ出力
```
## 💻 技術実装戦略
### 1. インタープリター組み込み方式
#### **新ファイル: `src/stdlib/mod.rs`**
```rust
//! 組み込み標準ライブラリ
//! nyash.linkなしで動作する基本的な標準関数群
use crate::boxes::*;
use std::collections::HashMap;
pub struct BuiltinStdlib {
pub namespaces: HashMap<String, BuiltinNamespace>,
}
pub struct BuiltinNamespace {
pub name: String,
pub static_boxes: HashMap<String, BuiltinStaticBox>,
}
pub struct BuiltinStaticBox {
pub name: String,
pub methods: HashMap<String, BuiltinMethod>,
}
pub type BuiltinMethod = fn(&[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, RuntimeError>;
impl BuiltinStdlib {
pub fn new() -> Self {
let mut stdlib = BuiltinStdlib {
namespaces: HashMap::new(),
};
// nyashstd名前空間登録
stdlib.register_nyashstd();
stdlib
}
fn register_nyashstd(&mut self) {
let mut nyashstd = BuiltinNamespace {
name: "nyashstd".to_string(),
static_boxes: HashMap::new(),
};
// string static box
nyashstd.static_boxes.insert("string".to_string(), self.create_string_box());
// math static box
nyashstd.static_boxes.insert("math".to_string(), self.create_math_box());
// array static box
nyashstd.static_boxes.insert("array".to_string(), self.create_array_box());
// io static box
nyashstd.static_boxes.insert("io".to_string(), self.create_io_box());
self.namespaces.insert("nyashstd".to_string(), nyashstd);
}
}
```
#### **文字列関数実装例**
```rust
impl BuiltinStdlib {
fn create_string_box(&self) -> BuiltinStaticBox {
let mut string_box = BuiltinStaticBox {
name: "string".to_string(),
methods: HashMap::new(),
};
// string.upper(str) -> String
string_box.methods.insert("upper".to_string(), |args| {
if args.len() != 1 {
return Err(RuntimeError::InvalidArguments(
"string.upper() takes exactly 1 argument".to_string()
));
}
let string_arg = args[0].to_string_box();
let result = StringBox::new(&string_arg.value.to_uppercase());
Ok(Box::new(result))
});
// string.lower(str) -> String
string_box.methods.insert("lower".to_string(), |args| {
if args.len() != 1 {
return Err(RuntimeError::InvalidArguments(
"string.lower() takes exactly 1 argument".to_string()
));
}
let string_arg = args[0].to_string_box();
let result = StringBox::new(&string_arg.value.to_lowercase());
Ok(Box::new(result))
});
// string.split(str, separator) -> Array
string_box.methods.insert("split".to_string(), |args| {
if args.len() != 2 {
return Err(RuntimeError::InvalidArguments(
"string.split() takes exactly 2 arguments".to_string()
));
}
let string_arg = args[0].to_string_box();
let sep_arg = args[1].to_string_box();
let string_box = StringBox::new(&string_arg.value);
let result = string_box.split(&sep_arg.value)?;
Ok(result)
});
string_box
}
}
```
### 2. インタープリター統合
#### **インタープリター拡張: `src/interpreter/core.rs`**
```rust
use crate::stdlib::BuiltinStdlib;
pub struct NyashInterpreter {
// 既存フィールド...
pub builtin_stdlib: BuiltinStdlib,
pub using_imports: HashMap<String, Vec<String>>, // ファイル別インポート
}
impl NyashInterpreter {
pub fn new() -> Self {
NyashInterpreter {
// 既存初期化...
builtin_stdlib: BuiltinStdlib::new(),
using_imports: HashMap::new(),
}
}
// using文実行
pub fn execute_using(&mut self, namespace_name: &str) -> Result<(), RuntimeError> {
// 組み込み名前空間かチェック
if self.builtin_stdlib.namespaces.contains_key(namespace_name) {
// 現在ファイルのインポートリストに追加
self.using_imports
.entry(self.current_file_id.clone())
.or_insert_with(Vec::new)
.push(namespace_name.to_string());
Ok(())
} else {
Err(RuntimeError::UndefinedNamespace(namespace_name.to_string()))
}
}
// 短縮名解決: string.upper() -> nyashstd.string.upper()
pub fn resolve_short_call(&self, box_name: &str, method_name: &str)
-> Option<(&str, &str, &str)> { // (namespace, box, method)
if let Some(imports) = self.using_imports.get(&self.current_file_id) {
for namespace_name in imports {
if let Some(namespace) = self.builtin_stdlib.namespaces.get(namespace_name) {
if namespace.static_boxes.contains_key(box_name) {
return Some((namespace_name, box_name, method_name));
}
}
}
}
None
}
// 組み込み関数呼び出し
pub fn call_builtin_method(&self, namespace: &str, box_name: &str, method_name: &str, args: Vec<Box<dyn NyashBox>>)
-> Result<Box<dyn NyashBox>, RuntimeError> {
if let Some(ns) = self.builtin_stdlib.namespaces.get(namespace) {
if let Some(static_box) = ns.static_boxes.get(box_name) {
if let Some(method) = static_box.methods.get(method_name) {
return method(&args);
}
}
}
Err(RuntimeError::UndefinedMethod(
format!("{}.{}.{}", namespace, box_name, method_name)
))
}
}
```
### 3. パーサー最小拡張
#### **トークナイザー: `src/tokenizer.rs`**
```rust
pub enum TokenType {
// 既存...
USING, // using キーワード
// NAMESPACE は後のPhaseで追加
}
```
#### **AST最小拡張: `src/ast.rs`**
```rust
pub enum ASTNode {
// 既存...
UsingStatement {
namespace_name: String, // "nyashstd" のみ対応
span: Span,
},
// QualifiedCall は後のPhaseで追加
}
```
#### **パーサー: `src/parser/statements.rs`**
```rust
impl NyashParser {
pub fn parse_using(&mut self) -> Result<ASTNode, ParseError> {
self.advance(); // consume 'using'
if let TokenType::IDENTIFIER(namespace_name) = &self.current_token().token_type {
let name = namespace_name.clone();
self.advance();
// Phase 0では "nyashstd" のみ許可
if name != "nyashstd" {
return Err(ParseError::UnsupportedNamespace(name));
}
Ok(ASTNode::UsingStatement {
namespace_name: name,
span: self.current_span(),
})
} else {
Err(ParseError::ExpectedIdentifier)
}
}
}
```
## 🧪 テスト戦略
### Phase 0テストケース
#### **基本using文テスト**
```nyash
# test_using_basic.nyash
using nyashstd
local result = string.upper("hello")
assert(result == "HELLO")
local lower = string.lower("WORLD")
assert(lower == "world")
```
#### **数学関数テスト**
```nyash
# test_math_basic.nyash
using nyashstd
local sin_result = math.sin(0)
assert(sin_result == 0)
local sqrt_result = math.sqrt(16)
assert(sqrt_result == 4)
```
#### **配列操作テスト**
```nyash
# test_array_basic.nyash
using nyashstd
local arr = [1, 2, 3]
local length = array.length(arr)
assert(length == 3)
local item = array.get(arr, 1)
assert(item == 2)
```
## 📊 実装マイルストーン
### ✅ Phase 0完了条件
- [ ] USING トークン認識
- [ ] using nyashstd 構文解析
- [ ] 組み込みnyashstd.string実装
- [ ] 組み込みnyashstd.math実装
- [ ] 組み込みnyashstd.array実装
- [ ] 組み込みnyashstd.io実装
- [ ] 基本テストケース全通過
### 🔮 将来の発展
#### **Phase 1: 完全修飾名対応**
```nyash
# using不要でも使える
nyashstd.string.upper("hello")
```
#### **Phase 2: namespace構文対応**
```nyash
# 組み込み以外の名前空間
namespace mylib {
static box utils {
static process(data) { ... }
}
}
```
#### **Phase 3: nyash.link統合**
```toml
# nyash.link
[dependencies]
mylib = { path = "./mylib.nyash" }
```
## 🎯 実装優先順位
### 🚨 Critical今すぐ
1. **USINGトークナイザー** - Token::USING追加
2. **using文パーサー** - "using nyashstd"解析
3. **BuiltinStdlib基盤** - src/stdlib/mod.rs作成
### ⚡ High今週中
4. **string関数実装** - upper, lower, split, join
5. **math関数実装** - sin, cos, sqrt, floor
6. **基本テスト** - using nyashstd動作確認
### 📝 Medium来週
7. **array関数実装** - length, get, push, slice
8. **io関数実装** - print, println, debug
9. **エラーハンドリング** - 適切なエラーメッセージ
---
**🎉 この戦略なら複雑なファイル依存関係システムなしで、すぐに実用的なnamespace/usingが実現できるにゃ🐱**

View File

@ -0,0 +1,625 @@
# なんでもAPI計画実世界での具体例
## 🌟 革命的開発体験の実例
### 🎮 ゲーム開発例Nyashブラウザゲーム
```nyash
# === nyash.link ===
[dependencies]
nyashstd = { builtin = true }
canvas_api = { bid = "./apis/canvas.yaml" }
dom_api = { bid = "./apis/dom.yaml" }
audio_api = { bid = "./apis/webaudio.yaml" }
# === game.nyash ===
using nyashstd
using canvas_api
using dom_api
using audio_api
static box Game {
init { canvas_id, score, player_x, player_y, enemies }
main() {
me.canvas_id = "game-canvas"
me.score = 0
me.player_x = 200
me.player_y = 300
me.enemies = new ArrayBox()
# DOMイベント設定FFI-ABI経由
dom.addEventListener("keydown", me.handleKeyDown)
# ゲームループ開始
me.gameLoop()
}
gameLoop() {
loop(true) {
me.update()
me.render()
# ブラウザのrequestAnimationFrameFFI-ABI
dom.requestAnimationFrame(me.gameLoop)
}
}
update() {
# 敵の移動(組み込み標準ライブラリ)
local i = 0
loop(i < array.length(me.enemies)) {
local enemy = array.get(me.enemies, i)
enemy.y = enemy.y + enemy.speed
i = i + 1
}
# 当たり判定(組み込み数学関数)
local distance = math.sqrt(
math.pow(me.player_x - enemy.x, 2) +
math.pow(me.player_y - enemy.y, 2)
)
if distance < 30 {
me.gameOver()
}
}
render() {
# 画面クリアCanvas API - FFI-ABI
canvas.fillRect(me.canvas_id, 0, 0, 800, 600, "black")
# プレイヤー描画
canvas.fillRect(me.canvas_id, me.player_x, me.player_y, 20, 20, "blue")
# 敵描画
local i = 0
loop(i < array.length(me.enemies)) {
local enemy = array.get(me.enemies, i)
canvas.fillRect(me.canvas_id, enemy.x, enemy.y, 15, 15, "red")
i = i + 1
}
# スコア表示
local score_text = "Score: " + string.toString(me.score)
canvas.fillText(me.canvas_id, score_text, 10, 30, "20px Arial", "white")
}
handleKeyDown(event) {
# キーボード入力処理DOM API経由
local key = dom.getEventKey(event)
if key == "ArrowLeft" {
me.player_x = me.player_x - 10
} else if key == "ArrowRight" {
me.player_x = me.player_x + 10
} else if key == " " { # スペースキー
me.shoot()
}
}
shoot() {
# 効果音再生Web Audio API - FFI-ABI
audio.playSound("shoot.wav")
# 弾の生成・発射処理
# ...
}
gameOver() {
# ゲームオーバー処理
audio.playSound("gameover.wav")
dom.alert("Game Over! Score: " + string.toString(me.score))
}
}
```
### 🔬 データサイエンス例:画像処理アプリ
```nyash
# === nyash.link ===
[dependencies]
nyashstd = { builtin = true }
opencv_api = { bid = "./apis/opencv.yaml", library = "./libs/opencv.so" }
numpy_api = { bid = "./apis/numpy.yaml", library = "./libs/numpy.so" }
matplotlib_api = { bid = "./apis/matplotlib.yaml", library = "./libs/matplotlib.so" }
file_api = { bid = "./apis/file.yaml" }
# === image_processor.nyash ===
using nyashstd
using opencv_api
using numpy_api
using matplotlib_api
using file_api
static box ImageProcessor {
init { input_path, output_path, processed_data }
main() {
me.input_path = "./images/input.jpg"
me.output_path = "./images/output.jpg"
# 画像読み込みOpenCV - FFI-ABI
local image = opencv.imread(me.input_path)
# 前処理
local gray = opencv.cvtColor(image, "BGR2GRAY")
local blurred = opencv.gaussianBlur(gray, 5, 5)
# エッジ検出
local edges = opencv.canny(blurred, 50, 150)
# NumPy配列操作NumPy - FFI-ABI
local edge_array = numpy.fromOpenCV(edges)
local normalized = numpy.normalize(edge_array, 0, 255)
# 統計計算(組み込み標準ライブラリ)
local edge_count = me.countEdgePixels(normalized)
local percentage = (edge_count * 100) / (image.width * image.height)
# 結果表示
io.println("Edge pixels: " + string.toString(edge_count))
io.println("Edge percentage: " + string.toString(percentage) + "%")
# 結果画像保存OpenCV
opencv.imwrite(me.output_path, edges)
# グラフ生成Matplotlib - FFI-ABI
me.generateHistogram(normalized)
}
countEdgePixels(image_array) {
local count = 0
local height = numpy.shape(image_array, 0)
local width = numpy.shape(image_array, 1)
local y = 0
loop(y < height) {
local x = 0
loop(x < width) {
local pixel = numpy.get(image_array, y, x)
if pixel > 0 {
count = count + 1
}
x = x + 1
}
y = y + 1
}
return count
}
generateHistogram(image_array) {
# ヒストグラム計算NumPy
local histogram = numpy.histogram(image_array, 256)
# グラフ描画Matplotlib
matplotlib.figure(800, 600)
matplotlib.plot(histogram.bins, histogram.values)
matplotlib.title("Edge Pixel Histogram")
matplotlib.xlabel("Pixel Intensity")
matplotlib.ylabel("Frequency")
matplotlib.savefig("./images/histogram.png")
matplotlib.show()
}
}
```
### 🌐 Webサーバー例RESTful API
```nyash
# === nyash.link ===
[dependencies]
nyashstd = { builtin = true }
http_server_api = { bid = "./apis/http_server.yaml" }
sqlite_api = { bid = "./apis/sqlite.yaml", library = "./libs/sqlite.so" }
json_api = { bid = "./apis/json.yaml" }
crypto_api = { bid = "./apis/crypto.yaml", library = "./libs/openssl.so" }
# === api_server.nyash ===
using nyashstd
using http_server_api
using sqlite_api
using json_api
using crypto_api
static box ApiServer {
init { server, database, port }
main() {
me.port = 8080
me.server = http_server.create()
me.database = sqlite.open("./data/app.db")
# データベース初期化
me.initDatabase()
# ルート設定
http_server.route(me.server, "GET", "/api/users", me.getUsers)
http_server.route(me.server, "POST", "/api/users", me.createUser)
http_server.route(me.server, "PUT", "/api/users/:id", me.updateUser)
http_server.route(me.server, "DELETE", "/api/users/:id", me.deleteUser)
# サーバー開始
io.println("Server starting on port " + string.toString(me.port))
http_server.listen(me.server, me.port)
}
initDatabase() {
local sql = "CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)"
sqlite.exec(me.database, sql)
}
getUsers(request, response) {
# クエリ実行SQLite - FFI-ABI
local sql = "SELECT id, name, email, created_at FROM users"
local results = sqlite.query(me.database, sql)
# JSON変換JSON API - FFI-ABI
local json_response = json.stringify(results)
# レスポンス送信HTTP Server API
http_server.setHeader(response, "Content-Type", "application/json")
http_server.setStatus(response, 200)
http_server.send(response, json_response)
}
createUser(request, response) {
# リクエストボディ解析
local body = http_server.getBody(request)
local user_data = json.parse(body)
# バリデーション(組み込み標準ライブラリ)
if string.length(user_data.name) < 2 {
me.sendError(response, 400, "Name must be at least 2 characters")
return
}
if not me.isValidEmail(user_data.email) {
me.sendError(response, 400, "Invalid email format")
return
}
# パスワードハッシュ化Crypto API - FFI-ABI
local password_hash = crypto.hashPassword(user_data.password)
# データベース挿入
local sql = "INSERT INTO users (name, email, password_hash) VALUES (?, ?, ?)"
local params = [user_data.name, user_data.email, password_hash]
try {
local user_id = sqlite.insert(me.database, sql, params)
# 作成されたユーザー情報を返す
local created_user = map.create()
map.set(created_user, "id", user_id)
map.set(created_user, "name", user_data.name)
map.set(created_user, "email", user_data.email)
local json_response = json.stringify(created_user)
http_server.setHeader(response, "Content-Type", "application/json")
http_server.setStatus(response, 201)
http_server.send(response, json_response)
} catch error {
io.println("Database error: " + error.message)
me.sendError(response, 500, "Failed to create user")
}
}
isValidEmail(email) {
# 簡単なメール検証(組み込み文字列関数)
local at_pos = string.indexOf(email, "@")
local dot_pos = string.lastIndexOf(email, ".")
return at_pos > 0 and dot_pos > at_pos and dot_pos < string.length(email) - 1
}
sendError(response, status, message) {
local error_obj = map.create()
map.set(error_obj, "error", message)
local json_error = json.stringify(error_obj)
http_server.setHeader(response, "Content-Type", "application/json")
http_server.setStatus(response, status)
http_server.send(response, json_error)
}
}
```
### 🔧 システムプログラミング例:ファイル監視ツール
```nyash
# === nyash.link ===
[dependencies]
nyashstd = { builtin = true }
libc_api = { bid = "./apis/libc.yaml", library = "system" }
inotify_api = { bid = "./apis/inotify.yaml", library = "system" }
filesystem_api = { bid = "./apis/filesystem.yaml" }
# === file_monitor.nyash ===
using nyashstd
using libc_api
using inotify_api
using filesystem_api
static box FileMonitor {
init { watch_path, inotify_fd, watch_descriptors, callbacks }
main() {
me.watch_path = "./watched_directory"
me.watch_descriptors = new ArrayBox()
me.callbacks = map.create()
# inotify初期化Linux inotify - FFI-ABI
me.inotify_fd = inotify.init()
if me.inotify_fd < 0 {
io.println("Failed to initialize inotify")
return
}
# ディレクトリ監視設定
me.addWatch(me.watch_path)
# コールバック設定
me.setupCallbacks()
io.println("File monitor started. Watching: " + me.watch_path)
# メインループ
me.eventLoop()
}
addWatch(path) {
# 監視フラグinotify constants
local flags = inotify.IN_CREATE or inotify.IN_DELETE or
inotify.IN_MODIFY or inotify.IN_MOVED_FROM or
inotify.IN_MOVED_TO
local wd = inotify.addWatch(me.inotify_fd, path, flags)
if wd >= 0 {
array.push(me.watch_descriptors, wd)
io.println("Added watch for: " + path)
} else {
io.println("Failed to add watch for: " + path)
}
}
setupCallbacks() {
# ファイル作成コールバック
map.set(me.callbacks, "CREATE", static function(event) {
io.println("File created: " + event.name)
# ファイル情報取得Filesystem API
local file_info = filesystem.stat(event.path)
local size = file_info.size
local permissions = file_info.permissions
io.println(" Size: " + string.toString(size) + " bytes")
io.println(" Permissions: " + permissions)
})
# ファイル変更コールバック
map.set(me.callbacks, "MODIFY", static function(event) {
io.println("File modified: " + event.name)
# 変更時刻記録
local timestamp = time.now()
local formatted_time = time.format(timestamp, "%Y-%m-%d %H:%M:%S")
io.println(" Modified at: " + formatted_time)
})
# ファイル削除コールバック
map.set(me.callbacks, "DELETE", static function(event) {
io.println("File deleted: " + event.name)
# ログファイルに記録
me.logEvent("DELETE", event.name, time.now())
})
}
eventLoop() {
local buffer_size = 4096
local buffer = libc.malloc(buffer_size)
loop(true) {
# inotify eventsを読み取りblocking read
local bytes_read = libc.read(me.inotify_fd, buffer, buffer_size)
if bytes_read > 0 {
me.processEvents(buffer, bytes_read)
} else if bytes_read == 0 {
# EOF
break
} else {
# エラー
local error_code = libc.errno()
io.println("Read error: " + string.toString(error_code))
break
}
}
libc.free(buffer)
}
processEvents(buffer, bytes_read) {
local offset = 0
loop(offset < bytes_read) {
# inotify_event構造体解析libc memory operations
local event = inotify.parseEvent(buffer, offset)
# イベントタイプ判定
local event_type = me.getEventType(event.mask)
# 対応するコールバック実行
if map.has(me.callbacks, event_type) {
local callback = map.get(me.callbacks, event_type)
callback(event)
}
# 次のイベントへ
offset = offset + event.size
}
}
getEventType(mask) {
if mask and inotify.IN_CREATE {
return "CREATE"
} else if mask and inotify.IN_MODIFY {
return "MODIFY"
} else if mask and inotify.IN_DELETE {
return "DELETE"
} else if mask and inotify.IN_MOVED_FROM {
return "MOVE_FROM"
} else if mask and inotify.IN_MOVED_TO {
return "MOVE_TO"
} else {
return "UNKNOWN"
}
}
logEvent(event_type, filename, timestamp) {
local log_entry = time.format(timestamp, "%Y-%m-%d %H:%M:%S") +
" [" + event_type + "] " + filename + "\n"
# ログファイルに追記Filesystem API
filesystem.appendFile("./file_monitor.log", log_entry)
}
}
```
## 📊 MIR同時拡張による最適化効果
### 🚀 最適化前後の比較
#### **従来の実装(最適化なし)**
```mir
; 非効率:毎回関数呼び出し
%1 = ExternCall env.canvas.fillRect ["canvas", 10, 10, 100, 100, "red"]
%2 = ExternCall env.canvas.fillRect ["canvas", 110, 10, 100, 100, "blue"]
%3 = ExternCall env.canvas.fillRect ["canvas", 220, 10, 100, 100, "green"]
```
#### **MIR最適化後バッチ処理**
```mir
; 効率化:バッチ処理
%rects = ArrayConstruct [
{x: 10, y: 10, w: 100, h: 100, color: "red"},
{x: 110, y: 10, w: 100, h: 100, color: "blue"},
{x: 220, y: 10, w: 100, h: 100, color: "green"}
]
%1 = ExternCall env.canvas.fillRectBatch ["canvas", %rects]
```
#### **Effect Systemによる並列化**
```mir
; pure関数は並列実行可能
%1 = BuiltinCall string.upper ["hello"] ; effect: pure
%2 = BuiltinCall math.sin [3.14] ; effect: pure
%3 = BuiltinCall string.lower ["WORLD"] ; effect: pure
; ↑ これらは並列実行される
%4 = ExternCall env.console.log [%1] ; effect: io
%5 = ExternCall env.console.log [%2] ; effect: io
; ↑ これらは順序保持される
```
### 🎯 バックエンド別最適化
#### **WASM最適化**
```wasm
;; BIDから自動生成された最適化WASM
(func $optimized_canvas_batch
(param $canvas_id i32) (param $canvas_id_len i32)
(param $rects_ptr i32) (param $rect_count i32)
;; ループ展開による高速化
(local $i i32)
(local $rect_ptr i32)
loop $rect_loop
;; 直接メモリアクセス(境界チェック済み)
local.get $rect_ptr
i32.load ;; x
local.get $rect_ptr
i32.load offset=4 ;; y
;; ... 高速描画処理
local.get $rect_ptr
i32.const 20
i32.add
local.set $rect_ptr
local.get $i
i32.const 1
i32.add
local.tee $i
local.get $rect_count
i32.lt_u
br_if $rect_loop
end
)
```
#### **AOT最適化LLVM IR**
```llvm
; LLVM IRレベルでの最適化
define void @optimized_image_processing(i8* %image_data, i32 %width, i32 %height) {
entry:
; ベクトル化された画像処理
%0 = bitcast i8* %image_data to <16 x i8>*
; SIMD命令による並列処理
br label %loop.header
loop.header:
%i = phi i32 [ 0, %entry ], [ %i.next, %loop.body ]
%cmp = icmp ult i32 %i, %height
br i1 %cmp, label %loop.body, label %exit
loop.body:
; 16ピクセル同時処理AVX2/NEON活用
%pixel_ptr = getelementptr <16 x i8>, <16 x i8>* %0, i32 %i
%pixels = load <16 x i8>, <16 x i8>* %pixel_ptr
; ベクトル化されたエッジ検出
%edges = call <16 x i8> @vectorized_edge_detection(<16 x i8> %pixels)
store <16 x i8> %edges, <16 x i8>* %pixel_ptr
%i.next = add i32 %i, 1
br label %loop.header
exit:
ret void
}
```
## 🌟 革命的効果
### 🚀 開発者体験の向上
- **学習コスト**: 一つの構文ですべてのAPIが使える
- **IDE統合**: 全APIの統一補完・エラー検出
- **デバッグ**: 統一エラーモデルによる一貫したデバッグ体験
### ⚡ パフォーマンス向上
- **MIRレベル最適化**: すべてのAPIで同じ最適化技術
- **Effect System**: 安全な並列化・順序最適化
- **バックエンド最適化**: WASM/AOT固有の最適化
### 🌍 エコシステム拡大
- **ライブラリ統合**: 既存C/Rustライブラリの簡単統合
- **クロスプラットフォーム**: 同じコードが全環境で動作
- **標準化**: BIDによる外部API標準化
---
**🎉 これが「なんでもAPI計画」の真の実力だにゃあらゆる開発が統一された美しい構文で実現できるにゃ🚀🐱**

View File

@ -0,0 +1,563 @@
# なんでもAPI計画nyash.link × FFI-ABI × MIR 統合設計
## 🌟 革命的統合ビジョン
### 📊 現状把握
-**nyash.linkシステム**: 標準関数・モジュール管理設計完了
-**FFI-ABI仕様**: BID(Box Interface Definition)による外部API統一
-**MIR ExternCall**: 外部関数呼び出しのMIRレベル実装
- 🎯 **統合目標**: 3つのシステムを統合し「なんでもAPI」を実現
### 🚀 統合後の開発体験
```nyash
# === 単一のusing構文ですべてが使える ===
using nyashstd # 組み込み標準ライブラリ
using console_api # ブラウザConsole API (FFI-ABI)
using canvas_api # Canvas API (FFI-ABI)
using opencv_api # OpenCV外部ライブラリ (FFI-ABI)
using mylib # 自作Nyashモジュール
# 全部同じ記法で使える!
string.upper("hello") # 組み込み標準ライブラリ
console.log("Hello Nyash!") # ブラウザAPI
canvas.fillRect("game", 10, 10, 80, 60, "red") # Canvas API
opencv.loadImage("photo.jpg") # 外部ライブラリ
mylib.processData("input") # 自作モジュール
```
## 🏗️ 統合アーキテクチャ設計
### 1. 拡張nyash.link仕様
#### **依存関係タイプの統合**
```toml
# nyash.link - 全API統一管理
[project]
name = "awesome-nyash-app"
version = "1.0.0"
[dependencies]
# === 組み込み標準ライブラリ ===
nyashstd = { builtin = true }
# === FFI-ABI経由外部API ===
console_api = { bid = "./apis/console.yaml" }
canvas_api = { bid = "./apis/canvas.yaml" }
webgl_api = { bid = "./apis/webgl.yaml" }
dom_api = { bid = "./apis/dom.yaml" }
# === システムライブラリ ===
libc = { bid = "./apis/libc.yaml", library = "system" }
math_lib = { bid = "./apis/math.yaml", library = "libm" }
# === 外部共有ライブラリ ===
opencv = { bid = "./apis/opencv.yaml", library = "./libs/opencv.so" }
sqlite = { bid = "./apis/sqlite.yaml", library = "./libs/sqlite.so" }
# === Nyashモジュール従来通り ===
mylib = { path = "./src/mylib.nyash" }
utils = { path = "./src/utils.nyash" }
models = { path = "./src/models/" }
# === 将来の外部パッケージ ===
# http_client = { version = "1.0.0", registry = "nyash-pkg" }
[build]
entry_point = "./src/main.nyash"
backends = ["vm", "wasm", "aot"] # 対象バックエンド指定
```
#### **BIDファイル例**
```yaml
# apis/console.yaml - Console API定義
version: 0
metadata:
name: "Browser Console API"
description: "Standard browser console interface"
target_environments: ["browser", "node"]
interfaces:
- name: console_api.console
box: Console
namespace: console_api
methods:
- name: log
params: [ {string: message} ]
returns: void
effect: io
description: "Output message to console"
- name: warn
params: [ {string: message} ]
returns: void
effect: io
- name: error
params: [ {string: message} ]
returns: void
effect: io
# apis/canvas.yaml - Canvas API定義
version: 0
interfaces:
- name: canvas_api.canvas
box: Canvas
namespace: canvas_api
methods:
- name: fillRect
params:
- {string: canvas_id}
- {i32: x}
- {i32: y}
- {i32: width}
- {i32: height}
- {string: color}
returns: void
effect: io
- name: fillText
params:
- {string: canvas_id}
- {string: text}
- {i32: x}
- {i32: y}
- {string: font}
- {string: color}
returns: void
effect: io
```
### 2. 統合名前空間レジストリ
#### **UniversalNamespaceRegistry設計**
```rust
// 新ファイル: src/registry/universal.rs
use crate::stdlib::BuiltinStdlib;
use crate::bid::BidDefinition;
use crate::module::ExternalModule;
pub struct UniversalNamespaceRegistry {
/// 組み込み標準ライブラリ
builtin: Arc<BuiltinStdlib>,
/// FFI-ABI経由の外部API
ffi_apis: HashMap<String, Arc<BidDefinition>>,
/// Nyashモジュール
nyash_modules: HashMap<String, Arc<ExternalModule>>,
/// using importsファイル別
using_imports: Arc<RwLock<HashMap<String, UsingContext>>>,
}
#[derive(Debug, Clone)]
pub struct UsingContext {
pub builtin_imports: Vec<String>, // ["nyashstd"]
pub ffi_imports: Vec<String>, // ["console_api", "canvas_api"]
pub module_imports: Vec<String>, // ["mylib", "utils"]
pub file_id: String,
}
impl UniversalNamespaceRegistry {
pub fn new(nyash_link: &NyashLink) -> Result<Self, RegistryError> {
let mut registry = UniversalNamespaceRegistry {
builtin: Arc::new(BuiltinStdlib::new()),
ffi_apis: HashMap::new(),
nyash_modules: HashMap::new(),
using_imports: Arc::new(RwLock::new(HashMap::new())),
};
// nyash.linkからFFI-ABI定義読み込み
registry.load_ffi_apis(nyash_link)?;
// Nyashモジュール読み込み
registry.load_nyash_modules(nyash_link)?;
Ok(registry)
}
/// 統合using文処理
pub fn execute_using(&mut self, namespace_name: &str, file_id: &str)
-> Result<(), RuntimeError> {
let context = self.using_imports
.write().unwrap()
.entry(file_id.to_string())
.or_insert_with(|| UsingContext {
builtin_imports: Vec::new(),
ffi_imports: Vec::new(),
module_imports: Vec::new(),
file_id: file_id.to_string(),
});
// 組み込み標準ライブラリ
if self.builtin.has_namespace(namespace_name) {
if !context.builtin_imports.contains(&namespace_name.to_string()) {
context.builtin_imports.push(namespace_name.to_string());
}
return Ok(());
}
// FFI-ABI API
if self.ffi_apis.contains_key(namespace_name) {
if !context.ffi_imports.contains(&namespace_name.to_string()) {
context.ffi_imports.push(namespace_name.to_string());
}
return Ok(());
}
// Nyashモジュール
if self.nyash_modules.contains_key(namespace_name) {
if !context.module_imports.contains(&namespace_name.to_string()) {
context.module_imports.push(namespace_name.to_string());
}
return Ok(());
}
Err(RuntimeError::UndefinedNamespace(namespace_name.to_string()))
}
/// 統合関数解決
pub fn resolve_call(&self, file_id: &str, path: &[String])
-> Result<CallTarget, RuntimeError> {
if path.len() != 2 {
return Err(RuntimeError::InvalidQualifiedName(path.join(".")));
}
let box_name = &path[0];
let method_name = &path[1];
if let Ok(imports) = self.using_imports.read() {
if let Some(context) = imports.get(file_id) {
// 1. 組み込み標準ライブラリ検索
for namespace in &context.builtin_imports {
if let Some(target) = self.builtin.resolve_call(namespace, box_name, method_name) {
return Ok(CallTarget::Builtin(target));
}
}
// 2. FFI-ABI API検索
for namespace in &context.ffi_imports {
if let Some(bid) = self.ffi_apis.get(namespace) {
if let Some(target) = bid.resolve_method(box_name, method_name) {
return Ok(CallTarget::FfiAbi(target));
}
}
}
// 3. Nyashモジュール検索
for namespace in &context.module_imports {
if let Some(module) = self.nyash_modules.get(namespace) {
if let Some(target) = module.resolve_method(box_name, method_name) {
return Ok(CallTarget::NyashModule(target));
}
}
}
}
}
Err(RuntimeError::UndefinedMethod(format!("{}.{}", box_name, method_name)))
}
}
#[derive(Debug)]
pub enum CallTarget {
Builtin(BuiltinMethodTarget),
FfiAbi(FfiMethodTarget),
NyashModule(NyashMethodTarget),
}
```
### 3. MIRレベル統合
#### **MIR命令拡張**
```rust
// src/mir/instruction.rs拡張
#[derive(Debug, Clone)]
pub enum MirInstruction {
// 既存命令...
// === 統合関数呼び出し ===
/// 組み込み標準ライブラリ呼び出し
BuiltinCall {
target: String, // "string.upper"
args: Vec<ValueId>,
result: ValueId,
effect: Effect,
},
/// FFI-ABI外部API呼び出し
ExternCall {
interface: String, // "console_api.console"
method: String, // "log"
args: Vec<ValueId>,
result: Option<ValueId>,
effect: Effect,
bid_signature: BidMethodSignature,
},
/// Nyashモジュール関数呼び出し
ModuleCall {
module: String, // "mylib"
function: String, // "processData"
args: Vec<ValueId>,
result: ValueId,
effect: Effect,
},
}
#[derive(Debug, Clone)]
pub enum Effect {
Pure, // 副作用なし、並び替え可能
Mut, // 同リソース内で順序保持
Io, // プログラム順序保持
Control, // 制御フロー影響
}
```
#### **MIR生成統合**
```rust
// src/mir/builder.rs拡張
impl MirBuilder {
pub fn build_unified_call(&mut self, target: CallTarget, args: Vec<ValueId>)
-> Result<ValueId, MirError> {
match target {
CallTarget::Builtin(builtin_target) => {
let result = self.new_value_id();
self.emit(MirInstruction::BuiltinCall {
target: builtin_target.qualified_name(),
args,
result,
effect: builtin_target.effect(),
});
Ok(result)
},
CallTarget::FfiAbi(ffi_target) => {
let result = if ffi_target.returns_void() {
None
} else {
Some(self.new_value_id())
};
self.emit(MirInstruction::ExternCall {
interface: ffi_target.interface_name(),
method: ffi_target.method_name(),
args,
result,
effect: ffi_target.effect(),
bid_signature: ffi_target.signature().clone(),
});
result.ok_or(MirError::VoidReturn)
},
CallTarget::NyashModule(module_target) => {
let result = self.new_value_id();
self.emit(MirInstruction::ModuleCall {
module: module_target.module_name(),
function: module_target.function_name(),
args,
result,
effect: Effect::Io, // デフォルト
});
Ok(result)
},
}
}
}
```
### 4. バックエンド統合実装
#### **VM実行統合**
```rust
// src/backend/vm.rs拡張
impl VmBackend {
pub fn execute_instruction(&mut self, instr: &MirInstruction)
-> Result<(), VmError> {
match instr {
MirInstruction::BuiltinCall { target, args, result, .. } => {
let evaluated_args = self.evaluate_args(args)?;
let output = self.builtin_executor.call(target, evaluated_args)?;
self.set_value(*result, output);
Ok(())
},
MirInstruction::ExternCall { interface, method, args, result, bid_signature, .. } => {
// VM環境ではスタブ実装
let evaluated_args = self.evaluate_args(args)?;
let output = self.extern_stub.call(interface, method, evaluated_args, bid_signature)?;
if let Some(res_id) = result {
self.set_value(*res_id, output);
}
Ok(())
},
MirInstruction::ModuleCall { module, function, args, result, .. } => {
let evaluated_args = self.evaluate_args(args)?;
let output = self.module_executor.call(module, function, evaluated_args)?;
self.set_value(*result, output);
Ok(())
},
// 既存命令処理...
}
}
}
```
#### **WASM生成統合**
```rust
// src/backend/wasm/codegen.rs拡張
impl WasmCodegen {
pub fn generate_instruction(&mut self, instr: &MirInstruction)
-> Result<(), WasmError> {
match instr {
MirInstruction::BuiltinCall { target, args, result, .. } => {
// 組み込み関数は直接実装
self.generate_builtin_call(target, args, *result)
},
MirInstruction::ExternCall { interface, method, args, bid_signature, .. } => {
// BIDから自動生成されたWASM import呼び出し
let import_name = format!("{}_{}",
interface.replace(".", "_"),
method
);
self.generate_extern_call(&import_name, args, bid_signature)
},
MirInstruction::ModuleCall { module, function, args, result, .. } => {
// 内部関数呼び出し
let function_name = format!("{}_{}", module, function);
self.generate_function_call(&function_name, args, *result)
},
}
}
/// BIDからWASM RuntimeImports自動生成
pub fn generate_runtime_imports(&mut self, bid_definitions: &[BidDefinition])
-> Result<String, WasmError> {
let mut imports = String::new();
for bid in bid_definitions {
for interface in &bid.interfaces {
for method in &interface.methods {
let import_name = format!("{}_{}",
interface.name.replace(".", "_"),
method.name
);
let signature = self.bid_to_wasm_signature(&method.params, &method.returns)?;
imports.push_str(&format!(
"(import \"env\" \"{}\" {})\n",
import_name, signature
));
}
}
}
Ok(imports)
}
}
```
#### **AOT生成統合**
```rust
// src/backend/aot/compiler.rs拡張
impl AotCompiler {
pub fn compile_instruction(&mut self, instr: &MirInstruction)
-> Result<(), AotError> {
match instr {
MirInstruction::ExternCall { interface, method, args, bid_signature, .. } => {
// LLVM IR外部関数宣言生成
let extern_func_name = format!("{}_{}",
interface.replace(".", "_"),
method
);
let signature = self.bid_to_llvm_signature(bid_signature)?;
self.declare_external_function(&extern_func_name, &signature)?;
self.generate_call(&extern_func_name, args)?;
Ok(())
},
// その他の命令処理...
}
}
}
```
## 🎯 段階的実装戦略
### Phase 0: 基盤統合2-3週間
1. **UniversalNamespaceRegistry実装** - 全API統一管理
2. **nyash.link拡張** - BID依存関係サポート
3. **統合using文** - 3種類のAPI統一インポート
### Phase 1: FFI-ABI統合3-4週間
1. **BID読み込み機能** - YAML解析・検証
2. **MIR ExternCall統合** - FFI-ABI→MIR変換
3. **WASM RuntimeImports自動生成** - BID→WASM import
### Phase 2: 完全統合4-6週間
1. **全バックエンド対応** - VM/WASM/AOT統合実装
2. **エラーハンドリング統合** - 統一エラーモデル
3. **パフォーマンス最適化** - 高速名前解決
## 🧪 統合テスト戦略
### 基本統合テスト
```nyash
# test_universal_integration.nyash
using nyashstd
using console_api
using mylib
# 3種類のAPIが同じように使える
assert(string.upper("test") == "TEST") # 組み込み
console.log("Integration test successful") # FFI-ABI
assert(mylib.process("data") == "processed") # Nyash
```
### FFI-ABI統合テスト
```nyash
# test_ffi_abi_integration.nyash
using canvas_api
# Canvas API経由での描画
canvas.fillRect("game-canvas", 10, 10, 100, 100, "red")
canvas.fillText("game-canvas", "Score: 100", 10, 30, "16px Arial", "white")
```
## 🌟 期待される革命的効果
### 🚀 開発者体験
- **統一API**: 組み込み・外部・自作すべて同じ書き方
- **IDE補完**: すべてのAPIが`ny`で補完される
- **エラー処理**: 統一エラーモデルで一貫性
### 🏗️ アーキテクチャ
- **MIRレベル統合**: 全バックエンドで同じパフォーマンス最適化
- **Effect System**: pure/mut/io/controlによる安全性保証
- **言語非依存**: BIDによる外部ライブラリ標準化
### 🌍 エコシステム
- **なんでもAPI**: あらゆる外部ライブラリがNyashから使える
- **バックエンド統一**: 同じコードがVM/WASM/AOTで動作
- **将来拡張**: パッケージレジストリでBID共有
---
**🎉 この統合設計で、Nyashが真に「なんでもできる」モダン言語になるにゃ🚀🐱**

View File

@ -0,0 +1,10 @@
# NyIR ドキュメント索引
- 仕様(骨子): `spec.md`
- フェーズ計画Phase 9.10: `../予定/native-plan/issues/phase_9_10_nyir_spec.md`
- BIDサンプル: `bid_samples/`console.yaml / canvas.yaml
- 計画全体Copilot用フルテキスト 9.7以降): `../予定/native-plan/copilot_issues.txt`
- 関連: ABI/BIDドラフトは `../予定/native-plan/box_ffi_abi.md`
補足:
- NyIR Core25命令は凍結。拡張は NyIR-Extexceptions/concurrency/atomicsで段階導入。

View File

@ -0,0 +1,26 @@
version: 0
interfaces:
- name: env.canvas
box: Canvas
methods:
- name: fillRect
params:
- { string: canvas_id }
- { i32: x }
- { i32: y }
- { i32: w }
- { i32: h }
- { string: color }
returns: void
effect: io
- name: fillText
params:
- { string: canvas_id }
- { string: text }
- { i32: x }
- { i32: y }
- { string: font }
- { string: color }
returns: void
effect: io

View File

@ -0,0 +1,10 @@
version: 0
interfaces:
- name: env.console
box: Console
methods:
- name: log
params:
- { string: msg }
returns: void
effect: io

View File

@ -0,0 +1,70 @@
# Phase 9.10: NyIR v1 仕様・フォーマット・検証器公開IRの確立
目的
- NyashのMIRを公開IRNyIR v1として凍結し、あらゆるフロントエンド/バックエンドの共通契約とする。
- 仕様・テキスト/バイナリフォーマット・厳格検証器・ツール群を整備し、移植性と一貫性を保証する。
成果物Deliverables
- 仕様書: `docs/nyir.md`(命令仕様/効果/未定義なし/検証ルール/等価変換指針)
- フォーマット: `.nyir`(テキスト), `.nybc`(バイナリ)
- 検証器: `nyir-verify`CLI/ライブラリ)
- 変換/実行ツール:
- `nyashel -S`Nyash→NyIRダンプ
- `nyir-run`NyIRインタプリタ
- 参考: `nyir-ll`NyIR→LLVM IR、Phase 10で拡張
- Golden NyIR: `golden/*.nyir`代表サンプルを固定、CIで全バックエンド一致を検証
仕様の要点NyIR v1
- 命令セット: 25命令Tier-0/1/2を凍結
- Tier-0: Const, BinOp, Compare, Branch, Jump, Phi, Call, Return
- Tier-1: NewBox, BoxFieldLoad, BoxFieldStore, BoxCall, Safepoint, RefGet, RefSet, WeakNew, WeakLoad, WeakCheck, Send, Recv
- Tier-2: TailCall, Adopt, Release, MemCopy, AtomicFence
- 効果Effects: pure / mut / io / control再順序化規則を明文化
- 所有フォレスト: 強参照の森strong in-degree ≤ 1、強循環禁止、weakは非伝播
- Weak: 失効時の挙動を決定WeakLoad=null / WeakCheck=false、世代タグ設計を想定
- Bus: ローカルは順序保証、リモートは at-least-onceまたは選択可能
- 未定義動作なし: 各命令の事前条件/失敗時挙動を明示
- バージョニング: `nyir{major.minor}`、featureビットで拡張告知
テキスト形式(.nyir
- 人間可読・差分レビュー向け
- 構造: moduleヘッダ / const pool / functionsblocks, instrs
- コメント/メタデータ/featureビットを扱える簡潔な構文
バイナリ形式(.nybc
- セクション化: header / features / const pool / functions / metadata
- エンコード: LEB128等の可変長を採用、識別子はstring table参照
- 将来の後方互換に備えた保守的設計
検証器Verifier
- 検査: 所有森/強循環/weak規則/効果整合/到達性/終端性/Phi入力整合
- 失敗時は明確なエラーを返し、ロード拒否
- CLI/ライブラリの二態(コンパイラ/実行系どちらからも利用)
Golden / Differential テスト
- `golden/*.nyir` を固定し、interp/vm/wasm/jit/llvm順次で出力一致をCIで検証
- 弱失効/分割fini/境界条件系を重点的に含める
タスクCopilot TODO
1) 仕様スケルトン: `docs/nyir.md` ひな形生成(命令/効果/検証/等価変換の目次)
2) `.nyir` パーサ/プリンタ(最小)
3) `.nybc` エンコーダ/デコーダ(最小)
4) `nyir-verify`(所有森/効果/Phi/到達/終端の基本チェック)
5) `nyashel -S` をNyIR出力対応に既存MIRダンプ経路から移行
6) Goldenサンプル作成3〜5本CIワークフロー雛形
受け入れ基準Acceptance
- 代表サンプルが `.nyir` で表現・検証・実行可能(`nyir-run`
- `.nybc` 読み書き往復で等価
- CIでinterp/vm/wasmの結果一致最小ケース
依存/関連
- 8.5: 25命令の確定仕様
- 9.7: ExternCall/ABINyIRにもmethodードor外部呼を表現。v1ではExternCallは拡張セクションで可
- 10.x: NyIR→LLVM IR別Phase
リスク
- 仕様凍結の硬直化 → 拡張はfeatureビット拡張セクションへ
- 実装の重複 → Verifier/フォーマットは共有ライブラリ化
最終更新: 2025-08-14

View File

@ -0,0 +1,126 @@
# NyIR v1 Specification (Draft Skeleton)
Purpose
- Define NyIR (public intermediate representation) as the portable contract for all frontends/backends.
- Freeze the 25-instruction set, effects, ownership forest, weak semantics, and bus contract.
Status
- Version: nyir1.0 (draft)
- Change policy: backward-compatible extensions via feature bits; no undefined behavior.
1. Instruction Set (26) — Semantic Summary
- Tier-0: Const, BinOp, Compare, Branch, Jump, Phi, Call, Return
- Tier-1: NewBox, BoxFieldLoad, BoxFieldStore, BoxCall, ExternCall, Safepoint, RefGet, RefSet, WeakNew, WeakLoad, WeakCheck, Send, Recv
- Tier-2: TailCall, Adopt, Release, MemCopy, AtomicFence
For each instruction (to be filled):
- Semantics: preconditions, side-effects, failure behavior
- Effects: pure/mut/io/control
- Verification: structural/formal checks
- Example: minimal snippet
2. Effects Model
- pure: no observable side effects; can reorder with pure
- mut: mutates owned state; preserve order per resource
- io: interacts with outside world; preserve program order
- control: affects control flow/terminators
3. Ownership Forest
- Strong edges form a forest (strong in-degree ≤ 1).
- No strong cycles.
- Weak edges do not propagate ownership.
- Adopt/Release rules; Safepoint and split-fini notes.
4. Weak Semantics
- Representation: {ptr, generation}
- WeakLoad: returns null if generation mismatch
- WeakCheck: returns false if invalid
- O(1) on-access validation
5. Bus Contract
- Local: in-order delivery
- Remote: at-least-once (or selectable); specify ordering/dup policy
6. Formats
- Text .nyir: human-readable; module header, features, const pool, functions (blocks, instrs)
- Binary .nybc: sectioned; header, features, const pool, functions, metadata; varint encodings
- Feature bits and extension sections for evolution
7. Verification
- Program well-formedness: reachability, termination, dominance
- Phi input consistency
- Effects ordering constraints
- Ownership forest & weak/generation rules
- Bus safety checks
8. External Calls (Core)
- ExternCall: Interface to external libraries as Everything is Box principle
- Format: ExternCall { dst, iface_name, method_name, args }
- Effect annotation required (pure/mut/io/control)
- BID (Box Interface Definition) provides external API contracts
9. Mapping Guidelines
- WASM: imports, memory rules, (ptr,len) strings
- VM: function table mapping
- LLVM: declare signatures; effect to attributes (readonly/readnone, etc.)
10. Golden/Differential Testing
- Golden .nyir corpus; cross-backend consistency (interp/vm/wasm/llvm)
11. Versioning & Compatibility
- nyir{major.minor}; feature negotiation and safe fallback
12. Glossary
- Box, Effect, Ownership forest, Weak, Safepoint, Bus, Feature bit
Appendix
- Minimal examples (to be added)
- Rationale notes
------------------------------------------------------------
NyIR-Ext拡張セット
------------------------------------------------------------
目的
- NyIR Core26命令は基本セマンティクス凍結。外部世界接続ExternCallを含む基本機能確立。
- 拡張は言語固有機能に限定:「例外」「軽量並行/非同期」「アトミック」の3領域を段階追加。
- Core機能: すべての言語で必要な基本セマンティクス制御フロー・Box操作・外部呼び出し
- Extension機能: 特定言語でのみ必要な高級機能(例外処理・並行処理・アトミック操作)
Ext-1: 例外/アンワインドexceptions
- 命令(案):
- Throw(value)
- TryBegin
- TryEnd(handlers=[type:block])
- 効果: control脱出。mut/io と混在する場合は当該効果も従属。
- 検証: Try の整合(入れ子/終端)、未捕捉 Throw のスコープ明示、no-throw 関数属性の尊重。
- バックエンド指針:
- LLVM: 言語EH or setjmp/longjmp 系へ lower
- WASM: v0は例外未使用なら「エラー戻り値」へ降格no-exception モード)
Ext-2: 軽量並行/非同期concurrency
- 命令(案):
- Spawn(fn, args...)
- Join(handle)
- Await(task|event) // または Wait
- 効果: ioスケジューラ相互作用 control待機・解除
- 検証: Join/Spawn のライフサイクル均衡、待機の整合(任意でデッドロック静的ヒント)。
- バックエンド指針:
- LLVM: pthread/std::thread/独自ランタイム
- WASM: スレッド未使用ならランループ/Promise/MessageChannel 等で近似
Ext-3: アトミックatomics
- 命令(案):
- AtomicRmw(op, addr, val, ordering=seq_cst)
- CAS(addr, expect, replace, ordering=seq_cst)
- 既存の AtomicFence は維持。
- 効果: mutアトミック副作用。必要に応じて atomic/volatile フラグを effect/属性で付与。
- バックエンド指針:
- LLVM: `atomicrmw`, `cmpxchg`
- WASM: Threads 提案が前提。未サポート環境では未実装 or 疑似ロック(デモ用途)
備考
- 可変引数は slice 表現で代替IR 追加不要)。
- クロージャ捕捉は Box + env フィールド + BoxCall で表現IR 追加不要)。
- 動的言語(辞書/配列/プロトタイプは標準Boxstdで受けるIR 追加不要)。
- 関数属性に「エラー戻り値モード/no-exception」などのメタを付与し、例外禁止環境へも対応する。

View File

@ -0,0 +1,44 @@
# NyIR を共通交換フォーマットにする計画All Languages → NyIR → All Targets
目的Goal
- あらゆる言語のプログラムを NyIR= Nyash MIR の公開版へ落とし、そこから任意の実行形態WASM/LLVM/VM/他言語)に変換する。
- 最適化は二の次。まずは意味保存semantics-preservingを最優先で実現し、可搬性と一貫性を担保する。
中核方針Core Policy
- NyIR Core26命令は基本セマンティクス凍結。ExternCallによる外部世界接続を含む。
- 拡張は NyIR-Extexceptions/concurrency/atomicsで言語固有機能を段階導入。
- Everything is Box哲学: 外部ライブラリもBIDによりBox統一インターフェースで利用。
- 仕様の正本は `docs/nyir/spec.md` に集約CoreExt
必要拡張Minimal Additions
- 例外/アンワインドThrow/TryBegin/TryEnd
- 軽量並行/非同期Spawn/Join/Await
- アトミックAtomicRmw/CAS + ordering
→ 詳細は `docs/nyir/spec.md` の NyIR-Ext 参照
フロントエンド指針Language → NyIR
- C/C++/Rust: 既存IRLLVM IR経由または専用パーサでサブセットから対応
- 例外→NyIR-Ext exceptions or エラー戻り値
- スレッド→Spawn/Join、atomic→CAS/RMW
- Java/Kotlin: JVM bytecode から構造復元→NyIR例外/スレッド/同期をExtへ
- Python/JS/TS: AST→NyIR。辞書/配列/プロトタイプは標準Boxへ写像、例外/非同期はExtへ
- Go: panic/recover→exceptions、goroutine→Spawn/Join へ写像(将来)
バックエンド指針NyIR → Target
- WASM: 同期・非例外・非スレッドの最小路線から段階対応Exceptions/Threads提案に合わせ拡張
- LLVM: 例外/スレッド/アトミックが揃っているため先行実装が容易
- VM: 仕様の正しさ検証の基準(簡易実装でも良い)
- 他言語(ソース生成): 可読性/慣用性は課題だが、機械的変換は可能(優先度低)
検証計画Golden/Diff
- Cサブセット→NyIR→C/WASM例外なし・CASあり
- Python/JSサブセット→NyIR→WASM辞書/例外/非同期のサブセット)
- JVM系→NyIR→JVM bytecode例外/スレッド)
- Rustサブセット→NyIR→LLVM所有・weakの温存
→ Golden NyIR を用い、interp/vm/wasm/llvm で出力一致をCI検証
関連リンク
- NyIR 仕様: `spec.md`
- ABI/BID: `../予定/native-plan/box_ffi_abi.md`
- 9.10 タスクCopilot向け: `../予定/native-plan/issues/phase_9_10_nyir_spec.md`

View File

@ -0,0 +1,306 @@
# 🚨 緊急修正 Issue: Everything is Box設計でのclone_box()問題根本解決
## 📋 Issue概要
**優先度**: 🔴 **URGENT** - 全ステートフルBoxSocketBox, P2PBox等に影響
**期間**: 2-3日
**担当**: Copilot様
## 🎯 問題の核心
**ユーザー指摘**: 「いや 単純に rustの使い方 へたなだけじゃーーい
**Gemini先生確認**: Everything is Box設計は正しい。問題は `clone_box()` を使うべきでない場所で使っていること
### 🚨 真犯人特定済み3箇所
1. **`src/interpreter/core.rs:366`** - `resolve_variable()`
2. **`src/instance.rs:275`** - `get_field()`
3. **`src/interpreter/expressions.rs:779`** - `execute_field_access()`
### 💥 現在の症状
```nyash
me.server.bind("127.0.0.1", 8080) // ✅ SocketBox ID=10, is_server=true
me.server.isServer() // ❌ SocketBox ID=19, is_server=false (別インスタンス!)
```
## 🛠️ 解決策Arc<dyn NyashBox>への段階的移行
**Gemini先生推奨**: `Box<dyn NyashBox>``Arc<dyn NyashBox>` で参照共有実現
---
## 📋 段階的修正手順Copilot実装ガイド
### **Phase 1: 型エイリアス導入**
#### 1.1 `src/box_trait.rs`に型エイリアス追加
```rust
// ファイル先頭のuse文の後に追加
use std::sync::Arc;
// 新しい型エイリアス - 将来的にBox<dyn NyashBox>を全て置き換える
pub type SharedNyashBox = Arc<dyn NyashBox>;
```
#### 1.2 NyashBoxトレイトに新メソッド追加
```rust
// src/box_trait.rs のNyashBoxトレイト内に追加
pub trait NyashBox: BoxCore + Debug {
// 既存メソッド...
/// Arc参照を返す新しいcloneメソッド参照共有
fn clone_arc(&self) -> SharedNyashBox {
Arc::new(self.clone())
}
/// 従来のclone_box互換性維持のため残す
fn clone_box(&self) -> Box<dyn NyashBox>;
}
```
### **Phase 2: データ構造変更**
#### 2.1 `src/instance.rs` - InstanceBox修正
```rust
// InstanceBox構造体のfields型変更
pub struct InstanceBox {
pub base: BoxBase,
pub class_name: String,
pub fields: Arc<Mutex<HashMap<String, SharedNyashBox>>>, // ← Box→Arc
// 他フィールドはそのまま
}
// コンストラクタ修正
impl InstanceBox {
pub fn new(class_name: String, fields: Vec<String>) -> Self {
let mut field_map: HashMap<String, SharedNyashBox> = HashMap::new();
for field in fields {
field_map.insert(field, Arc::new(VoidBox::new())); // Box::new → Arc::new
}
InstanceBox {
base: BoxBase::new(),
class_name,
fields: Arc::new(Mutex::new(field_map)),
}
}
}
```
#### 2.2 `src/interpreter/core.rs` - NyashInterpreter修正
```rust
// NyashInterpreter構造体の変数管理型変更
pub struct NyashInterpreter {
// 既存フィールド...
pub local_vars: HashMap<String, SharedNyashBox>, // ← Box→Arc
pub outbox_vars: HashMap<String, SharedNyashBox>, // ← Box→Arc
// 他フィールドはそのまま
}
```
### **Phase 3: 問題箇所修正(真犯人退治)**
#### 3.1 `src/interpreter/core.rs:366` - resolve_variable修正
```rust
// 修正前:
let cloned_value = local_value.clone_box(); // ← 新インスタンス作成(問題)
return Ok(cloned_value);
// 修正後:
pub(super) fn resolve_variable(&self, name: &str) -> Result<SharedNyashBox, RuntimeError> {
// ... 既存のログ処理
// 2. local変数をチェック
if let Some(local_value) = self.local_vars.get(name) {
eprintln!("🔍 DEBUG: Found '{}' in local_vars", name);
// 🔧 修正clone_box() → Arc::clone() で参照共有
let shared_value = Arc::clone(local_value);
core_deep_debug_log(&format!("✅ RESOLVE_VARIABLE shared reference: {} id={}",
name, shared_value.box_id()));
return Ok(shared_value);
}
// 残りの処理も同様にSharedNyashBoxを返すよう修正
// ...
}
```
#### 3.2 `src/instance.rs:275` - get_field修正
```rust
// 修正前:
pub fn get_field(&self, field_name: &str) -> Option<Box<dyn NyashBox>> {
self.fields.lock().unwrap().get(field_name).map(|v| v.clone_box()) // ← 複製(問題)
}
// 修正後:
pub fn get_field(&self, field_name: &str) -> Option<SharedNyashBox> {
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)
}
```
#### 3.3 `src/interpreter/expressions.rs:779` - execute_field_access修正
```rust
// 修正前:
let field_value = instance.get_field(field) // get_fieldがBoxを返していた
// 修正後:
fn execute_field_access(&mut self, object: &ASTNode, field: &str)
-> Result<SharedNyashBox, RuntimeError> { // ← 戻り値型変更
// オブジェクト評価
let obj_value = self.execute_expression(object)?;
if let Some(instance) = obj_value.as_any().downcast_ref::<InstanceBox>() {
// フィールドアクセス - get_fieldがArc参照を返すように修正済み
let field_value = instance.get_field(field)
.ok_or_else(|| RuntimeError::InvalidOperation {
message: format!("Field '{}' not found in {}", field, instance.class_name),
})?;
eprintln!("✅ FIELD ACCESS: Returning shared reference id={}", field_value.box_id());
Ok(field_value) // Arc参照を返す
} else {
// エラー処理...
}
}
```
### **Phase 4: set_field修正**
#### 4.1 `src/instance.rs` - set_field修正
```rust
// set_fieldも引数の型をSharedNyashBoxに変更
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 {
Err(format!("Field '{}' does not exist in {}", field_name, self.class_name))
}
}
```
---
## 🧪 テスト方法
### テストファイル作成
```bash
# テスト用Nyashコード
echo 'static box Main {
init { server }
main() {
me.server = new SocketBox()
print("=== Before bind ===")
print("isServer: " + me.server.isServer())
me.server.bind("127.0.0.1", 8080)
print("=== After bind ===")
print("isServer: " + me.server.isServer()) // これがtrueになれば修正成功
return me.server.isServer()
}
}' > test_arc_fix.nyash
```
### 実行・検証
```bash
# ビルド・実行
cargo build --release
./target/release/nyash test_arc_fix.nyash
# 期待される結果:
# === Before bind ===
# isServer: false
# === After bind ===
# isServer: true ← これが true になれば成功!
```
---
## 📋 修正対象ファイル一覧
### 必須修正ファイル
1. **`src/box_trait.rs`** - 型エイリアス・clone_arcメソッド追加
2. **`src/instance.rs`** - InstanceBox構造体・get_field・set_field修正
3. **`src/interpreter/core.rs`** - NyashInterpreter・resolve_variable修正
4. **`src/interpreter/expressions.rs`** - execute_field_access修正
### 追加修正が必要になる可能性があるファイル
- `src/interpreter/statements.rs` - 代入処理
- `src/interpreter/objects.rs` - オブジェクト生成処理
- その他 `Box<dyn NyashBox>` を使用している箇所
## 🎯 修正完了条件
### ✅ 成功条件
1. **テスト成功**: `test_arc_fix.nyash``isServer: true` が表示される
2. **コンパイル成功**: `cargo build --release` でエラーなし
3. **既存テスト成功**: `cargo test` でテスト通過
4. **デバッグログ確認**: 同一SocketBox IDが維持される
### 🔍 確認ポイント
- SocketBoxログで同じIDが表示されるID変化なし
- 状態が正しく保持されるbind後にisServer=true
- メモリリークが発生しないArc参照カウント正常
---
## 💡 実装のコツCopilot向け
### 段階的実装推奨
1. **まず型エイリアス追加** → コンパイルエラー確認
2. **データ構造を段階的に変更** → 各ファイル別に修正
3. **最後に問題の3箇所修正** → 動作テスト実行
### よくあるコンパイルエラー対処
- **型不一致**: `Box<dyn NyashBox>``SharedNyashBox` の混在
→ 段階的に `SharedNyashBox` に統一
- **ライフタイム問題**: Arc使用により大部分が解決
- **メソッドシグネチャ不一致**: 戻り値型を `SharedNyashBox` に変更
### デバッグのポイント
- 修正前後でSocketBox IDが同じになることを確認
- `Arc::strong_count()` で参照数確認(デバッグ用)
---
## 🚀 期待される効果
### 🎉 修正後の動作
```nyash
me.server.bind("127.0.0.1", 8080) // ✅ SocketBox ID=10, is_server=true
me.server.isServer() // ✅ SocketBox ID=10, is_server=true (同じインスタンス!)
```
### 📈 影響範囲
- **全ステートフルBox**: SocketBox, P2PBox, HTTPServerBox等が正常動作
- **全フィールドアクセス**: `obj.field` で状態保持
- **全変数アクセス**: `me`変数で状態保持
- **性能向上**: 不要なclone処理削減
### 🏆 Everything is Box設計完成
ユーザー指摘通り、設計は正しく、**Rustの所有権システムを正しく使う**ことで、真の「Everything is Box」が実現されます
---
**実装担当**: Copilot様
**レビュー**: Claude & User
**完了目標**: 2-3日以内