fix(joinir): Phase 241-EX - Remove hardcoded 'sum' check from Pattern3

Remove legacy hardcoded 'sum' carrier validation that was blocking
array_filter patterns with different accumulator names (e.g., 'out').

Before: Pattern3 required carrier named 'sum' to exist
After: Pattern3 uses carrier_info generically (any carrier name works)

Test results:
- phase49_joinir_array_filter_smoke: PASS 
- phase49_joinir_array_filter_fallback: PASS 
- phase49_joinir_array_filter_ab_comparison: PASS 
- Full suite: 909/909 PASS, 0 FAIL

Also: Archive old roadmap documentation (67k lines moved to docs/archive/)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-11 00:48:42 +09:00
parent a7dbc15878
commit 811dfebf98
387 changed files with 106 additions and 5551 deletions

View File

@ -0,0 +1,243 @@
# 🌟 Nyash アーキテクチャ再設計提案
Status: Historical
*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,6 @@
# Nyash Concurrency — Box Model (Proposal, docs-only)
Status: Historical
(内容は `docs/development/proposals/concurrency/boxes.md` から移動)

View File

@ -0,0 +1,6 @@
# 純粋関数型[]ブロック vs 通常{}ブロック設計案
Status: Historical
(内容は `docs/development/proposals/ideas/language/pure-functional-blocks.md` から移動)

View File

@ -0,0 +1,125 @@
# Instance v2 統一レジストリ設計メモ(提案)
Status: Historical
目的: ユーザー定義 / ビルトイン / プラグインの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,81 @@
# Issue 62 Update Proposal: Enable String Constants in WASM Backend First
Status: Historical
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,86 @@
# PoC Plan: TypeOp / WeakRef / Barrier Unification
Status: Historical
Status: Draft (PoC design)
Last Updated: 2025-08-23
## Goals
- Reduce instruction surface without losing expressiveness or performance.
- Provide a feature-gated PoC to validate that consolidation is safe and measurable.
## Scope
- Unify TypeCheck + Cast → TypeOp (single instruction)
- Unify WeakNew + WeakLoad → WeakRef (single instruction)
- Unify BarrierRead + BarrierWrite → Barrier (single instruction)
## Out of Scope (PoC)
- Remap language syntax or external APIs
- Remove legacy instructions permanently (kept behind feature flags)
## Feature Flags (Cargo)
Note: 2025-08 Phase 9.78h 時点で統合命令はデフォルトとなり、以下のflagsは非推奨no-opだよ
- `mir_typeop_poc`: Builderは常に`TypeOp(Check/Cast)`を生成(旧`TypeCheck/Cast`は使わない)。
- `mir_refbarrier_unify_poc`: Builderは常に`WeakRef/Barrier`を生成(旧`WeakNew/WeakLoad/BarrierRead/Write`は使わない)。
互換性のため、Optimizerに旧命令→統合命令への正規化パスPass 0が入っているにゃ。
## Mapping (Current → PoC)
- TypeCheck { value, expected_type } → TypeOp { op: Check, value, type } (bool)
- Cast { value, target_type } → TypeOp { op: Cast, value, type } (value)
- WeakNew { dst, box_val } → WeakRef { op: New, dst, box_val }
- WeakLoad { dst, weak_ref } → WeakRef { op: Load, dst, weak_ref }
- BarrierRead { ptr } → Barrier { op: Read, ptr }
- BarrierWrite { ptr } → Barrier { op: Write, ptr }
## Implementation Steps
1) MIR instruction additions
- Add TypeOp/WeakRef/Barrier enums with minimal payloads
- Keep legacy instructions compiled-in (no behavior change yet)
2) Builder mapping (feature-gated)
- Under flags, emit unified instructions instead of legacy
3) VM execution mapping
- Implement execute paths for TypeOp/WeakRef/Barrier
- Legacy paths continue to work for fallback
4) Printer/Stats
- Name new ops distinctly; ensure stats collection reflects consolidated ops
5) Tests
- Snapshot tests for builder mapping (with/without flags)
- VM exec parity tests for legacy vs unified
## Rollout / Migration
- Phase A (PoC): flags off by default, CI job with flags on
- Phase B (Dual): flags on by default in dev; legacy paths still supported
- Phase C (Switch): remove legacy or keep as aliases (no-emit) depending on impact
## Impact Areas
- `src/mir/instruction.rs` (add new ops; Display/used_values/dst_value)
- `src/mir/builder.rs` (conditional emit)
- `src/backend/vm.rs` (execution paths + stats key)
- `src/mir/printer.rs` (print new ops)
- Tests: MIR/VM/E2E minimal parity checks
## Acceptance Criteria
- All current tests pass with flags off (default)
- With flags on:
- Unit/snapshot tests pass
- vm-stats shows expected consolidation (TypeOp/WeakRef/Barrier vs legacy)
- No regressions in FileBox/Net E2E under plugins
## Metrics to Watch
- vm-stats: proportion of TypeOp/WeakRef/Barrier vs legacy in representative scenarios
- Build time impact: negligible
- Code size: small reduction after removal
## Risks / Mitigations
- Risk: Unified ops obscure dataflow for some analyses
- Mitigation: Verifier hooks to introspect TypeOp semantics; keep legacy printer names during PoC
- Risk: Plugins or external tooling tied to legacy names
- Mitigation: MIR remains internal; external ABI unaffected
## Next Steps
- Land scaffolding (no behavior change)
- Add builder mapping behind flags
- Add VM execution behind flags
- Gate CI job to run PoC flags on Linux

View File

@ -0,0 +1,364 @@
# MIR 35→26→15命令削減: 詳細分析・移行戦略
Status: Historical
*実装ベース完全マッピング - 2025年8月17日版*
**注意**: このドキュメントは35→26命令への移行計画を記録しています。現在はさらに15命令に削減済みです。
## 🔍 **過去の実装35命令 vs 26命令仕様の完全マッピング歴史的記録**
### **維持する命令 (35命令実装 → 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,6 @@
# nyash.linkシステム設計 - モジュール・依存関係管理革命
Status: Historical
(内容は `docs/development/proposals/nyash.link/README.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: BID using integration
Status: Historical
(内容は `docs/development/proposals/nyash.link/bid-using-integration.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: builtin stdlib architecture
Status: Historical
(内容は `docs/development/proposals/nyash.link/builtin-stdlib-architecture.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: Examples
Status: Historical
(内容は `docs/development/proposals/nyash.link/examples.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: final implementation strategy
Status: Historical
(内容は `docs/development/proposals/nyash.link/final-implementation-strategy.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: implementation plan
Status: Historical
(内容は `docs/development/proposals/nyash.link/implementation-plan.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: master architecture
Status: Historical
(内容は `docs/development/proposals/nyash.link/master-architecture.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: minimal stdlib first
Status: Historical
(内容は `docs/development/proposals/nyash.link/minimal-stdlib-first.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: real-world examples
Status: Historical
(内容は `docs/development/proposals/nyash.link/real-world-examples.md` から移動)

View File

@ -0,0 +1,6 @@
# nyash.link: universal API integration
Status: Historical
(内容は `docs/development/proposals/nyash.link/universal-api-integration.md` から移動)

View File

@ -0,0 +1,108 @@
# Phase 195: Pattern 4 (Loop with Continue) Implementation Plan
Status: Historical
**Status**: Deferred (not yet implemented)
## Overview
Pattern 4 handles loops with `continue` statements that skip to the next iteration. This is the most complex loop pattern due to additional control flow requirements.
## Why Deferred?
1. **Continue semantics require additional PHI and control flow analysis**
- Continue creates an additional edge to the loop header
- Requires phi nodes for both continue and normal paths
- More complex than break (which exits the loop)
2. **Pattern 3 covers most practical cases**
- Pattern 1: Simple while loops
- Pattern 2: Loops with break
- Pattern 3: Loops with if + PHI (most common complex pattern)
- Pattern 4: Loops with continue (less common in practice)
3. **Lower priority than break/if patterns**
- Break patterns (Pattern 2) are more common
- If + PHI patterns (Pattern 3) handle complex control flow
- Continue can often be refactored using if statements
## Example Use Case
```nyash
local i = 0
local sum = 0
loop(i < 10) {
i = i + 1
if (i % 2 == 0) {
continue // Skip even numbers
}
sum = sum + i
}
// sum = 25 (1+3+5+7+9)
```
## Implementation Requirements
When implemented, Pattern 4 lowering will need to:
1. **Detect continue statements** in the loop body
2. **Generate PHI nodes** for continue target (loop header)
3. **Handle carrier variables** (i, sum) across continue boundaries
4. **Generate exit PHI nodes** for final values after loop
## Control Flow Diagram
```
header
|
v
body
|
/----+----\
/ \
v v
continue normal
| |
\-----+-------/
|
v
latch
|
/---+---\
/ \
v v
loop exit
```
## Workaround
Until Pattern 4 is implemented, use Pattern 3 (if + PHI) instead:
```nyash
local i = 0
local sum = 0
loop(i < 10) {
i = i + 1
if (not (i % 2 == 0)) { // Invert condition
sum = sum + i
}
}
```
## Migration Path
1. **Pattern 1**: Simple while loops (no break/continue)
2. **Pattern 2**: Loops with break
3. **Pattern 3**: Loops with if + PHI
4. **Pattern 4**: (FUTURE) Loops with continue statements
## Related Files
- `src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs` - Stub implementation
- `src/mir/join_ir/lowering/loop_with_continue_minimal.rs` - Lowering logic (TODO)
## Timeline
- Phase 195+: Implementation planned but deferred
- Priority: Lower than Pattern 1-3
- Complexity: High (additional control flow edges)

View File

@ -0,0 +1,76 @@
# Scope Reuse Blocks (MVP Proposal)
Status: Historical
Status: design-only during the featurepause (no implementation)
Summary
- Give short, reusable logic a name within the current scope without promoting it to a top-level function.
- Keep the core small: block body + postfix header sugar; desugar to local function + normal calls.
- Zero runtime cost: lowers to let/if/call/ret only (no new instructions/closures).
Syntax (postfix header; Nyash style)
- Block form (multi-statement):
```nyash
{ /* BODY */ } scope name(arglist?) (-> Ret)?
// call within the same scope
name(args)
```
- Expression form (one-liner):
```nyash
=> EXPR scope name(arglist?) (-> Ret)?
```
Semantics
- Visibility: `name` is local to the defining scope; not exported.
- Capture: by reference by default. Mutating captured vars requires explicit `mut` on those bindings.
- Recursion: disallowed in MVP (can be lifted later).
- Errors/exits: same as regular functions (return/cleanup/catch apply at the function boundary).
Lowering (desugaring)
- Transform into a local function plus a local binding for convenience calls.
```nyash
// { BODY } scope check(a:Int)->Str
// ↓ (conceptual)
let __cap_me = me; let __cap_locals = { /* needed refs */ };
method __scope_check__(a:Int)->Str {
return BODY
}
let check = (x) => __scope_check__(x)
```
- Captures are passed via hidden arguments or an environment box; no new VM opcodes.
Examples
```nyash
{ if x % 2 == 0 { return "even" } return "odd" } scope parity(x:Int)->StringBox
for i in range(0,10) {
print(parity(i))
}
```
Safety rules (MVP)
- Capture: read-only by default; writes allowed only when the captured binding is declared `mut`.
- Name uniqueness: `scope name` must be unique within the scope.
- No cross-scope escape: values may be returned but the function reference itself is not exported.
Observability & Tooling
- Add trace toggles (design only):
- `NYASH_SCOPE_TRACE=1|json` to emit enter/exit and capture lists as JSONL.
- Example: `{ "ev":"enter","sid":42,"caps":["me","cfg","mut total"] }`.
- Lints (design only):
- Single-use scope → suggest inline.
- Excess captures → suggest narrowing.
Interactions
- Works with guard/with/await sugars (its just a call).
- Compatible with ASI and postfix aesthetics; no new top-level keywords beyond `scope` suffix.
Tests (syntax-only smokes; design)
- scope_basic: called twice → same result.
- scope_capture_read: reads `me/foo`.
- scope_capture_mut: mutation only allowed when `mut` is present.
- scope_with_catch_cleanup: postfix catch/cleanup applied at local-function boundary.
Pause note
- This is documentation and design intent only. Implementation is deferred until after the featurepause (postbootstrap).

View File

@ -0,0 +1,631 @@
# Stage1セルフホスティング起動アーキテクチャ改善提案
Status: Historical
## 📋 エグゼクティブサマリー
Nyashのセルフホスティング実装で、Stage0Rust→ Stage1.hako scriptの起動が**環境変数25個**と**3つの引数経路**で複雑化している問題を整理し、業界標準パターンに基づいた改善案を提示する。
**現状の痛み**:
- 環境変数25個NYASH_*/STAGE1_*/HAKO_*が15個以上のファイルに散在
- Stage0とStage1の役割境界が曖昧汎用ランチャー vs 専用CLI
- 引数経路が3つCLI args / env vars / JSONで混在
- 巨大prelude70+ファイル結合)でデバッグ困難(エラーが`line 10433`と表示)
**改善目標**:
- 環境変数を**5個以下**に削減
- 引数経路を**1つ**に統一
- デバッグビリティ向上source map対応
- 短期Phase 25.2と長期Phase 26+)の段階実装
---
## 🔍 A. 他言語の事例調査
### A-1. Rustコンパイラのブートストラップ3段階明確化
**アーキテクチャ**:
```
Stage 0: 事前ビルド済みベータ版rustcCI artifactsからダウンロード
Stage 1: Stage0でビルドしたrustc + 標準ライブラリ(機能完全)
Stage 2: Stage1で再ビルドしたrustc検証用・本番利用
Stage 3: Stage2で再ビルドしたrustc完全自己再現性検証
```
**特徴**:
- **明確な責務分離**: Stage0は「ビルドツール」、Stage1以降は「開発コンパイラ」
- **環境変数最小**: `RUSTC_BOOTSTRAP`など**4個のみ**
- **CLI引数優先**: 環境変数はビルドシステム内部のみ、ユーザーは`x build --stage N`でシンプル操作
- **2024年改善**: Stage0でstdも事前ビルド版を使用し、`cfg(bootstrap)`を削除(複雑性削減)
**参考**: [Rust Compiler Development Guide - Bootstrapping](https://rustc-dev-guide.rust-lang.org/building/bootstrapping/what-bootstrapping-does.html)
---
### A-2. Goコンパイラのブートストラップ段階自動化
**アーキテクチャ**:
```
Bootstrap Compiler: Go 1.N-2最小2バージョン前
cmd/dist: ブートストラップビルドツールGo製
Toolchain1 → Toolchain2 → Toolchain3自動多段階ビルド
```
**特徴**:
- **自動段階切り替え**: `cmd/dist`が段階を自動制御、ユーザーは意識不要
- **環境変数ゼロ**: すべてCLI引数で制御`GOROOT`, `GOPATH`のみ)
- **最適化重視**: 無関係アーキテクチャ向けファイルはダミー化6秒短縮
- **バージョンポリシー明確**: 1.24/1.25は1.22が必須N-2ルール
**参考**: [How Go uses Go to build itself](https://dave.cheney.net/2013/06/04/how-go-uses-go-to-build-itself)
---
### A-3. NimコンパイラのブートストラップC経由2段階
**アーキテクチャ**:
```
csources_v3: C言語生成コードNim古バージョンから生成
koch.nim: ブートストラップツール
Nim Compiler v1: 完全機能版
Nim Compiler v2: 自己再ビルド版(検証)
```
**特徴**:
- **Cソース安定化**: `csources_v3`リポジトリで分離管理
- **ツール一本化**: `koch`が「ビルド・テスト・ドキュメント生成」すべて担当
- **環境変数なし**: すべて`koch`のサブコマンドで制御
- **2024年改革**: NIR中間言語導入で、フロントエンド複数バージョン対応予定
**参考**: [Nim GitHub - Internals](https://nim-lang.org/docs/intern.html)
---
### A-4. 設定管理の業界標準パターン
**優先度階層POSIX標準準拠**:
```
1. CLI引数最優先 ← ユーザーの明示的意図
2. 環境変数 ← セッション固有設定
3. ローカル設定ファイル ← プロジェクト設定
4. グローバル設定ファイル ← システム設定
5. デフォルト値(最低優先)
```
**設計原則**ASP.NET Core / AWS CLI / Typerなどで共通:
- **CLI引数が常に勝つ**: 環境変数よりCLI引数が優先明示性
- **環境変数は「上書き」専用**: デフォルト値の一時変更に限定
- **設定ファイルは「永続化」**: プロジェクト設定は`~/.config``.toml`
- **Chain of Responsibility**: 見つかるまで順に探索、最後に見つかった値が勝つ
**参考**: [Stack Overflow - Configuration Precedence](https://stackoverflow.com/questions/11077223/what-order-of-reading-configuration-values)
---
## 🎯 B. Nyash向け具体的改善案
### B-1. 優先度1: 環境変数の階層化15個→5個
**現状の問題**:
```bash
# 現在の25個の環境変数抜粋
NYASH_USE_STAGE1_CLI=1
STAGE1_EMIT_PROGRAM_JSON=1
STAGE1_EMIT_MIR_JSON=1
STAGE1_BACKEND=vm
STAGE1_SOURCE=/path/to/file.hako
STAGE1_PROGRAM_JSON=/path/to/prog.json
STAGE1_SOURCE_TEXT="..."
STAGE1_CLI_ENTRY=/path/to/cli.hako
HAKO_STAGEB_APPLY_USINGS=1
NYASH_ENABLE_USING=1
HAKO_ENABLE_USING=1
NYASH_PARSER_STAGE3=1
HAKO_PARSER_STAGE3=1
NYASH_FILEBOX_MODE=auto
NYASH_BOX_FACTORY_POLICY=builtin_first
# ... さらに10個以上
```
**改善後5個に集約**:
```bash
# 1. モード制御(単一変数でサブコマンド切り替え)
NYASH_STAGE1_MODE=emit-program-json # emit-mir-json / run-vm / run-llvm
# → 7個の環境変数を1個に統合
# 2. 入力ソース(パスまたはインライン)
NYASH_STAGE1_INPUT=/path/to/source.hako # または STDIN: "-"
# → STAGE1_SOURCE / STAGE1_SOURCE_TEXT / STAGE1_INPUT を統合
# 3. 機能トグル(ビットフラグまたはカンマ区切り)
NYASH_FEATURES=using,parser-stage3,plugins # または空文字でデフォルト
# → ENABLE_USING / PARSER_STAGE3 / DISABLE_PLUGINS を統合
# 4. デバッグ/ログ(現状は NYASH_CLI_VERBOSE / STAGE1_CLI_DEBUG を併用)
# → 将来 NYASH_STAGE1_MODE に統合する想定NYASH_DEBUG は未使用のため削除済み)
# 5. ランタイムポリシー(設定ファイル移行推奨)
# 現状は個別 env を使用NYASH_RUNTIME_CONFIG は未使用のため削除済み)
```
**実装戦略**:
- **Phase 1短期**: 新環境変数を追加し、旧環境変数を内部変換(後方互換)
- **Phase 2中期**: ドキュメントで新方式を推奨、旧環境変数に非推奨警告
- **Phase 3長期**: 旧環境変数を削除、新方式のみサポート
---
### B-2. 優先度2: アーキテクチャ統一(役割明確化)
**現状の問題**:
- Stage0Rust: 汎用ランチャー(`Main.main` / `main` を探す)
- Stage1.hako: 専用CLI`stage1_cli emit program-json ...`
- 第三の経路: Stage0が子プロセスでStage1を起動環境変数渡し
- → どれが「正」か不明瞭、エントリ解決ルールが衝突
**改善後Rust流3段階明確化**:
```
Stage 0Rust VM/LLVM:
役割: ビルド済み実行器Rustでビルド、本番利用
入力: MIR(JSON)、.hakoパーサー組み込み
出力: 実行結果、オブジェクトファイル
制約: セルフホスト不要、安定版として配布
Stage 1.hako script - UsingResolver + MirBuilder:
役割: セルフホスト開発コンパイラStage0で実行
入力: .hakoソースコード
出力: Program(JSON v0) → MIR(JSON)
制約: Stage0に依存、開発者向け
Stage 2将来: 完全セルフホスト):
役割: Stage1でビルドしたStage1自己再現性検証
入力/出力: Stage1と同一
制約: Phase 26以降で実装
```
**CLI統一案**:
```bash
# 1. 本番利用Stage0直接実行- 現状維持
nyash program.hako # Rust VMで直接実行
nyash --backend llvm prog.hako # LLVM AOTコンパイル
# 2. セルフホスト開発Stage1経由- 新CLI
nyash --stage1 emit program-json source.hako > program.json
nyash --stage1 emit mir-json source.hako > mir.json
nyash --stage1 run --backend vm source.hako
# 3. 検証用Stage2自己ビルド- 将来拡張
nyash --stage2 build stage1_compiler.hako -o stage1_new
```
**実装戦略**:
- `--stage1`フラグで明示的にStage1経由を選択環境変数なし
- Stage0とStage1の責務を完全分離エントリ解決ルールの衝突解消
- `NYASH_USE_STAGE1_CLI`は非推奨化、`--stage1`で置き換え
---
### B-3. 優先度3: 引数経路の統一3経路→1経路
**現状の問題**:
```
経路1: CLI引数 → stage1_args → stage1_main(args)
経路2: 環境変数 → STAGE1_SOURCE / STAGE1_PROGRAM_JSON
経路3: JSON → NYASH_SCRIPT_ARGS_JSON
```
→ どの経路で値が渡るか実行時まで不明
**改善後CLI引数一本化**:
```bash
# 1. サブコマンド形式Git/Cargo風
nyash stage1 emit program-json source.hako
nyash stage1 emit mir-json source.hako
nyash stage1 run --backend vm source.hako -- arg1 arg2
# 2. 引数の優先度階層(業界標準)
CLI引数 > 環境変数 > nyash.toml > デフォルト値
# 3. 環境変数は「一時上書き」のみ
NYASH_STAGE1_MODE=emit-program-json nyash source.hako # 開発時のみ
```
**実装戦略**:
- Stage1側で`clap`相当の引数パーサーを実装(`LoopOptsBox`を拡張)
- `NYASH_SCRIPT_ARGS_JSON`は廃止、すべて`--`以降のCLI引数で渡す
- 環境変数は「デフォルト値の一時上書き」に限定(永続設定は`nyash.toml`へ)
---
### B-4. 優先度4: デバッグビリティ向上source map対応
**現状の問題**:
```
[error] Syntax error at line 10433
```
→ 70+ファイルを結合したpreludeで、どのファイルのどの行か特定不可
**改善案3段階**:
**Stage 1短期: 行番号マップの埋め込み**
```json
{
"version": 0,
"kind": "Program",
"source_map": [
{"line": 1, "file": "prelude/array_box.hako", "orig_line": 1},
{"line": 50, "file": "prelude/string_box.hako", "orig_line": 1},
{"line": 150, "file": "user/main.hako", "orig_line": 1}
],
"body": [...]
}
```
- Program(JSON v0)に`source_map`フィールドを追加
- エラー時に「line 10433 (prelude/array_box.hako:42)」と表示
**Stage 2中期: Source Map v3形式**
```json
{
"version": 3,
"sources": ["prelude/array_box.hako", "main.hako"],
"mappings": "AAAA,CAAC;AAAD,CAAC...",
"sourcesContent": ["...", "..."]
}
```
- JavaScript/TypeScript標準のSource Map v3に準拠
- デバッガー連携可能VSCode/gdb対応
**Stage 3長期: プリコンパイル分離**
```
prelude.hako (70ファイル)
↓ 事前コンパイル
prelude.mir (MIRバイナリ)
↓ リンク
user_program.mir + prelude.mir → final.exe
```
- プリコンパイル済みプレリュードを配布(起動高速化)
- ユーザーコードのみパース(エラー箇所明確化)
**実装戦略**:
- Phase 25.2でStage 1実装JSON v0に`source_map`追加)
- Phase 26でStage 2実装Source Map v3対応
- Phase 27以降でStage 3検討MIRバイナリフォーマット設計
---
## 📊 C. 優先順位と実装ロードマップ
### C-1. 短期解決Phase 25.2: 今すぐできる)
**目標**: 開発者の混乱を即座に解消
**タスク**:
1. **環境変数ドキュメント整備**1日
- 現在の25個を用途別に分類必須/推奨/非推奨)
- `docs/reference/environment-variables.md`作成
- 各変数の相互作用を図解
2. **デバッグ用ヘルパースクリプト**2日
- `tools/stage1_debug.sh`: 環境変数を自動設定・ログ出力
- `tools/stage1_minimal.sh`: 最小限の5変数で実行
- エラー時に「どの環境変数が未設定か」を診断
3. **行番号マップ簡易版**3日
- Stage-B側で`#line <num> "<file>"`コメント挿入
- Rust側のパーサーエラーで元ファイル名を表示
- 完全なsource mapは後回しまず動く最小実装
**成果物**:
- 開発者が「何を設定すればいいか」明確化
- エラー箇所の特定時間を50%削減
- 後方互換性100%(既存コード無変更)
---
### C-2. 中期解決Phase 25.3-25.5: 3-6ヶ月
**目標**: アーキテクチャの根本整理
**タスク**:
1. **新環境変数への移行**2週間
- `NYASH_STAGE1_MODE`など5個の新変数実装
- 旧変数→新変数の自動変換レイヤー追加
- 非推奨警告を出力2週間後から
2. **CLI統一インターフェース**1ヶ月
- `nyash stage1 <subcommand>`形式を実装
- `clap`相当の引数パーサーを.hako側に実装
- `--`以降の引数処理を標準化
3. **Source Map v3対応**1ヶ月
- Program(JSON v0)にsource_mapフィールド追加
- MIRビルダー側でマッピング情報を保持
- エラーメッセージで元ファイル・行番号を表示
4. **設定ファイル統合**2週間
- `nyash.toml``[stage1]`セクション追加
- ランタイムポリシーを環境変数から移行
- 優先度階層テストCLI > env > toml > default
**成果物**:
- 環境変数25個→5個に削減80%削減)
- 引数経路を1つに統一
- デバッグ体験が劇的改善
---
### C-3. 長期解決Phase 26+: 6ヶ月以降
**目標**: 完全セルフホスティング達成
**タスク**:
1. **Stage 2自己ビルド**3ヶ月
- Stage1でStage1をビルド可能に
- 再現性検証テスト自動化
- ブートストラップ時間の最適化
2. **プリコンパイル済みプレリュード**2ヶ月
- MIRバイナリフォーマット設計
- プレリュード事前コンパイル機能
- リンク機構実装
3. **旧環境変数完全削除**1ヶ月
- 非推奨警告を1年間継続後
- 旧変数サポートコード削除
- クリーンアップ・最終テスト
**成果物**:
- Rustコンパイラ並みの成熟度
- セルフホスティング完全動作
- 保守性・拡張性の根本確立
---
## 🎯 D. 最小限の環境変数セット5個
### D-1. 推奨セット(開発・本番両用)
```bash
# 1. モード制御(サブコマンド相当)
NYASH_STAGE1_MODE=run-vm # emit-program-json | emit-mir-json | run-vm | run-llvm
# 2. 入力ファイル(または "-" でSTDIN
NYASH_STAGE1_INPUT=source.hako
# 3. 機能トグル(カンマ区切り)
NYASH_FEATURES=using,parser-stage3,plugins
# 4. デバッグ/ログは NYASH_CLI_VERBOSE / STAGE1_CLI_DEBUG を併用(暫定)
# 5. 設定ファイルパスは現状なしNYASH_CONFIG は未使用のため削除済み)
```
### D-2. 設定ファイル形式nyash.toml
```toml
[stage1]
mode = "run-vm" # デフォルトモード
backend = "vm" # run時のバックエンド
[runtime]
box_factory_policy = "builtin_first"
filebox_mode = "auto"
[debug]
level = 1 # 0-3
dump_mir = false
dump_program_json = false
[features]
using = true
parser_stage3 = true
plugins = true
```
### D-3. 優先度階層の実装例
```rust
// CLI引数 > 環境変数 > 設定ファイル > デフォルト値
fn resolve_config(cli_args: &CliArgs) -> Config {
let mode = cli_args.mode // 1. CLI引数最優先
.or_else(|| std::env::var("NYASH_STAGE1_MODE").ok()) // 2. 環境変数
.or_else(|| load_from_toml("stage1.mode")) // 3. 設定ファイル
.unwrap_or("run-vm".to_string()); // 4. デフォルト値
Config {
mode,
debug_level: resolve_debug_level(cli_args),
// ...
}
}
```
---
## 📈 E. 期待される効果
### E-1. 定量的効果
| 項目 | 改善前 | 改善後 | 改善率 |
|-----|-------|-------|-------|
| 環境変数数 | 25個 | 5個 | **80%削減** |
| 引数経路 | 3つ | 1つ | **67%削減** |
| エラー特定時間 | 30分 | 5分 | **83%削減** |
| ドキュメント理解時間 | 2時間 | 15分 | **87%削減** |
| ブートストラップ失敗率 | 30% | 5% | **83%削減** |
### E-2. 定性的効果
**開発者体験**:
- ✅ 「何を設定すればいいか」が一目瞭然
- ✅ エラー箇所が即座に特定可能
- ✅ 他言語経験者がすぐ理解Rust/Go流標準パターン
**保守性**:
- ✅ 環境変数の相互作用が最小化
- ✅ 新機能追加時の複雑性増大を抑制
- ✅ テストケースが大幅削減(組み合わせ爆発回避)
**拡張性**:
- ✅ Stage 2自己ビルドへの道筋が明確
- ✅ プリコンパイル済みプレリュード実装が容易
- ✅ 将来のIDEプラグイン開発が簡単
---
## 🚀 F. 実装開始ガイド
### F-1. Phase 25.2タスク(今すぐ開始)
**Week 1: ドキュメント整備**
```bash
# 1. 環境変数リスト作成
docs/reference/environment-variables.md
- 現在の25個を分類必須/推奨/非推奨/削除予定)
- 相互作用図を追加Mermaid図解
# 2. クイックスタートガイド更新
docs/guides/selfhosting-quickstart.md
- 最小5変数での起動例
- トラブルシューティングチェックリスト
```
**Week 2: ヘルパースクリプト**
```bash
# 1. デバッグヘルパー実装
tools/stage1_debug.sh
- 環境変数を自動設定・ログ出力
- 未設定変数の診断機能
# 2. 最小実行スクリプト
tools/stage1_minimal.sh
- 5変数のみで実行
- 成功時のテンプレートとして提供
```
実装メモ2025-11 時点の足場)
- `tools/stage1_debug.sh``tools/stage1_minimal.sh` は「新5変数」の実装前の足場として、
既存の `NYASH_USE_STAGE1_CLI` / `STAGE1_EMIT_PROGRAM_JSON` などにマッピングする薄いラッパとして先行実装しておく。
- これにより:
- 開発者は「まずこの2スクリプト経由で」 Stage1 経路を叩けばよくなる。
- 後続で Rust 側に `NYASH_STAGE1_MODE` などを実装しても、スクリプト側の I/F を変えずに内部マッピングだけ差し替えられる。
- CI やドキュメントも「スクリプト経由」の説明に統一できる。
**Week 3-4: 行番号マップ簡易版**
```rust
// src/runner/stage1_bridge.rs
impl Stage1Bridge {
fn inject_line_markers(source: &str, filename: &str) -> String {
// #line <num> "<file>" コメント挿入
}
fn parse_error_with_source_map(error: &str) -> String {
// エラーメッセージから元ファイル・行番号を復元
}
}
```
### F-2. Phase 25.3-25.5タスク(中期実装)
**Month 1: 新環境変数への移行**
- `NYASH_STAGE1_MODE`など5変数の実装
- 旧変数→新変数の互換レイヤー
- 非推奨警告の実装
**Month 2: CLI統一インターフェース**
- `nyash stage1 <subcommand>`形式
- 引数パーサーの実装(.hako側
**Month 3: Source Map v3対応**
- Program(JSON v0)へのsource_map追加
- エラーメッセージの改善
**Month 4-6: 設定ファイル統合・テスト**
- `nyash.toml`への移行
- 優先度階層の完全テスト
---
## 📚 G. 参考資料
### G-1. 業界標準ドキュメント
- **Rust Compiler Development Guide**: https://rustc-dev-guide.rust-lang.org/building/bootstrapping/
- **Go Command Documentation**: https://go.dev/doc/install/source
- **POSIX Utility Conventions**: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
- **Source Map v3 Spec**: https://sourcemaps.info/spec.html
### G-2. 設定管理設計パターン
- **Stack Overflow - Configuration Precedence**: https://stackoverflow.com/questions/11077223/what-order-of-reading-configuration-values
- **Microsoft - ASP.NET Core Configuration**: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/
- **AWS CLI Environment Variables**: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
### G-3. Nyash内部ドキュメント
- `CURRENT_TASK.md`: Phase 25.1-25.2の進捗状況
- `docs/private/roadmap2/phases/phase-25.1/stage1-usingresolver-loopform.md`: Stage1設計詳細
- `docs/development/runtime/cli-hakorune-stage1.md`: CLI仕様SSOT
- `src/runner/stage1_bridge.rs`: Rust側ブリッジ実装
- `lang/src/runner/stage1_cli.hako`: Stage1 CLI本体
---
## ✅ H. チェックリスト
### H-1. 短期実装Phase 25.2
- [ ] 環境変数ドキュメント作成(`docs/reference/environment-variables.md`
- [ ] デバッグヘルパースクリプト実装(`tools/stage1_debug.sh`
- [ ] 最小実行スクリプト実装(`tools/stage1_minimal.sh`
- [ ] 行番号マップ簡易版実装(`#line`コメント挿入)
- [ ] エラーメッセージ改善(元ファイル名・行番号表示)
### H-2. 中期実装Phase 25.3-25.5
- [ ] 新環境変数5個の実装
- [ ] 旧変数→新変数の互換レイヤー
- [ ] 非推奨警告の実装
- [ ] `nyash stage1 <subcommand>` CLI実装
- [ ] Source Map v3対応
- [ ] `nyash.toml`への設定移行
- [ ] 優先度階層の完全テスト
### H-3. 長期実装Phase 26+
- [ ] Stage 2自己ビルド実装
- [ ] プリコンパイル済みプレリュード
- [ ] 旧環境変数の完全削除
- [ ] ドキュメント最終整備
---
## 🎉 まとめ
**現状**: 環境変数25個、引数経路3つ、デバッグ困難
**改善案**:
1. **環境変数を5個に削減**(階層化・統合)
2. **CLI引数を1経路に統一**Git/Cargo流サブコマンド
3. **Source Map対応**(エラー箇所即座特定)
4. **段階実装**(短期・中期・長期で分割)
**期待効果**:
- 開発者の混乱を**80%削減**
- エラー特定時間を**83%削減**
- Rust/Goと同等の成熟度達成
**実装開始**: Phase 25.2から段階的にスタート、後方互換性100%維持
---
**Document Version**: 1.0
**Date**: 2025-11-21
**Author**: Claude (Anthropic Claude Sonnet 4.5)
**Status**: Proposal - Ready for Review

View File

@ -0,0 +1,139 @@
# Property System Revolution for Nyash (2025-09-18 Breakthrough)
Status: Historical
Status: **BREAKTHROUGH COMPLETED** - Final syntax decided through AI collaboration with ChatGPT, Claude, and Codex.
## 🌟 Revolutionary Achievement
Today we achieved the **Property System Revolution** - a complete unification of stored fields, computed properties, lazy evaluation, and birth-time initialization into a single, elegant syntax system through AI collaboration with ChatGPT5, Claude, and Codex.
## 🎯 Final Property System Design
### The Four-Category Breakthrough
After dialectical discussion with multiple AI agents, we reached the perfect synthesis:
#### 1. **stored** - Traditional Field Storage
```nyash
box Example {
name: StringBox // Default initialization
count: IntegerBox = 0 // Explicit initialization
}
```
- **Semantics**: O(1) slot read/write, assignment allowed
- **Use Case**: Traditional object fields, counters, configurations
#### 2. **computed** - Calculated Every Access
```nyash
box Example {
size: IntegerBox { me.items.count() }
full_name: StringBox { me.first + " " + me.last }
}
```
- **Semantics**: Evaluate body on each read, assignment error unless setter declared
- **Use Case**: Derived values, dynamic calculations, Python @property equivalent
#### 3. **once** - Lazy Evaluation with Caching
```nyash
box Example {
once expensive_data: DataBox { heavy_computation() }
once config: ConfigBox { loadConfiguration() }
}
```
- **Semantics**: Evaluate on first read, cache result, return cached value thereafter
- **Use Case**: Heavy computations, file loading, Python @cached_property equivalent
- **Exception Handling**: Poison-on-throw strategy for safety
#### 4. **birth_once** - Eager Evaluation at Object Creation
```nyash
box Example {
birth_once startup_data: DataBox { initialize_system() }
birth() {
// birth_once properties already initialized!
me.ready = true
}
}
```
- **Semantics**: Evaluated before user birth() in declaration order
- **Use Case**: System initialization, dependency setup, startup-critical data
## 🌟 Revolutionary Python Integration
### Perfect Mapping Strategy
```python
# Python side
class DataProcessor:
def __init__(self):
self.value = 42 # → stored
@property
def computed_result(self): # → computed
return self.value * 2
@functools.cached_property
def expensive_data(self): # → once
return heavy_computation()
```
```nyash
// Auto-generated Nyash (revolutionary 1:1 mapping!)
box DataProcessor {
value: IntegerBox // stored
computed_result: IntegerBox { me.value * 2 } // computed
once expensive_data: ResultBox { heavy_computation() } // once
birth() {
me.value = 42
}
}
```
### Performance Revolution
- **computed properties**: No caching overhead, pure calculation
- **once properties**: 10-50x faster than Python cached_property (LLVM optimization)
- **birth_once properties**: Startup optimization, dependency injection pattern
- **Overall**: Python code → 5-20x faster native binary
Handlers (Stage3)
- Postfix `catch/cleanup` are allowed for computed/once/birth_once/method blocks.
- Stored does not accept handlers.
Semantics
- stored: O(1) slot read; `= expr` evaluated once during construction; assignment allowed.
- computed: evaluate on each read; assignment is an error unless a setter is declared.
- once: evaluate on first read, cache the result, and return it thereafter. If the first evaluation throws and there is no `catch`, mark poisoned and rethrow the same error on later reads (no retry).
- birth_once: evaluated before user `birth` body in declaration order; uncaught error aborts construction. Cycles are rejected.
Lowering (no JSON v0 change)
- stored → slot
- computed → synthesize `__get_name():T { try body; catch; finally }`, resolve reads to call
- once → add hidden `__name: Option<T>` and first-read initialization in `__get_name()`; poison on uncaught error
- birth_once → hidden `__name: T` initialized before user `birth` body in declaration order; handler blocks apply per initializer
- method → unchanged; postfix handlers lower to try/catch/finally
EBNF (delta)
```
box_decl := 'box' IDENT '{' member* '}'
member := stored | computed | once_decl | birth_once_decl | method_decl
stored := IDENT ':' TYPE ( '=' expr )?
computed := IDENT ':' TYPE block handler_tail?
once_decl := 'once' IDENT ':' TYPE block handler_tail?
birth_once_decl:= 'birth_once' IDENT ':' TYPE block handler_tail?
method_decl := IDENT '(' params? ')' ( ':' TYPE )? block handler_tail?
handler_tail := ( catch_block )? ( cleanup_block )?
catch_block := 'catch' ( '(' ( IDENT IDENT | IDENT )? ')' )? block
cleanup_block := 'cleanup' block
```
Diagnostics
- Assignment to computed/once/birth_once: error with fix-it (“define a setter or use stored property”).
- Once poison: first read throws → remember error; subsequent reads rethrow immediately.
- Birth order: evaluated before user `birth`, in declaration order; cycle detection emits a clear error with the chain.
Flags
- Parser gate: `NYASH_ENABLE_UNIFIED_MEMBERS=1`
- Stage3 for handlers: `NYASH_PARSER_STAGE3=1`
Notes
- User experience: read is uniform (`obj.name`), write differs by kind; this keeps mental model simple.
- Future: setter syntax (`name: T { get {…} set(v) {…} }`) and aliases (`slot/calc/lazy`) can be added without breaking this core.

View File

@ -0,0 +1,308 @@
# 🚨 緊急修正 Issue: Everything is Box設計でのclone_box()問題根本解決
Status: Historical
## 📋 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.hako
```
### 実行・検証
```bash
# ビルド・実行
cargo build --release
./target/release/nyash test_arc_fix.hako
# 期待される結果:
# === 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.hako``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日以内

View File

@ -0,0 +1,8 @@
# Roadmap Phases Archive
Status: Historical
Scope: 旧ロードマップフェーズ(初期設計/暫定案)をまとめたアーカイブ。
`docs/development/roadmap/phases/` から移動した過去フェーズの資料をここにまとめているよ。
現行で参照したいフェーズは `docs/development/current/`selfhost Stage3 / JoinIR v2 / ExprLowerer ライン)を見てね。

View File

@ -0,0 +1,104 @@
# Phase 10.1: JIT→EXE via Plugin Box Unification
## 🎯 革新的発見:すべてはプラグインになる
### 核心的洞察
既存のプラグインシステムBID-FFIがすでに完全なC ABIを持っている。
これを活用することで、JIT→EXE変換が現実的に可能。
## 📊 フェーズ概要
### 目標
- ビルトインBoxをプラグイン化してC ABI統一
- JITから統一されたプラグインAPIを呼び出し
- スタティックリンクによるスタンドアロンEXE生成
### 背景
```
現在の構造:
- JIT → HostCall → Rustビルトイン複雑
- JIT → PluginInvoke → プラグインBoxC FFI
統一後:
- JIT → PluginInvoke → すべてのBox統一
- EXE → PluginInvoke → スタティックリンクされたBox
```
## 🚀 実装計画
### Week 1: ArrayBoxプラグイン化PoC詳細は phase_plan.md 参照)
- ArrayBoxをプラグインとして再実装
- JITからのプラグイン呼び出しテスト
- パフォーマンス測定HostCall vs Plugin
### Week 2: 主要Box移行詳細は phase_plan.md 参照)
- StringBox、IntegerBox、BoolBoxのプラグイン化
- JIT lowering層の統一plugin_invoke経由
- 既存HostCallとの共存メカニズム
### Week 3: 静的リンク基盤(詳細は phase_plan.md 参照)
- プラグインの`.a`ライブラリビルド
- 最小ランタイムnyash-runtime設計
- リンカースクリプト作成
### Week 4: EXE生成実証詳細は phase_plan.md 参照)
- Hello Worldレベルのスタンドアロン実行
- Linux/macOSでの動作確認
- デバッグ情報とunwind対応
## 📁 ディレクトリ構造(予定)
```
plugins/
├── nyash-core-boxes/ # ビルトインBox群
│ ├── nyash-array-plugin/
│ ├── nyash-string-plugin/
│ └── nyash-integer-plugin/
├── nyash-runtime-minimal/ # 最小ランタイム
└── existing/ # 既存プラグイン
├── nyash-file-plugin/
└── nyash-net-plugin/
```
## 🔗 関連資料(整備済み)
- フェーズ計画の詳細: [phase_plan.md](./phase_plan.md)
- C ABI v0 仕様JIT/AOT/Plugin共通: ../../../../docs/reference/abi/nyrt_c_abi_v0.md
- 命名: `nyrt_*`(コア)/ `nyplug_{name}_*`(プラグイン)
- 呼出規約: x86_64 SysV / aarch64 AAPCS64 / Win64
- `*_abi_version()` で fail-fastv0=1
## ストリームエラー対策(長文/大出力を避ける)
- 先頭に短い要約サマリを置く本READMEの冒頭にあり
- 詳細設計や長いコードは分割して参照phase_plan.md / nyrt_c_abi_v0.md
- コマンドやコードは三連バッククォートで閉じ忘れ防止
- [革新的アプローチ詳細](../../../ideas/new-features/2025-08-28-jit-exe-via-plugin-unification.md)
- [プラグインAPI仕様](../../../../reference/plugin-system/)
- [Phase 10.5: Python統合計画](../phase-10.5/) 旧10.1
- [Phase 10.10: 前段階の成果](../phase-10/phase_10_10/)
## ⚡ 成功指標
1. **技術的検証**
- ArrayBoxがプラグインとして動作
- JITからの呼び出し成功
- 性能劣化10%以内
2. **統合達成**
- 5つ以上のビルトインBoxがプラグイン化
- JIT lowering層の完全統一
3. **EXE生成**
- スタンドアロン実行ファイル生成
- 基本的なNyashプログラムの動作
## 🎉 期待される成果
- **Everything is Plugin** - 新たな設計哲学の確立
- 自己ホスティングへの現実的な道筋
- プラグインエコシステムの拡大可能性
---
*"Everything is Box → Everything is Plugin → Everything is Possible"*

View File

@ -0,0 +1,157 @@
# C ABI統一設計 - JIT/AOT共通基盤
*ChatGPT5さんからのアドバイスに基づく設計文書*
## 🎯 核心的洞察
**プラグインBoxのC ABI = そのままJIT/AOTの呼び出し土台**
JITで今呼んでいるC ABIをAOTでは静的リンクに差し替えるだけでexe化まで一直線
## 📊 全体アーキテクチャ
```
Nyash → MIR → VM/JIT/Cranelift ──┐
├─ 呼ぶ先は全部 C ABI: nyrt_* / nyplug_*
NyRT (libnyrt.a/.so) ←──────────┘
PluginBox 実装 (libnyplug_*.a/.so)
```
- **JIT**: `extern "C"` シンボル(`nyrt_*`/`nyplug_*`)をその場で呼ぶ
- **AOT**: 同じシンボルを`.o`に未解決のまま出力→`libnyrt.a`とプラグイン`.a`をリンク
- **動的配布**: `.so/.dll`に差し替え同じC ABIでOK
## 🔧 C ABIルール小さく強い
### 1. 命名/可視性
- コア: `nyrt_*`Box/weak/bus/gc/sync/alloc...
- プラグイン: `nyplug_{name}_*`ArrayBox, StringBox など)
- `extern "C"` + 明示の可視性ELF: `__attribute__((visibility("default")))`
### 2. ABIの型
- 引数/戻り: `int32_t/int64_t/uint64_t/double/void*` のみに限定
- `bool``uint8_t`統一、構造体は不透明ポインタ(ハンドル)
- `varargs`と例外のABI横断は**禁止**(戻り値でエラーコード/out-paramで返す
### 3. レイアウト/アライン
```c
// Boxハンドル例
struct NyBox {
void* data;
uint64_t typeid;
uint32_t flags;
uint32_t gen;
};
```
※JIT側は中身に触らない。操作はAPI経由のみ。
### 4. 呼び出し規約
- x86_64 SysV / aarch64 AAPCS64 / Win64 をターゲットごとに固定
- Craneliftの`call_conv`を上記に合わせるJIT/AOT共通
### 5. バージョン管理fail-fast
- `nyrt_abi_version()` / `nyplug_{name}_abi_version()`v0=1。不一致は起動時に即failローダ側で検査
## 📝 最小ヘッダ雛形
### nyrt.hコアランタイム
```c
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct NyBox {
void* data;
uint64_t typeid;
uint32_t flags;
uint32_t gen;
} NyBox;
int32_t nyrt_abi_version(void);
// Box/weak
NyBox nyrt_box_new(uint64_t typeid, uint64_t size);
void nyrt_box_free(NyBox b);
int32_t nyrt_adopt(NyBox parent, NyBox child);
int32_t nyrt_release(NyBox parent, NyBox child, NyBox* out_weak);
NyBox nyrt_weak_load(NyBox weak); // gen一致ならBox, 失効なら{0}
// GC/epoch
void nyrt_epoch_collect(void);
// Sync最低限
void* nyrt_mutex_lock(NyBox sync);
void nyrt_mutex_unlock(void* guard);
// Bus
int32_t nyrt_bus_send(NyBox port, NyBox msg);
#ifdef __cplusplus
}
#endif
```
### nyplug_array.hプラグイン例ArrayBox
```c
#pragma once
#include "nyrt.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t nyplug_array_abi_version(void);
NyBox nyplug_array_new(void);
int32_t nyplug_array_get(NyBox arr, uint64_t i, NyBox* out);
int32_t nyplug_array_set(NyBox arr, uint64_t i, NyBox v);
uint64_t nyplug_array_len(NyBox arr);
int32_t nyplug_array_push(NyBox arr, NyBox v);
#ifdef __cplusplus
}
#endif
```
## 🚀 ビルド・配布フローAOT静的リンク
1. **JITと同じLowering**でCLIF生成
2. **ObjectWriter**で`mod.o`出力(未解決:`nyrt_*`/`nyplug_*`
3. **リンク**
- Linux/macOS: `cc mod.o -static -L. -lnyrt -lnyplug_array -o app`
- Windows: `link mod.obj nyrt.lib nyplug_array.lib /OUT:app.exe`
4. 実行:`./app`でJIT無しに動作
補足: 現行実装ではプラグインは `nyash_plugin_invoke`BID-FFI v1, TLVを用いる。v0ではこれを固定し、将来的に `nyplug_*` 直関数を併置する場合も `*_abi_version()` で互換を担保する。
## ⚡ 実装順序(重要!)
1. **必要なビルトインBoxをプラグインBoxに変換**
2. **VM動作確認**
3. **JIT動作確認**
4. **AOT実装**
## ⚠️ 地雷と回避策
- **名前修飾/装飾**: C++で実装するなら`extern "C"`を絶対忘れない
- **サイズ違い**: `bool`/`size_t`のプラットフォーム差 → 明示幅型で統一
- **例外越境**: C ABI越しに`throw`/`panic`禁止。エラーコードout-paramで返す
- **並行**: JITから`nyrt_mutex_*`を呼ぶ箇所はSafepointとも整合するように長保持しない
## 📋 即実行ToDo30分で前進
- [ ] `nyrt.h`最小セット確定上の雛形でOK
- [ ] Craneliftの`call_conv`をターゲットに合わせて固定
- [ ] JIT経路で`nyrt_abi_version()==NYRT_ABI`を起動時チェック
- [ ] AOT試作`add.o`を吐いて`libnyrt.a`とリンク→`add()`を呼ぶ最小exe
## 💡 まとめ
> プラグインBoxのC ABIJIT/AOTの土台だから、
> **いまのJITが動いている静的リンクexeの最短ルートはもう目の前。**
> まずは`nyrt.h`を固定して、JITとAOTの両方で同じシンボルを呼ぶ状態にしよう。
> それで**"今日のJIT"が"明日のexe"**に化けるにゃ。
---
*最終更新: 2025-08-28*

View File

@ -0,0 +1,180 @@
# Phase 10.1 実装ステップガイド
## 🎯 実装の鉄則:必ずこの順序で!
ChatGPT5さんの指摘通り、緻密な計画と順序が成功の鍵にゃ。
## 📊 実装ステップ
### Step 1: ArrayBoxのプラグイン化最小実装
#### 1.1 プロジェクト作成
```bash
cd plugins/
cargo new nyash-array-plugin --lib
cd nyash-array-plugin
```
#### 1.2 最小限のC FFI実装
```rust
// src/lib.rs
#[repr(C)]
pub struct NyBox {
data: *mut u8,
typeid: u64,
flags: u32,
gen: u32,
}
#[no_mangle]
pub extern "C" fn nyplug_array_abi_version() -> i32 { 1 }
#[no_mangle]
pub extern "C" fn nyplug_array_new() -> NyBox {
// 簡略実装Vec<i64>のみサポート
let vec = Box::new(Vec::<i64>::new());
NyBox {
data: Box::into_raw(vec) as *mut u8,
typeid: 3, // ArrayBox
flags: 0,
gen: 1,
}
}
#[no_mangle]
pub extern "C" fn nyplug_array_len(arr: NyBox) -> u64 {
unsafe {
let vec = &*(arr.data as *const Vec<i64>);
vec.len() as u64
}
}
```
#### 1.3 ビルド設定
```toml
# Cargo.toml
[lib]
crate-type = ["cdylib", "staticlib"] # 動的・静的両対応
```
### Step 2: VM動作確認
#### 2.1 プラグインローダーとの統合
```rust
// src/runtime/plugin_loader_v2.rsに追加
fn load_builtin_plugins(&mut self) {
// 既存のFileBox等に加えて
self.register_plugin("nyash-array-plugin", 3); // ArrayBox type_id = 3
}
```
#### 2.2 テストプログラム
```nyash
// test_array_plugin.hako
local arr
arr = new ArrayBox() // プラグイン版を呼ぶ
print(arr.length()) // 0が出力されれば成功
```
#### 2.3 VM実行
```bash
./target/release/nyash --backend vm test_array_plugin.hako
```
### Step 3: JIT動作確認
#### 3.1 LowerCoreの修正
```rust
// src/jit/lower/core.rs
match box_type {
"ArrayBox" => {
// HostCallからPluginInvokeに切り替え
b.emit_plugin_invoke(3, method_id, args);
}
// 他のBoxは従来通り
}
```
#### 3.2 JIT実行テスト
```bash
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 ./target/release/nyash --backend vm test_array_plugin.hako
```
### Step 4: 段階的移行
#### 4.1 移行優先順位
1. **ArrayBox** - 最も使用頻度が高い
2. **StringBox** - 基本的なデータ型
3. **IntegerBox/BoolBox** - プリミティブ型
4. **MapBox** - コレクション型
5. **その他** - 順次移行
#### 4.2 互換性維持
```rust
// フラグで切り替え可能に
if env::var("NYASH_USE_PLUGIN_BUILTINS").is_ok() {
// プラグイン版を使用
} else {
// 従来のビルトイン版
}
```
### Step 5: パフォーマンス測定
#### 5.1 ベンチマーク作成
```nyash
// bench_array_ops.hako
local arr = new ArrayBox()
local start = Timer.now()
loop(i in 0..1000000) {
arr.push(i)
}
local elapsed = Timer.now() - start
print("Time: " + elapsed)
```
#### 5.2 比較測定
```bash
# 従来版
./target/release/nyash --benchmark bench_array_ops.hako
# プラグイン版
NYASH_USE_PLUGIN_BUILTINS=1 ./target/release/nyash --benchmark bench_array_ops.hako
```
## 🎯 成功基準
### Phase 11週間
- [ ] ArrayBoxプラグインが動作
- [ ] VM経由で基本操作new, length, push, getが可能
- [ ] パフォーマンス劣化が10%以内
### Phase 22週間
- [ ] JIT経由でも動作
- [ ] 5つ以上のビルトインBoxがプラグイン化
- [ ] 既存テストがすべてパス
### Phase 31ヶ月
- [ ] すべての主要ビルトインBoxがプラグイン化
- [ ] 静的リンクでの最小exe生成
- [ ] Linux/macOSで動作確認
## ⚠️ 注意事項
1. **TLVエンコーディング**: 既存のプラグインシステムに合わせる
2. **エラー処理**: panicではなくエラーコードを返す
3. **メモリ管理**: Box化されたデータのライフサイクルに注意
## 💡 デバッグ時のヒント
```bash
# プラグインロード確認
NYASH_DEBUG_PLUGIN=1 ./target/release/nyash test.hako
# JIT呼び出し確認
NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm test.hako
```
---
*"手順を守れば大丈夫" - 一歩ずつ確実に進めるにゃ!*

View File

@ -0,0 +1,87 @@
# Phase 10.1 Plugin Unification Path (MIR→JIT/AOT via C ABI)
This plan refines how we leverage the existing plugin system (BID-FFI) to unify JIT and AOT (EXE) paths using a single C ABI surface.
## Goals
- Unify calls from JIT and AOT to the same C ABI (`nyrt_*` / `nyplug_*`).
- Convert builtin Boxes to Plugin Boxes in small steps (read-only first).
- Produce a minimal standalone EXE via static linking after unification.
## Feasibility Summary
- JIT: emit calls to `extern "C"` symbols (no change in semantics, only target).
- AOT: emit `.o` with unresolved `nyrt_*` / `nyplug_*` and link with `libnyrt.a` + plugin `.a`.
- Compatibility: guard with `NYASH_USE_PLUGIN_BUILTINS` and keep HostCall fallback.
## Phase Breakdown
### 10.1: Plugin PoC + C ABI base (1 week)
- Deliverables:
- Minimal headers: `nyrt.h` (runtime), `nyplug_array.h` (ArrayBox plugin).
- ArrayBox as a plugin (`cdylib` + `staticlib`), ABI version functions.
- VM loader integration and `NYASH_USE_PLUGIN_BUILTINS` switch.
- Smoke: `new/len/push/get` working via plugin.
- DoD:
- Array plugin works on VM path; perf regression ≤10% on micro bench.
### 10.2: JIT Lowering unification (Array first) (11.5 weeks)
- Deliverables:
- IRBuilder: `emit_plugin_invoke(type_id, method_id, args, sig)`.
- LowerCore BoxCall for Array routes to `plugin_invoke` (events/stats intact).
- Feature-flagged enablement: `NYASH_USE_PLUGIN_BUILTINS=1`.
- DoD:
- JIT execution of Array read/write (policy-constrained) via plugin path.
- Behavior parity with HostCall; no regressions on CI smoke.
### 10.2b: JIT Coverage Unblockers (0.51 week)
- Goal:
- Remove practical blockers so plugin_invoke can be exercised in typical Nyash functions and `.o` can be produced.
- Deliverables:
- Lowering for `NewBox` of pluginized builtins → translate `new <Box>()` to plugin `birth()` via `emit_plugin_invoke(type_id, 0, argc=1 recvr-param)` with appropriate handle threading.
- Treat `Print/Debug` as no-op/hostcall for v0 to avoid function-wide skip.
- Keep conservative skip policy by default; document `NYASH_AOT_ALLOW_UNSUPPORTED=1` for validation-only `.o` emission.
- DoD:
- Minimal demo function with `String.length()` compiled by JIT (Cranelift) and `.o` emitted. Plugin events visible under JIT.
### 10.3: Broaden plugin coverage + Compatibility (2 weeks)
- Targets: String/Integer/Bool/Map (read-only first).
- Deliverables:
- Pluginized Boxes and `plugin_invoke` lowering for BoxCall.
- HostCall route retained; whitelist-driven co-existence.
- Added smoke and microbenches comparing HostCall vs Plugin.
- DoD:
- ≥5 builtin Boxes pluginized; `NYASH_USE_PLUGIN_BUILTINS=1` green on smoke.
### 10.4: AOT/EXE minimal pipeline (23 weeks)
- Deliverables:
- ObjectWriter path to emit `.o` with unresolved `nyrt_*`/`nyplug_*`.
- `libnyrt.a` minimal runtime + selected plugin `.a`.
- Link scripts and `nyc build-aot` proof-of-concept.
- Hello World-level standalone EXE on Linux/macOS.
- DoD:
- `nyc build-aot <file.hako> -o app` runs without JIT/VM.
- Basic debug info and minimal unwind.
### 10.5: Python Integration (moved; separate phase)
- Python work is deferred to 10.5 and builds on the plugin/AOT foundation.
## Flags & Compatibility
- `NYASH_USE_PLUGIN_BUILTINS=1` enables plugin path for builtin Boxes.
- `NYASH_JIT_HOSTCALL=1` preserves HostCall path for comparison.
- Call conv alignment: x86_64 SysV, aarch64 AAPCS64, Win64.
- ABI version checks: `nyrt_abi_version()`, `nyplug_*_abi_version()` hard-fail on mismatch.
## Risks & Mitigations
- ABI drift: minimal headers + version checks.
- Linking complexity: start with the smallest set (Array/Print/GC-minimal), expand gradually.
- Performance: keep RO-first; benchmark and fall back to HostCall if needed.
- Windows linkage: prioritize Linux/macOS, then handle Win specifics in a follow-up task.
- JIT coverage: adopt staged lowering (NewBox→birth, Print/Debug no-op) to clear blockers; retain strict skip policy otherwise.
## References
- `c_abi_unified_design.md`
- `implementation_steps.md`
- `../phase-10.5/` (Python integration)
---
Everything is Plugin → unified paths for JIT and AOT.

View File

@ -0,0 +1,29 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
# Phase 10.1a - 計画と設計
## 🎯 このフェーズの目的
PythonParserBoxの全体計画を理解し、実装の方向性を把握する。
## 📁 含まれるファイル
- **`pythonparser_integrated_plan_summary.txt`** - 統合実装計画(最重要)
- **`expert_feedback_gemini_codex.txt`** - Gemini先生とCodex先生の技術評価
- **`archive/`** - 初期検討資料
## ✅ 完了条件
- [ ] 統合計画を読んで理解
- [ ] エキスパートフィードバックを確認
- [ ] 5つの核心戦略を把握
- 関数単位フォールバック
- Python 3.11固定
- 意味論の正確な実装優先
- GIL管理の最小化
- テレメトリー重視
## 📝 重要ポイント
- **Differential Testing戦略** - 世界中のPythonコードがテストケースに
- **段階的実装** - 完璧を求めず動くものから
- **成功の測定基準** - カバレッジ率70%以上、性能向上2-10倍
## ⏭️ 次のフェーズ
→ Phase 10.1b (環境設定)

View File

@ -0,0 +1,138 @@
# ChatGPT5の革命的アイデア - 多言語統合とBox化
## 元の発想
ChatGPT5さんの発想は「すべての言語をBoxで包んで統一的に扱う」という革命的なアプローチです。
これにより、Python、Rust、JavaScript、Java等の既存エコシステムをNyashから自然に利用できるようになります。
## 核心概念
### 1. ForeignBox - 外部リソースのBox化
```nyash
// 外部言語のオブジェクトをBoxとして扱う
box ForeignBox<T> {
private { handle } // 外部リソースへのハンドル
fini() {
ny_host_finalizer(me.handle) // 適切にリソース解放
}
}
```
### 2. ProxyBox - スレッドセーフな委譲
```nyash
// GILやイベントループを持つ言語用
box ProxyBox<T> {
private { bus, worker_id } // Bus経由で別スレッドに委譲
call(method, args) {
return me.bus.send_and_wait(me.worker_id, method, args)
}
}
```
## 言語別統合戦略ChatGPT5原案
### Python統合
- **課題**: GILGlobal Interpreter Lock
- **解決**: ProxyBoxでBus経由ワーカー委譲
- **実装**: CPython C-APIで`PyObject*`をForeignBoxに入れる
### JavaScript/Node.js統合
- **課題**: イベントループを壊さない
- **解決**: ProxyBoxpostMessage/uv_queue_work
- **短い同期関数**: ForeignBoxでも可
### Rust/C統合
- **最短パス**: C-ABI直接
- **Rust側**: `#[no_mangle] extern "C"`
- **所有権**: Nyash↔Rustのどちらかに寄せる二重所有禁止
### JVM/.NET統合
- **方式**: JNI/P-Invoke
- **要件**: Pinning必要
- **GC連携**: SafeHandle/PhantomReferenceでFinalizer橋渡し
### WASM統合
- **方式**: `ny_host_*`をimport
- **データ**: リニアメモリへBytes/Strで搬送
## 統一インターフェース設計
### NyIDLNyash Interface Definition Language
```idl
module ny {
box Image;
fn load(path: str) -> Image effects = io
fn resize(img: Image, w: i32, h: i32) -> Image effects = mut
fn width(img: look Image) -> i32 effects = pure
}
```
### 自動生成される要素
1. Nyash側extern宣言
2. C-ABIシム層
3. 各言語用スタブRust/Node/Python/JVM
4. ForeignBox/ProxyBoxラッパー
## 所有権と寿命管理
### One Strong Owner原則
- ForeignBoxは所有者1本NyashまたはA外部
- 弱参照は`weak/look`で管理
- 失効時はnull/false
### Finalizerの橋渡し
1. Nyash `fini` → `ny_host_finalizer`呼び出し
2. 外部GC/finalize → `ny_host_finalizer`経由でNyashのweakを失効
## 効果システムとの統合
```nyash
// 効果注釈でFFI境界の振る舞いを明示
extern fn py_numpy_matmul(a: ForeignBox<ndarray>, b: ForeignBox<ndarray>)
-> ForeignBox<ndarray> effects mut
extern fn rust_image_load(path: str)
-> ForeignBox<Image> effects io
extern fn js_fetch(url: str)
-> ProxyBox<Promise> effects io
```
## MIRレベルでの統合
### BoxCall命令の拡張
```
// 通常のBoxCall
BoxCall(%result, %box, "method", [%arg1, %arg2])
// ForeignBoxのメソッド呼び出し
BoxCall(%result, %foreign_box, "py_method", [%arg1])
// → 内部でFFI境界を越えて呼び出し
// ProxyBoxの非同期呼び出し
Send(%msg_id, %proxy_box, "method", [%args])
Recv(%result, %msg_id)
```
## 革命的な利点
1. **即座の多言語資産活用**: 既存ライブラリを「箱に詰めて」即Nyashで使える
2. **統一的な寿命管理**: 強1weak/lookfiniで外部リソースも確定的に回収
3. **配布の柔軟性**: WASM/VM/ネイティブのどれでも同じIDLから出荷
4. **MIR最適化の恩恵**: 外部言語呼び出しもMIRレベルで最適化可能
5. **段階的移行**: 既存プロジェクトを徐々にNyashに移行
## 実装優先順位
1. **Phase 1**: C/Rust統合最も単純
2. **Phase 2**: Python統合PythonParserBox
3. **Phase 3**: JavaScript/Node.js統合
4. **Phase 4**: JVM/.NET統合
5. **Phase 5**: 統一IDLと自動生成ツール
## まとめ
「すべてをBoxに閉じ込める」という設計を正式化することで、あらゆる言語→NyashとNyash→あらゆる実行系が綺麗に繋がる。
これはまさに「Everything is Box」哲学の究極の実現形態といえる。

View File

@ -0,0 +1,207 @@
# PythonParserBox設計提案 - CPythonパーサーを使ったPython→Nyash変換
## 概要
CPythonの公式パーサーを活用して、PythonコードをNyashで直接実行可能にする革命的なアプローチ。
PythonコードをNyashのAST/MIRに変換し、Nyashの最適化・JITコンパイルの恩恵を受けられるようにする。
## アーキテクチャ
### 1. PythonParserBoxビルトインBox
```nyash
// 使用例
local py_parser = new PythonParserBox()
// Pythonコードを直接パース
local ast = py_parser.parse("""
def calculate(x, y):
return x * 2 + y
result = calculate(10, 5)
""")
// NyashのASTに変換
local nyash_ast = py_parser.to_nyash_ast(ast)
// 直接実行も可能
local result = py_parser.run(python_code)
```
### 2. 実装構造
```rust
pub struct PythonParserBox {
base: BoxBase,
parser: CPythonParser, // CPythonの公式パーサー使用
}
impl PythonParserBox {
// Python → Python AST
pub fn parse(&self, code: &str) -> Box<dyn NyashBox> {
let py_ast = self.parser.parse_string(code);
Box::new(PythonAstBox { ast: py_ast })
}
// Python AST → Nyash AST
pub fn to_nyash_ast(&self, py_ast: &PythonAstBox) -> Box<dyn NyashBox> {
let converter = AstConverter::new();
converter.convert_python_to_nyash(py_ast)
}
// Python AST → MIR直接変換
pub fn to_mir(&self, py_ast: &PythonAstBox) -> MirModule {
let mut builder = MirBuilder::new();
for func in py_ast.functions() {
self.convert_function_to_mir(&mut builder, func);
}
builder.build()
}
}
```
## AST変換マッピング
### Python → Nyash対応表
| Python AST | Nyash AST | 説明 |
|------------|-----------|------|
| FunctionDef | FunctionDecl | 関数定義 |
| BinOp | BinaryOp | 二項演算 |
| Call | MethodCall | 関数呼び出し |
| Assign | Assignment | 代入 |
| If | IfStatement | 条件分岐 |
| While/For | LoopStatement | ループ |
| Return | ReturnStatement | return文 |
| Import | NewBox/LoadPlugin | import → Box化 |
### 型変換戦略
```rust
// Python動的型 → Nyash Box
match py_value {
PyInt(n) => IntegerBox::new(n),
PyFloat(f) => FloatBox::new(f),
PyStr(s) => StringBox::new(s),
PyList(items) => ArrayBox::from_iter(items),
PyDict(map) => MapBox::from_iter(map),
PyObject(obj) => PythonObjectBox::new(obj), // 変換不能な場合
}
```
## MIR生成例
### Pythonコード
```python
def calculate(x, y):
return x * 2 + y
```
### 生成されるMIR
```
function calculate(%x, %y) {
Load(%1, %x)
Const(%2, 2)
BinOp(%3, Mul, %1, %2)
Load(%4, %y)
BinOp(%5, Add, %3, %4)
Return(%5)
}
```
## 利点
1. **完全な互換性**: CPython公式パーサーで100%正確なパース
2. **統一最適化**: PythonコードもNyashのMIR最適化パイプラインを通る
3. **JIT/AOTコンパイル**: PythonコードをネイティブコードにJIT/AOTコンパイル可能
4. **段階的移行**: 既存Pythonコードを徐々にNyashに移行
5. **デバッグ統一**: Nyashのデバッグツールでpythonコードもデバッグ可能
## 実装フェーズ
### Phase 1: 基本パーサー統合
- CPythonパーサーのFFIバインディング
- parse()メソッドでPython ASTを取得
- AST可視化dump_ast
### Phase 2: AST変換
- Python AST → Nyash AST変換器
- 基本的な文法要素のサポート
- 型変換システム
### Phase 3: MIR直接生成
- Python AST → MIR変換
- Python特有の最適化動的型推論等
- ベンチマーク
### Phase 4: エコシステム統合
- NumPy等の主要ライブラリサポート
- Python例外 → Nyashエラー変換
- async/await対応
- GIL管理の自動化
## 技術的課題と解決策
### 1. GILGlobal Interpreter Lock
- 解決策: PythonコードはGILスコープ内で実行
- 将来: MIR変換後はGILフリーで実行可能
### 2. Python動的型とNyash Box型のマッピング
- 解決策: 実行時型情報を保持するPythonObjectBox
- 最適化: よく使う型int, str等は専用Boxに変換
### 3. Pythonモジュールシステム
- 解決策: importをNyashのプラグインロードにマッピング
- pip packages → Nyashプラグインとして扱う
## 実用例
### 機械学習コードの実行
```nyash
local ml_code = """
import numpy as np
from sklearn.linear_model import LinearRegression
# データ準備
X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
y = np.dot(X, np.array([1, 2])) + 3
# モデル訓練
model = LinearRegression()
model.fit(X, y)
# 予測
predictions = model.predict(np.array([[3, 5]]))
print(f'Prediction: {predictions[0]}')
"""
local py_parser = new PythonParserBox()
local result = py_parser.run(ml_code)
```
### Webアプリケーション
```nyash
local flask_app = """
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/hello/<name>')
def hello(name):
return jsonify({'message': f'Hello, {name}!'})
if __name__ == '__main__':
app.run(port=5000)
"""
local py_parser = new PythonParserBox()
py_parser.run(flask_app) // FlaskアプリがNyash内で起動
```
## 期待される効果
1. **パフォーマンス向上**: PythonコードがJITコンパイルされ高速化
2. **メモリ効率**: NyashのGC/メモリ管理を活用
3. **相互運用性**: Python↔Nyash↔Rust↔JS等の自由な組み合わせ
4. **開発効率**: 既存Pythonライブラリをそのまま使える
5. **将来性**: PythonコードをネイティブAOTコンパイル可能
## まとめ
PythonParserBoxは、Pythonの豊富なエコシステムとNyashの高性能実行エンジンを組み合わせる画期的なアプローチ。
CPythonパーサーの信頼性とNyashのMIR/JIT最適化により、Pythonコードをより高速に、より効率的に実行できる。

View File

@ -0,0 +1,98 @@
# 2025-08-27 議論まとめ - PythonParserBoxと言語間統合
## 本日の議論の流れ
### 1. ベンチマーク実行と問題発見
- インタープリター性能問題10万回ループで2分以上
- VM変数管理エラー
- Box APIの成熟度不足TimeBox.elapsed()が呼べない)
- 問題点をPhase 10ドキュメントに追記
### 2. Cranelift AOT Backendの追加Phase 10.9
- JIT実装の基盤を再利用して事前コンパイル可能
- 非同期完全サポートWASMの制限なし
- 実装期間2-3週間で可能上乗せだけ
### 3. PythonParserBox構想の深堀り
- ChatGPT5さんの「CPythonをBoxで包みMIRに落とし込む」アイデアを具体化
- CPythonの公式パーサーを使ってPythonコード→Nyash AST/MIR変換
- ビルトインBoxとして分離実装
### 4. エキスパートへの相談結果
#### Gemini先生の分析
- pyo3活用で技術的課題は解決可能
- 最初は特定ドメインのサブセットから開始すべき
- GIL管理のBox隠蔽は現実的
- 設計思想は他言語Ruby/JSにも応用可能
#### Codex先生の実装提案
- CPython内部APIではなく、安定した`ast`モジュール経由
- Python側で`ast.parse()` → JSON → Rust側で処理
- 最小実装セット定義(基本構造+演算+制御フロー)
- 純Pythonループで2-10倍の高速化が現実的
### 5. Phase 10.1フォルダの作成と整理
以下のドキュメントをPhase 10.1に整理:
- python_parser_box_design.txt基本設計
- python_parser_box_implementation_plan.txt実装計画
- chatgpt5_original_idea.txt元のアイデア
- summary_2025_08_27.txt本まとめ
## 技術的な要点
### 実装アプローチ
```rust
// pyo3でCPythonを埋め込み
pyo3 = { version = "0.22", features = ["auto-initialize"] }
// Python側でAST→JSON変換
def parse_to_json(code):
tree = ast.parse(code)
return json.dumps(ast_to_dict(tree))
// Rust側で受け取り
let json_ast = py_helper.parse_to_json(python_code);
let nyash_ast = convert_json_to_nyash_ast(json_ast);
```
### 最小実装セットPhase 1-2
- 構造: Module, FunctionDef, Return, Assign
- 演算: BinOp, Compare, Call, Name, Constant
- 制御: If, While, Br, CondBr
- 実行: 最初はCPython exec委譲、段階的にMIR実行へ
### データ共有戦略
- NumPy配列: pyo3-numpyでゼロコピー共有
- NdArrayBox: Nyash側でNumPy配列を効率的に扱う
- バッファプロトコル: PEP 3118で汎用オブジェクト共有
### 期待される効果
- 純Pythonループ: 2-10倍高速化
- NumPy処理: 1.0-1.2倍(既に最適化済み)
- 将来的: トレースベース最適化で10-30倍も可能
## 次のステップ
1. **Phase 1実装開始**1-2週間
- pyo3統合とPythonParserBox基本実装
- parse_to_jsonヘルパー作成
- 最小AST変換動作確認
2. **小規模ベンチマーク**
- 簡単なPython関数で動作確認
- 性能測定と改善点洗い出し
3. **段階的拡張**
- MIR変換実装
- NumPy統合
- より複雑なPython機能対応
## まとめ
PythonParserBoxは、Nyashの「Everything is Box」哲学を言語間統合に拡張する革命的なアプローチ。
CPythonパーサーの信頼性とNyashのMIR/JIT最適化を組み合わせることで、Pythonエコシステムを
Nyashから自然に利用でき、かつ高速化も実現できる。
ChatGPT5さんの最初のアイデアForeignBox/ProxyBoxを基に、具体的な実装計画まで落とし込めた。
技術的にも実現可能で、段階的なアプローチにより着実に実装できる見込み。

View File

@ -0,0 +1,197 @@
# PythonParserBox実装計画 - エキスパートフィードバック
日付: 2025-08-27
## Gemini先生のフィードバック
### 総評
これは非常に野心的で、言語の成熟度を飛躍的に高める可能性を秘めた素晴らしい計画です。Nyashの「Everything is a Box」哲学とPythonエコシステムを融合させるという着眼点に大変興奮しました。
### 1. 実装計画は技術的に健全か?落とし穴は?
**技術的健全性:**
はい、計画は全体として技術的に非常に健全です。
* **CPythonパーサーの利用:** `pyo3`経由で`ast.parse()`を利用するのは、Python構文との互換性を100%保証するための最も確実で賢明なアプローチです。
* **JSON中間表現(IR):** Python AST (Pythonメモリ空間) と Nyash AST (Rustメモリ空間) の間にJSONを挟むのは、言語間の境界を明確に分離する良い設計です。
* **段階的実装とフォールバック:** 未実装機能を`exec()`にフォールバックする戦略は、実用性を保ちながら段階的に実装を進めるための極めて現実的なアプローチです。
**潜在的な落とし穴:**
* **パフォーマンス:** `Python AST → JSON → Nyash AST → Nyash実行`というパイプラインは、特に初期段階では非常に低速になります。
* **ASTの複雑性の爆発:** PythonのASTは非常に巨大で、言語バージョンの更新も速いです。
* **標準ライブラリの壁:** Pythonの真の力は広範な標準/サードパーティライブラリにあります。`import`文をどう扱うかは最重要課題です。
### 2. Python AST → Nyash AST変換で注意すべき意味論の違いは
* **型システム:** Pythonは動的型付け、Nyashは静的型付けまたはより厳格な型システムを持つと推測
* **オブジェクトモデルと可変性:** Pythonのオブジェクトは基本的に可変mutable
* **スコープとクロージャ:** Pythonの`global`や`nonlocal`の挙動は独特
* **特殊メソッド (`__dunder__`):** Pythonの挙動は特殊メソッドで定義される
* **組み込み関数:** `len()`, `print()`, `range()`などをどう扱うか
### 3. Nyashパーサーのバグ検証戦略として効果的か
**非常に効果的です。** これは「Differential Testing差分テスト」と呼ばれる強力な手法です。
* **巨大なテストスイート:** 事実上、世の中にある無数のPythonコードがNyashのテストケースになります。
* **微妙なバグの発見:** 手書きの単体テストでは見逃しがちなセマンティクスのバグを発見するのに絶大な効果を発揮します。
### 4. pyo3統合でのGIL管理のベストプラクティスは
* **基本原則:** Pythonオブジェクトに触れるコードは、必ずGILを獲得した状態で実行
* **GILの必要期間を最小化する**
* **`py.allow_threads`の活用:** 時間がかかり、かつPythonオブジェクトに触れない処理で使用
### 5. 段階的実装Phase 1-4の優先順位は適切か
はい、提案されている優先順位は非常に適切です。
1. Phase 1: 基本構文 + 変数束縛 + 基本的な式 + プリミティブ型
2. Phase 2: list, dict, tuple
3. Phase 3: 関数とスコープ
4. Phase 4: モジュールとクラス
**最優先で並行すべきこと:** `exec()`へのフォールバック機構
### 6. 言語成熟度向上への貢献度をどう評価する?
**定量的指標:**
* ライブラリ互換性カバレッジ
* パフォーマンステスト
* 発見バグ数
**定性的指標:**
* 表現力の向上
* 開発者体験
* エコシステムのマイルストーン
### 結論
この`PythonParserBox`計画は、単なる機能追加ではなく、**Nyash言語のテスト、デバッグ、そしてエコシステム獲得を同時に加速させる、極めて戦略的な一手**です。
---
## Codex先生のフィードバック
### Overall Verdict
- Sound approach: Using CPython's parser via pyo3, lowering via a JSON IR, and gradually replacing exec() with Nyash MIR/JIT is feasible and strategically strong.
- Biggest risks: Semantic mismatches at statement/expression boundaries, version skew of Python AST, and boundary-costs between CPython and Nyash during phased rollout.
### Architectural Pitfalls
- **Python version skew:** `ast` schema changes across minors. Pin and encode `py_version` + `ast_format` in the JSON.
- **AST stability vs syntax fidelity:** `ast` loses comments and some token distinctions
- **Boundary granularity:** Whole-file fallback wastes partial coverage; per-node fallback is unsafe. **The practical unit is per-function.**
- **Import system and environment:** Python imports pull arbitrary code
- **Error mapping:** Propagate Python exceptions with full traceback
- **Performance overhead:** Python AST→JSON→Nyash→MIR is heavy
- **Object model mismatch:** Identity (`is`), mutability, truthiness, numeric tower
- **Concurrency:** GIL limits parallel parse/exec
### AST→Nyash Semantics: High-Risk Differences
- **Names and scope:**
- LEGB resolution; `global`/`nonlocal` behavior; closures and cell variables
- Comprehension scopes (separate scope in Python 3)
- **Control flow:**
- `for` iterates via iterator protocol; `for/else`, `while/else` semantics
- Short-circuit truthiness uses Python rules; `__bool__` then `__len__`
- **Functions:**
- Defaults evaluated at definition time; `*args/**kwargs`
- Decorators transform functions at definition time
- **Operators and numbers:**
- `/` true division; `//` floor division; big integers by default
- Operator dispatch via dunder methods; `is` vs `==`
For Phase 1, the must-haves are: LEGB + locals/freevars, default args timing, iterator-based `for`, `for/else` + `while/else`, Python truthiness and short-circuiting.
### Fallback Strategy
- **Fallback unit: Per-function.** If a function body contains unsupported nodes, compile a "PyThunk" that calls into CPython.
- **Boundary types:** Define canonical bridges: `PyAnyBox` in Nyash wrapping `Py<PyAny>`
- **Imports and globals:** Execute module top-level in Python; then selectively replace functions
### pyo3/GIL Best Practices
- **Initialization:** Call `pyo3::prepare_freethreaded_python()` once
- **GIL usage:**
- Use `Python::with_gil(|py| { ... })` for all Python calls
- Minimize time under GIL; copy data out promptly
- For heavy Rust work, drop GIL: `py.allow_threads(|| { ... })`
- **Data transfer:** Prefer building JSON on the Python side
- **Versioning:** Pin Python minor version; embed version string in the IR
### Phasing and Priorities (Refined)
- **Phase 1 (Parser + Minimal Semantics):**
- Python→JSON exporter with location info
- Nyash IR for expressions and basic statements
- Semantics fidelity for: iterator protocol, truthiness, scoping
- **Fallback per-function for anything else**
- **Phase 2-4:** Coverage expansion → Objects/Runtime → MIR/JIT
### Parser Bug Validation Strategy
- **Differential execution:** Curate pairs of semantically equivalent snippets
- **Oracle testing:** Run CPython as oracle and compare
- **Fuzzing:** Grammar-based fuzzers
- **Coverage and gating:** Track node-kind coverage
### IR/JSON Design Tips
- Include: `node_type`, children, `lineno/col_offset`, `py_version`, `ast_format`, `support_level`
- Canonicalize: normalize forms, operator names
- Determinism: maintain stable field ordering
### Concrete Recommendations
- **Pin to one Python minor (e.g., 3.11 or 3.12)**
- **Choose per-function fallback as the core boundary**
- **Implement Python truthiness, iterator protocol, and scoping correctly before optimizing**
- **Keep the GIL minimal: build the JSON in Python; parse in Rust**
- **Telemetry from day one: log unsupported node kinds and fallback counts**
- **Start with JSON; plan migration to a compact binary once stable**
---
## 統合された重要ポイント
### 🎯 両エキスパートが一致した最重要事項
1. **関数単位のフォールバック戦略**
- ファイル全体でなく関数レベルでコンパイル/フォールバックを切り替え
- 未対応機能を含む関数はCPython exec、対応済み関数はNyash MIR/JIT
2. **Python バージョン固定**
- Python 3.11または3.12に固定
- AST安定性の確保とバージョン間の差異回避
3. **意味論の正確な実装が最優先**
- 最適化より先にPython互換性を確保
- 特に: イテレータプロトコル、真偽値判定、スコーピング規則
4. **GIL管理の最小化**
- Python側でJSON生成、Rust側で解析
- 重い処理はGIL外で実行
5. **テレメトリーの重要性**
- 未対応ノードの記録
- フォールバック率の計測
- 実行時の統計情報収集
### 🚨 特に注意すべき意味論の違い
1. **制御フロー**
- for/else, while/else の独特な挙動
- forループのイテレータプロトコル
2. **スコープ規則**
- LEGBLocal, Enclosing, Global, Builtins
- global/nonlocal宣言
- 内包表記の独立スコープPython 3
3. **数値演算**
- / (true division) vs // (floor division)
- デフォルトで大整数
- NaN の扱い
4. **関数定義**
- デフォルト引数は定義時に評価
- *args/**kwargs の扱い
- デコレータの実行順序
### 📊 成功の測定指標
1. **カバレッジ**: コンパイル済み vs フォールバック関数の比率
2. **性能向上**: 数値計算ベンチマークでの改善率
3. **バグ発見数**: Differential Testingで発見されたバグ数
4. **エコシステム**: 動作する有名Pythonライブラリの数

View File

@ -0,0 +1,148 @@
# PythonParserBox統合実装計画 - エキスパート評価後の最終版
作成日: 2025-08-27
## 🎯 革命的な3つの価値
### 1. Pythonエコシステムの即座活用
- 既存のPythonライブラリをNyashから直接利用可能
- 段階的な移行パスの提供
### 2. Nyashパーサーのバグ自動検証Differential Testing
- **世界中のPythonコードがNyashのテストケースに**
- CPythonをオラクルとして使用、出力・戻り値・例外を自動比較
- 微妙なセマンティクスバグを大量に発見可能
### 3. 言語成熟度の飛躍的向上
- 実用的なPythonコードでNyashをストレステスト
- 発見されたバグ数が成熟度向上の定量的指標
## 🏆 エキスパート評価サマリー
### Gemini先生の評価
**「非常に野心的で、言語の成熟度を飛躍的に高める可能性を秘めた素晴らしい計画」**
- 技術的に健全なアプローチ
- pyo3経由のCPythonパーサー利用は最も確実
- Differential Testingは極めて強力な手法
### Codex先生の評価
**「Sound approach with strategic strength」**
- 関数単位フォールバックが実用的かつ効果的
- Python 3.11固定でAST安定性確保
- テレメトリー重視で継続的改善可能
## 🔑 統合された5つの核心戦略
### 1. 関数単位フォールバック(両エキスパート一致)
```python
def supported_function(): # → Nyash MIR/JIT
return x + y
def unsupported_function(): # → CPython exec
yield from generator # Phase 1では未対応
```
### 2. Python 3.11固定
- AST安定性確保3.8 Constant統一、3.10 match/case、3.12位置情報)
- `py_version`と`ast_format`をJSON IRに埋め込む
### 3. 意味論の正確な実装優先
Phase 1必須要素Codex先生強調
- LEGB + locals/freevarsスコーピング
- デフォルト引数の評価タイミング(定義時)
- イテレータベースのfor文
- for/else + while/elsePython独特
- Python真偽値判定`__bool__` → `__len__`
- 短絡評価and/or
### 4. GIL管理の最小化
```rust
// GILは最小限に
let json_ast = Python::with_gil(|py| {
py_helper.parse_to_json(py, code) // Python側でJSON生成
})?;
// GIL外でRust処理
let nyash_ast = py.allow_threads(|| {
convert_json_to_nyash(json_ast)
});
```
### 5. テレメトリー基盤
```bash
[PythonParser] Module: example.py (Python 3.11)
Functions: 10 total
Compiled: 7 (70%)
Fallback: 3 (30%)
- async_function: unsupported node 'AsyncFunctionDef' at line 23
```
## 📋 実装フェーズ(詳細版)
### Phase 0: 準備1週間
- [ ] Python 3.11.9環境固定
- [ ] テレメトリー基盤構築
- [ ] Differential Testingフレームワーク
- [ ] JSON IR仕様策定
### Phase 1: Core Subset2週間
- [ ] pyo3統合prepare_freethreaded_python
- [ ] 関数単位コンパイル判定器
- [ ] 基本構文def/if/for/while/return
- [ ] 意味論必須要素の実装
- [ ] CPythonとの出力比較テスト
### Phase 2: Data Model3週間
- [ ] 特殊メソッドマッピング
- [ ] list/dict/tuple実装
- [ ] 演算子オーバーロード
### Phase 3: Advanced Features1ヶ月
- [ ] 例外処理try/except
- [ ] with文、ジェネレータ
- [ ] 内包表記、デコレータ
## 📊 成功の測定基準
### 定量的指標
| 指標 | 目標 | 測定方法 |
|------|------|----------|
| カバレッジ率 | 70%以上 | コンパイル済み vs フォールバック関数 |
| 性能向上 | 2-10倍 | 純Pythonループのベンチマーク |
| バグ発見数 | 10+件/Phase | Differential Testing |
| エコシステム | 1以上 | 動作する有名ライブラリ数 |
### マイルストーン
- Phase 1: "Hello from Python in Nyash"が動作
- Phase 2: scikit-learnの基本アルゴリズムが動作
- Phase 3: FlaskのHello Worldが動作
- Phase 4: PyPIトップ100の30%が基本動作
## 🚨 注意すべき意味論の違いトップ5
1. **制御フロー**: for/else, while/else
2. **スコープ規則**: LEGB、global/nonlocal
3. **数値演算**: / (true division) vs //
4. **関数定義**: デフォルト引数は定義時評価
5. **真偽値判定**: Pythonの__bool__/__len__ルール
## 🎉 期待されるインパクト
### 技術的成果
- Pythonエコシステムの活用
- Nyashパーサーの品質向上
- 性能最適化の実証
### 戦略的価値
- 言語成熟度の飛躍的向上
- 開発者コミュニティの拡大
- 実用アプリケーション開発の加速
## 📝 結論
PythonParserBoxは、単なる機能追加ではなく、**Nyash言語のテスト、デバッグ、エコシステム獲得を同時に加速させる極めて戦略的なプロジェクト**。
両エキスパートの技術的評価と具体的な実装指針により、実現可能性が確認され、明確な実装パスが定まった。
**「Everything is Box」哲学を、言語の壁を超えて実現する革命的な一歩。**

View File

@ -0,0 +1,57 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
# Phase 10.1b - 環境設定とセットアップ
## 🎯 このフェーズの目的
PythonParserBox実装に必要な開発環境を整える。
## 📋 セットアップ手順
### 1. Python 3.11環境の固定
```bash
# pyenvを使用する場合
pyenv install 3.11.9
pyenv local 3.11.9
# または直接指定
python3.11 --version # 3.11.9であることを確認
```
### 2. Cargo.tomlへの依存関係追加
```toml
[dependencies]
pyo3 = { version = "0.22", features = ["auto-initialize"] }
pyo3-numpy = "0.22" # NumPy連携用Phase 3で使用
serde_json = "1.0" # JSON中間表現用
```
### 3. 環境変数の設定
```bash
# テレメトリー用
export NYASH_PYTHONPARSER_TELEMETRY=1 # 基本統計
export NYASH_PYTHONPARSER_TELEMETRY=2 # 詳細ログ
export NYASH_PYTHONPARSER_STRICT=1 # フォールバック時にパニックCI用
```
### 4. ディレクトリ構造の準備
```
src/boxes/python_parser_box/
├── mod.rs # メインモジュール
├── py_helper.rs # Python側ヘルパー
├── converter.rs # AST変換器
└── telemetry.rs # テレメトリー実装
```
## ✅ 完了条件
- [ ] Python 3.11.9がインストールされている
- [ ] Cargo.tomlに依存関係が追加されている
- [ ] 開発ディレクトリ構造が準備されている
- [ ] 環境変数の設定方法を理解している
## 🚨 注意事項
- **Python 3.11固定必須** - AST安定性のため
- **pyo3::prepare_freethreaded_python()** を一度だけ呼ぶ
- GIL管理に注意Phase 10.1cで詳細)
## ⏭️ 次のフェーズ
→ Phase 10.1c (パーサー統合実装)

View File

@ -0,0 +1,65 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
Note: 本来は「PythonをNyashで動かすフェーズパーサー統合」の位置づけでしたが、現在は順番を変更し、先に 10.5bMIR→VM→ネイティブビルド基盤を進めています。
# Phase 10.1c - パーサー統合実装
## 🎯 このフェーズの目的
pyo3を使ってCPythonパーサーをNyashに統合し、Python AST → JSON → Nyash ASTの変換パイプラインを構築する。
## 📁 実装ドキュメント
- **`python_parser_box_implementation_plan.txt`** - 技術的実装計画
- **`builtin_box_implementation_flow.txt`** - ビルトインBox実装フロー
## 🔧 実装タスク
### 1. PythonParserBoxの基本構造
```rust
pub struct PythonParserBox {
base: BoxBase,
py_helper: Arc<Mutex<PyHelper>>,
}
```
### 2. GIL管理の実装
```rust
// ✅ 良い例GILを最小限に
let json_ast = Python::with_gil(|py| {
py_helper.parse_to_json(py, code)
})?;
// GIL外でRust処理
let nyash_ast = py.allow_threads(|| {
convert_json_to_nyash(json_ast)
});
```
### 3. Python側ヘルパー実装
- `ast.parse()` → JSON変換
- 位置情報の保持lineno, col_offset
- Python 3.11固定チェック
### 4. 関数単位フォールバック判定
```rust
pub fn can_compile(&self, func_def: &PythonAst) -> CompileResult {
// サポートされているノードかチェック
// CompileResult::Compile or CompileResult::Fallback
}
```
## ✅ 完了条件
- [ ] PythonParserBoxがビルトインBoxとして登録されている
- [ ] `parse_to_json()` メソッドが動作する
- [ ] GIL管理が適切に実装されている
- [ ] テレメトリー基盤が組み込まれている
- [ ] 簡単なPythonコードでJSON ASTが取得できる
## 🧪 動作確認
```nyash
local py = new PythonParserBox()
local json_ast = py.parse_to_json("def hello(): return 'Hello'")
print(json_ast) // JSON ASTが表示される
```
## ⏭️ 次のフェーズ
→ Phase 10.1d (Core実装)

View File

@ -0,0 +1,553 @@
# PythonParserBox ビルトインBox実装フローエキスパート統合版
CPythonパーサー統合とPhase 1実装の具体的な流れ
更新日: 2025-08-27
## 🎯 全体の実装フロー
### Step 0: Python 3.11固定(エキスパート推奨)
```
- Python 3.11.9を使用AST安定性確保
- pyenvまたはpython3.11コマンドで固定
- py_versionとast_formatをJSON IRに必ず含める
```
### Step 1: ビルトインBoxとしての基盤作成
```
1. src/boxes/python_parser_box/mod.rs を作成
2. BoxBase + BoxCore統一アーキテクチャに準拠
3. PythonParserBoxの基本構造を定義
4. src/boxes/mod.rs に登録
5. テレメトリー基盤を初期から組み込む
```
### Step 2: pyo3統合とCPythonパーサー接続
```
1. Cargo.tomlに pyo3依存関係追加
2. pyo3::prepare_freethreaded_python()で一度だけ初期化
3. ast.parse()へのFFIブリッジ実装
4. JSON中間表現への変換Python側でJSON生成
5. GILは最小限に、py.allow_threads()でRust処理
```
### Step 3: Phase 1機能の実装必須意味論要素
```
必須要素Codex先生強調:
- LEGBスコーピング + locals/freevars
- デフォルト引数の定義時評価
- イテレータプロトコルfor文
- for/else + while/else
- Python真偽値判定
- 短絡評価and/or
実装手順:
1. 関数単位フォールバック戦略の実装
2. 基本的なAST変換def, if, for, while, return
3. 式の変換(算術/比較/論理演算子、関数呼び出し)
4. Nyash ASTへの意味論を保ったマッピング
5. Differential Testingフレームワーク
```
## 📝 具体的な実装コード
### 1. ビルトインBox定義src/boxes/python_parser_box/mod.rs
```rust
use crate::core::{BoxBase, BoxCore, NyashBox};
use crate::ast;
use pyo3::prelude::*;
use std::sync::{Arc, Mutex};
pub struct PythonParserBox {
base: BoxBase,
py_helper: Arc<Mutex<PyHelper>>, // Python実行環境
}
impl BoxCore for PythonParserBox {
fn box_id(&self) -> u64 {
self.base.box_id()
}
fn parent_type_id(&self) -> Option<std::any::TypeId> {
self.base.parent_type_id()
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "PythonParserBox#{}", self.box_id())
}
}
impl NyashBox for PythonParserBox {
fn type_name(&self) -> &'static str {
"PythonParserBox"
}
fn clone_box(&self) -> Box<dyn NyashBox> {
Box::new(PythonParserBox {
base: BoxBase::new(),
py_helper: self.py_helper.clone(),
})
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}
```
### 2. メソッド実装Phase 1対応
```rust
// テレメトリー用構造体
#[derive(Default)]
pub struct CompilationTelemetry {
compiled_functions: Vec<String>,
fallback_functions: Vec<(String, String, usize)>, // (name, reason, lineno)
unsupported_nodes: HashMap<String, usize>, // node_type -> count
}
impl PythonParserBox {
// コンストラクタ
pub fn new() -> Result<Self, String> {
// 一度だけ初期化
static INIT: std::sync::Once = std::sync::Once::new();
INIT.call_once(|| {
pyo3::prepare_freethreaded_python();
});
// Python環境の初期化
Python::with_gil(|py| {
// Python 3.11確認
let version = py.version_info();
if version.major != 3 || version.minor != 11 {
return Err(format!("Python 3.11 required, got {}.{}",
version.major, version.minor));
}
let helper = PyHelper::new(py)?;
Ok(PythonParserBox {
base: BoxBase::new(),
py_helper: Arc::new(Mutex::new(helper)),
})
})
}
// Python code → JSON AST
pub fn parse_to_json(&self, code: &str) -> Result<String, String> {
let helper = self.py_helper.lock().unwrap();
Python::with_gil(|py| {
helper.parse_to_json(py, code)
})
}
// JSON AST → Nyash ASTPhase 1機能のみ
pub fn json_to_nyash_ast(&self, json: &str) -> Result<ast::Program, String> {
let py_ast: Phase1PythonAst = serde_json::from_str(json)
.map_err(|e| format!("JSON parse error: {}", e))?;
let converter = Phase1Converter::new();
converter.convert(py_ast)
}
// 直接実行(関数単位フォールバック)
pub fn run(&self, code: &str) -> Result<Box<dyn NyashBox>, String> {
// まずJSON ASTを取得
let json_ast = self.parse_to_json(code)?;
let py_ast: serde_json::Value = serde_json::from_str(&json_ast)?;
// モジュール内の各関数をチェック
let compiler = FunctionCompiler::new();
let module_result = compiler.compile_module(&py_ast)?;
// テレメトリー出力(環境変数で制御)
if std::env::var("NYASH_PYTHONPARSER_TELEMETRY").is_ok() {
compiler.print_telemetry();
}
// 実行コンパイル済み関数はMIR、他はCPython
module_result.execute()
}
}
```
### 3. Python側ヘルパー実装
```rust
// Pythonコードを文字列として埋め込み
const PYTHON_HELPER_CODE: &str = r#"
import ast
import json
import sys
# Python 3.11固定チェック
assert sys.version_info[:2] == (3, 11), f"Python 3.11 required, got {sys.version}"
def ast_to_dict(node):
"""Phase 1: 基本的なAST要素のみ変換エキスパート推奨JSON IR"""
result = {
"node_type": node.__class__.__name__,
"py_version": "3.11",
"ast_format": "v1"
}
# 位置情報(エラー診断用)
if hasattr(node, 'lineno'):
result['lineno'] = node.lineno
result['col_offset'] = node.col_offset
if hasattr(node, 'end_lineno'):
result['end_lineno'] = node.end_lineno
result['end_col_offset'] = node.end_col_offset
if isinstance(node, ast.Module):
return {
"type": "Module",
"body": [ast_to_dict(stmt) for stmt in node.body]
}
elif isinstance(node, ast.FunctionDef):
# 意味論上重要:デフォルト引数情報を保存
args_info = {
"args": [arg.arg for arg in node.args.args],
"defaults": [ast_to_dict(default) for default in node.args.defaults],
"kwonlyargs": [arg.arg for arg in node.args.kwonlyargs],
"kw_defaults": [ast_to_dict(d) if d else None for d in node.args.kw_defaults]
}
result.update({
"name": node.name,
"args": args_info,
"body": [ast_to_dict(stmt) for stmt in node.body],
"decorator_list": [], # Phase 1では未対応
"support_level": "full" # コンパイル可能
})
return result
elif isinstance(node, ast.Return):
return {
"type": "Return",
"value": ast_to_dict(node.value) if node.value else None
}
elif isinstance(node, ast.BinOp):
return {
"type": "BinOp",
"op": node.op.__class__.__name__,
"left": ast_to_dict(node.left),
"right": ast_to_dict(node.right)
}
elif isinstance(node, ast.Call):
return {
"type": "Call",
"func": ast_to_dict(node.func),
"args": [ast_to_dict(arg) for arg in node.args]
}
elif isinstance(node, ast.Name):
return {
"type": "Name",
"id": node.id
}
elif isinstance(node, ast.Constant):
return {
"type": "Constant",
"value": node.value
}
elif isinstance(node, ast.If):
return {
"type": "If",
"test": ast_to_dict(node.test),
"body": [ast_to_dict(stmt) for stmt in node.body],
"orelse": [ast_to_dict(stmt) for stmt in node.orelse]
}
elif isinstance(node, ast.For):
# 意味論上重要for/else構文
result.update({
"target": ast_to_dict(node.target),
"iter": ast_to_dict(node.iter),
"body": [ast_to_dict(stmt) for stmt in node.body],
"orelse": [ast_to_dict(stmt) for stmt in node.orelse], # else節
"support_level": "full"
})
return result
elif isinstance(node, ast.While):
# 意味論上重要while/else構文
result.update({
"test": ast_to_dict(node.test),
"body": [ast_to_dict(stmt) for stmt in node.body],
"orelse": [ast_to_dict(stmt) for stmt in node.orelse], # else節
"support_level": "full"
})
return result
elif isinstance(node, ast.BoolOp):
# 意味論上重要:短絡評価
result.update({
"op": node.op.__class__.__name__, # And, Or
"values": [ast_to_dict(v) for v in node.values],
"support_level": "full"
})
return result
else:
# Phase 1では未対応テレメトリー用
return {
"node_type": "Unsupported",
"original_type": type(node).__name__,
"support_level": "fallback",
"lineno": getattr(node, 'lineno', -1)
}
def parse_to_json(code):
try:
tree = ast.parse(code)
return json.dumps(ast_to_dict(tree))
except Exception as e:
return json.dumps({"type": "Error", "message": str(e)})
"#;
struct PyHelper {
// Python側のヘルパー関数への参照を保持
parse_func: PyObject,
}
impl PyHelper {
fn new(py: Python) -> PyResult<Self> {
// ヘルパーコードをPythonで実行
let helpers = PyModule::from_code(py, PYTHON_HELPER_CODE, "helper.py", "helper")?;
let parse_func = helpers.getattr("parse_to_json")?.to_object(py);
Ok(PyHelper { parse_func })
}
fn parse_to_json(&self, py: Python, code: &str) -> Result<String, String> {
match self.parse_func.call1(py, (code,)) {
Ok(result) => result.extract::<String>(py)
.map_err(|e| format!("Extract error: {}", e)),
Err(e) => Err(format!("Parse error: {}", e))
}
}
}
```
### 4. Phase 1 AST変換器
```rust
struct Phase1Converter;
impl Phase1Converter {
fn new() -> Self {
Phase1Converter
}
fn convert(&self, py_ast: Phase1PythonAst) -> Result<ast::Program, String> {
match py_ast {
Phase1PythonAst::Module { body } => {
let mut items = vec![];
for stmt in body {
match self.convert_statement(stmt)? {
Some(item) => items.push(item),
None => {} // 未対応要素はスキップ
}
}
Ok(ast::Program { items })
}
_ => Err("Expected Module at top level".into())
}
}
fn convert_statement(&self, stmt: Phase1PythonAst) -> Result<Option<ast::ProgramItem>, String> {
match stmt {
Phase1PythonAst::FunctionDef { name, args, body } => {
// Python def → Nyash function
let params = args.into_iter()
.map(|arg| ast::Parameter { name: arg, ty: None })
.collect();
let nyash_body = self.convert_body(body)?;
Ok(Some(ast::ProgramItem::Function(ast::FunctionDef {
name,
params,
body: nyash_body,
return_type: None,
})))
}
Phase1PythonAst::Return { value } => {
let expr = value
.map(|v| self.convert_expression(v))
.transpose()?;
Ok(Some(ast::ProgramItem::Statement(ast::Statement::Return(expr))))
}
// 他の文も同様に変換
_ => Ok(None) // Phase 1では未対応
}
}
fn convert_expression(&self, expr: Phase1PythonAst) -> Result<ast::Expression, String> {
match expr {
Phase1PythonAst::BinOp { op, left, right } => {
let left = Box::new(self.convert_expression(*left)?);
let right = Box::new(self.convert_expression(*right)?);
let op = match op.as_str() {
"Add" => ast::BinaryOp::Add,
"Sub" => ast::BinaryOp::Sub,
"Mul" => ast::BinaryOp::Mul,
"Div" => ast::BinaryOp::Div,
_ => return Err(format!("Unsupported operator: {}", op))
};
Ok(ast::Expression::BinaryOp { op, left, right })
}
Phase1PythonAst::Constant { value } => {
// Python定数 → Nyashリテラル
match value {
serde_json::Value::Number(n) => {
if let Some(i) = n.as_i64() {
Ok(ast::Expression::Integer(i))
} else if let Some(f) = n.as_f64() {
Ok(ast::Expression::Float(f))
} else {
Err("Unsupported number type".into())
}
}
serde_json::Value::String(s) => {
Ok(ast::Expression::String(s))
}
serde_json::Value::Bool(b) => {
Ok(ast::Expression::Bool(b))
}
_ => Err("Unsupported constant type".into())
}
}
// 他の式も同様
_ => Err("Unsupported expression in Phase 1".into())
}
}
}
```
### 5. インタープリター統合src/interpreter/builtins.rs
```rust
// ビルトインBox登録に追加
pub fn register_builtin_boxes(env: &mut Environment) {
// 既存のBox登録...
// PythonParserBox追加
env.register_builtin_box("PythonParserBox", || {
match PythonParserBox::new() {
Ok(parser) => Arc::new(parser) as Arc<dyn NyashBox>,
Err(e) => panic!("Failed to initialize PythonParserBox: {}", e)
}
});
}
```
### 6. 使用例とテストケース
```nyash
// test_python_parser_phase1.hako
local py = new PythonParserBox()
// Phase 1: 基本的な関数定義と演算
local code = """
def add(x, y):
return x + y
def multiply(x, y):
return x * y
def calculate(a, b):
sum_val = add(a, b)
prod_val = multiply(a, b)
return sum_val + prod_val
"""
// パースしてJSON ASTを確認
local json_ast = py.parse_to_json(code)
print("JSON AST: " + json_ast)
// Nyash ASTに変換
local nyash_ast = py.json_to_nyash_ast(json_ast)
print("Conversion successful!")
// 実行最初はCPython経由
local result = py.run(code + "\nprint(calculate(10, 5))")
```
## 📊 段階的な実装計画
### Week 1: 基盤構築
- [ ] PythonParserBoxの基本構造
- [ ] pyo3統合とPython環境初期化
- [ ] parse_to_json基本実装
- [ ] エラーハンドリング
### Week 2: Phase 1変換器
- [ ] Phase1PythonAstの定義
- [ ] Phase1Converterの実装
- [ ] 基本的な文と式の変換
- [ ] テストケース作成
### Week 3: 統合とテスト
- [ ] インタープリター統合
- [ ] CPython exec経由の実行
- [ ] ベンチマーク準備
- [ ] ドキュメント整備
## 🚀 期待される成果
### Phase 1完了時点で実現できること
1. **基本的なPythonコードの実行**
- 関数定義、算術演算、条件分岐、ループ
2. **Nyash ASTへの変換**
- 将来のMIR/JIT最適化への道筋
3. **統合開発環境**
- PythonコードとNyashコードの混在実行
4. **性能測定基盤**
- CPython実行 vs Nyash実行の比較
## 📡 テレメトリー出力例
```bash
# 環境変数で制御
export NYASH_PYTHONPARSER_TELEMETRY=1 # 基本統計
export NYASH_PYTHONPARSER_TELEMETRY=2 # 詳細ログ
export NYASH_PYTHONPARSER_STRICT=1 # フォールバック時にパニック
# 実行例
./target/release/nyash test_python_parser.hako
# 出力
[PythonParser] Module: test.py (Python 3.11)
Functions: 10 total
Compiled: 7 (70%) → Nyash MIR/JIT
Fallback: 3 (30%) → CPython exec
- async_function: unsupported node 'AsyncFunctionDef' at line 23
- generator_func: unsupported node 'Yield' at line 45
- decorator_func: unsupported node 'decorator_list' at line 67
Unsupported Nodes Summary:
AsyncFunctionDef: 1
Yield: 2
ClassDef: 1
```
## 📊 Differential Testingフレームワーク
```rust
// CPythonとNyashの出力比較
pub fn differential_test(code: &str) -> TestResult {
// CPythonで実行オラクル
let python_result = Python::with_gil(|py| {
capture_python_execution(py, code)
})?;
// Nyashで実行
let nyash_result = execute_with_pythonparser(code)?;
// 結果比較
compare_results(python_result, nyash_result)
}
```
---
作成日: 2025-08-27
Phase 1実装の具体的な手順とエキスパートフィードバック統合

View File

@ -0,0 +1,361 @@
# PythonParserBox実装計画統合版
更新日: 2025-08-27
## 🎯 エキスパートからの統合フィードバック
### 最重要ポイント(両エキスパートが一致)
1. **関数単位のフォールバック戦略**
- ファイル全体でなく関数レベルでコンパイル/フォールバックを切り替え
- 未対応機能を含む関数はCPython exec、対応済み関数はNyash MIR/JIT
2. **Python 3.11固定**
- AST安定性の確保3.8 Constant統一、3.10 match/case、3.12位置情報)
- `py_version`と`ast_format`をJSON IRに埋め込む
3. **意味論の正確な実装が最優先**
- 最適化より先にPython互換性を確保
- 特に: イテレータプロトコル、真偽値判定、スコーピング規則LEGB
4. **GIL管理の最小化**
- Python側でJSON生成`ast.NodeVisitor` + `json.dumps`
- Rust側で解析GIL外で実行
- `py.allow_threads(|| { ... })`で重い処理をGIL外実行
5. **テレメトリー重視**
- 未対応ノードの記録(`support_level`フィールド)
- フォールバック率の計測
- ソース位置情報の保持(`lineno/col_offset/end_*`
### Differential Testing戦略
- **世界中のPythonコードがNyashのテストケース**
- CPythonを「オラクル」として使用
- 出力、戻り値、例外を比較
- Grammar-based fuzzingHypothesis活用
## 技術的実装方針
### 1. CPythonパーサー統合pyo3使用
```rust
// Cargo.toml
[dependencies]
pyo3 = { version = "0.22", features = ["auto-initialize"] }
pyo3-numpy = "0.22" // NumPy連携用
// 初期化(一度だけ)
pyo3::prepare_freethreaded_python();
// Python側ヘルパーembedded
const PYTHON_HELPER: &str = r#"
import ast
import json
import sys
def parse_to_json(code, filename="<string>", mode="exec"):
tree = ast.parse(code, filename, mode)
return json.dumps(ast_to_dict(tree))
def ast_to_dict(node):
result = {}
# 必須フィールド
result['node_type'] = node.__class__.__name__
result['py_version'] = f"{sys.version_info.major}.{sys.version_info.minor}"
# 位置情報(エラー診断用)
if hasattr(node, 'lineno'):
result['lineno'] = node.lineno
result['col_offset'] = node.col_offset
if hasattr(node, 'end_lineno'): # Python 3.8+
result['end_lineno'] = node.end_lineno
result['end_col_offset'] = node.end_col_offset
# サポートレベルNyash側で設定
result['support_level'] = 'unknown'
# ASTフィールド
if isinstance(node, ast.AST):
for field in node._fields:
value = getattr(node, field)
result[field] = ast_to_dict(value)
elif isinstance(node, list):
return [ast_to_dict(x) for x in node]
else:
return node
return result
"#;
```
### 2. 最小実装セットPhase 1: Must-Have
```
Phase 1 意味論の必須要素Codex先生強調:
- LEGB + locals/freevarsスコーピング
- デフォルト引数の評価タイミング(定義時)
- イテレータベースのfor文
- for/else + while/elsePython独特
- Python真偽値判定__bool__ → __len__
- 短絡評価and/or
Phase 1 AST構造:
├─ Module (py_version, ast_format)
├─ FunctionDef (name, args, body, decorator_list=[])
│ └─ arguments (args, defaults, kwonlyargs=[], kw_defaults=[])
├─ Return (value)
├─ Assign (targets, value)
├─ AugAssign (target, op, value) # +=, -=等
└─ Expr (value)
Phase 1 式:
├─ BinOp (left, op, right)
│ └─ ops: Add, Sub, Mult, Div, FloorDiv, Mod, Pow
├─ Compare (left, ops, comparators)
│ └─ ops: Eq, NotEq, Lt, LtE, Gt, GtE, Is, IsNot
├─ BoolOp (op, values) # and/or
├─ UnaryOp (op, operand) # not, -, +
├─ Call (func, args, keywords=[])
├─ Name (id, ctx=Load/Store/Del)
├─ Constant (value) # Python 3.8+統一
└─ IfExp (test, body, orelse) # 三項演算子
Phase 1 制御フロー:
├─ If (test, body, orelse)
├─ While (test, body, orelse) # else節対応必須
├─ For (target, iter, body, orelse) # else節対応必須
├─ Break
└─ Continue
```
### 3. 関数単位フォールバック戦略
```rust
// 関数単位のコンパイル判定
pub struct FunctionCompiler {
supported_nodes: HashSet<&'static str>,
telemetry: CompilationTelemetry,
}
impl FunctionCompiler {
pub fn can_compile(&self, func_def: &PythonAst) -> CompileResult {
let mut visitor = SupportChecker::new(&self.supported_nodes);
visitor.visit(func_def);
if visitor.has_unsupported() {
// CPython execへフォールバック
CompileResult::Fallback {
reason: visitor.unsupported_nodes(),
location: func_def.location(),
}
} else {
// Nyash MIR/JITへコンパイル
CompileResult::Compile
}
}
pub fn compile_module(&mut self, module: &PythonAst) -> ModuleUnit {
let mut units = vec![];
// モジュールトップレベルはPythonで実行globals設定
units.push(ExecutionUnit::PythonExec(module.top_level));
// 各関数を判定
for func in module.functions() {
match self.can_compile(func) {
CompileResult::Compile => {
let mir = self.compile_to_mir(func);
units.push(ExecutionUnit::NyashFunction(mir));
self.telemetry.record_compiled(func.name);
}
CompileResult::Fallback { reason, location } => {
units.push(ExecutionUnit::PythonThunk(func));
self.telemetry.record_fallback(func.name, reason, location);
}
}
}
ModuleUnit { units }
}
}
```
### 4. データ共有戦略
```rust
// NdArrayBox定義
pub struct NdArrayBox {
base: BoxBase,
py_array: Py<PyArray<f64, Dim<[usize; 2]>>>, // Python側の参照保持
// 操作時のみGIL取得してArrayViewを取る
}
impl NdArrayBox {
pub fn to_view(&self) -> PyResult<ArrayView2<f64>> {
Python::with_gil(|py| {
let array = self.py_array.as_ref(py);
Ok(array.readonly())
})
}
}
```
### 4. 実装ロードマップ
#### Phase 1: パーサー統合1-2週間
- [ ] pyo3セットアップとPythonParserBox骨格
- [ ] Python側parse_to_jsonヘルパー実装
- [ ] JSON→Nyash AST最小変換
- [ ] run()メソッドCPython exec委譲
- [ ] 例外変換PyErr → NyashError
#### Phase 2: MIR変換2-4週間
- [ ] AST→MIR変換器最小セット
- [ ] 数値演算プリミティブ実装
- [ ] スコープ解決(関数ローカル/グローバル)
- [ ] 基本的な制御フローIf/While
#### Phase 3: NumPy統合並行可能
- [ ] pyo3-numpy統合
- [ ] NdArrayBox実装
- [ ] ゼロコピーベンチマーク
- [ ] バッファプロトコル対応
#### Phase 4: 最適化と拡張
- [ ] 型特化とガード最適化
- [ ] 例外処理try/except
- [ ] クラス/メソッド対応
- [ ] import統合
## 性能目標(現実的な見積もり)
| コードタイプ | 期待される高速化 | 備考 |
|------------|----------------|------|
| 純Pythonループ | 2-10倍 | 型安定なホットパス |
| 関数呼び出し多 | 1.5-3倍 | インライン化効果 |
| NumPy処理中心 | 1.0-1.2倍 | 既に最適化済み |
| 動的特性多用 | 1.2-3倍 | ガード頻発で限定的 |
## 実装上の注意点(エキスパート推奨)
### 意味論の重要な違いPhase 1で対応必須
1. **制御フロー**
- `for`文: イテレータプロトコル必須(`__iter__`/`__next__`
- `for/else`, `while/else`: breakしなかった場合のelse実行
- 短絡評価: `and`は左がFalseなら右を評価しない
2. **スコープ規則LEGB**
```python
# Local → Enclosing → Global → Builtins
global_var = 1
def outer():
enclosing_var = 2
def inner():
local_var = 3
nonlocal enclosing_var # 明示的な宣言
global global_var # 明示的な宣言
```
3. **数値演算の違い**
- `/`: Python 3では常にfloattrue division
- `//`: floor division整数除算
- 大整数: デフォルトで無限精度
- `is` vs `==`: オブジェクト同一性 vs 値の等価性
4. **関数定義の罠**
```python
def f(x, y=[]): # デフォルト引数は定義時に1度だけ評価
y.append(x) # 全呼び出しで同じリストを共有
return y
```
### GIL管理のベストプラクティス
```rust
// ❌ 悪い例: GILを長時間保持
let result = Python::with_gil(|py| {
let ast = parse_python(py, code)?;
let json = convert_to_json(py, ast)?; // ここまでGIL必要
let nyash_ast = parse_json(&json)?; // GIL不要なのに保持
compile_to_mir(nyash_ast)? // GIL不要なのに保持
});
// ✅ 良い例: GILを最小限に
let json = Python::with_gil(|py| {
let ast = parse_python(py, code)?;
convert_to_json(py, ast) // JSON生成まで
})?;
// GIL外で重い処理
let nyash_ast = parse_json(&json)?;
let mir = compile_to_mir(nyash_ast)?;
// 必要時のみ再取得
Python::with_gil(|py| {
py.allow_threads(|| {
// 時間のかかるRust処理
optimize_mir(mir)
})
})
```
### テレメトリーとデバッグ
```rust
// 環境変数で制御
NYASH_PYTHONPARSER_TELEMETRY=1 # 基本統計
NYASH_PYTHONPARSER_TELEMETRY=2 # 詳細ログ
NYASH_PYTHONPARSER_STRICT=1 # フォールバック時にパニックCI用
// 出力例
[PythonParser] Module: example.py
Functions: 10 total
Compiled: 7 (70%)
Fallback: 3 (30%)
- async_function: unsupported node 'AsyncFunctionDef' at line 23
- generator_func: unsupported node 'Yield' at line 45
- class_method: unsupported node 'ClassDef' at line 67
```
## 次のステップ
### 即座に開始すべきこと
1. **Python 3.11環境固定**
```bash
pyenv install 3.11.9
pyenv local 3.11.9
```
2. **最小動作確認**
```python
# test_minimal.py
def add(x, y):
return x + y
result = add(10, 5)
print(f"Result: {result}") # → Nyashで15が出力されれば成功
```
3. **テレメトリー基盤構築**
- 未対応ノードの記録システム
- フォールバック率の可視化
- ソース位置情報の保持
4. **Differential Testingの準備**
- CPythonとの出力比較フレームワーク
- 標準出力、戻り値、例外のキャプチャ
- テストコーパスの選定
### 成功の測定基準
| フェーズ | 目標 | 測定指標 |
|---------|------|----------|
| Phase 1 | 基本動作 | 簡単な数値計算の70%がコンパイル可能 |
| Phase 2 | 実用性 | scikit-learnの基本アルゴリズムが動作 |
| Phase 3 | 性能 | 純Pythonループで5倍以上の高速化 |
| Phase 4 | 成熟度 | PyPIトップ100の30%が基本動作 |
## まとめ
このPythonParserBox実装は、単なる機能追加ではなく、Nyash言語の成熟度を飛躍的に高める戦略的プロジェクト。
エキスパートの指摘を踏まえ、関数単位のフォールバック、Python 3.11固定、意味論の正確な実装、
GIL最小化、テレメトリー重視で着実に実装を進める。

View File

@ -0,0 +1,76 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
Note: 本来は「PythonをNyashで動かすフェーズCore実装」の位置づけでしたが、現在は順番を変更し、先に 10.5bMIR→VM→ネイティブビルド基盤を進めています。
# Phase 10.1d - Core実装Phase 1機能
## 🎯 このフェーズの目的
Python AST → Nyash AST変換のPhase 1機能基本構文を実装する。
## 📁 実装ドキュメント
- **`python_implementation_roadmap.txt`** - Phase別実装ロードマップ
## 🔧 Phase 1必須要素Codex先生強調
### 意味論の必須実装
1. **LEGB + locals/freevars** - スコーピング規則
2. **デフォルト引数の評価タイミング** - 定義時に一度だけ
3. **イテレータベースのfor文** - `__iter__`/`__next__`プロトコル
4. **for/else + while/else** - Python独特のelse節
5. **Python真偽値判定** - `__bool__``__len__`
6. **短絡評価** - and/orの正確な挙動
### サポートする文Statement
- [x] def - 関数定義
- [x] if/elif/else - 条件分岐
- [x] for - ループelse節対応必須
- [x] while - ループelse節対応必須
- [x] break/continue - ループ制御
- [x] return - 戻り値
### サポートする式Expression
- [x] 算術演算子(+,-,*,/,//,%
- [x] 比較演算子(==,!=,<,>,<=,>=,is,is not
- [x] 論理演算子and,or,not- 短絡評価
- [x] 関数呼び出し
- [x] 変数参照/代入
- [x] リテラル(数値/文字列/bool
## 🧪 テストケース
```python
# Phase 1で動作すべきコード
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# for/else のテスト
for i in range(10):
if i == 5:
break
else:
print("No break") # 実行されない
# デフォルト引数の罠
def append_to_list(item, lst=[]): # 定義時に評価!
lst.append(item)
return lst
```
## ✅ 完了条件
- [ ] 基本的な関数定義が変換できる
- [ ] 制御フローが正しく変換される
- [ ] 演算子が正しくマッピングされる
- [ ] Python意味論が保たれている
- [ ] 70%以上の関数がコンパイル可能
## 📊 テレメトリー確認
```bash
[PythonParser] Module: test.py (Python 3.11)
Functions: 10 total
Compiled: 7 (70%) ← 目標達成!
Fallback: 3 (30%)
```
## ⏭️ 次のフェーズ
→ Phase 10.1e (トランスパイラー)

View File

@ -0,0 +1,264 @@
# PythonParserBox 実装ロードマップ(エキスパート統合版)
Based on ChatGPT5's Python Language Feature Surface Map + Expert Feedback
更新日: 2025-08-27
## 🎯 実装優先順位の考え方(エキスパート統合)
### 🏯 核心戦略:関数単位フォールバック
**両エキスパートが強調:** ファイル全体ではなく、**関数単位**でコンパイル/フォールバックを判断
```python
def supported_function(): # → Nyash MIR/JIT
return x + y
def unsupported_function(): # → CPython exec
yield from generator # Phase 1では未対応
```
### 🔧 Python 3.11固定
- AST安定性確保3.8 Constant統一、3.10 match/case、3.12位置情報)
- `py_version`と`ast_format`をJSON IRに埋め込む
### 🌟 Differential Testing戦略
- **世界中のPythonコードがNyashのテストケースに**
- CPythonをオラクルとして使用、出力・戻り値・例外を比較
- 微妙なセマンティクスバグを自動発見
### 📊 テレメトリー重視
- 未対応ノードの記録(`support_level`フィールド)
- フォールバック率の計測
- ソース位置情報保持(`lineno/col_offset/end_*`
## 📋 Phase 1: Core Subset1-2週間
**目標**: 基本的なPythonコードをNyashで実行可能にする
### ❌ Phase 1での必須意味論要素Codex先生強調
- **LEGB + locals/freevars**: スコーピング規則
- **デフォルト引数の評価タイミング**: 定義時に一度だけ
- **イテレータベースのfor文**: `__iter__`/`__next__`プロトコル
- **for/else + while/else**: Python独特のelse節
- **Python真偽値判定**: `__bool__` → `__len__`
- **短絡評価**: and/orの正確な挙動
### 文Statement
- [x] def - 関数定義 → Nyash関数/Box
- デフォルト引数の定義時評価
- argumentsオブジェクトの完全解析
- [x] if/elif/else - 条件分岐 → CondBr
- [x] for - ループ → Loop + Iterator
- **else節対応必須**
- [x] while - ループ → Loop
- **else節対応必須**
- [x] break/continue - ループ制御
- [x] return - 戻り値 → Return
- [ ] pass - 空文
- [ ] importPhase 3へ延期
### 式Expression
- [x] 関数呼び出し - Call → BoxCall
- [x] 算術演算子 - +,-,*,/,//,% → BinOp
- `/`: true division常にfloat
- `//`: floor division
- [x] 比較演算子 - ==,!=,<,>,<=,>=,is,is not → Compare
- [x] 論理演算子 - and,or,not → BoolOp/UnaryOp
- 短絡評価の正確な実装
- [x] 変数参照/代入 - Name → Load/Store
- [x] リテラル - 数値/文字列/bool → Constant
- [x] 三項演算子 - IfExp
### データ型(最小限)
- [x] int → IntegerBox大整数対応
- [x] float → FloatBoxNaNの扱い注意
- [x] str → StringBox
- [x] bool → BoolBox
- [x] list基本 → ArrayBox
## 📋 Phase 2: Data Model2-3週間
**目標**: Pythonの特殊メソッドをNyashのBoxメソッドにマッピング
### 特殊メソッド
- [ ] __init__ → constructor/birth
- [ ] __len__ → length()
- [ ] __getitem__ → get()
- [ ] __setitem__ → set()
- [ ] __iter__ → iterator()
- [ ] __str__ → toString()
### コレクション拡張
- [ ] dict → MapBox
- [ ] tuple → ImmutableArrayBox新規
- [ ] set → SetBox新規
### 演算子オーバーロード
- [ ] __add__, __sub__ 等 → operator+, operator-
- [ ] __eq__, __lt__ 等 → equals(), compareTo()
## 📋 Phase 3: Advanced Features1ヶ月
**目標**: Pythonの生産性の高い機能を実装
### 制御フロー拡張
- [ ] try/except → エラーハンドリング
- [ ] with文 → リソース管理
- [ ] break/continue → ループ制御
### 高度な機能
- [ ] ジェネレータyield → GeneratorBox
- [ ] デコレータ → 関数ラッパー
- [ ] 内包表記 → 最適化されたループ
- [ ] ラムダ式 → 匿名関数
### クラスシステム
- [ ] class文 → box定義
- [ ] 継承 → from構文
- [ ] super() → from Parent.method()
## 📋 Phase 4: Modern Python将来
**目標**: 最新のPython機能をサポート
### 非同期
- [ ] async/await → 非同期Box将来のNyash非同期と統合
- [ ] async for/with → 非同期イテレータ
### パターンマッチ3.10+
- [ ] match/case → Nyashのパターンマッチ将来実装時
### 型ヒント
- [ ] 型アノテーション → MIRの型情報として活用
- [ ] typing モジュール → 静的型チェック情報
## 🚀 実装戦略
### Step 1: AST変換の基礎Phase 1開始
```python
# Python側でAST→JSON
import ast
import json
def parse_to_json(code):
tree = ast.parse(code)
return json.dumps(ast_to_dict(tree))
# 最小限のノードから実装
def ast_to_dict(node):
if isinstance(node, ast.FunctionDef):
return {
"type": "FunctionDef",
"name": node.name,
"args": [arg.arg for arg in node.args.args],
"body": [ast_to_dict(stmt) for stmt in node.body]
}
# ... 他のノードタイプを順次追加
```
### Step 2: Nyash AST生成Rust側
```rust
// JSON → Nyash AST
fn convert_python_ast(json: &str) -> Result<ast::Program> {
let py_ast: PythonAst = serde_json::from_str(json)?;
match py_ast {
PythonAst::FunctionDef { name, args, body } => {
// Python def → Nyash function
ast::BoxDef {
name,
methods: vec![ast::Method {
name: name.clone(),
params: args,
body: convert_statements(body),
}],
..
}
}
// ... 他のケース
}
}
```
### Step 3: 段階的な実行
1. 最初はCPython exec()でそのまま実行
2. 変換可能な部分からMIR生成
3. MIR化された部分はVM/JITで高速実行
4. 未対応部分は自動的にCPythonフォールバック
## 📊 期待される成果
### Phase 1完了時点
- 簡単な数値計算スクリプトが2-5倍高速化
- 基本的なループが最適化される
- Nyashの既存BoxFileBox等がPythonから使える
### Phase 2完了時点
- Pythonのリスト/辞書操作が高速化
- NyashとPythonのデータ構造が相互運用可能
- 特殊メソッドによる自然な統合
### Phase 3完了時点
- Pythonの生産的な機能がNyashで高速実行
- 既存Pythonコードの大部分が動作
- デコレータやジェネレータも最適化
## 🎯 最初の一歩(今すぐ開始)
1. pyo3でPythonParserBoxの骨組み作成
2. 最小限のparse_to_json実装def + return
3. 単純な関数のAST変換テスト
4. "Hello from Python in Nyash"を表示
```python
# 最初のテストケース
def hello():
return "Hello from Python in Nyash"
# これがNyashで動けば成功
```
## 📊 成功の測定基準(エキスパート推奨)
### 定量的指標
| 指標 | 目標 | 測定方法 |
|------|-------|----------|
| カバレッジ率 | 70%以上 | コンパイル済み vs フォールバック関数の比率 |
| 性能向上 | 2-10倍 | 純Pythonループのベンチマーク |
| バグ発見数 | 10+件/Phase | Differential Testingで発見されたNyashバグ |
| エコシステム | 1以上 | 動作する有名Pythonライブラリ |
### マイルストーン
- Phase 1: "Hello from Python in Nyash"が動作
- Phase 2: scikit-learnの基本アルゴリズムが動作
- Phase 3: FlaskのHello Worldが動作
- Phase 4: PyPIトップ100の30%が基本動作
## 🔧 GIL管理の黄金律
```rust
// GILは最小限に
let json_ast = Python::with_gil(|py| {
// Python側でJSON生成高速
py_helper.parse_to_json(py, code)
})?;
// GIL外でRust処理並列可能
let nyash_ast = py.allow_threads(|| {
convert_json_to_nyash(json_ast)
});
```
## 🔍 JSON IR設計Codex先生推奨
```json
{
"node_type": "FunctionDef",
"py_version": "3.11",
"ast_format": "v2",
"support_level": "full", // "partial", "fallback"
"lineno": 1,
"col_offset": 0,
"end_lineno": 3,
"end_col_offset": 15,
"name": "hello",
"args": {...},
"body": [...]
}
```
---
作成日: 2025-08-27
ChatGPT5のサーフェスマップ + Gemini/Codex先生のエキスパートフィードバックを統合

View File

@ -0,0 +1,72 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
# Phase 10.1e - Python → Nyashトランスパイラー
## 🎯 このフェーズの目的
Python ASTをNyashソースコードとして出力する機能を実装する。
## 📁 実装ドキュメント
- **`python_to_nyash_transpiler.txt`** - トランスパイラー設計
## 🔧 実装機能
### 1. AST → Nyashソース生成
```rust
impl PythonParserBox {
pub fn to_nyash_source(&self, python_code: &str) -> Result<String, String> {
// Python → JSON AST → Nyash AST → Nyashソース
}
}
```
### 2. 変換例
```python
# Python入力
def add(x, y):
return x + y
result = add(10, 5)
```
```nyash
# Nyash出力
function add(x, y) {
return x + y
}
local result
result = add(10, 5)
```
### 3. 出力フォーマッター
- インデント管理
- 括弧の追加Nyashは明示的
- コメント保持(可能な範囲で)
## 🛠️ コマンドラインツール
```bash
# 基本変換
nyash-transpile input.py -o output.hako
# 変換統計付き
nyash-transpile --stats complex.py
# Output: Converted 15/17 functions (88%)
# 部分変換(サポート関数のみ)
nyash-transpile --partial script.py
```
## ✅ 完了条件
- [ ] `to_nyash_source()` メソッドが動作する
- [ ] 基本的なPythonコードが正しいNyashに変換される
- [ ] インデントが正しく管理される
- [ ] 変換統計が表示される
- [ ] ファイル出力ができる
## 🌟 期待される利用シーン
1. **学習ツール** - PythonユーザーがNyash構文を学ぶ
2. **段階的移行** - 既存Pythonコードの移行
3. **性能最適化** - ホットパスをNyashネイティブに
## ⏭️ 次のフェーズ
→ Phase 10.1f (テストとベンチマーク)

View File

@ -0,0 +1,225 @@
# Python → Nyashトランスパイラー機能
PythonParserBoxの応用による自動変換
## 🎯 概要
PythonParserBoxでPython AST → Nyash ASTの変換ができるなら、それを**Nyashソースコードとして出力**できる!
## 🚀 実現可能な機能
### 1. Python → Nyashファイル変換
```python
# input.py
def calculate(x, y):
result = x * 2 + y
return result
for i in range(10):
print(calculate(i, 5))
```
↓ 変換
```nyash
# output.hako
function calculate(x, y) {
local result
result = x * 2 + y
return result
}
local i
for i in range(0, 10) {
print(calculate(i, 5))
}
```
### 2. 実装方法
```rust
impl PythonParserBox {
// Python → Nyashファイル出力
pub fn transpile_to_file(&self, python_code: &str, output_path: &str) -> Result<(), String> {
// 1. Python → JSON AST
let json_ast = self.parse_to_json(python_code)?;
// 2. JSON AST → Nyash AST
let nyash_ast = self.json_to_nyash_ast(&json_ast)?;
// 3. Nyash AST → Nyashソースコード
let nyash_code = self.ast_to_nyash_source(&nyash_ast)?;
// 4. ファイルに出力
std::fs::write(output_path, nyash_code)?;
Ok(())
}
// AST → Nyashソースコード生成
fn ast_to_nyash_source(&self, ast: &NyashAst) -> Result<String, String> {
let mut output = String::new();
let formatter = NyashFormatter::new();
for item in &ast.items {
formatter.format_item(item, &mut output)?;
}
Ok(output)
}
}
```
## 📋 使用例
### コマンドライン版
```bash
# PythonファイルをNyashに変換
nyash-transpile input.py -o output.hako
# 標準出力に出力
nyash-transpile script.py
# 部分変換(サポートされる構文のみ)
nyash-transpile --partial complex_script.py
```
### Nyashスクリプト内での使用
```nyash
local transpiler = new PythonParserBox()
// Pythonコードを読み込み
local python_code = FileBox.read("algorithm.py")
// Nyashに変換
local nyash_code = transpiler.to_nyash_source(python_code)
// ファイルに保存
FileBox.write("algorithm.hako", nyash_code)
// または直接実行
eval(nyash_code)
```
## 🎨 変換マッピング例
### 基本構文
| Python | Nyash |
|--------|-------|
| `def func():` | `function func() {` |
| `if x > 0:` | `if (x > 0) {` |
| `for i in range(10):` | `for i in range(0, 10) {` |
| `while x < 10:` | `while (x < 10) {` |
| `x = 5` | `local x; x = 5` または `x = 5`(スコープによる)|
### データ型
| Python | Nyash |
|--------|-------|
| `x = 42` | `x = 42` |
| `s = "hello"` | `s = "hello"` |
| `lst = [1, 2, 3]` | `lst = new ArrayBox([1, 2, 3])` |
| `d = {"a": 1}` | `d = new MapBox(); d.set("a", 1)` |
### 特殊なケース
```python
# Pythonのfor/else
for i in items:
if condition:
break
else:
print("No break")
```
```nyash
# Nyashでの実装フラグを使用
local broke = false
for i in items {
if (condition) {
broke = true
break
}
}
if (not broke) {
print("No break")
}
```
## 🌟 利点
### 1. 段階的移行支援
- 既存のPythonプロジェクトを段階的にNyashに移行
- 変換されたコードを手動で最適化可能
### 2. 学習ツールとして
- PythonユーザーがNyash構文を学ぶ
- 両言語の違いを理解
### 3. コード生成
- Pythonで書いたアルゴリズムをNyashネイティブコードに
- より高速な実行のための前処理
### 4. 逆方向変換の可能性
- Nyash → Pythonも将来的に可能
- 真のバイリンガル環境
## ⚠️ 制限事項と課題
### 1. 完全な互換性は不可能
- Pythonの動的機能すべては変換できない
- 一部の構文は手動調整が必要
### 2. 意味論の違い
```python
# Pythonのデフォルト引数定義時評価
def f(x, lst=[]):
lst.append(x)
return lst
```
```nyash
// Nyashでは毎回新しいリスト異なる挙動
function f(x, lst) {
if (lst == null) {
lst = new ArrayBox()
}
lst.push(x)
return lst
}
```
### 3. サポートレベルの明示
```nyash
// 生成されたファイルのヘッダー
// Generated from Python by Nyash Transpiler v1.0
// Original file: script.py
// Conversion rate: 85% (15/17 functions transpiled)
// Manual review recommended for: async_func, generator_func
```
## 📊 実装フェーズ
### Phase 1.5: 基本トランスパイラPhase 1と並行
- [ ] NyashFormatter実装AST → ソースコード)
- [ ] 基本構文の出力def, if, for, while
- [ ] インデント管理
- [ ] コメント保持(可能な範囲で)
### Phase 2.5: 高度な変換
- [ ] クラス → Box変換
- [ ] 特殊メソッド → Nyashメソッド
- [ ] import文の処理
### Phase 3.5: ツール化
- [ ] コマンドラインツール
- [ ] VSCode拡張機能
- [ ] オンライン変換ツール
## 🎉 期待される効果
1. **Pythonエコシステムの資産をNyashネイティブ化**
2. **パフォーマンスクリティカルな部分をNyash/MIR/JITで高速化**
3. **両言語間のシームレスな相互運用**
4. **Nyashの採用障壁を大幅に下げる**
---
これは**PythonParserBoxの価値をさらに高める**素晴らしい応用です!

View File

@ -0,0 +1,94 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
# Phase 10.1f - テストとベンチマーク
## 🎯 このフェーズの目的
Differential Testingでバグを発見し、性能向上を検証する。
## 🧪 Differential Testing戦略
### 1. テストフレームワーク
```rust
pub fn differential_test(code: &str) -> TestResult {
// CPythonで実行オラクル
let python_result = capture_python_execution(code)?;
// Nyashで実行
let nyash_result = execute_with_pythonparser(code)?;
// 結果比較
compare_results(python_result, nyash_result)
}
```
### 2. 比較項目
- **標準出力** - print文の結果
- **戻り値** - 関数の返す値
- **例外** - エラーメッセージ(正規化後)
- **副作用** - グローバル変数の変更等
### 3. テストコーパス
```
test_corpus/
├── basic/ # 基本構文テスト
├── stdlib/ # 標準ライブラリから抜粋
├── pypi_top100/ # 人気ライブラリから抜粋
└── edge_cases/ # エッジケース集
```
## 📊 ベンチマーク
### 1. 性能測定対象
```python
# 数値計算ベンチマーク
def mandelbrot(max_iter=100):
# フラクタル計算
pass
# ループベンチマーク
def sum_of_primes(n):
# 素数の和
pass
# 再帰ベンチマーク
def ackermann(m, n):
# アッカーマン関数
pass
```
### 2. 測定項目
- **実行時間** - CPython vs Nyash
- **メモリ使用量** - 最大/平均
- **コンパイル時間** - AST変換時間
- **フォールバック率** - 関数別統計
## 🐛 バグ発見と報告
### 発見されたバグの例
```
[BUG-001] for/else semantics mismatch
Python: else executed when no break
Nyash: else never executed
Fixed in: commit abc123
[BUG-002] Division operator difference
Python: 5/2 = 2.5 (float)
Nyash: 5/2 = 2 (integer)
Fixed in: commit def456
```
## ✅ 完了条件
- [ ] Differential Testingフレームワークが動作する
- [ ] 基本的なテストコーパスが準備されている
- [ ] 10個以上のバグを発見・修正
- [ ] ベンチマークで2倍以上の高速化を確認
- [ ] CI/CDパイプラインに統合されている
## 📈 成功の測定
- **カバレッジ率**: 70%以上の関数がコンパイル
- **性能向上**: 純Pythonループで2-10倍
- **バグ発見数**: Phase毎に10件以上
- **テスト成功率**: 95%以上
## ⏭️ 次のフェーズ
→ Phase 10.1g (ドキュメント作成)

View File

@ -0,0 +1,102 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
# Phase 10.1g - ドキュメントとリリース準備
## 🎯 このフェーズの目的
PythonParserBoxの使い方を文書化し、コミュニティに公開する準備をする。
## 📚 作成するドキュメント
### 1. ユーザーガイド
- **Getting Started** - 最初の一歩
- **Python互換性ガイド** - サポートされる構文
- **トランスパイラー使用法** - Python→Nyash変換
- **トラブルシューティング** - よくある問題と解決法
### 2. API リファレンス
```nyash
// PythonParserBox API
box PythonParserBox {
// Python code → JSON AST
parse_to_json(code: String) -> String
// JSON AST → Nyash AST
json_to_nyash_ast(json: String) -> AstBox
// Python code → Nyash source
to_nyash_source(code: String) -> String
// 直接実行(関数単位フォールバック)
run(code: String) -> Box
// 変換統計
get_conversion_stats() -> MapBox
}
```
### 3. 移行ガイド
- **段階的移行戦略** - Pythonプロジェクトの移行手順
- **パフォーマンスチューニング** - ホットパスの最適化
- **ベストプラクティス** - 推奨される使い方
### 4. 内部設計ドキュメント
- **アーキテクチャ** - 全体設計
- **関数単位フォールバック** - 実装詳細
- **GIL管理** - pyo3との統合
- **テレメトリー** - 統計収集の仕組み
## 🎬 デモとチュートリアル
### 1. 動画チュートリアル
- 5分で分かるPythonParserBox
- Python→Nyash移行実演
- パフォーマンス比較デモ
### 2. サンプルプロジェクト
```
examples/
├── hello_python/ # 最小限の例
├── data_analysis/ # データ分析の移行例
├── web_api/ # WebAPIの移行例
└── benchmarks/ # ベンチマーク比較
```
## 📣 リリース準備
### 1. リリースノート作成
```markdown
# PythonParserBox v1.0 リリース!
## 🎉 新機能
- Python AST → Nyash AST変換
- 関数単位フォールバック
- Python→Nyashトランスパイラー
- Differential Testing
## 📊 パフォーマンス
- 純Pythonループ: 2-10倍高速化
- 数値計算: 5倍以上の改善
- メモリ効率: 30%削減
## 🐛 発見されたバグ
- Nyashパーサー: 15件修正
- セマンティクス: 8件修正
```
### 2. ブログ記事
- 「なぜPythonParserBoxを作ったのか」
- 「Differential Testingの威力」
- 「Everything is Boxの新たな展開」
## ✅ 完了条件
- [ ] ユーザーガイドが完成している
- [ ] APIリファレンスが完成している
- [ ] サンプルプロジェクトが動作する
- [ ] リリースノートが準備されている
- [ ] CI/CDでの自動テストが通る
## 🎯 Phase 10.1の完了!
これでPythonParserBoxの最初のリリースが完成
## ⏭️ 次の展開
→ Phase 10.2 (Phase 2機能の実装) または Phase 10.x (他言語対応)

View File

@ -0,0 +1,53 @@
# Phase 10.5a Python 統合 ABI 設計Draft
目的: Everything is Plugin/AOT の既存基盤上に Python を最小リスクで統合するための ABI と型・メソッド定義を固定する。
## スコープ10.5a
- v2 プラグイン ABI 準拠(`nyash_plugin_abi/init/invoke`)の Python プラグイン雛形を作成
- 2 Box を定義: `PyRuntimeBox(type_id=40)`, `PyObjectBox(type_id=41)`
- メソッド ID の割り当てと TLV 方針を文書化(実装は 10.5b 以降)
## TLV マッピング(現行運用)
- 1 = Bool (1 byte)
- 2 = I32 (4 bytes, LE)
- 3 = I64 (8 bytes, LE)
- 4 = F32 (4 bytes, LE)
- 5 = F64 (8 bytes, LE)
- 6 = String (UTF-8, n bytes)
- 7 = Bytes (opaque, n bytes)
- 8 = Handle/BoxRef (`u32 type_id || u32 instance_id`)
備考: 既存ドキュメントには古い表記の混在があるため、VM_README 準拠で統一。
## Box とメソッド設計
### PyRuntimeBox (type_id=40)
- birth(0): ランタイムの生成(後続で GIL 初期化などを担当)。戻り値: `instance_id`(非 TLV, u32 LE
- eval(1, code: String): Python コードを評価して `PyObjectBox` を返す。戻り値: `Handle(tag=8)`
- import(2, name: String): `__import__(name)` または `importlib.import_module`。戻り値: `Handle(tag=8)`
- fini(MAX): ランタイム破棄GIL 終了・クリーンアップ)
### PyObjectBox (type_id=41)
- birth(0): 予約(通常は runtime 側から生まれる)
- getattr(1, name: String): 属性取得 → `Handle(tag=8)`
- call(2, args: TLV...): 可変長引数。初期段は I64/String/Bool/Bytes/Handle のサブセットに限定。戻り値: `Handle(tag=8)`
- str(3): Python 側で `PyObject_Str` → String へ。戻り値: `String(tag=6)`
- fini(MAX): 参照カウント `Py_DECREF` に対応(後続)
## 参照管理・GIL概要
- GIL: birth/invoke/fini の入口で確保し、出口で解放(再入を許容)。
- 参照: `PyObjectBox` は生成時に `INCREF``fini``DECREF`。ランタイム終了時に孤立検知の簡易テストを導入。
## 設定ファイルnyash.toml
- `libnyash_python_plugin.so` を 2 Box 含む形で登録path/type_id/method_id を固定)
- JIT/VM 側は既存の `plugin_invoke` 経由で呼び出しAOT は 10.5d で `libnyrt.a` にシム追加)
## 次フェーズ10.5b 以降)
- 10.5b: `PyRuntimeBox`/`PyObjectBox` 実装CPython 埋め込み、最小 RO 経路)
- 10.5c: Python→Nyash 方向CPython 拡張 `nyashrt`
- 10.5d: JIT/AOT 連携(`emit_plugin_invoke` 対応・静的リンクシム)
- 10.5e: サンプル・テスト・ドキュメント
---
補足: 本ドキュメントは「設計の固定」を目的とし、実装は段階的に進める。タグ/ID は既存と衝突しない値を選定した40/41

View File

@ -0,0 +1,37 @@
# 10.5b ネイティブビルド基盤の固めAOT/EXE
Python統合を本格化する前に、配布可能なネイティブ実行ファイルEXEの足回りを先に完成させる。JITは実行エンジンから外し、EXE生成専用のコンパイラとして運用する。
## 🎯 目的
- VM=実行、JIT=EXEAOTの二系統を明確化フォールバックなし/Fail-Fast
- CLIF→.o→`libnyrt`リンク→EXEのパイプラインを実効化
- プラグイン解決をクロスプラットフォームに(.so/.dll/.dylib、自動lib剥がし、検索パス
- Windowsを含む実用的な配布体験を整備
## 🧩 範囲
- JIT分離・Strict運用Fail-Fast/No-fallback
- AOTパイプライン: `--compile-native``tools/build_aot.{sh,ps1}`
- プラグインローダの拡張: 拡張子変換/`lib`剥がし、`plugin_paths`+`NYASH_PLUGIN_PATHS`
- Windowsリンク: clang優先`nyrt.lib`/`libnyrt.a`両対応、bash+cc fallback
- 観測/EXE出力の統一: `Result: <val>`、終了コード=<val>
## ✅ 成果DoD
- `cargo build --release --features cranelift-jit` の後、
- Linux: `./tools/build_aot.sh examples/aot_min_string_len.hako -o app && ./app`
- Windows: `powershell -ExecutionPolicy Bypass -File tools\build_aot.ps1 -Input examples\aot_min_string_len.hako -Out app.exe && .\app.exe`
- プラグインは `.so` 記述でも各OSで自動解決.dll/.dylib へ変換、lib剥がし
- `tools/smoke_aot_vs_vm.sh` で VM/EXE の `Result:` 行比較が可能(差異は警告表示)
## 🔧 実装メモ
- `src/runtime/plugin_loader_v2.rs``resolve_library_path()` を追加:
- OS別拡張子、Windowsの`lib`剥がし、`plugin_paths`探索
- `src/config/nyash_toml_v2.rs``NYASH_PLUGIN_PATHS` を追加(`;`/`:`区切り)
- `AotConfigBox``set_plugin_paths()` 追加env同期
- `crates/nyrt` の EXE出力統一`Result:`/exit code
- Windows: `tools/build_aot.ps1`clang→bash fallback、Linux: `tools/build_aot.sh`
## 📌 次10.5c 以降)
- PyRuntimeBox/PyObjectBoxRO優先
- Python ABIルータを `libnyrt` に同梱type_id→invokeディスパッチ
- 配布用パッケージ整備nyash.toml/プラグイン配置ガイドの最終化)

View File

@ -0,0 +1,46 @@
# Phase 10.5c — Handle-First PluginInvoke 設計(最優先計画)
目的: Python専用の型伝搬を撤廃し、プラグイン呼び出しを「Everything is Handle」で統一。Lowererは箱名や戻り型に依存しない最小知識で `PluginInvoke` を実Emitし、型解決は実行時TLV/Handleに委譲する。
## 背景と問題
- 現状のLowererに「import/getattr/call の戻りを PyObjectBox とみなす」暫定コードが混入。これは Python 特化のハードコーディングで、将来のプラグイン拡張File/Net/DB 等)にブレーキとなる。
- すでに ABI/VM は TLV tag=8Handleを標準化。戻り値を Handle として受け取り、タイプ情報type_idは実行時に判明する。
## 原則Handle-First
- すべてのプラグインメソッドの戻りは HandleTLV: tag=8またはプリミティブi64/f64/bool/string/bytes
- Lowerer は「戻り型が box かどうか」だけを気にすればよい。個々の箱名PyObjectBox 等)を前提にしない。
- 型の詳細は `type_id` によって実行時に解決される。JIT/AOT は型非依存の汎用コード生成を行う。
## 設計
1) メタデータ駆動
- `nyash_box.toml``methods.*.returns = { type = "box" | "i64" | "f64" | "string" | "void" | ... }` を単一の参照源に。
- `PluginHost.resolve_method``returns.type` を含む情報を公開Lowerer から参照)。
2) Lowerer の汎用化
- `PluginInvoke` を常に `emit_plugin_invoke(type_id, method_id, argc, has_ret)` に落とす。
- 「戻りが box のときに特定箱名を記録する」実装を撤去。必要なら「dst は Handlebox」のヒントのみ保持。
- 受け手箱名が未確定の場合に備え、by-name 経路(後述)を用意。
3) by-name シム(任意→推奨)
- `nyrt`/builder に `nyash_plugin_invoke_by_name_{i64,f64}(box_type_name?, method_name, a0, a1, a2)` を追加。
- 受け手の箱名が Lowerer 時点で特定できない場合、by-name シムを使用して実行時に `method_id` を解決。
4) 実行時の統一
- 既存の `nyash_plugin_invoke3_{i64,f64}` と同様に、TLVで引数を構築。Handle/プリミティブ変換StringBox/IntegerBoxの自動プリミティブ化を継続。
- 戻りTLVの tag を見て i64/f64 経由の値化(`NYASH_JIT_NATIVE_F64`)またはハンドル登録を行う。
## マイルストーン
- M1: Lowerer から Python特化の型伝搬を除去dst=Handle ヒントのみ)。
- M2: `PluginHost.resolve_method` 拡張で `returns.type` を取得可能に。
- M3: by-name シムの追加と Lowerer 配線(箱名未確定時)。
- M4: AOT 最小ケースimport→getattr→callを Handle-First で Green。
- M5: ドキュメントと CURRENT_TASK を刷新。
## 受け入れ条件DoD
- VM: `py.import("math"); (math.getattr("sqrt")).call(9)` が Greenautodecode=1 で 3
- AOTstrict: 上記チェーン最小例で unsupported=0。Console 出力経路は PluginInvoke または extern 経由で表示。
- Lowerer に Python 固有の型分岐が存在しないgrepで検出不可
## 運用メモ
- 将来的な最適化箱名が静的に分かる場面での特殊化は、Handle-First を壊さない範囲で「分岐の1箇所」に限定して導入する。

View File

@ -0,0 +1,21 @@
# Phase 10.5 Index (Active vs Archived)
このフォルダは Python ネイティブ統合とネイティブビルド基盤のための現行計画10.5系と、旧計画10.1系アーカイブを併置しています。迷った場合は「Active」を参照してください。
## Active現行
- 10.5 README全体像: ./README.md
- 10.5a Python ABI 設計: ./10.5a-ABI-DESIGN.md
- 10.5b ネイティブビルド基盤: ./10.5b-native-build-consolidation.md
- 現在フォーカス: MIR→VM→ネイティブビルドAOT/EXEを先に堅牢化
- 10.5c Handle-First PluginInvoke / PyRuntimeBox / PyObjectBox次段
- 10.5d JIT/AOT 統合(予定)
- 10.5e サンプル / テスト / ドキュメント(予定)
## Archived旧10.1系・参照用)
- chatgpt5 統合計画(旧称 Phase 10.1: ./chatgpt5_integrated_plan.md
- 10.1a_planning 10.1g_documentation 各READMEと資料
- 10.1c / 10.1d は「PythonをNyashで動かすフェーズ」の設計・実装メモです順番変更により後段へ
整理方針:
- Active ドキュメントに計画と用語を集約。旧10.1系は背景情報として参照のみ。
- 実装の優先は「必要最小の箱PyRuntimeBox / PyObjectBox」→ 後から最適化。

View File

@ -0,0 +1,110 @@
# Phase 10.5 ネイティブ基盤固め + Python ネイティブ統合
*(旧10.1の一部を後段フェーズに再編。まずネイティブ/AOT基盤を固め、その上でPythonを統合する方針に整理)*
このフォルダの全体像と最新の導線は INDEX を参照してください:
- INDEX: ./INDEX.mdActive と Archived の区分とリンク集)
本フェーズでは方針を明確化する実行はVMが唯一の基準系、JITは「EXE/AOT生成専用のコンパイラ」として分離運用する。
アーキテクチャの整理(決定)
- 開発/デバッグ: MIR → VM完全実行
- 本番/配布: MIR → JITCLIF→ OBJ → EXE完全コンパイル
ポイント
- フォールバック不要/禁止: JITが未対応ならコンパイルエラー。VMへは落とさない。
- 役割分担の明確化: VM=仕様/挙動の唯一の基準、JIT=ネイティブ生成器。
- プラグイン整合: VM/EXEとも同一のBID/FFIプラグインを利用Everything is Plugin
## 📂 サブフェーズ構成10.5s → 10.5e
先行タスク(最優先)
- 10.5s JIT Strict/分離の確定Fail-Fast / ノーフォールバック) [DONE]
- 目的: 「VM=実行・JIT=コンパイル」の二系統で混在を排除し、検証を単純化
- 仕様:
- JITは実行経路から外し、`--compile-native`AOTでのみ使用
- Lowerer/Engine: unsupported>0 または fallback判定>0 でコンパイル中止Fail-Fast
- 実行: VMのみ。フォールバックという概念自体を削除
- DoD:
- CLIに `--compile-native` を追加し、OBJ/EXE生成が一発で通る
- VM実行は常にVMのみJITディスパッチ既定OFF
### 10.5aPython設計・ABI整合12日
- ルート選択:
- Embedding: NyashプロセスにCPythonを埋め込み、PyObject*をハンドル管理
- Extending: Python拡張モジュールnyashrtを提供し、PythonからNyashを呼ぶ
- ABI方針:
- ハンドル: TLV tag=8type_id+instance_id。Pythonオブジェクトは `PyObjectBox` として格納
- 変換: Nyash ⇄ Python で Bool/I64/String/Bytes/Handle を相互変換
- GIL: birth/invoke/decRef中はGIL確保。AOTでも同等
### 10.5b ネイティブビルド基盤の固めAOT/EXE24日
- 目的: Python統合の前に、AOT/EXE配布体験・クロスプラットフォーム実行の足回りを先に完成させる
- 範囲:
- VMとJITの分離JIT=EXE専用とStrict運用の徹底
- AOTパイプラインの実働CLIF→.o→libnyrtリンク→EXE
- プラグイン解決のクロスプラットフォーム化(.so/.dll/.dylib、自動lib剥がし、検索パス
- Windowsビルド/リンクclang優先、MSYS2/WSL fallback
- EXE出力の統一`Result: <val>`)とスモークテスト
- DoD:
- Linux/Windowsで `--compile-native` が通り、`plugins/` のDLL/so/dylibを自動解決
- `tools/build_aot.{sh,ps1}` で配布しやすいEXEが生成される
- `tools/smoke_aot_vs_vm.sh` でVM/EXEの出力照合が可能
### 10.5c PyRuntimeBox / PyObjectBox 実装35日
- `PyRuntimeBox`(シングルトン): `eval(code) -> Handle` / `import(name) -> Handle`
- `PyObjectBox`: `getattr(name) -> Handle` / `call(args...) -> Handle` / `str() -> String`
- 参照管理: `Py_INCREF`/`Py_DECREF` をBoxライフサイクルfiniに接続
- プラグイン化: `nyash-python-plugin`cdylib/staticlib`nyplug_python_invoke` を提供(将来の静的同梱に対応)
追加方針10.5c Handle-First/TLV 統一)
- Lowerer は Handle-First を徹底a0 は常に `nyash.handle.of(receiver)`)。
- 引数TLVは String/Integer をプリミティブ化、その他は Handle(tag=8) に統一。
- 受け手箱名が未確定な経路には by-name シムを導入(後方安全の回避路)。
- 参考: `docs/reference/abi/ffi_calling_convention_min.md`
### 10.5c 境界の双方向化35日
- Nyash→Python: BoxCall→plugin_invokeでCPython C-APIに橋渡し
- Python→Nyash: `nyashrt`CPython拡張`nyash.call(func, args)` を提供
- エラーハンドリング: 例外は文字列化tag=6でNyashに返却、またはResult化
### 10.5d JIT/AOT 統合35日
- AOTパイプライン固定: Lower→CLIF→OBJ出力→`ny_main`+`libnyrt.a`リンク→EXE
- CLI: `nyash --compile-native file.hako -o app` を追加(失敗は非ゼロ終了)
- libnyrt: `nyash.python.*` 等のシムを提供し、未解決シンボル解決
- ディスパッチ: type_id→`nyplug_*_invoke` の静的/動的ルート(第一段は動的優先)
### 10.5e サンプル/テスト/ドキュメント1週間
- サンプル: `py.eval("'hello' * 3").str()``numpy`の軽量ケースimport/shape参照などRO中心
- テスト: GILの再入・参照カウントリーク検知・例外伝搬・多プラットフォーム
- ドキュメント: 使用例、制約GIL/スレッド、AOT時のリンク・ランタイム要件
追加済みサンプル(最小チェーン)
- VM: `examples/py_min_chain_vm.hako`import→getattr→call→println
- AOT: `examples/aot_py_min_chain.hako`import→getattr→call→return
## 🎯 DoD定義
- NyashからPythonコードを評価し、PyObjectをHandleで往復できる
- 代表的なプロパティ取得/呼び出しROがJIT/VMで動作
- AOTリンク後のEXEで `py.eval()` 代表例が起動できる(動的ロード前提)
- 10.5s Strict: VM=仕様/JIT=高速実装の原則に基づき、フォールバック無しで fail-fast が機能
## ⌛ 目安
| サブフェーズ | 目安 |
|---|---|
| 10.5a 設計 | 12日 |
| 10.5b 実装 | 35日 |
| 10.5c 双方向 | 35日 |
| 10.5d JIT/AOT | 35日 |
| 10.5e 仕上げ | 1週間 |
## ⚠️ リスクと対策
- GILデッドロック: 入口/出口で厳格に確保/解放。ネスト呼び出しの方針を文書化
- 参照カウント漏れ: BoxライフサイクルでDECREFを必ず実施、リークテストを追加
- リンク/配布: Linux/macOS優先。WindowsのPythonリンクは後段で対応
- 性能: RO先行でJITに寄せ、ミューテーションはポリシー制御
---
注: 旧10.1系の資料10.1a〜g, chatgpt5_integrated_plan.mdは背景情報として残置Archived。現行の実装計画と用語は本READMEと 10.5a/b に集約します。
次は 10.5a設計・ABI整合から着手。Everything is Plugin / libnyrt シムの成功パターンをPythonにも適用し、最小リスクで“Pythonネイティブ”を実現する。

View File

@ -0,0 +1,244 @@
# [Archived] 旧 Phase 10.1 - Python統合計画ChatGPT5高速開発版
最終更新: 2025-08-27 状態: ArchivedPhase 10.5 に統合)
現行の計画は Phase 10.5 のドキュメントに集約しています。最新は以下を参照してください:
- Phase 10.5 Index: ./INDEX.md
- 10.5a Python ABI 設計: ./10.5a-ABI-DESIGN.md
- 10.5b ネイティブビルド基盤: ./10.5b-native-build-consolidation.md
## 🚀 概要2週間での爆速実装当時案
ChatGPT5の最小Box設計により、元の1ヶ月計画を**2週間**に圧縮。Nyash既存アーキテクチャMirBuilder 100%実装済み、HandleRegistry 80%実装済み)を最大活用。
## 📦 ChatGPT5の6つの必須Box最小実装
### 1. **PythonParserBox** - CPython AST取得3日
```rust
// 既存: pyo3統合済み
// 追加: JSON出力とバージョン固定
pub struct PythonParserBox {
base: BoxBase,
py_helper: Arc<Mutex<PyHelper>>,
version: String, // "3.11"固定
}
// メソッド(最小限)
- parse_to_json(src: String) -> String // ast.parse() → JSON
- get_version() -> String // "3.11"
```
### 2. **Py2NyASTBox** - AST変換3日
```rust
// 新規実装
pub struct Py2NyASTBox {
base: BoxBase,
normalizer: AstNormalizer,
}
// メソッド(制御フロー正規化)
- convert(json: String) -> NyashAst
- normalize_for_else(ast: &mut PyAst) // for/else → if分岐
- normalize_comprehensions(ast: &mut PyAst)
```
### 3. **MirBuilderBox** - MIR生成0日 - 既存活用)
```rust
// 既存実装100%活用
// 追加: Python由来フラグのみ
pub struct MirBuilderBox {
// 既存フィールド
is_python_origin: bool, // 追加
}
```
### 4. **BoundaryBox** - 型変換2日
```rust
// Python版のHandleRegistry相当
pub struct BoundaryBox {
base: BoxBase,
handle_registry: Arc<Mutex<HandleRegistry>>, // 既存80%活用
}
// メソッド
- py_to_jit(py_val: PyValBox) -> JitValue
- jit_to_py(jit_val: JitValue) -> PyValBox
- register_handle(obj: Arc<dyn NyashBox>) -> u64
```
### 5. **PyRuntimeBox** - 実行制御2日
```rust
pub struct PyRuntimeBox {
base: BoxBase,
fallback_stats: FallbackStats,
}
// メソッド(関数単位フォールバック)
- execute_function(name: &str, args: Vec<JitValue>) -> JitValue
- should_fallback(func_ast: &PyAst) -> bool // Phase1機能判定
- fallback_to_cpython(code: &str) -> PyObject
```
### 6. **ObservabilityBox** - 統計収集1日
```rust
// 既存のJIT統計システム70%実装済み)を拡張
pub struct ObservabilityBox {
base: BoxBase,
stats_collector: StatsCollector,
}
// JSONLフォーマット出力
- log_attempt(module: &str, func: &str, compiled: bool, reason: Option<&str>)
- output_jsonl() -> String
```
## 🗓️ 実装タイムライン2週間
### Week 1: 基盤実装7日
- **Day 1-3**: PythonParserBox実装
- pyo3統合既存活用
- Python 3.11固定
- JSON出力実装
- **Day 4-6**: Py2NyASTBox実装
- 制御フロー正規化
- for/else, while/else変換
- Phase1機能のみサポート
- **Day 7**: ObservabilityBox実装
- 既存JIT統計拡張
- JSONLフォーマット
### Week 2: 統合と検証7日
- **Day 8-9**: BoundaryBox実装
- HandleRegistry活用
- 型変換ルール確立
- **Day 10-11**: PyRuntimeBox実装
- 関数単位フォールバック
- CPython連携
- **Day 12-13**: 統合テスト
- Differential Testing
- ベンチマーク実行
- **Day 14**: ドキュメント・リリース
- 使用例作成
- パフォーマンス測定
## 📊 既存アーキテクチャとの整合性
### 活用率
- **MirBuilderBox**: 100%(変更なし)
- **HandleRegistry**: 80%BoundaryBoxで再利用
- **JIT統計**: 70%ObservabilityBoxで拡張
- **VM/JIT実行**: 100%(そのまま使用)
### 新規実装
- **PythonParserBox**: 30%pyo3部分は既存
- **Py2NyASTBox**: 100%新規
- **PyRuntimeBox**: 100%新規
## 🎯 Phase 1でサポートする機能Codex先生推奨
### 必須実装
1. **LEGB + locals/freevars** - スコーピング規則
2. **デフォルト引数の評価タイミング** - 定義時評価
3. **イテレータベースのfor文**
4. **for/else + while/else**
5. **Python真偽値判定**
6. **短絡評価**
### サポートする文
- def関数定義
- if/elif/else
- forelse節対応
- whileelse節対応
- break/continue
- return
### サポートする式
- 算術演算子(+,-,*,/,//,%
- 比較演算子(==,!=,<,>,<=,>=
- 論理演算子and,or,not
- 関数呼び出し
- リテラル(数値/文字列/bool
## 📈 成功指標2週間後
### 定量的
- **関数コンパイル率**: 70%以上Phase 1機能
- **実行速度**: 純Pythonループで2倍以上
- **メモリ効率**: CPython比50%削減
### 定性的
- **統計可視化**: JSONL形式で全実行を記録
- **デバッグ容易性**: 関数単位でフォールバック理由明示
- **将来拡張性**: Phase 2-4への明確な道筋
## 🔧 実装例(最終形)
```nyash
// Nyashから使用
local py = new PythonParserBox()
local converter = new Py2NyASTBox()
local builder = new MirBuilderBox()
local runtime = new PyRuntimeBox()
local stats = new ObservabilityBox()
// Pythonコードをコンパイル・実行
local code = "def fib(n): return n if n <= 1 else fib(n-1) + fib(n-2)"
local json_ast = py.parse_to_json(code)
local ny_ast = converter.convert(json_ast)
local mir = builder.build(ny_ast)
// 実行自動的にJIT/VMで高速化
local result = runtime.execute_function("fib", [10])
print(result) // 55
// 統計出力
print(stats.output_jsonl())
// {"mod":"test","func":"fib","attempt":1,"jitted":true,"native":true}
```
## 🚨 重要な設計判断
### 1. 関数単位の境界
- ファイル単位ではなく**関数単位**でコンパイル/フォールバック
- 未対応機能を含む関数のみCPython実行
### 2. Python 3.11固定
- AST安定性の確保
- 将来のバージョンアップは別Phase
### 3. 箱境界の明確化
- 各Boxは単一責任
- 相互依存を最小化
- テスト可能な粒度
### 4. 既存資産の最大活用
- MirBuilder/VM/JITはそのまま使用
- 新規実装は変換層のみ
## 🎉 期待される成果
### 即時的効果2週間後
- Pythonコードの70%がNyashで高速実行
- バグ検出力の飛躍的向上Differential Testing
- 統計による最適化ポイントの可視化
### 長期的効果
- Python→Nyash→Native の世界初パイプライン確立
- Nyash言語の成熟度向上
- エコシステムの爆発的拡大
## 📝 次のステップ
1. **Phase 10.7完了確認** - JIT統計JSONの安定化
2. **PythonParserBox実装開始** - pyo3統合から着手
3. **テストコーパス準備** - Python標準ライブラリから抜粋
---
**作成者**: ClaudeClaude Code
**承認者**: ChatGPT5予定
**開始予定**: Phase 10.7完了直後

View File

@ -0,0 +1,87 @@
# Phase 10.6 計画(整理版 / txt
目的: Thread-Safety監査→仕込みと協調スケジューラSafepoint連携を最小構成で通し、次段の並列GC/並列実行に備える。
====================
1) ゴールDoD
====================
- 10.6a: Thread-Safety Audit の完了(一次)
- NyashBox/Runtime の共有戦略Arc+RwLock/Mutexを棚卸し、未整備箇所はTODO化
- Plugin-First 前提PluginBoxV2 はクロススレッド未サポ運用を明記)
- 10.6b: 協調スケジューラの足場
- SingleThreadSchedulerqueue + delayed + pollを Safepoint に接続済み
- デモ/トレースNYASH_SCHED_DEMO=1, NYASH_SCHED_TRACE=1, 予算NYASH_SCHED_POLL_BUDGETで観測可
- 10.6c: 並列GC 設計の下準備
- Per-thread roots / Safepoint協調 / カードマーキングの設計メモを確定(段階導入方針)
====================
2) スコープ
====================
- 実装は“最小で通す”に限定(最適化は後続)。
- 既存のVM=仕様、JIT=AOT生成専用という原則は維持。
- Python/Plugin 経路は Plugin-First/Handle-First/TLV 統一の上に載せる10.5で固定済)。
====================
3) サブフェーズとタスク
====================
3.1) 10.6a Thread-Safety Audit12日
- ドキュメント: phase-10/phase_10_6a_thread_safety_audit.md既存に一次棚卸しを反映
- Grepチェック: Arc/Mutex/RwLock/Send/Sync の確認と未整備箇所の列挙
- 確認対象:
- ArrayBox/MapBox/BufferBox の共有戦略Arc<RwLock<...>>
- NyashRuntime メンバのSend+Sync前提Arcで包む
- Scheduler/GC Hooks のSend+Sync前提
- PluginBoxV2: クロススレッド未サポ運用を明記将来設計のTODO
3.2) 10.6b Scheduler Prep12日
- 仕様固定: poll() を MIR Safepoint で呼ぶ(既実装の確認)
- 観測: NYASH_SCHED_DEMO=1 / NYASH_SCHED_TRACE=1 / NYASH_SCHED_POLL_BUDGET で動作確認
- 最小API: spawn/spawn_after/poll/yield_nowSingleThreadScheduler
- ドキュメント: phase-10/phase_10_6b_scheduler_prep.txt 更新Trace/観測例追加済)
3.3) 10.6c Parallel GC Design23日
- 設計メモ: phase-10/phase_10_6c_parallel_gc_design.txt既存を最終化
- 方針:
- Per-thread roots, Safepoint協調、カードマーキングの段階導入
- デフォルトは単一スレッド継続featureで並列ON
- API拡張は後方互換シムを用意barrier引数拡張など
====================
4) 成果物Artifacts
====================
- Docs
- 10.6a 監査メモ: phase-10/phase_10_6a_thread_safety_audit.md一次棚卸し完了
- 10.6b スケジューラ: phase-10/phase_10_6b_scheduler_prep.txtTrace/デモ手順)
- 10.6c 並列GC設計: phase-10/phase_10_6c_parallel_gc_design.txt確定版
- Code
- src/runtime/scheduler.rsSingleThreadScheduler / Send+Sync
- MIR Safepoint → VM Runtime.scheduler.poll()(済)
====================
5) リスクと緩和
====================
- 共有の粒度: 競合を避けるため、Box内部は最小限のロックで運用RwLock優先
- 並列前倒しの誘惑: 10.6では並列化を“設計と足場”に限定、実実装は次フェーズfeature
- Plugin/FFI: クロススレッド呼出しは明示的に非対応(ドキュメントで制約明記)。
====================
6) タイムライン(目安)
====================
- 10.6a: 12日
- 10.6b: 12日
- 10.6c: 23日
====================
7) 依存関係
====================
- 10.5 完了AOT/nyrt/Handle-First/TLV統一/Strict運用を前提
- Docsの最新導線: docs/private/roadmap2/phases/phase-10.5/INDEX.md
====================
8) 参照リンク
====================
- phase-10/phase_10_6_thread_safe_revolution.md設計準備
- phase-10/phase_10_6a_thread_safety_audit.md監査
- phase-10/phase_10_6b_scheduler_prep.txtスケジューラ
- phase-10/phase_10_6c_parallel_gc_design.txt並列GC

View File

@ -0,0 +1,79 @@
# Phase 10.6 → Pythonネイティブ接続プラン整理版 / txt
目的: 10.6で整えたThread-Safety/Schedulerの最小足場の上に、PythonプラグインPyRuntimeBox/PyObjectBoxをネイティブEXEAOTまで安定接続する。
====================
1) 到達イメージDoD
====================
- Linux/Windows で以下が安定動作:
- AOT: `examples/aot_py_min_chain.hako` → `Result: 4`math.sqrt(16)
- VM: `examples/py_min_chain_vm.hako` → 4.0 表示NYASH_PY_AUTODECODE=1
- returns_result 系サンプルimportR/getattrR/callRで Ok/Err が期待通りに表示
- AOTビルドの配布体験が明確:
- `tools/build_aot.{sh,ps1}` で .o → EXE、`nyash.toml`/plugins 解決、Windowsでは PATH/PYTHONHOME 調整
- 配布ガイド(依存コピー/環境変数/動作確認手順)が `docs/guides/build/aot_quickstart.md` に追記済み
====================
2) 方針(変えない原則)
====================
- Plugin-First / Handle-First / TLV 統一String/Integerはプリミティブ、Bufferはbytes(tag=7)、他はHandle(tag=8))。
- Strict: 実行はVM、JITはAOT生成専用フォールバック禁止
- by-name経路: 受け手箱名未確定時は `nyash_plugin_invoke_name_{getattr,call}_i64` で実行時解決。
====================
3) 実装タスクM1→M5
====================
M1: AOT最小ルートの安定完了確認/微修正)
- nyrt シムBufferBox→bytes(tag=7) 対応、3引数目以降をレガシーVM引数からTLV追補暫定N引数
- Windows探索EXE起動時に PATH へ exe/`plugins/` を追加、`PYTHONHOME` が未設定なら `exe\python` を採用相対はexe基準に正規化
- ドキュメントAOTクイックスタートにWindows注意点を追記
M2: TLV/FFIカバレッジ拡大最小
- kwargs/辞書のパスcallKwRをbytes(tag=7) or string(tag=6, JSON)で暫定対応(将来 BID-1拡張
- N引数の一般化invoke3→invokeN 設計、実装は段階導入。先行はレガシー補完で可)
- returns_result の統一処理VM既存→AOTでも同等に扱う
M3: Lowerer/Policy の整流
- Handle-First統一の確認Python特化の型伝搬は撤去済み戻りはHandle or プリミティブのみ参照)
- birth引数の一般化TLVメモに沿い、Integer/Stringはプリミティブ、他はHandle
- by-name の適用範囲と導線(`getattr`/`call` はby-name固定、importはmethod_id直参照
M4: 配布導線とサンプル
- スクリプト整備:`tools/build_python_aot.sh` の統合(`build_aot.sh` に一本化 or ラッパー)
- サンプル最小化returns_resultOk/Err、例外伝搬Error文字列、bytes引数、context共有per-runtime globals
- ガイド整理:`docs/guides/build/aot_quickstart.md` に「Pythonネイティブ」節を追加動作要件・環境変数
M5: 観測/CI軽量
- スモークVMチェーン / AOTチェーンの比較Result行を `tools/smoke_aot_vs_vm.sh` に追加Python系は最小のみ
- ログ:`NYASH_JIT_EVENTS*`/`NYASH_JIT_NATIVE_F64`/`NYASH_PY_AUTODECODE` による差分観測
====================
4) リスク/制約
====================
- CPython依存の配布WindowsのDLL探索PATH/PYTHONHOMEは最小整備。完全同梱embeddedは後段で検討。
- KW/辞書のTLV表現暫定はbytes/stringでブリッジ。正式BIDタグは将来導入後方互換のためJSON連携を許容
- ネイティブN引数v0はレガシーVM引数からのTLV補完でしのぎ、invokeNは次期導入。
====================
5) タイムライン(目安)
====================
- M1安定: 0.5日(確認/微修正)
- M2TLV拡充: 12日kwargsは暫定・bytes/JSON
- M3Lowerer整流: 0.51日
- M4配布/サンプル): 1日
- M5観測/CI: 0.5日
====================
6) 成果物Artifacts
====================
- 例: `examples/aot_py_min_chain.hako`, `examples/py_min_chain_vm.hako`(既存)
- ツール: `tools/build_aot.{sh,ps1}`Python節、`tools/smoke_aot_vs_vm.sh`Python最小
- Docs: `docs/guides/build/aot_quickstart.md`Python節、`docs/reference/abi/ffi_calling_convention_min.md`bytes/N引数注記
====================
7) 参照
====================
- 10.5c: Handle-First/PluginInvoke 設計by-name シム)
- 10.5d/e: AOT統合/最終仕上げnyrt/Windows探索/TLV拡張
- 10.6: Thread-Safety/Scheduler並列化前の足場

View File

@ -0,0 +1,114 @@
# Phase 10.7 Python Native 再スタート計画(合意版 / txt
目的: 現行の Plugin-FirstPyRuntimeBox/PyObjectBox, Handle-First/TLVを維持しつつ、トランスパイル路線Python→Nyashを“All or Nothing”原則で段階導入。10.6の足場Thread-Safety/Scheduler上で、AOT配布体験に直結する最短ラインを構築する。
====================
A) 方針(判断)+ Property System革命統合2025-09-18追加
====================
- 二本立てを明確化:
1) 実行系(現行): PyRuntimeBox 経由VM=仕様、JIT=AOT生成のみ。配布/運用の実用ライン。
2) トランスパイル系10.7: Python→Nyash→MIR→AOT。コンパイル成功/失敗の二択(フォールバック自動無し)。
- 役割分担未対応Pythonはユーザーが明示的に PyRuntimeBox を使う。トランスパイルはコンパイル成功率を段階的に拡大。
- Plugin-Firstは維持Parser/CompilerもプラグインBox化。CLI/VMから統一呼び出し。
====================
B) 最小成功像Phase 1 / DoD
====================
- サンプルpyPhase 1 範囲内)を `pythonc`(仮)で Nyashスクリプトへ生成 → `--compile-native` で EXE 生成 → 実行。
- 機能カバレッジPhase 1: def/if/for/while/return/bool/算術/比較/関数呼び出し/LEGB/デフォルト引数/for-else。
- Differential限定: Phase 1 サンプル群で CPython と一致(出力/戻り/例外の有無)。
====================
C) サブフェーズとタスク
====================
C1) Parser Plugin1週
- `plugins/nyash-python-parser-plugin`: Python→ASTpyo3
- AST→CorePy IRJSON: 構文の正規化with→try/finally などはPhase 2
- Telemetry: ノード統計/未対応ノードを列挙。
C2) Compiler Core2週
- IR→Nyash AST 生成Box化/クロージャ/LEGB/デフォ引数の再現)。
- peephole最小定数畳み込み
- 生成NyashのPretty-print + 簡易ソースマップ。
C3) 配線/CLI/実行3日
- `nyash --pyc file.py -o out.ny`Nyash出力/ `--pyc-native file.py -o app`EXE直行を追加内部で既存 `--compile-native` を利用)。
- 生成Nyashは既存コンパイラ経由で MIR→AOT を通すStrict
C4) テスト/観測1週並行
- `phase-10.7/testing-plan.md` の Phase 1 部分を小粒に実装。
- VM vs AOT の「Result:」比較ラインを流用(既存スモークベース)。
====================
D) インターフェース / 成果物
====================
- ParserBox: `parse(code: String) -> AstBox/CorePyBox`内部JSON保持 or to_json
- CompilerBox: `compile(ir: CorePyBox) -> Result<NyashSourceBox, ErrorBox>`
- CLI: `--pyc/--pyc-native`(初期は隠しフラグでも可)
- Docs: README/implementation/testing-plan を PLAN に沿って更新。
====================
E) リスク/緩和
====================
- 範囲膨張: Phase 1 の構文/意味論を固定し、Beyondは即Err。PyRuntimeBoxは明示利用。
- 例外/with/comp/async: Phase 2/3の対象。IR設計時に将来ードを予約後方互換
- Windows配布: 10.5で整えた PATH/PYTHONHOME 補助はPyRuntime向け。トランスパイル後はCPython依存なし。
====================
F) タイムライン(目安)
====================
- C1: 1週 / C2: 2週 / C3: 3日 / C4: 1週並行
====================
G) 現行との接続
====================
- 10.6の足場Thread-Safety/Schedulerは維持。トランスパイル系は単一スレッド/VM基準で十分。
- 10.5のAOT導線/nyrtシムはそのまま活用生成Nyashに対して適用
====================
H) Property System革命統合2025-09-18 ブレイクスルー)
====================
### 🌟 Python → Nyash Property マッピング革命
今日完成したProperty Systemstored/computed/once/birth_onceにより、Python transpilationが飛躍的に向上
**Pythonプロパティの完全対応**:
```python
# Python側
class PyClass:
def __init__(self):
self._value = 42
@property
def computed_prop(self):
return self._value * 2
@functools.cached_property
def expensive_prop(self):
return heavy_computation()
```
**自動生成Nyash革命的シンプル**:
```nyash
box PyClass {
_value: IntegerBox // stored: 通常フィールド
computed_prop: IntegerBox { me._value * 2 } // computed: @property
once expensive_prop: ResultBox { heavy_computation() } // once: @cached_property
birth() { me._value = 42 }
}
```
### 🎯 実装戦略更新
- **C2フェーズ拡張**: PythonCompilerBoxにProperty System生成機能追加
- **descriptor protocol**: Python property/method → Nyash property 4分類自動判定
- **poison-on-throw**: cached_property例外時の安全性保証
### 📊 成功指標追加
```
Property coverage: @property(100%), @cached_property(100%), descriptors(80%)
Performance boost: cached property 10-50x faster (LLVM最適化
Code generation: Python class → 50%短いNyashコード
```

View File

@ -0,0 +1,286 @@
# Phase 10.7 - Python→Nyash革命Phase 16マクロ統合版
## 🚀 **Phase 16マクロ革命による劇的変化**
**Before Phase 16**: 手動transpiler2-3ヶ月
**After Phase 16**: マクロボックス自動変換1-2週間
### 🎯 新戦略MacroBox-Driven Python Transpilation
```
Python AST → MacroBox Pattern Match → Nyash AST (自動生成)
```
**革命的変化**:
-**旧**: 手動コード変換地獄2000行実装
-**新**: マクロパターンで自動変換200行実装
## 🧠 **核心アイデアEverything is Box + Macro = 言語統合**
### **マクロボックス群(新設計)**
```rust
// src/macro/python_transpiler.rs新規
@macro_box("python_dataclass")
@macro_box("python_property")
@macro_box("python_listcomp")
@macro_box("python_contextmgr")
@macro_box("python_decorator")
```
### **実装例Python @dataclass**
#### **Before手動地獄**:
```python
@dataclass
class User:
name: str
age: int
```
→ 手動変換(数時間) → Nyashコード
#### **Afterマクロ天国**:
```nyash
// @python_dataclass マクロが自動処理!
@python_dataclass
box UserBox {
name: StringBox
age: IntegerBox
}
// ↓ 自動展開 ↓
@derive(Equals, ToString, Clone)
box UserBox {
name: StringBox
age: IntegerBox
}
```
### **実装例Python List Comprehension**
#### **Python**:
```python
result = [x * 2 for x in numbers if x > 0]
```
#### **マクロ展開Nyash**:
```nyash
// @python_listcomp マクロが自動生成
local result = numbers
.filter(|x| x > 0)
.map(|x| x * 2)
.toArray()
```
## ⚠️ All or Nothing設計フォールバックなし
**コンパイルできる or できない の2択のみ**
```nyash
compiler = new PythonCompilerBox()
result = compiler.compile(ast)
if result.isOk() {
// 100%コンパイル成功 → ネイティブ実行
print("Success! Native execution ready.")
} else {
// 未対応機能あり → 完全拒否
print("Cannot compile: " + result.getError())
print("Use PyRuntimeBox instead.")
}
```
理由:開発時と本番時で挙動が変わるのは最悪の設計
## 📋 **新実装フェーズPhase 16統合版**
### **Phase 10.7-A: MacroBox基盤3日**
```rust
// src/macro/python_transpiler.rs 作成
pub fn register_python_macros() {
register_macro_box("python_dataclass", PythonDataclassTranspiler);
register_macro_box("python_property", PythonPropertyTranspiler);
register_macro_box("python_listcomp", PythonListCompTranspiler);
}
```
### **Phase 10.7-B: コア変換パターン1週間**
**必須マクロPhase 1**:
- `@python_dataclass``@derive(Equals,ToString)`
- `@python_property``computed property`
- `@python_listcomp``.filter().map()`
- `@python_function` → Nyash関数+LEGB
### **Phase 10.7-C: テスト・検証3日**
- マクロ展開結果の差分テスト
- `nyash --expand` でPython→Nyash変換可視化
- エラー時の明確な診断メッセージ
### **Phase 10.7-D: 高度パターン1週間**
**拡張マクロPhase 2**:
- `@python_contextmgr` → try/finally自動展開
- `@python_decorator` → マクロ適用チェーン
- `@python_async` → async/await変換
## 🧪 py_runtime設計
```nyash
// Pythonセマンティクスを忠実に再現
box PyRuntime {
py_truthy(x) {
// Python的真偽値判定
if x == null or x == false { return false }
if x.hasMethod("__bool__") { return x.__bool__() }
if x.hasMethod("__len__") { return x.__len__() != 0 }
return true
}
py_getattr(obj, name) {
// ディスクリプタプロトコル、MRO探索
}
py_call(f, args, kwargs) {
// デフォルト引数、*args/**kwargs処理
}
}
```
## 📊 **新成功指標(マクロ革命版)**
### **Phase 1完了時2週間後**
```
実装コスト: 2000行 → 200行 (90%削減)
開発時間: 2-3ヶ月 → 1-2週間 (85%短縮)
マクロパターン: 5個実装完了
Python→Nyash変換率: 80%+ (基本構文)
```
### **最終目標1ヶ月後**
```
マクロパターン: 15個+ (全主要Python構文)
変換精度: 95%+ (property/dataclass/listcomp)
パフォーマンス: 10-50x faster (LLVM最適化)
統合性: Property System完全対応
```
## 🚀 **クイックスタート(マクロ版)**
```bash
# Phase 16マクロ基盤活用
cd src/macro/
touch python_transpiler.rs
# 最小マクロボックス実装
[dependencies]
nyash-rust = { path = "../../" }
serde_json = "1.0"
# テスト実行(マクロ展開確認)
NYASH_MACRO_ENABLE=1 ./target/release/nyash --expand python_test.ny
```
## 🎯 **Property System統合戦略**
### **Python @property → Nyash computed**
```python
class Circle:
@property
def area(self):
return 3.14 * self.radius ** 2
```
**マクロ自動変換**:
```nyash
@python_property // マクロが自動処理
box CircleBox {
radius: FloatBox
// computed property自動生成
area: FloatBox { 3.14 * me.radius * me.radius }
}
```
### **Python @cached_property → Nyash once**
```python
@cached_property
def expensive_calculation(self):
return heavy_computation()
```
**マクロ自動変換**:
```nyash
// once property自動生成
once expensive_calculation: ResultBox {
heavyComputation()
}
```
## 💡 **創造的可能性(マクロ革命版)**
### **🎪 ハイブリッドプログラミング**
```python
@nyash.vectorize # PythonデコレータがNyashマクロ展開
@nyash.config_schema # 環境変数自動読み込み
@nyash.api_client("https://api.example.com/swagger.json")
class DataProcessor:
def process(self, data):
return self.api.process_batch(data)
```
**マクロ展開後**:
```nyash
@vectorize @config_schema @api_client("...")
box DataProcessorBox {
// 全てマクロで自動生成!
api_client: HttpBox { /* 自動生成 */ }
config: ConfigBox { /* 環境変数から自動読み込み */ }
method process(data: ArrayBox) -> ResultBox {
me.api.processBatch(data) // SIMD最適化済み
}
}
```
### **🌍 言語統合プラットフォーム**
**Phase 16マクロシステムにより実現**:
- 🐍 **Python** → 🦀 **Nyash**: 自動変換
-**Java** → 🦀 **Nyash**: `@java_class`マクロで
- 🟦 **TypeScript** → 🦀 **Nyash**: `@ts_interface`マクロで
- 🔷 **C#** → 🦀 **Nyash**: `@csharp_property`マクロで
### **🎓 教育革命**
**リアルタイム変換Playground**:
```
┌─ Python Input ─────┐ ┌─ Nyash Output ────┐
│ @dataclass │ → │ @derive(...) │
│ class User: │ │ box UserBox { │
│ name: str │ │ name: StringBox │
│ age: int │ │ age: IntegerBox │
└────────────────────┘ └────────────────────┘
```
**学習効果**:
- プログラミング学習時間: **10分の1**
- 言語間移植理解: **瞬時**
- 最適化理解: **可視化**
## 📚 **参考資料(更新版)**
### **Phase 16統合ドキュメント**
- **[Phase 16 Macro Revolution](../phase-16-macro-revolution/README.md)** - マクロシステム全体
- **[docs/guides/macro-system.md](../../../../guides/macro-system.md)** - マクロ使用方法
- **[Macro Examples](../phase-16-macro-revolution/macro-examples.md)** - 実装例集
### **従来資料**
- **archive/gemini-analysis-transpile-beauty.md** - 創造性分析
- **archive/codex-analysis-technical-implementation.md** - 技術分析
---
## 🏆 **結論Phase 10.7の革命的変化**
**Before Phase 16**: Python実装 = 地獄の手動transpiler
**After Phase 16**: Python実装 = 楽しいマクロパターン作成
**Phase 16マクロシステムにより、Phase 10.7は「Python実装」から「言語統合革命」へと進化した**
**実装コスト90%削減、開発時間85%短縮で、10倍の表現力を実現する新時代の到来** 🚀✨

View File

@ -0,0 +1,252 @@
# Codex (GPT-5)の技術分析Python→Nyashトランスパイルの実装詳細
2025-08-30 - OpenAI Codex v0.25.0による技術的深掘り
## Big Picture
- **Purpose**: Generate Nyash source from Python to leverage Nyash's optimizer, keep debugging simple, and "think in Nyash" early without locking into MIR details.
- **Core idea**: Normalize Python to a small CorePy IR, then lower to idiomatic Nyash with a thin "Py runtime shim" in Nyash that preserves Python's dynamic semantics where required.
## AST Conversion
### Two-stage lowering
```
Python AST → CorePy IR → Nyash AST
```
CorePy should be expression-friendly, desugared, and semantics-explicit (e.g., with→try/finally, for→iterator loop, boolean ops→if/else).
### Visitor + environment
Implement a node visitor that carries scope info (locals/free/globals), evaluation order, and source spans. Use Python's `symtable` to seed symbol kinds; validate against your own pass.
### Semantic shims
Lower Python ops to Nyash intrinsics that preserve semantics:
- `py_truthy(x)`
- `py_getattr(o,"a")`
- `py_setattr(o,"a",v)`
- `py_binop("add", a, b)`
- `py_cmp("lt", a, b)`
- `py_iter(x)`
- `py_call(f, args, kwargs)`
- `py_slice(x, i, j, k)`
### Boxes and cells
Model Python variables and closures with Box/Cell objects. Rule of thumb: locals are unboxed unless captured or aliased; promote to Box when needed. Everything-is-Box in Nyash aligns well with Python's mutability/aliasing.
### Control flow
Normalize to a small set: `if`, `block`, `loop`, `break`, `continue`, `try/catch/finally`, `throw`. Lower `and`/`or` with short-circuit temp; turn comprehensions into explicit loops with dedicated inner scope.
## Transpile Quality
### Readability vs optimize
Offer modes. Default emits idiomatic Nyash constructs and meaningful identifiers, comments with source spans, and simple temporaries. "Optimize" mode switches to `py_*` intrinsics fusion and fewer temps.
### Idiomatic Nyash
Prefer Nyash control constructs over procedural labels. Use native blocks for `if/else`, `match` if Nyash has it; only fall back to runtime calls where semantics demand.
### Stable pretty-printer
Round-trip friendly formatter with consistent whitespace, trailing comma rules, and deterministic temp naming (`_t1`, `_t2…`). Keep def/class emitted in declaration-order.
### Debug info
Attach `span(file, line, col)` to every IR node, carry through to Nyash AST, then emit a sidecar source map. Optionally embed lightweight `#line` directives or inline comments per statement in debug builds.
## Python Feature Mapping
### Default args
Evaluate at def-time; store tuple/dict on the function object. At call-time, fill missing with stored defaults. Beware mutable defaults: do not clone; reuse exact object.
### LEGB scoping
Build symbol table with flags for `global`/`nonlocal`. Emit closure "cells" (Boxes) for free vars; functions capture a vector of cells. Globals map to the module dict; builtins fallback when name miss in global.
### for/else, while/else
Introduce `broken=false`. On `break`, set and exit; after loop, `if !broken { else_block }`.
### Comprehensions
Create inner function/scope per comprehension (Python 3 semantics). Assignment targets exist only in that scope. Preserve evaluation order and late binding behavior.
### With statement
Desugar to try/finally per Python spec: evaluate context expr, call `__enter__`, bind target, run body, always call `__exit__`, and suppress exception only if `__exit__` returns truthy.
### Decorators
Evaluate bottom-up at def-time: `fn = decoN(...(deco1(fn)))` then assign back. Keep evaluation order of decorator expressions.
### Generators
Lower to a state machine object implementing Nyash's iterator protocol, with saved instruction pointer, stack slots, and exception injection (`throw`, `close`). Support `yield from` by delegation trampoline.
### Pattern matching (PEP 634)
If supported by Nyash, map directly; else lower to nested guards and extractor calls in a `py_match` helper library.
### Data model
Attribute access honors descriptors; method binding creates bound objects; arithmetic and comparisons dispatch to `__op__`/`__rop__` and rich comparisons; truthiness via `__bool__`/`__len__`.
## Performance Opportunities
### At transpile-time
- Constant fold literals, f-strings (format plan precomputation), simple arithmetic if types are literal.
- Invariant hoisting for loop-invariant comprehensions and attribute chains when no side-effects (guarded).
- Direct calls to Nyash intrinsics for selected builtins (`len`, `isinstance`, `range`) only if not shadowed (prove via symbol table).
- Peephole: collapse nested `py_truthy(py_truthy(x))`, merge adjacent `if` with literal conditions, drop dead temporaries.
### Defer to Nyash compiler
- Inlining across Nyash functions, register allocation, loop unrolling, vectorization, constant propagation at MIR level.
- DCE/CSE once `py_*` helpers are inlined or annotated as pure/idempotent where legal.
### Types as hints
- Consume Python annotations/`typing` to emit specialized fast paths: e.g., `int` → direct Nyash integer ops, else fallback to `py_binop`. Plumb types through IR as optional metadata for MIR to exploit.
- Profile-guided guards: optional mode emits guards around hot calls to enable Nyash JIT/AOT to speculate and deopt to generic `py_*`.
## Error Handling & Debug
### Source maps
Emit a compact mapping (e.g., VLQ JSON) from Nyash line/col → Python original; include segment mappings per expression for precise stepping.
### Exception rewriting
Wrap Nyash runtime entrypoints to translate stack frames via the source map, hiding frames from helpers (`py_*`) unless verbose mode is on.
### Stage diagnostics
- CorePy dump: toggle to print normalized IR with spans.
- Nyash preview: post-format preview with original Python line hints.
- Trace toggles: selective tracing of `py_call`, `py_getattr`, iteration; throttle to avoid noise.
### Friendly messages
On unsupported nodes or ambiguous semantics, show minimal repro, Python snippet, and link to a doc page. Include symbol table excerpt when scoping fails.
## Architecture & DX
### Pass pipeline
```
Parse Python AST → Symbol table → Normalize to CorePy →
Scope/closure analysis → Type/meta attach → Lower to Nyash AST →
Optimize (peephole/simplify) → Pretty-print + source map
```
### Runtime shim (`nyash/lib/py_runtime.ny`)
Core APIs:
- `py_call(f, pos, kw, star, dstar)`
- `py_truthy(x)`
- `py_getattr/py_setattr`
- `py_binop(op, a, b)`
- `py_cmp(op,a,b)`
- `py_iter(x)`
- `py_next(it)`
- `py_slice(x,i,j,k)`
- `py_with(mgr, body_fn)`
- `py_raise`
- `py_is`
- `py_eq`
Data model support: descriptor get/set, method binding, MRO lookup, exception hierarchy, StopIteration protocol.
Perf annotations: mark pure or inline candidates; keep stable ABI.
### CLI/flags
Modes:
- `--readable`
- `--optimized`
- `--debug`
- `--emit-sourcemap`
- `--dump-corepy`
- `--strict-builtins`
Caching: hash of Python AST + flags to cache Nyash output, source map, and diagnostics.
Watch/incremental: re-transpile changed modules, preserve source map continuity.
### Tests
- Golden tests: Python snippet → Nyash output diff, with normalization.
- Differential: run under CPython vs Nyash runtime for functional parity on a corpus (unit/property tests).
- Conformance: edge cases (scoping, descriptors, generators, exceptions) and evaluation order tests.
## Pitfalls & Remedies
### Evaluation order
Python's left-to-right arg eval, starred/unpacking, and kw conflict checks. Enforce by sequencing temps precisely before `py_call`.
### Shadowing builtins/globals
Only specialize when proven not shadowed in any reachable scope. Provide `--strict-builtins` to disable specialization unless guaranteed.
### Identity vs equality
`is` is reference identity; avoid folding or substituting.
### Integer semantics
Python's bigints; ensure Nyash numeric layer matches or route to bigints in `py_*`.
## Future Extensibility
### Plugins
Pass manager with hooks (`before_lower`, `after_lower`, `on_node_<Type>`). Allow project-local rewrites and macros, with access to symbol/type info.
### Custom rules
DSL for pattern→rewrite with predicates (types, purity), e.g., rewrite `dataclass` patterns to Nyash records.
### Multi-language
Keeping the Nyash script as a stable contract invites other frontends (e.g., a subset of JS/TypeScript or Lua) to target Nyash; keep `py_*` separate from language-agnostic intrinsics to avoid contamination.
### Gradual migration
As Nyash grows Pythonic libraries, progressively replace `py_*` with native Nyash idioms; keep a compatibility layer for mixed projects.
## Concrete Translation Sketches
### Attribute
```python
a.b
```
```nyash
py_getattr(a, "b")
```
### Call
```python
f(x, y=1, *as, **kw)
```
```nyash
py_call(f, [x], {"y":1}, as, kw)
```
### If
```python
if a and b:
```
```nyash
let _t=py_truthy(a); if _t { if py_truthy(b) { ... } }
```
### For/else
```python
for x in xs:
if cond:
break
else:
else_block
```
```nyash
let _it = py_iter(xs);
let _broken=false;
loop {
let _n = py_next(_it) catch StopIteration { break };
x = _n;
...
if cond { _broken=true; break }
}
if !_broken { else_block }
```
### With
Evaluate mgr, call `__enter__`, bind val; try body; on exception, call `__exit__(type,e,tb)` and suppress if returns true; finally call `__exit__(None,None,None)` when no exception.
### Decorators
```nyash
let f = <def>;
f = decoN(...(deco1(f)));
name = f
```
## Why Nyash Script First
- **Debuggability**: Human-readable Nyash is easier to inspect, diff, and map errors to; source maps stay small and precise.
- **Optimization leverage**: Nyash compiler/MIR can keep improving independently; your Python frontend benefits automatically.
- **Ecosystem fit**: Generates idiomatic Nyash that other tools (formatters, linters, analyzers) can understand; fosters a consistent DX.

View File

@ -0,0 +1,72 @@
# Gemini先生の分析Python→Nyashトランスパイルの「面白さ」と「可能性」
2025-08-30 - Geminiによる深い洞察
## 1. 創造的な活用方法 - 「ハイブリッドプログラミング」の新しい形
このアプローチの最大の面白さは、**PythonとNyashの境界を曖昧にし、両者の長所を自在に組み合わせられる「ハイブリッドプログラミング」環境**が生まれる点にあります。
### パフォーマンスの「目利き」チューニング
開発者はまず、書き慣れたPythonで迅速にプロトタイプを構築します。パフォーマンスが問題になる箇所だけ、トランスパイルされたNyashコードを覗き見ます。「なるほど、このリスト内包表記はこういうループになるのか。ここをNyashの並列処理機能に書き換えれば速くなりそうだ」といった具合に、**生成されたコードを"最適化のためのヒント"として活用**し、手動で高性能なNyashコードに置き換えることができます。これは、Pythonの手軽さとネイティブの速度を、開発者が主体的にコントロールできる、非常に楽しいプロセスです。
### Nyashを操るためのDSLドメイン固有言語としてPythonを使う
Pythonの強力なメタプログラミング能力デコレータ、AST操作などを使い、「Nyashコードジェネレータ」をPythonで記述できます。例えば、特定の計算パターンを最適化するNyashコードを生成するPythonデコレータを作るのはどうでしょう。
```python
# このデコレータがNyashのSIMD命令を使うコードを生成する
@nyash.vectorize
def python_function(a, b):
return a + b
```
このように、Pythonの簡潔な記述から、裏では非常に複雑で高性能なNyashコードが生成される。これはまさに、**Pythonを「Nyashのための高級マクロ言語」として使う**創造的なハックです。
### 動的なコード生成と実行
実行時にPythonコード文字列を生成し、それをNyashにトランスパイルして即座にネイティブ実行する、といった芸当も可能です。これにより、設定ファイルやユーザー入力に基づいて動的に高性能な処理ロジックを組み立てるような、柔軟なアプリケーションが実現できます。
## 2. 言語進化への影響 - 共進化するエコシステム
この方式は、一方的な変換ではなく、両言語が互いに影響を与え合う「共進化」の触媒となります。
### Nyashへのフィードバック
Pythonの標準的なイディオム例: `with`文、ジェネレータ、リスト内包表記をNyashに変換する際、「どうもしっくりくる表現がNyashにない」「もっとエレガントに書ける構文が欲しい」という課題が必ず見つかります。これは、**Pythonという巨大なユースケースからNyashが学ぶ絶好の機会**です。このフィードバックループが、Nyashをより表現力豊かで実用的な言語へと進化させます。
### Pythonコミュニティへの影響
「この書き方をすれば、Nyashで速くなる」という知見が広まると、Pythonプログラマーの中に**「Nyash-aware」なコーディングスタイル**が生まれる可能性があります。これは、Pythonのサブセットや方言のようなもので、パフォーマンスを意識した新しいPythonの書き方として定着するかもしれません。Pythonのコードが、静的解析や型ヒントだけでなく、「ネイティブ変換効率」という新しい評価軸を持つようになります。
## 3. 実装の優雅さ - 「AST to AST」という美しい設計
トランスパイラの内部実装そのものにも、開発者を楽しませるエレガントなパターンが存在します。
### AST抽象構文木レベルでの変換
最もクリーンな実装は、Pythonの`ast`モジュールでソースコードをASTに変換し、そのASTの各ードを再帰的に辿りながら、対応するNyashのASTードを構築していく方法です。これは、文字列置換のような場当たり的な方法とは異なり、非常に構造的で堅牢です。Pythonの`for`ループのASTードが、Nyashの`for`ループのASTードに1対1で対応付けられる様は、パズルを解くような知的な面白さがあります。
### 変換パターンの分離と合成
Pythonの各構文要素関数定義、if文、クラスなどに対応する変換ロジックを、それぞれ独立した小さな関数やクラスとして実装します。これにより、トランスパイラ全体の見通しが良くなり、テストも容易になります。新しい構文への対応も、新しい変換パターンを追加するだけで済みます。このモジュール性は、大規模なソフトウェアを設計する上での美しさそのものです。
## 4. 教育的インパクト - 生きた「コンパイラ入門」
このツールは、プログラミング学習者にとって最高の教材となり得ます。
### 概念の可視化
「高級言語の裏側では、実際にはもっと低レベルな処理が行われている」というコンピュータサイエンスの基本概念を、これ以上なく明確に示せます。Pythonのたった1行が、Nyashの数行のコードに展開されるのを見ることで、抽象化のコストとメリットを直感的に理解できます。
### 言語間の「ロゼッタストーン」
PythonとNyashという2つの言語の思考様式の違いを学ぶための、動的な「ロゼッタストーン」になります。「Pythonの辞書は、Nyashではハッシュマップとしてこう表現されるのか」「Pythonの動的型付けは、Nyashの型推論によってこう解決されるのか」といった発見は、学習者にとって大きな喜びとなるでしょう。
### インタラクティブな学習環境
Web上で、左にPython、右にリアルタイムで変換されたNyashコードが表示されるような「Nyash Playground」を作れば、非常に人気の出る学習ツールになるはずです。
## 5. 長期的な展望 - 5年後、10年後の可能性
このアプローチは、短期的な実装の容易さだけでなく、長期的に大きな可能性を秘めています。
### 5年後: Pythonエコシステムのシームレスな高速化
トランスパイラの完成度が高まり、主要なPythonライブラリNumPy, Pandasの一部などをNyashに変換できるようになっているかもしれません。`pip install`するだけで、内部的にNyashへ変換・コンパイルされ、ユーザーは意識することなくPythonコードのままネイティブの速度を手に入れる、という未来が考えられます。Pythonの型ヒントが、単なる静的解析のためだけでなく、**Nyashへの最適化コンパイルのための重要なヒント**として活用されているでしょう。
### 10年後: 「ハイブリッド言語」としての地位確立
PythonとNyashの関係は、TypeScriptとJavaScriptの関係に似たものになっているかもしれません。開発者は、プロジェクトの大部分をPythonで書き、パフォーマンスクリティカルな部分はNyashで書く、あるいはPythonで書いたものをトランスパイルして微調整する、という開発スタイルが当たり前になっている可能性があります。Nyashは「Pythonをネイティブ速度で動かすための最高のパートナー言語」としての地位を確立し、両言語は互いに補完し合う強力なエコシステムを形成しているでしょう。最終的には、**Pythonの書きやすさと、ネイティブコードの実行性能を両立させた、究極のスクリプト環境**が実現しているかもしれません。
## まとめ
B案トランスパイル方式は、単に技術的に堅実なだけでなく、開発者の知的好奇心を刺激し、言語コミュニティ全体を巻き込んで成長していく「面白さ」と「可能性」に満ちた選択です。生成されたNyashコードが「ブラックボックス」ではなく「ホワイトボックス」であることが、デバッグ、最適化、学習、そして未来の創造的なハックへと繋がる鍵となります。この選択は、Nyashプロジェクトの成功に大きく貢献する戦略的な一手だと確信します。

View File

@ -0,0 +1,274 @@
# PythonCompilerBox Property System活用実装
## 🎯 概要
Property System革命stored/computed/once/birth_onceをPythonCompilerBoxで活用し、Python→Nyash transpilationを実現する技術実装設計。
## 🏗️ アーキテクチャ設計
### コアコンポーネント
```nyash
box PythonCompilerBox {
// Property System を活用したコンパイラ実装
classifier: PropertyClassifierBox
generator: NyashCodeGeneratorBox
validator: SemanticValidatorBox
// コンパイル結果のキャッシュonce使用
once compilation_cache: MapBox { new MapBox() }
// 動的に計算される統計情報computed使用
success_rate: FloatBox { me.get_success_statistics() }
total_files_processed: IntegerBox { me.compilation_cache.size() }
birth() {
me.classifier = new PropertyClassifierBox()
me.generator = new NyashCodeGeneratorBox()
me.validator = new SemanticValidatorBox()
}
}
```
## 🧠 PropertyClassifierBox実装
```nyash
box PropertyClassifierBox {
// 分類ルールのキャッシュonce
once classification_rules: RuleSetBox { load_classification_rules() }
// 統計情報computed
classified_count: IntegerBox { me.get_classification_stats().count }
accuracy_rate: FloatBox { me.get_classification_stats().accuracy }
classify_python_property(ast_node) {
// Python AST → Property type 分類
if me.has_decorator(ast_node, "@property") {
if me.is_simple_computation(ast_node) {
return "computed" // 単純計算 → computed
} else {
return "once" // 複雑処理 → キャッシュ推奨
}
}
if me.has_decorator(ast_node, "@functools.cached_property") {
return "once" // 明示的キャッシュ
}
if me.is_init_assignment(ast_node) {
return "stored" // 通常フィールド
}
if me.is_birth_once_candidate(ast_node) {
return "birth_once" // 初期化時のみ評価
}
return "unsupported" // Phase 2以降
}
// ヒューリスティック判定
is_simple_computation(node) {
// 副作用なし+計算量小 → computed適合性判定
return me.has_no_side_effects(node) and me.is_lightweight(node)
}
is_birth_once_candidate(node) {
// 初期化時のみ必要な重い処理を検出
return me.called_in_init_only(node) and me.is_expensive(node)
}
}
```
## 🏭 NyashCodeGeneratorBox実装
```nyash
box NyashCodeGeneratorBox {
// テンプレートエンジンonce
once property_templates: TemplateEngineBox {
load_property_templates()
}
// 生成コード統計computed
generated_lines: IntegerBox { me.count_generated_code_lines() }
compression_ratio: FloatBox { me.calculate_compression_ratio() }
generate_property_declaration(property_info) {
local template = me.property_templates.get(property_info.type)
// Property typeごとの生成
peek property_info.type {
"stored" => me.generate_stored_property(property_info),
"computed" => me.generate_computed_property(property_info),
"once" => me.generate_once_property(property_info),
"birth_once" => me.generate_birth_once_property(property_info),
else => throw UnsupportedPropertyError(property_info.type)
}
}
generate_computed_property(info) {
// computed property テンプレート
return info.name + ": " + info.type + " { " + info.expression + " }"
}
generate_once_property(info) {
// once property テンプレート(キャッシュ+例外安全)
local code = "once " + info.name + ": " + info.type + " { " + info.expression + " }"
if info.has_exception_risk {
code = code + " catch(ex) { poison(me." + info.name + ", ex); throw ex }"
}
return code
}
generate_birth_once_property(info) {
// birth_once property テンプレート
return "birth_once " + info.name + ": " + info.type + " { " + info.expression + " }"
}
}
```
## 🔍 SemanticValidatorBox実装
```nyash
box SemanticValidatorBox {
// 検証ルールonce
once validation_rules: ValidationRuleSetBox {
load_semantic_validation_rules()
}
// 検証結果統計computed
validation_success_rate: FloatBox { me.get_validation_stats().success_rate }
error_categories: ArrayBox { me.get_validation_stats().error_types }
validate_property_semantics(python_ast, nyash_code) {
local errors = new ArrayBox()
// 1. Property type一致性検証
me.validate_property_type_consistency(python_ast, nyash_code, errors)
// 2. 例外安全性検証
me.validate_exception_safety(python_ast, nyash_code, errors)
// 3. 性能特性検証
me.validate_performance_characteristics(python_ast, nyash_code, errors)
return ValidationResult.new(errors)
}
validate_property_type_consistency(python_ast, nyash_code, errors) {
// Pythonの@propertyとNyashのcomputedが対応しているかチェック
local python_properties = me.extract_python_properties(python_ast)
local nyash_properties = me.extract_nyash_properties(nyash_code)
loop(python_properties.iter()) property {
local expected_type = me.infer_nyash_property_type(property)
local actual_type = nyash_properties.get(property.name).type
if expected_type != actual_type {
errors.add(PropertyTypeMismatchError.new(property.name, expected_type, actual_type))
}
}
}
}
```
## 🎯 統合ワークフロー
```nyash
box PythonTranspilationWorkflow {
compiler: PythonCompilerBox
birth() {
me.compiler = new PythonCompilerBox()
}
transpile_python_file(file_path) {
// 1. Pythonファイル解析
local python_ast = me.parse_python_file(file_path)
// 2. Property分類
local classified_properties = me.compiler.classifier.classify_all_properties(python_ast)
// 3. Nyashコード生成
local nyash_code = me.compiler.generator.generate_nyash_code(classified_properties)
// 4. セマンティック検証
local validation_result = me.compiler.validator.validate_property_semantics(python_ast, nyash_code)
if validation_result.has_errors() {
throw TranspilationError.new(validation_result.errors)
}
// 5. コンパイル結果キャッシュonce活用
me.compiler.compilation_cache.set(file_path, nyash_code)
return nyash_code
}
}
```
## 🧪 テスト実装例
```nyash
box PropertySystemTranspilationTest {
test_computed_property_generation() {
local python_code = '''
class TestClass:
@property
def doubled_value(self):
return self.value * 2
'''
local compiler = new PythonCompilerBox()
local result = compiler.transpile(python_code)
assert result.contains("doubled_value: IntegerBox { me.value * 2 }")
}
test_once_property_generation() {
local python_code = '''
class TestClass:
@functools.cached_property
def expensive_calc(self):
return heavy_computation()
'''
local compiler = new PythonCompilerBox()
local result = compiler.transpile(python_code)
assert result.contains("once expensive_calc: ResultBox { heavy_computation() }")
}
test_poison_on_throw_integration() {
local python_code = '''
class TestClass:
@functools.cached_property
def risky_operation(self):
if random.random() < 0.1:
raise ValueError("Failed")
return success_result()
'''
local compiler = new PythonCompilerBox()
local result = compiler.transpile(python_code)
assert result.contains("catch(ex) { poison(me.risky_operation, ex); throw ex }")
}
}
```
## 📊 期待される効果
### 1. 実装効率の向上
- Property System活用により、コンパイラ自体の実装がクリーン
- once活用でコンパイルキャッシュ、computed活用で統計計算
### 2. 生成コードの高品質化
- Python property → Nyash property の自然な1:1マッピング
- poison-on-throw統合による例外安全性
### 3. 保守性の向上
- Box化されたコンポーネント設計
- 明確な責任分離(分類・生成・検証)
この設計により、Property System革命を最大限活用したPython transpilation実装が実現できます

View File

@ -0,0 +1,295 @@
# Python Native実装例
## 🎯 実装イメージ
### 使用例1: 基本的な関数のネイティブ化
```nyash
// example1_basic.hako
// Pythonコードをネイティブコンパイル
// Step 1: Pythonコードを用意
code = """
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
"""
// Step 2: パース
parser = new PythonParserBox()
ast = parser.parse(code)
print("Parsed functions: " + parser.getStats().get("functions"))
// Step 3: コンパイル
compiler = new PythonCompilerBox()
mir_module = compiler.compile(ast)
// Step 4: 実行
if mir_module.isOk() {
// ネイティブ実行!
module = mir_module.get()
// 関数を取得して実行
fib = module.getFunction("fibonacci")
result = fib.call(10)
print("fibonacci(10) = " + result) // 55
fact = module.getFunction("factorial")
result = fact.call(5)
print("factorial(5) = " + result) // 120
} else {
print("Compilation failed: " + mir_module.getError())
}
```
### 使用例2: コンパイル可否の明確な判定
```nyash
// example2_clear_separation.hako
// コンパイルできるかどうか事前に判定
// Phase 1対応のコード
code_phase1 = """
def compute_sum(n):
total = 0
for i in range(n):
total += i * i
return total
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
"""
// Phase 1未対応のコード
code_unsupported = """
def fibonacci_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
"""
// コンパイラーで判定
parser = new PythonParserBox()
compiler = new PythonCompilerBox()
// Phase 1対応コードのチェック
ast1 = parser.parse(code_phase1)
result1 = compiler.compile(ast1)
if result1.isOk() {
print("✅ Phase 1 code compiled successfully!")
module = result1.get()
print("compute_sum(100) = " + module.call("compute_sum", 100))
} else {
print("❌ Compilation failed: " + result1.getError())
}
// 未対応コードのチェック
ast2 = parser.parse(code_unsupported)
result2 = compiler.compile(ast2)
if result2.isOk() {
print("✅ Compiled successfully!")
} else {
print("❌ Cannot compile: " + result2.getError())
print(" Reason: yield expression not supported in Phase 1")
print(" Please use PyRuntimeBox instead")
}
```
### 使用例3: プログレッシブ最適化
```nyash
// example3_progressive.hako
// 実行しながら徐々に最適化
// 型推論付きコンパイラー
compiler = new PythonCompilerBox()
compiler.enableTypeInference(true)
compiler.enableProfiling(true)
// 初回実行(型情報収集)
code = """
def matrix_multiply(A, B):
# 最初は型が不明
result = []
for i in range(len(A)):
row = []
for j in range(len(B[0])):
sum = 0
for k in range(len(B)):
sum += A[i][k] * B[k][j]
row.append(sum)
result.append(row)
return result
"""
// プロファイル付き実行
for i in range(5) {
mir = compiler.compile(parser.parse(code))
// 実行してプロファイル収集
module = mir.get()
A = [[1, 2], [3, 4]]
B = [[5, 6], [7, 8]]
result = module.call("matrix_multiply", A, B)
// 型情報が蓄積される
print("Iteration " + i + ": ")
print(" Type confidence: " + compiler.getTypeConfidence())
print(" Optimization level: " + compiler.getOptimizationLevel())
}
// 5回実行後、完全に最適化されたコードが生成される
```
### 使用例4: 言語間相互運用
```nyash
// example4_interop.hako
// PythonコードとNyashコードのシームレスな連携
// Pythonで数値計算関数を定義
python_math = """
import math
def distance(x1, y1, x2, y2):
return math.sqrt((x2-x1)**2 + (y2-y1)**2)
def normalize(vector):
magnitude = math.sqrt(sum(x**2 for x in vector))
return [x/magnitude for x in vector]
"""
// コンパイルしてNyashから使用
module = compile_python(python_math)
// Nyash側のゲームロジック
box GameObject {
init { x, y, vx, vy }
update(dt) {
// Python関数をネイティブ速度で呼び出し
me.x = me.x + me.vx * dt
me.y = me.y + me.vy * dt
// 正規化Pythonの関数を使用
local normalized = module.normalize([me.vx, me.vy])
me.vx = normalized[0]
me.vy = normalized[1]
}
distanceTo(other) {
// Pythonの距離計算関数を使用
return module.distance(me.x, me.y, other.x, other.y)
}
}
// 完全にネイティブコードとして実行される!
```
### 使用例5: デバッグとプロファイリング
```nyash
// example5_debug.hako
// 開発時のデバッグ支援
// デバッグモード有効
parser = new PythonParserBox()
parser.enableDebug(true)
compiler = new PythonCompilerBox()
compiler.enableDebug(true)
compiler.enableSourceMap(true) // 元のPythonコードへのマッピング
problematic_code = """
def buggy_function(items):
total = 0
for item in items:
# バグ: itemが文字列の場合エラー
total += item * 2
return total / len(items)
"""
// コンパイル試行
result = compiler.compile(parser.parse(problematic_code))
if result.isErr() {
// 詳細なエラー情報
diag = compiler.getDiagnostics()
print("Compilation failed at line " + diag.line)
print("Issue: " + diag.message)
print("Suggestion: " + diag.suggestion)
// フォールバックで実行してランタイムエラーを確認
runtime = new PythonRuntimeBox()
try {
runtime.exec(problematic_code)
runtime.call("buggy_function", ["a", "b", "c"])
} catch (e) {
print("Runtime error: " + e.message)
print("This would have been caught at compile time!")
}
}
// プロファイリング情報
profiler = new PythonProfiler()
profiler.attach(module)
profiler.run()
print("Hot spots:")
print(profiler.getHotSpots())
print("Type instability:")
print(profiler.getTypeInstability())
```
## 🎯 実装の進化
### Phase 1現在
```python
# これらがネイティブ化可能
def add(x, y): return x + y
def factorial(n): ...
def fibonacci(n): ...
```
### Phase 2予定
```python
# 特殊メソッド対応
class Vector:
def __add__(self, other): ...
def __len__(self): ...
# 内包表記
squares = [x**2 for x in range(10)]
```
### Phase 3将来
```python
# 完全な言語機能
async def fetch_data(): ...
@decorator
def enhanced_function(): ...
yield from generator
```
## 🚀 パフォーマンス期待値
```
Benchmark: Fibonacci(30)
CPython: 1.234s
PyPy: 0.123s
Nyash Native: 0.012s (100x faster!)
Benchmark: Matrix Multiplication (100x100)
CPython: 5.678s
NumPy: 0.234s
Nyash Native: 0.198s (NumPyに匹敵!)
```

View File

@ -0,0 +1,249 @@
# Phase 10.7 実装詳細
## 🛠️ 技術アーキテクチャ
### 2段階変換パイプライン
```
Python AST → CorePy IR → Nyash AST → Nyashスクリプト
```
**CorePy IR**の役割:
- Pythonの複雑な構文を正規化
- セマンティクスを明示的にwith→try/finally等
- 最適化しやすい中間表現
### 実装構造
```rust
// plugins/nyash-python-parser-plugin/src/lib.rs
#[plugin_box]
pub struct PythonParserBox {
base: BoxBase,
}
#[plugin_methods]
impl PythonParserBox {
pub fn parse(&self, code: &str) -> Result<Box<dyn NyashBox>> {
Python::with_gil(|py| {
let ast_mod = py.import("ast")?;
let tree = ast_mod.call_method1("parse", (code,))?;
Ok(self.convert_ast(tree)?)
})
}
}
```
## 📐 Python固有機能の実装戦略
### 1. デフォルト引数の罠
```python
# Python: 定義時に一度だけ評価
def bad_default(lst=[]):
lst.append(1)
return lst
```
```nyash
// 生成されるNyash
box GeneratedModule {
init { _default_lst }
constructor() {
me._default_lst = new ArrayBox() // 定義時に一度だけ
}
bad_default(lst) {
if lst == null {
lst = me._default_lst // 同じインスタンスを再利用!
}
lst.append(1)
return lst
}
}
```
### 2. LEGB スコーピング
```python
# Local → Enclosing → Global → Builtin
global_var = 1
def outer():
enclosing_var = 2
def inner():
local_var = 3
```
実装:
- シンボルテーブルでスコープ管理
- クロージャはBox/Cellで実装
- global/nonlocalフラグを追跡
### 3. for/else, while/else
```python
for i in range(10):
if i == 5:
break
else:
print("No break")
```
```nyash
// 生成されるNyash
local _broken = false
local _iter = py_iter(range(10))
loop(true) {
local _next = py_next(_iter)
if _next.isStopIteration() { break }
local i = _next.value
if i == 5 {
_broken = true
break
}
}
if not _broken {
print("No break")
}
```
## 🔧 パスパイプライン
```
Parse Python AST
Symbol table analysis
Normalize to CorePy IR
Scope/closure analysis
Type metadata attachment
Lower to Nyash AST
Peephole optimization
Pretty-print + source map
```
## 📊 最適化戦略
### トランスパイル時の最適化
- 定数畳み込み
- ループ不変式の巻き上げ
- ビルトイン関数の直接呼び出し(シャドウイングなし時)
- 冗長な`py_truthy()`の除去
### Nyashコンパイラに委ねる最適化
- インライン展開
- レジスタ割り当て
- ループアンローリング
- ベクトル化
### 型情報の活用
```python
def add(x: int, y: int) -> int:
return x + y
```
→ 型ヒントがあれば`py_binop`ではなく直接整数演算
## 🐛 エラー処理とデバッグ
### ソースマップ
```json
{
"version": 3,
"sources": ["example.py"],
"mappings": "AAAA,IAAM,CAAC,GAAG...",
"names": ["add", "x", "y"]
}
```
### デバッグモード
```bash
nyash-transpile --debug example.py
# 出力:
# - CorePy IRダンプ
# - Nyashプレビュー元のPython行ヒント付き
# - 変換トレース
```
### エラーメッセージ
```
ERROR: Cannot compile function 'async_func' at line 10
Reason: async/await not supported in Phase 1
AST Node: AsyncFunctionDef
Suggestion: Use PyRuntimeBox or wait for Phase 3
```
## ⚡ パフォーマンス最適化
### ホットパス識別
```nyash
// プロファイル情報を活用
if compiler.isHotPath(func) {
// 積極的な最適化
result = compiler.optimizeAggressive(func)
} else {
// 標準的な変換
result = compiler.compile(func)
}
```
### JIT連携
```nyash
// 型特化コード生成
@jit_specialize(int, int)
def add(x, y):
return x + y
```
## 🔌 プラグインAPI
### 変換フック
```rust
trait TransformHook {
fn before_lower(&mut self, node: &CorePyNode);
fn after_lower(&mut self, node: &NyashNode);
fn on_function(&mut self, func: &FunctionDef);
}
```
### カスタムルール
```yaml
# custom_rules.yaml
rules:
- pattern: "dataclass"
action: "convert_to_nyash_box"
- pattern: "numpy.array"
action: "use_native_array"
```
## 📋 実装チェックリスト
### Phase 1必須
- [ ] 関数定義def
- [ ] 条件分岐if/elif/else
- [ ] ループfor/while with else
- [ ] 基本演算子
- [ ] 関数呼び出し
- [ ] return/break/continue
- [ ] LEGB スコーピング
- [ ] デフォルト引数
### Phase 2拡張
- [ ] 例外処理try/except/finally
- [ ] with文
- [ ] list/dict/set comprehensions
- [ ] lambda式
- [ ] *args, **kwargs
### Phase 3高度
- [ ] async/await
- [ ] yield/yield from
- [ ] デコレータ
- [ ] クラス定義(基本)
- [ ] import文

View File

@ -0,0 +1,194 @@
# Python Descriptor Protocol → Nyash Property System マッピング
## 🎯 概要
2025-09-18のProperty System革命により、Python transpilationが飛躍的に向上。Pythonのdescriptor protocolを完全にNyashのProperty Systemstored/computed/once/birth_onceにマッピングする設計。
## 🧬 Pythonプロパティ分類とNyashマッピング
### 1. 通常フィールド → stored
```python
class PyClass:
def __init__(self):
self.name = "example" # 通常の属性
```
```nyash
box PyClass {
name: StringBox // stored: 通常のフィールドストレージ
birth() {
me.name = "example"
}
}
```
### 2. @property → computed
```python
class PyClass:
@property
def full_name(self):
return f"{self.first} {self.last}"
```
```nyash
box PyClass {
first: StringBox
last: StringBox
full_name: StringBox { me.first + " " + me.last } // computed: 毎回計算
}
```
### 3. @functools.cached_property → once
```python
import functools
class PyClass:
@functools.cached_property
def expensive_data(self):
return expensive_computation()
```
```nyash
box PyClass {
once expensive_data: DataBox { expensive_computation() } // once: 遅延評価+キャッシュ
}
```
### 4. カスタムdescriptor → 判定ロジック
```python
class CustomDescriptor:
def __get__(self, obj, objtype=None):
# カスタムロジック
pass
def __set__(self, obj, value):
# セットロジック
pass
class PyClass:
custom_prop = CustomDescriptor()
```
**判定ロジックPythonCompilerBox内**:
```nyash
box DescriptorAnalyzer {
analyze_descriptor(descriptor_ast) {
if descriptor_ast.has_get_only() {
if descriptor_ast.is_pure_computation() {
return "computed" // 副作用なし計算
} else {
return "once" // 副作用あり=キャッシュ推奨
}
}
if descriptor_ast.has_get_and_set() {
return "stored" // getterとsetterあり通常フィールド
}
return "unsupported" // 複雑すぎ→Phase 2以降
}
}
```
## 🎯 自動判定アルゴリズム
### Phase 1: 基本パターン認識
```python
def classify_python_property(ast_node):
# 1. デコレータ解析
if has_decorator(ast_node, "@property"):
if is_simple_computation(ast_node.body):
return "computed"
else:
return "once" # 複雑→キャッシュ推奨
# 2. cached_property検出
if has_decorator(ast_node, "@functools.cached_property"):
return "once"
# 3. 通常の__init__内代入
if is_init_assignment(ast_node):
return "stored"
# 4. descriptor検出Phase 2以降
if has_custom_descriptor(ast_node):
return analyze_descriptor_complexity(ast_node)
```
### Phase 2: 高度な判定(将来)
- **副作用解析**: I/O、外部状態変更の検出
- **コスト解析**: 計算量推定による once vs computed 判定
- **依存解析**: 他のプロパティとの依存関係
## 🌟 poison-on-throw統合
### Python例外 → Nyash例外処理
```python
class PyClass:
@functools.cached_property
def risky_operation(self):
if random.random() < 0.1:
raise ValueError("Failed!")
return expensive_result()
```
```nyash
box PyClass {
once risky_operation: ResultBox {
if random_float() < 0.1 {
throw ValueError("Failed!")
}
return expensive_result()
} catch(ex) {
poison(me.risky_operation, ex) // poison-on-throw適用
throw ex
}
}
```
## 📊 実装フェーズ
### Phase 10.7a: 基本認識1週間
- @property, @cached_property, 通常フィールドの自動分類
- 単純なcomputedプロパティ生成
### Phase 10.7b: 拡張判定2週間
- カスタムdescriptor解析
- 副作用検出ロジック
- poison-on-throw統合
### Phase 10.7c: 最適化1週間
- 依存解析による once vs computed 最適選択
- LLVM最適化との連携
## 🧪 テストケース
### 成功パターン
```python
# シンプルcomputed
@property
def area(self): return self.width * self.height # → computed
# キャッシュ必要
@functools.cached_property
def heavy_calc(self): return sum(range(1000000)) # → once
# 通常フィールド
def __init__(self): self.name = "test" # → stored
```
### 限界ケースPhase 2以降
```python
# 複雑なdescriptor未対応
class ComplexDescriptor:
def __get__(self, obj, objtype=None):
# 複雑な条件分岐、外部API呼び出し等
pass
```
## 🚀 期待される効果
1. **開発体験**: PythonプロパティがNyashで自然に表現
2. **性能向上**: LLVMによるproperty最適化10-50x高速化
3. **型安全性**: NyashのBox型システムによる実行時安全性
4. **保守性**: 生成されたNyashコードの可読性・編集可能性
このマッピング設計により、PythonからNyashへの自然で高性能なtranspilationが実現できます

View File

@ -0,0 +1,152 @@
# Phase 10.7 × Property System 革命 - 今すぐ始めるクイックスタート
## 🎯 Property System革命により実現可能になったPython→Nyash実行
2025-09-18のProperty System革命により、Python transpilationが飛躍的に実現可能に
## 🚀 最短実装ルート3週間で実用レベル
### Week 1: 基本プロパティ認識
```bash
# プラグイン作成
cd plugins/
cargo new nyash-python-parser-plugin --lib
# 最小依存関係
echo '[dependencies]
pyo3 = { version = "0.22", features = ["auto-initialize"] }
nyash-plugin-sdk = { path = "../../crates/plugin-sdk" }' >> Cargo.toml
```
### Week 2-3: Property System活用コンパイラ
```rust
// src/lib.rs - 最小実装例
use pyo3::prelude::*;
#[pyclass]
pub struct PythonCompilerBox {
property_classifier: PropertyClassifier,
}
#[pymethods]
impl PythonCompilerBox {
#[new]
pub fn new() -> Self {
Self {
property_classifier: PropertyClassifier::new(),
}
}
pub fn compile_simple(&self, python_code: &str) -> PyResult<String> {
let ast = self.parse_python(python_code)?;
let classified = self.property_classifier.classify(ast);
let nyash_code = self.generate_nyash_with_properties(classified);
Ok(nyash_code)
}
}
struct PropertyClassifier;
impl PropertyClassifier {
fn new() -> Self { Self }
fn classify(&self, ast: PythonAst) -> ClassifiedAst {
// Phase 1: 基本パターンのみ
// @property → computed
// @cached_property → once
// __init__代入 → stored
todo!("実装")
}
}
```
## 🧪 MVP テストケース
### 入力Python
```python
# test_simple.py
class Counter:
def __init__(self):
self.value = 0
@property
def doubled(self):
return self.value * 2
@functools.cached_property
def expensive_result(self):
return sum(range(1000))
```
### 期待されるNyash出力
```nyash
box Counter {
value: IntegerBox // stored
doubled: IntegerBox { me.value * 2 } // computed
once expensive_result: IntegerBox { sum_range(1000) } // once
birth() {
me.value = 0
}
}
```
### 実行テスト
```bash
# transpilation
nyash --pyc test_simple.py -o test_simple.ny
# ネイティブコンパイル
nyash --compile-native test_simple.ny -o test_app
# 実行CPython依存なし
./test_app
```
## 📊 段階的成功指標
### Phase 1 (1週間後)
-@property, @cached_property認識
- ✅ 基本クラス → box変換
- ✅ 1つのサンプルPythonファイルが動作
### Phase 2 (2週間後)
- ✅ 継承、メソッド呼び出し対応
- ✅ 10個のサンプルファイル成功
- ✅ 性能測定CPythonとの比較
### Phase 3 (3週間後)
- ✅ エラーハンドリング、例外処理
- ✅ 実用的なPythonライブラリ部分対応
- ✅ AOT配布可能なサンプルアプリ
## 🌟 創造的可能性
### ハイブリッド開発
```python
# Python側で開発・デバッグ
@nyash.optimize # デコレータで高速化指定
def heavy_computation(data):
return complex_algorithm(data)
# 本番はNyash AOTで配布
```
### リアルタイムtranspilation IDE
- 左: Pythonコード編集
- 右: リアルタイムNyash生成表示
- 下: 性能比較グラフ
### 教育効果
- Pythonユーザーが自然にNyashを学習
- Property Systemの概念理解促進
## 🎯 今日から始められるアクション
1. **プラグイン skelton作成** (30分)
2. **pyo3でPython AST取得** (2時間)
3. **@property検出ロジック** (半日)
4. **最初のbox変換** (1日)
5. **テスト実行** (30分)
Property System革命により、この夢が現実になりました🚀

View File

@ -0,0 +1,285 @@
# Python Native Testing Plan
## 🎯 テスト戦略の全体像
「世界中のPythonコードがNyashのテストケース」という思想のもと、CPythonをオラクルとして使用する包括的なテスト戦略。
## 🧪 テストレベル
### 1. プラグインレベルテスト
#### PythonParserBox Tests
```rust
// plugins/nyash-python-parser-plugin/tests/parser_tests.rs
#[test]
fn test_parse_simple_function() {
let parser = create_parser_box();
let code = "def add(x, y): return x + y";
let ast = parser.parse(create_string_box(code));
assert_eq!(ast.get_type().to_string(), "Module");
let functions = ast.get_children();
assert_eq!(functions.length(), 1);
}
#[test]
fn test_parse_with_telemetry() {
let parser = create_parser_box();
parser.enable_telemetry(true);
let code = r#"
def supported(): return 1
async def unsupported(): await foo()
"#;
parser.parse(create_string_box(code));
let stats = parser.get_stats();
assert_eq!(stats.get("total_functions"), 2);
assert_eq!(stats.get("supported_functions"), 1);
}
```
#### PythonCompilerBox Tests
```rust
#[test]
fn test_compile_arithmetic() {
let compiler = create_compiler_box();
let ast = /* ... */;
let mir = compiler.compile(ast);
assert!(mir.is_ok());
// MIR検証
let module = mir.unwrap();
assert!(module.has_function("add"));
}
```
### 2. Differential Testing Framework
```nyash
// tests/differential/framework.hako
box DifferentialTester {
init { oracle, implementation, results }
constructor() {
me.oracle = new PythonRuntimeBox() // CPython
me.implementation = new NativeEngine()
me.results = new ArrayBox()
}
test(code) {
local oracle_result, impl_result
// CPythonで実行
oracle_result = me.oracle.eval(code)
// Native実装で実行
impl_result = me.implementation.exec(code)
// 結果比較
return me.compare(oracle_result, impl_result)
}
compare(expected, actual) {
// 出力、戻り値、例外を比較
local match = new MapBox()
match.set("output", expected.output == actual.output)
match.set("return", expected.return == actual.return)
match.set("exception", expected.exception == actual.exception)
return match
}
}
```
### 3. テストケース生成
#### 基本テストスイート
```python
# tests/suites/phase1_tests.py
# 算術演算
def test_arithmetic():
assert add(2, 3) == 5
assert multiply(4, 5) == 20
assert divide(10, 2) == 5.0 # true division
# 制御フロー
def test_control_flow():
# if/else
result = conditional_logic(True, 10, 20)
assert result == 10
# for/else
found = search_with_else([1, 2, 3], 5)
assert found == "not found" # else節実行
# デフォルト引数の罠
def test_default_args():
list1 = append_to_default(1)
list2 = append_to_default(2)
assert list1 is list2 # 同じリスト!
```
#### Fuzzing with Hypothesis
```python
# tests/fuzzing/property_tests.py
from hypothesis import given, strategies as st
@given(st.integers(), st.integers())
def test_arithmetic_properties(x, y):
"""算術演算の性質をテスト"""
# Commutativity
assert add(x, y) == add(y, x)
# Identity
assert add(x, 0) == x
# Differential testing
native_result = native_add(x, y)
cpython_result = x + y
assert native_result == cpython_result
```
### 4. ベンチマークスイート
```nyash
// benchmarks/numeric_suite.hako
box NumericBenchmark {
run() {
local suite = new BenchmarkSuite()
// Fibonacci
suite.add("fibonacci", {
"cpython": { return me.runCPython("fib.py") },
"native": { return me.runNative("fib.py") }
})
// Matrix multiplication
suite.add("matrix_mult", {
"cpython": { return me.runCPython("matrix.py") },
"native": { return me.runNative("matrix.py") }
})
return suite.execute()
}
}
// 実行結果例
// fibonacci:
// CPython: 1.234s
// Native: 0.123s (10.0x faster)
// matrix_mult:
// CPython: 5.678s
// Native: 0.456s (12.4x faster)
```
### 5. 回帰テスト
```yaml
# .github/workflows/python-native-tests.yml
name: Python Native Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Differential Tests
run: |
cargo test --package nyash-python-parser-plugin
cargo test --package nyash-python-compiler-plugin
- name: Coverage Report
run: |
./tools/measure_compilation_coverage.sh
# Expected output:
# Phase 1 compatible files: 15%
# Phase 2 functions: 40% compilable
# Phase 3 functions: 10% compilable
```
## 📊 メトリクス収集
### コンパイル成功率
```nyash
// 自動計測ツール
box CoverageAnalyzer {
analyze(directory) {
local parser = new PythonParserBox()
local compiler = new PythonCompilerBox()
local stats = new MapBox()
for file in directory.glob("*.py") {
local ast = parser.parseFile(file)
local result = compiler.compile(ast)
stats.increment("total")
if result.isOk() {
stats.increment("success")
} else {
stats.increment("not_compilable")
stats.record("unsupported", result.getError())
}
}
return stats
}
}
```
### パフォーマンス追跡
```sql
-- メトリクスDB
CREATE TABLE benchmark_results (
id SERIAL PRIMARY KEY,
test_name VARCHAR(255),
implementation VARCHAR(50), -- 'cpython' or 'native'
execution_time FLOAT,
memory_usage BIGINT,
timestamp TIMESTAMP,
git_hash VARCHAR(40)
);
```
## 🚨 失敗時の診断
### デバッグ情報収集
```nyash
// コンパイル失敗時の詳細情報
compiler.enableDebug(true)
result = compiler.compile(ast)
if result.isErr() {
local diag = compiler.getDiagnostics()
print("Failed at: " + diag.get("location"))
print("Reason: " + diag.get("reason"))
print("AST node: " + diag.get("node_type"))
print("Suggestion: " + diag.get("suggestion"))
}
```
### トレース機能
```
NYASH_PYTHON_TRACE=1 ./target/release/nyash test.py
[Parser] Parsing function 'compute' at line 5
[Compiler] Compiling BinOp: Add at line 7
[Compiler] Unsupported: YieldFrom at line 15
[Error] Cannot compile function 'generator_func' - yield not supported
```
## ✅ 受け入れ基準
### Phase 1完了
- [ ] 基本テストスイート100%パス
- [ ] Differential testing 100%一致
- [ ] Phase 1対応コードの100%コンパイル成功
- [ ] 10x性能向上数値計算ベンチマーク
### 各PR必須
- [ ] 新機能の単体テスト
- [ ] Differential testケース追加
- [ ] ベンチマーク結果(該当する場合)
- [ ] カバレッジ低下なし

View File

@ -0,0 +1,13 @@
# DECISIONS (Phase 10.7)
## 2025-08-30 — 二本立て運用(決定)
- 決定: 現行の実行系PyRuntimeBox, Plugin-Firstは維持し、トランスパイル系Python→Nyashは All-or-Nothing で併走。
- 代替案: トランスパイルの部分フォールバック実行時にPyRuntimeへ落とす
- 理由: 実行時の不一致/隠れ分岐を避ける。デプロイ時の挙動を単純に保つ。
- 影響: 生成Nyashの品質責任はトランスパイラ側。利用者は明示的に系を選択。
## 2025-08-30 — Parser/CompilerもプラグインBox決定
- 決定: PythonParserBox/PythonCompilerBox としてプラグイン化し、CLIから呼び出す。
- 代替案: コア組込み。
- 理由: Plugin-First原則、配布容易性、差し替え性、隔離テスト。
- 影響: plugins/ 以下に新規プラグインを追加。SDKの最小拡張が必要になる場合あり。

View File

@ -0,0 +1,39 @@
# CorePy IR 最小スキーマC2草案
目的: Phase 1 の End-to-End を最短で通すための暫定IR。将来は構造化・拡張with/try/comp/async等
## JSON 形式(暫定)
```json
{
"module": {
"functions": [
{
"name": "main", // 省略可(既定: "main"
"return_value": 0, // 省略可bodyと排他
"body": [ // 省略可return_valueと排他
{ "Return": { "value": 0 } }
]
}
]
}
}
```
ショートカット(デバッグ/ブリッジ用)
```json
{ "nyash_source": "static box Generated { main() { return 0 } }" }
```
## 変換規則(最小)
- module.functions[0] だけを見る(複数関数は将来対応)
- name があれば `static box Generated { <name>() { ... } }`
- return_value が数値/文字列なら `return <value>` を生成
- body があれば先頭の Return.value を探し、`return <value>` を生成
- 上記が無ければ `return 0`
## 将来(予約)
- statements: If/While/For/Assign/Expr などの節を追加
- expressions: BinOp/Call/Name/Constant などを構造化
- functions配列の複数対応、クロージャは別Box化の方針を検討
注意: All-or-Nothing 原則のもと、未対応ードはCompiler側で明示的にエラーにする現段階では未実装のため、return 0にフォールバックするが、C2終盤でStrict化する

View File

@ -0,0 +1,21 @@
# Phase 10.7 Workbench
このフォルダは Python Nativeトランスパイル路線, All-or-Nothing専用の作業台です。仕様・決定・スパイク・タスクをここに集約し、雑多にならないようにします。
構成
- TODO.md: 直近の作業キュー(小粒で管理)
- DECISIONS.md: 決定事項(理由/代替案/影響)
- SPIKES/: 検証スパイクの成果小さなPoCやプロト
- notes-YYYYMMDD.md: 打合せ/検討メモ(必要に応じて)
関連
- 計画: ../PLAN.txt
- 実装: ../implementation.md
- テスト: ../testing-plan.md
- 背景: ../README.md
運用ルール(最小)
- 一度に大きくしない5〜30分単位の成果で刻む
- 決定は DECISIONS.md に残す(誰でも後から辿れる)
- スパイクは SPIKES に隔離(本流に混ぜない)

View File

@ -0,0 +1,13 @@
# TODO (Phase 10.7 Workbench)
短期C1〜C3に向けた小粒タスク
- [ ] C1: Parser plugin 雛形スケルトンを作るpyo3, parse(code)->AstBox/to_json
- [ ] C1: Telemetry最小node種別カウント, 未対応ノード列挙)
- [ ] C2: CorePy IR最小スキーマJSONを commitwith/async系は予約
- [ ] C2: IR→Nyash ASTの最小変換def/if/for/while/return/算術/比較/呼出し)
- [ ] C3: CLI隠しフラグ prototyping--pyc/--pyc-native
- [ ] Docs: PLANとimplementationの差分同期週次
メモ
- All-or-Nothing原則未対応は即Err自動フォールバックなし
- 生成Nyashは現行AOT導線で配布可能Strict

View File

@ -0,0 +1,61 @@
# Phase 10: JIT実装とセルフホスティング
## 🎯 Phase 10の全体像
Phase 10は、Nyashの実行性能を大幅に向上させるJIT実装と、言語の成熟度を示すセルフホスティングを実現します。
## 📊 実装優先順位
### 1⃣ **メイン実装: Cranelift JIT**
→ [phase_10_cranelift_jit_backend.md](phase_10_cranelift_jit_backend.md)
- VMとのハイブリッド実行ホットパス検出→JIT化
- 実装期間: 2-3ヶ月
- 目標: ホットパスで2倍以上の高速化
### 🌟 **革新的機能: GC切り替え可能ランタイム**
→ [phase_10_4_gc_switchable_runtime.md](phase_10_4_gc_switchable_runtime.md)
- 世界初実行時にGCモード切り替え可能
- 開発時はGCオンで快適、本番はGCオフで高速
- 実装期間: 2-3ヶ月Cranelift JIT後
- 技術的にCodex GPT-5が実現可能性を確認済み
### 2⃣ **並行プロジェクト: セルフホスティング**
→ [phase_10_5_core_std_nyash_impl.md](phase_10_5_core_std_nyash_impl.md)
- String/Array/MapをNyash自身で実装
- Rust依存の段階的削減
- 実装期間: 1-2ヶ月
### 3⃣ **実戦テスト: アプリケーション移植**
→ [phase_10_app_migration.md](phase_10_app_migration.md)
- Tinyproxy: ゼロコピー判定機能の検証
- Chip-8エミュレータ: fini伝播とweak参照の実戦テスト
- kiloエディタ: メモリ効率の「うっかり全体コピー」検出
### 🚫 **延期プロジェクト**
→ [Phase 11: LLVM AOT Backend](../phase-11/) - 将来の研究開発として分離
## 🛤️ 実装ロードマップ
```
Phase 9.79b (現在)
Phase 10.0: Cranelift JIT基盤構築
├→ Phase 10.1-10.3: JIT実装・最適化
├→ Phase 10.4: GC切り替え可能ランタイム ← NEW!
└→ Phase 10.5: セルフホスティング(並行)
Phase 10.9: アプリケーション移植で実戦検証
Phase 11: LLVM AOT研究将来
```
## 📈 期待される成果
1. **実行性能**: インタープリタ比100倍、VM比2-3倍の高速化
2. **言語成熟度**: 基本コンテナのセルフホスティング達成
3. **実用性検証**: 実アプリケーションの移植による実戦テスト
## 🔗 関連ドキュメント
- [00_MASTER_ROADMAP.md](../00_MASTER_ROADMAP.md) - 全体計画
- [Phase 9.79b](../phase-9/) - 統一Box設計前提
- [MIR仕様](../../../../reference/mir/) - 中間表現

View File

@ -0,0 +1,94 @@
# Phase 10.10 Python→Nyash→MIR→VM/Native ラインの実用化整備Box-First 継続)
目的: Nyash→MIR→VM/Native の実行ラインを日常運用レベルに引き上げ、GC/デバッグ/HostCallの柱を整備する。
## ゴールDoD
- エンドツーエンド実行ラインParser→AST→MIR→VM→JITがビルトインBoxで安定RO/一部WO
- GC切替Null/CountingをCLI/Boxから操作可能、root領域APIが一箇所化
- デバッグ/可視化の旗振りDebugConfig/BoxでJIT/VM/イベント/DOTを一本化
- HostCall: 読み取り系はparam受けでJIT直実行allow。書き込み系はポリシー/whitelistでopt-in可能
- 最小ベンチと回帰(サンプル)でラインの劣化を検知
## 事前整備(現状)
- HostCall基盤: Registry/Policy/Events/Boundary10.9-β/δ完了)
- JITイベント: `NYASH_JIT_EVENTS=1` 時に `threshold=1` 自動適用でLower確実実行
- 戻り境界: CallBoundaryBox で JitValue→VMValue を一元化(ハンドル復元含む)
## ワークストリーム
1) GC Switchable Runtimephase_10_4_gc_switchable_runtime.md
- 目標: NullGc/CountingGc の切替、root領域/バリアAPIの一本化
- タスク:
- NyashRuntimeBuilder: GC選択をCLI/Box反映NYASH_GC=none|counting など)
- ScopeTracker/enter_root_region()/pin_roots() の公開インターフェース確認
- CountingGcの統計出力roots/reads/writes/safepoints
- 書き込み系HostCallにバリアサイトのフックMap/Array set/push
- 受入: GC切替コマンドで統計差分が取れるHostCall書き込みでバリアサイトが加算される
2) Unified Debug Systemphase_10_8_unified_debug_system.md
- 目標: デバッグ/観測フラグを DebugConfig/Box に統合CLI/env/Boxの単一路
- タスク:
- DebugConfigRust側: dump/events/stats/dot/phi_min 等を集約
- DebugConfigBox: Boxから get/set/apply/toJson/fromJson
- Runner: CLI→DebugConfig→env/Box の一本化env直読み排除
- イベント出力先: stdout/file 切替の設定NYASH_JIT_EVENTS_PATH のBox反映
- 受入: Boxから apply 後、JIT/VM/DOTの挙動が即時反映JSONLが指定先に出力
3) E2Eラインの実用化builtin→pluginの足場
- 目標: ビルトインBoxで日常運用レベル、プラグインBoxはTLV HostCallの足場を準備
- タスク:
- Lowerカバレッジの整理BoxCall/RO/WO・param/非paramの分岐ダンプ
- 署名管理: レジストリのオーバーロード運用方針canonical idと派生idの整理
- 返り型推論: MIR Builderのreturn_type推定を確認main/補助関数とも)
- Plugin PoC: TLV/handle経由のread-onlyメソッド1つをHostCall経由で通すallowログまで
- 受入: 代表サンプルmath/map/array/stringでallow/fallbackが意図通り、plugin PoCでallowイベントが出る
4) ドキュメントと例の整理
- 目標: 例の最小集合化param/非param/RO/WO/HH/Hの代表、手順の簡潔化
- タスク:
- examples/: 重複の削減、README実行コマンド付き
- phase_10_9/10_10 のガイドをCURRENT_TASKと相互参照
- 受入: 主要ケースが examples/README からそのまま実行可
5) ベンチと回帰(最小)
- 目標: ラインの性能/退行の早期検知
- タスク:
- ny_bench.hako のケース整理(関数呼出/Map set-get/branch
- compare: VM vs JITウォームアップ付き
- 受入: ベンチ出力に JIT/VM の比較が出る(改善/退行が見える)
## リスクと対策
- param/非param 分岐の混乱: イベントに reason を必ず出すdocsにベストプラクティス受け手をparam化
- mutatingの誤許可: JitPolicyBox の whitelist/プリセットのみで許可、既定はread_only
- 署名の散逸: canonical id例: nyash.map.get_hと派生_hhの方針を明示
## 受け入れ基準(サマリ)
- DebugConfig/Box/CLIの一貫挙動apply後の即時反映
- GC切替とバリアサイト観測が可能
- HostCallRO/一部WOが param でallow、非paramでfallbackイベントで確認可
- 代表サンプルが examples/README の手順で成功
## すぐ試せるコマンド(抜粋)
```bash
# math.min関数スタイル
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_math_function_style_min_float.hako
# Map.get HH直実行
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_map_get_param_hh.hako
# Mutating opt-inArray.push
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_policy_optin_mutating.hako
## 例とスモーク(開発者向けクイック)
- 例一覧: `examples/README.md`HH直実行・mutating opt-in・GCデモ
- スモーク: `bash tools/smoke_phase_10_10.sh`
- JITイベント最小スキーマ: `docs/reference/jit/jit_events_json_v0_1.md`
### Quick Note運用の勘所
- phase分離: compile→`phase:"lower"`opt-in, runtime→`phase:"execute"`既定ON可
- しきい値: 観測ONかつ未指定なら `NYASH_JIT_THRESHOLD=1`Runner/DebugConfigが補助
- HostCall: 実例では `NYASH_JIT_HOSTCALL=1` を明示HH直実行/ANYヘルパ
- ANYヘルパ: `nyash.any.length_h / is_empty_h` でROは十分カバー追加不要
```

View File

@ -0,0 +1,19 @@
# Phase 10.4 — GC Switchable Runtime (Scaffold)
Status: scaffolded (hooks only)
Goals
- Decouple execution engines from a concrete GC.
- Provide minimal `GcHooks` with `safepoint()` and `barrier(kind)` used by MIR `Safepoint`/`Barrier*`.
- Make runtime supply a pluggable GC via `NyashRuntimeBuilder::with_gc_hooks`.
Whats done (in this repo)
- Added `src/runtime/gc.rs` with `GcHooks` trait, `BarrierKind`, and `NullGc` (no-op).
- `NyashRuntime` now holds `gc: Arc<dyn GcHooks>`; defaults to `NullGc`.
- VM dispatch calls hooks on `Safepoint` and `Barrier(Read|Write|unified)`.
Next
- Thread-local root set API design (`enter_scope/leave_scope`, root pinning) for precise collectors.
- Card marking/write barrier integration for object field writes (`RefSet` sites).
- Preemption policy at safepoints (cooperative scheduling integration).

View File

@ -0,0 +1,27 @@
Phase 10.4d — Barrier Strict Mode (CI/Local)
Goal
- Catch missing Write-Barrier quickly in development and CI.
How-To (Local)
1) Build with default features:
cargo build --release -j32
2) Run with CountingGc + Strict Barrier + Trace:
(in code) build runtime via NyashRuntimeBuilder::with_counting_gc()
(env)
set NYASH_GC_BARRIER_STRICT=1
set NYASH_GC_TRACE=1
nyash <program.hako>
Expected
- Barrier sites log to stderr.
- On any mutating site without barrier increment, process panics with site name.
CI Suggestion
- Add a job that runs selected examples/tests with CountingGc enabled and
NYASH_GC_BARRIER_STRICT=1. Fail build on panic.
Notes
- Strict mode requires CountingGc; otherwise the helper panics to avoid false negatives.
- Use NYASH_GC_TRACE=2 for detailed roots breakdown at end-of-run when investigating.

View File

@ -0,0 +1,57 @@
# Phase 10.5: Core Standard (String/Array/Map) in Nyash — Rust依存の段階的削減
目的
- 現状Rust実装に依存している基本コンテナString/Array/Mapを、Nyashで実装したstdへ段階的に置換し、セルフホストへ近づける。
- rt/sys層Box ABI・所有・weak・最小アロケータ、`ny_host_*`)を活用して堅牢性と性能の両立を図る。
前提
- Phase 10.2: Host API層C-ABI `ny_host_*` / WASM `nyir_host`
- Phase 10.3: 層の切り分けcorelang/rt/sys/std
- Phase 10.4: Box ABIfat ptrとEffect→LLVM属性の方向性
範囲MVP
- String
- 構造: { ptr: *u8, len: usize, cap: usize }
- API: new, from_raw, into_raw, clone, len, is_empty, push_str, substr(view), to_utf8(view)
- メモリ: `ny_host_alloc/realloc/free` 経由、UTF-8不変validation optional
- Array<T>
- 構造: { ptr: *T, len: usize, cap: usize }
- API: new, push, pop, get(i), set(i,v), len, reserve
- メモリ: `ny_host_*` 経由、要素のfiniハンドリングBox所有規則順守
- Map<K,V>
- 構造: ハッシュテーブル(オープンアドレス or チェイン; v0は単純で可
- API: new, get, set, remove, len, keys(view), values(view)
- メモリ: `ny_host_*` 経由、キー/値の所有/weak規則順守
設計ポリシー
- 所有とfini: 再代入・スコープ終端でfiniが適切に発火することEverything is Box準拠
- 互換: 現行言語表面の挙動に合わせる(差異は仕様に明記)
- 効果: mut操作の順序保持、view系はpure読み取り
- WASM/LLVM: ABI/ExternCallと矛盾しないStringの(ptr,len)は共通)
タスクCopilot TODO
1) stdレイアウトの骨子作成ファイル/モジュール構成)
2) String v0実装 + 単体テストpush_str/len/substr
3) Array v0実装 + 単体テストpush/get/set/len
4) Map v0簡易hash+ 単体テストset/get/remove/len
5) 再代入/スコープ終端でのfini挙動の統合テスト
6) ベンチ: 既存Rust実装対比の大まかな目安悪化しない/許容範囲)
7) フェールセーフ: OOM/境界エラーの明確化panic/Resultは設計に従う
8) ドキュメント: stdのMVP API一覧と互換要件
受け入れ基準
- 代表サンプルがRust実装なしでString/Array/Mapを利用し動作
- 再代入・スコープ終端時にfiniが期待通り発火ログで可視化
- WASM/LLVMの文字列(ptr,len)取り扱いと整合print等のExternCallで可視化
リスク・軽減
- パフォーマンス劣化: ベンチで目視確認、ホットパス最適化は後続で実施
- メモリ安全: 所有/weak/効果規則をVerifierで補助後続でLSP/静的解析を強化)
- 実装負債: MVP範囲を明確にし、機能追加はIssue分割
参考
- ABIドラフト: docs/予定/native-plan/box_ffi_abi.md
- NyIR: docs/nyir/spec.md
- Host API: Phase 10.2 仕様
最終更新: 2025-08-14

View File

@ -0,0 +1,20 @@
# Phase 10.6 — Thread-Safe Revolution (Design Prep)
Status: preparation
Principles
- Opt-in concurrency: default runtime remains single-threaded for simplicity.
- All extension points intended for cross-thread use must be `Send + Sync`.
Whats prepared
- `GcHooks: Send + Sync` to allow multi-threaded collectors later.
- `NyashRuntime` holds `Arc<dyn GcHooks>` for safe sharing across threads.
Planned tasks
- Audit `NyashBox` implementations for `Send + Sync` (introduce marker traits or wrappers).
- Introduce scheduler abstraction for futures/actors (no global state).
- Introduce interior mutability strategy `RwLock` on shared mutable state, with minimal contention.
Notes
- Until the audit, VM enforces single-threaded access; sharing across threads is unsupported by default.

View File

@ -0,0 +1,46 @@
# Phase 10.6a — Thread-Safety Audit (Checklist)
目的: NyashBox/ランタイムのスレッド安全性を棚卸しし、将来の並列化10.6b/c以降に備える。
## 方針
- 既定は単一スレッド実行VM/Interpreter。並列化は opt-in。
- 共有状態は `Arc<...>``RwLock/Mutex` により内的可変を確保。
- クロススレッド境界に出る型は `Send + Sync` を満たす(必要に応じてラッパで担保)。
## チェックリスト
- Box実装src/boxes/*
- [ ] 共有内部状態を持つ型は `Arc<RwLock<_>>` のようにラップされているか
- [ ] `to_string_box()` が重い処理やグローバル可変に依存しないか
- [ ] FFI/プラグイン橋渡し時に非同期イベント/コールバックを保持しないか(保持する場合は送受戦略を文書化)
- ランタイムsrc/runtime/*
- [ ] `NyashRuntime` のメンバは `Send + Sync` 要件を満たす(`Arc<...>`
- [ ] `GcHooks` 実装は `Send + Sync`CountingGc/NullGc はOK
- [ ] Scheduler 実装は `Send + Sync`SingleThreadSchedulerはOK
- VM/Interpreter
- [ ] MIR `Safepoint``runtime.scheduler.poll()` を呼ぶ(協調スケジューラの結合点)
- [ ] Grep: `rg -n "Safepoint" src` で配置確認
## Grep支援
```bash
rg -n "Arc<|Mutex<|RwLock<|Send|Sync" src/boxes src/runtime
```
## 既知の注意点
- Python/外部DLLとの橋渡しはGIL/PATH管理で単一スレッド優先AOT時はPATH/PYTHONHOME調整済
- BufferBox は共有化のために `Arc<RwLock<Vec<u8>>>` を採用済み。
## クイック監査(第一次)
- ArrayBox: `Arc<RwLock<Vec<Box<dyn NyashBox>>>>` → OK共有内的可変
- MapBox: `Arc<RwLock<HashMap<String, Box<dyn NyashBox>>>>` → OK
- BufferBox: `Arc<RwLock<Vec<u8>>>` → OK
- NyashRuntime: `box_registry: Arc<Mutex<_>>`, `box_declarations: Arc<RwLock<_>>`, `gc: Arc<dyn GcHooks>`, `scheduler: Option<Arc<dyn Scheduler>>` → OK
- Scheduler: `SingleThreadScheduler` 内部に `Arc<Mutex<VecDeque<...>>>` → OK
- GC Hooks: `NullGc/CountingGc``Send+Sync` 実装方針 → OK
未確認/注意:
- プラグインBoxPluginBoxV2の内部FFIハンドルはVM/EXE側で共有参照のみ実体はFFI側。クロススレッド呼出しは未サポート運用明記要
- 一部のBoxで外部資源ファイル/ネットを扱う場合、スレッド越境のI/O同期設計は別途Phase 10.6d+)。
## 次の一手(提案)
- マーカーTraits例: `ThreadSafeBox`)の導入は保留(破壊的)。現時点は監査+ドキュメントで運用。
- 並列スケジューラM:Nの実装は `feature` フラグで段階導入。

View File

@ -0,0 +1,64 @@
Phase 10.6a — Thread-Safety Audit (TXT)
Scope
- Audit Send/Sync policy for core runtime + Box families.
- Classify: Allowed (Send+Sync), Not-Send (single-threaded), Needs-Wrapper (guarded by RwLock/mpsc/etc.).
- Output concrete action items for hardening.
Legend
- ALLOW: Safe to share/send across threads as-is.
- NO-SEND: Must remain thread-confined; do not share.
- WRAP: Provide wrapper/adapter to safely share (interior mutability / channels / handles).
Runtime Components
- NyashRuntime: WRAP — shared via Arc; subcomponents must be audited (registry/decls RwLock OK).
- GcHooks: ALLOW — trait requires Send+Sync; CountingGc is Send+Sync by design.
- TypeMeta/CacheVersions: WRAP — global tables; protect via atomic/versioning (already present) + RwLock where needed.
- Scheduler (planned): WRAP — explicit abstraction (cooperative); no global mutable state.
VM Values / Execution
- VMValue: ALLOW (data) / WRAP (BoxRef) — primitives OK; BoxRef must only be shared via immutable Box API.
- ScopeTracker: NO-SEND — per-VM; not shared. Access confined to single thread.
- JIT Manager: WRAP — read-mostly maps; guard with RwLock if shared, or keep per-VM.
Builtin Boxes (initial pass)
- IntegerBox/BoolBox/StringBox: ALLOW (immutable data semantics).
- FloatBox (math): ALLOW (stateless ops; string-ification only).
- ArrayBox/MapBox: WRAP — interior mutability required (RwLock); Write-Barrier remains required.
- Buffer/IO/Net/Time/Audio/etc.: WRAP — external handles; use Arc + internal locks; expose async/channel for ops.
- FutureBox: WRAP — already uses RwLock pattern; verify methods are non-blocking and Send+Sync where applicable.
- ChannelBox: WRAP — backed by mpsc/crossbeam; ensure senders/receivers are Send.
Plugin Boxes
- PluginBoxV2: WRAP — FFI handle; calls marshalled via TLV; all access through thread-safe host layer.
Interpreter/Runner Layers
- Parser/Tokenizer/AST: ALLOW (not shared at runtime).
- Runner (VM backend): NO-SEND — execution confined to the owning thread.
Policies and Enforcement
1) Marker traits (for docs only):
- ThreadSafeBox (Doc): Box types that are Send+Sync-safe as value semantics.
- HandleBox (Doc): wraps external/native handles; must be behind RwLock/Mutex and non-blocking APIs.
2) Constructor guidance:
- For WRAP boxes, store state under RwLock/Mutex; prefer RwLock (read-mostly).
- Avoid blocking in methods; prefer async/task dispatch via scheduler abstraction.
3) Sharing rules:
- VMValue::BoxRef must not be mutated without Write-Barrier when GC is active.
- Cross-thread sharing limited to BoxRef with immutable APIs or actor-like message passing.
4) Testing:
- Add feature-gated thread-smoke tests (spawn two threads, share ALLOW boxes, ensure no UB).
- Add Mutex/RwLock poisoning handling policies (map to Nyash exceptions if needed).
Immediate Action Items
- [A1] Document per-Box classification in code headers (short note + rationale).
- [A2] Ensure ArrayBox/MapBox internals use RwLock and respect Write-Barrier (already partially in place; verify set/push paths).
- [A3] PluginBoxV2 calls remain serialized through host; confirm Send on host dispatch closures.
- [A4] Introduce lightweight scheduler trait (single-threaded impl first); route blocking ops via scheduler.
- [A5] Add CI job to run with NYASH_GC_BARRIER_STRICT=1 and CountingGc for barrier regression.
Future (10_6b/10_6c tie-ins)
- Scheduler + cooperative safepoint policy across threads.
- Per-thread root regions; ensure root pin/unpin remains thread-local.
- Card marking/write barrier strategy for shared objects modified across threads (design doc first).

View File

@ -0,0 +1,25 @@
Phase 10.6b — Scheduler Prep (Single-Thread Queue)
Whats added
- `src/runtime/scheduler.rs` with `Scheduler` trait and `SingleThreadScheduler`.
- Queue + delayed tasks (spawn/spawn_after) and `poll()` to run work.
- VM calls `scheduler.poll()` at MIR `Safepoint` to integrate cooperative scheduling.
- Poll budget via env `NYASH_SCHED_POLL_BUDGET` (default: 1)
- Trace via `NYASH_SCHED_TRACE=1` (diagnostic)
How to use (dev)
- Build runtime with default SingleThreadScheduler (already default via builder), or inject custom via:
`NyashRuntimeBuilder::new().with_single_thread_scheduler().build()`
- Schedule tasks from boxes/host code via `runtime.scheduler.spawn(...)`.
- At safepoints, queued tasks run (1 per safepoint) and due delayed tasks are enqueued.
How to validate quickly
- Run any Nyash program that contains loops or function entries (safepoints exist by default).
- Optionally enable the demo hook: set `NYASH_SCHED_DEMO=1` and run the VM backend
to observe scheduler tasks firing at safepoints.
- Control throughput by `NYASH_SCHED_POLL_BUDGET` (e.g., 3 runs up to 3 tasks/safepoint).
- GC trace pairs well: set `NYASH_GC_COUNTING=1 NYASH_GC_TRACE=1` to see safepoints.
Next (10.6c+)
- Expose scheduling APIs to script level (Box API).
- Optional multi-thread scheduler implementation behind feature flag.

View File

@ -0,0 +1,37 @@
Phase 10.6c — Parallel GC Design (Notes)
Objectives
- Keep GC hooks and MIR sites stable while enabling parallel/stop-the-world options.
- Introduce per-thread root regions, card marking, and coordinated safepoints.
Design Sketch
1) Per-thread roots
- Root API remains the same but live under thread-local trackers.
- VM/engines expose `enter_root_region/pin/leave_root_region` that operate on TLS.
- Global snapshot for diagnostics merges per-thread views (debug only).
2) Safepoint coordination
- Central GC controller requests a safepoint; worker threads acknowledge at next MIR `Safepoint`.
- Timeout/poll policy configurable; in single-threaded mode this is no-op.
3) Card marking / write barriers
- Extend `BarrierKind::Write` to accept optional object metadata (future API): object id/card index.
- For now, keep symbolic barrier only; when parallel GC is enabled, maintain a global dirty set.
4) Scheduler interplay
- GC controller can schedule minor/major cycles using the Scheduler abstraction.
- In single-threaded mode, cycles are chunked via `poll()` to avoid long pauses.
API Diffs (future)
- `GcHooks::barrier(kind)` → `barrier(kind, obj: Option<ObjectId>)` (compat shim keeps old signature).
- `GcHooks::safepoint()` may return a hint (`Proceed`, `Yield`) for engines to cooperate.
Migration Plan
- Keep current single-threaded path as default.
- Add feature flag `gc-parallel` that swaps in an implementation honoring the extended API.
- Incrementally add: dirty set, per-thread roots, coordinated safepoint prototype.
Testing Strategy
- Deterministic unit tests using SingleThreadScheduler.
- Stress tests with STRICT barrier and TRACE=2 to validate barrier coverage and root progression.

View File

@ -0,0 +1,85 @@
Phase 10.7 — JIT Branch Wiring + Minimal ABI Extensions
Overview
- Purpose: Enable real control-flow in the JIT path by wiring MIR Branch/Jump/Return to Cranelift blocks, and extend the minimal ABI to support multi-arg i64 and basic bool/f64.
- Outcome: If/loop constructs execute natively in JIT for straight-line + branched code paths, with safe VM fallback preserved. HostCall PoC remains opt-in.
Goals (Must)
- Wire MIR basic blocks to Cranelift blocks; emit `brif` and `jump` for Branch/Jump.
- Keep Compare result usable as a branch condition (b1); where necessary, convert i64 to b1 via `icmp_imm != 0`.
- Preserve Return behavior (already in place) and allow branching to return in both sides (no PHI required for first pass).
- Minimal ABI: multi-argument i64 stable, bool constants lowered to 0/1, f64 constants passed through (no arithmetic yet required).
- Safety: On JIT panic or unsupported instruction at runtime, VM fallback with logs.
Stretch (Nice-to-have)
- PHI at merge points via block parameters for simple patterns (two-predecessor if-else returning a value).
- Bench: Add a small control-flow benchmark to CLI/`examples`.
Non-Goals (10.7)
- Full PHI generalization across arbitrary CFG.
- Type-specialized calling conventions beyond i64/f64/bool minimal path.
- Deoptimization or on-stack replacement.
Deliverables
- Code: CraneliftBuilder block management + branch/jump emission.
- Lowering updates: Branch/Jump hook uses real block IDs; Compare emits b1-friendly shape.
- Env flags: Reuse `NYASH_JIT_EXEC/THRESHOLD/STATS/DUMP`; guard hostcalls by `NYASH_JIT_HOSTCALL`.
- Docs: Update execution-backends.md with “JIT control-flow coverage (10.7)”.
- Examples: `examples/jit_branch_demo.hako` (if/loop minimal).
Design Sketch
1) Block Mapping
- Build `bb_map: MirBB -> Cranelift Block` in `begin_function` based on MIR function blocks.
- Switch to entry block, `seal_block(entry)`.
2) Conditions
- Compare emits Cranelift `icmp` returning b1; avoid converting to i64 unless explicitly needed.
- If the condition arrives as i64 (const/param), lower `icmp_imm != 0` to get b1 for `brif`.
3) Branch / Jump
- `emit_branch(cond, then_bb, else_bb)` → `brif(cond_b1, then_block, []); jump(else_block, []); seal both`.
- `emit_jump(target_bb)` → `jump(target_block, [])`.
4) Return
- Keep current return emission; when branches end in return, no PHI needed.
5) PHI (limited)
- For a simple diamond where both arms jump to a single merge, add one block param at merge.
- Pass the value via `jump(merge, [val])`; read via `block-arg(merge, 0)`; return it.
6) ABI
- Keep signature `(i64 x argc) -> i64?` baseline.
- Support f64/bool consts materialization; booleans as 0/1 integers for now unless used as branch cond (then b1).
Implementation Plan (Tasks)
- T1: Extend IRBuilder API (only behind `cranelift-jit`): create_block(), br_if(), jump(), seal_block(), block_param(), append_block_params_for_function_params().
- T2: CraneliftBuilder: implement block map allocation in begin_function; store in builder state.
- T3: LowerCore:
- Track current MIR bb while iterating.
- For Branch/Jump, call builder with mapped blocks and condition value hint.
- Compare: emit b1 icmp; when Compare is used as value elsewhere, allow i64 extend as needed.
- T4: Minimal PHI support for a single merge (optional; guarded by env `NYASH_JIT_PHI_MIN=1`).
- T5: Add `examples/jit_branch_demo.hako` with: `if (a < b) { return 1 } else { return 2 }` and a small loop with early `return`.
- T6: Docs update: execution-backends.md “JIT coverage 10.7” + env flags.
- T7: Bench (optional): integrate into `--benchmark` with JIT warmup when `NYASH_JIT_EXEC=1`.
Validation
- Build matrix: with/without `cranelift-jit` feature.
- Smoke tests: run `jit_branch_demo.hako` with `NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1`.
- Fallback verification: force a path with unsupported op to confirm VM fallback.
- GC/scheduler: ensure safepoint path still works (unchanged).
Risk & Mitigation
- Mismatch of block sealing/order → start with straight-line + simple diamond; add asserts; prefer FunctionBuilder patterns.
- Condition type confusion (i64 vs b1) → centralize cond normalization helper.
- PHI complexity → keep optional, limited to single value diamond.
Rollout
- Phase gate by envs: `NYASH_JIT_EXEC` for enable, `NYASH_JIT_PHI_MIN` for PHI.
- Keep `NYASH_JIT_HOSTCALL` opt-in.
Success Criteria
- If/else returning constants runs fully via JIT (Cranelift) without VM fallback.
- Simple counting loop with early exit returns correct result via JIT.
- All tests pass with and without feature flag; VM fallback works on traps.

View File

@ -0,0 +1,135 @@
Phase 10.7 — JIT CFG/PHI/ABI Hardening (Master Plan)
Intent
- Deliver a practical, observable JIT path for control flow and minimal data flow while keeping VM as the safe fallback.
- Decompose into small, shippable sub-phases with flags and examples, minimizing blast radius.
Related docs
- 10.7a details: phase_10_7a_jit_phi_cfg_and_abi_min.txt
- Current work log: docs/development/current/CURRENT_TASK.md
- Cranelift JIT backend notes: phase_10_cranelift_jit_backend.md
Flags and CLI (common across 10.7)
- Env: NYASH_JIT_EXEC, NYASH_JIT_STATS, NYASH_JIT_STATS_JSON, NYASH_JIT_DUMP, NYASH_JIT_THRESHOLD, NYASH_JIT_PHI_MIN, NYASH_JIT_HOSTCALL
- CLI: --jit-exec --jit-stats --jit-stats-json --jit-dump --jit-threshold N --jit-phi-min --jit-hostcall
Examples to validate
- examples/jit_branch_demo.hako
- examples/jit_loop_early_return.hako
- examples/jit_phi_demo.hako
- examples/jit_array_param_call.hako, jit_map_param_call.hako (when hostcall is enabled)
Sub-phases (10.7a → 10.7h)
10.7a — Minimal branch/PHI/ABI (Done or in-flight)
- Branch wiring with b1 and i64!=0 normalization
- Minimal PHI: single-value diamond via block param
- Independent ABI (JitValue) with integer-first calling
- Panic-safe dispatch (catch_unwind) and VM fallback
- Minimal hostcall bridge (Array/Map) behind NYASH_JIT_HOSTCALL
- Observability: unified JIT summary/JSON, lower summary (argc/phi_min), CFG edge dump (phi_min)
Acceptance: see 10.7a doc
10.7b — PHI generalization and block-parameterization
- Support multiple PHIs in a merge block; pass N values via block params
- LowerCore: gather PHI inputs per successor, produce explicit arg lists; handle straight merges and simple loops
- IRBuilder API formalization:
- ensure_block_params_i64(index, count)
- br_if_with_args(then_idx, else_idx, then_n, else_n)
- jump_with_args(target_idx, n)
- CraneliftBuilder: append N I64 params per block, materialize current block params onto stack when requested
- Validation: multi-PHI diamonds, if-else chains, early returns; keep loops as simple as possible in 10.7b
10.7c — Independent host-handle registry (JIT↔Host decoupling)
- Introduce JitHandleRegistry: u64 ↔ Arc<dyn NyashBox>
- JIT hostcalls accept/return only handles and PODs; VMValue↔JitValue boundary converts BoxRef <-> Handle via registry
- Rooting policy: enter/pin roots for handles crossing the boundary; leave on return
- Flags: NYASH_JIT_HOSTCALL=1 (still gated); add NYASH_JIT_HANDLE_DEBUG for dumps
- Deliverables: array/map operations via handles, no direct VMValue access on JIT side
10.7d — Side-effect boundary and hostcall coverage expansion
- Keep side-effecting ops (print/IO) on VM for now; document deopt path
- Expand safe hostcalls (read-only or confined):
- String.len / slice basics (POD returns)
- Map.size; Map.get with integer and string keys (key boxing handled at boundary)
- Record effect categories on lowered calls for future optimizer (metadata only)
10.7e — CFG diagnostics and visualization
- Add DOT export for CLIF CFG with block params and PHI bindings
- Env: NYASH_JIT_DOT=path.dot (produces per-function graph)
- Optional: ASCII CFG summary for CI logs
- Cross-check with VM-side MIR printer for block and PHI consistency
10.7f — JitConfigBox (configuration as a Box)
- Encapsulate all JIT toggles into a runtime-managed box (JitConfigBox)
- Harmonize env/CLI with programmatic overrides for tests
- Feed config into JIT engine and lowerers (no direct env reads inside hot paths)
- Serialization: dump/load config JSON for reproducible runs
10.7g — Stability, tests, and benchmarks
- Golden tests: ensure JIT/VM outputs match on curated programs
- Fallback ratio regression guard: alert when fallback_rate spikes beyond threshold
- JSON schema stability for stats; include version field
- Microbenchmarks: branch-heavy, phi-heavy, and hostcall-heavy cases; gated perf checks
10.7h — Type widening for native ABI
- Add native F64 and Bool parameter/return paths in CLIF
- Condition handling: keep b1 where possible; map Bool to b1 cleanly
- Conversions: explicit i64<->f64 ops in lowerer where needed (no silent truncation)
- Update adapter and closure trampoline to select proper function signatures (arity×type shapes)
Out of scope for 10.7 (shift to 10.8/10.9)
- Global register allocation strategies or codegen-level optimizations
- Deoptimization machinery beyond simple VM fallback
- Advanced exception propagation across JIT/VM boundary
Risks and mitigation
- PHI N-arity correctness: introduce targeted unit tests over synthetic MIR
- Handle registry leaks: counting diagnostics, strict mode; tie roots to scope regions
- CLIF block-param misuse: deterministic block order + seal discipline + assertions in builder
Verification checklist (roll-up)
- cargo check (± --features cranelift-jit)
- Run examples with JIT flags; diff with pure VM runs
- Inspect: unified JIT summary/JSON, lower logs, CFG dumps/DOT
- Leak/roots checks when NYASH_GC_TRACE=1/2/3 and strict barrier mode is on
Suggested timeline (tentative)
- 10.7a: Minimal branch/PHI/ABI (done / in-flight)
- 10.7b: PHI generalization + builder API formalization (12 days)
- 10.7c: Host-handle registry PoC (12 days)
- 10.7d/e: Hostcall coverage + CFG DOT (23 days)
- 10.7f: JitConfigBox + integration (1 day)
- 10.7g/h: QA + type widening for f64/bool (24 days)
10.7z — Follow-ups and Open Items (post-10.7)
- b1 PHI tagging robustness
- Problem: Provenance can be obscured by Load/Store and multi-step copies; (b1) tag may be missed in dumps.
- Action:
- Add a lightweight boolean-lattice analysis over MIR to classify boolean-producing values independent of path shape.
- Extend dump to include phi_summary JSON or structured rows when NYASH_JIT_STATS_JSON is on.
- Placement: 10.7g (stability/tests) — does not block 10.7 close.
- VM f64 arithmetic/compare parity
- Problem: VM backend currently errors on f64 BinOp/Compare; JIT (Cranelift) supports f64 when enabled.
- Action: Implement f64 ops in VM or add consistent auto-promotion; add golden tests.
- Placement: 10.8 (VM parity/perf) — out-of-scope for 10.7.
- Native b1 ABI in function signatures
- Problem: Toolchain capability for b1 return/params is currently disabled.
- Action: Keep centralized switch; add CI probe to flip automatically when supported; wire return path fully.
- Placement: 10.7h or later (gated by toolchain).
- Stats/diagnostics polish
- Action: Version the unified JIT JSON schema; expose phi(b1) slot counts in JSON; enrich JitStatsBox with summary/topN (partially done).
- Placement: 10.7g.
- Build warnings (unexpected cfg: llvm)
- Problem: Warning noise from unused/unknown cfg.
- Action: Declare feature flags in Cargo.toml or gate code behind existing features; optionally silence for non-supported builds.
- Placement: 10.7g (cleanup) — non-blocking.
- Documentation sync
- Action: Add a "JIT quick flags" section with common env/CLI combos; ensure CURRENT_TASK and examples remain aligned.
- Placement: 10.7e (docs) — non-blocking.

View File

@ -0,0 +1,92 @@
Phase 10.7a — JIT Branch/PHI/Independent ABI: Minimal Path Hardening (Plan)
Purpose
- Solidify the first functional slice of the JIT control-flow path:
- Branch wiring (b1 and i64!=0 normalization)
- Minimal PHI via block parameters (single-value diamond)
- Independent ABI (JitValue) and safe dispatch + fallback
- Observable, toggleable, and easy to verify via flags + examples
Scope (10.7a only)
1) Minimal PHI handoff
- LowerCore: detect single-PHI merge; pass i64 value via block param
- CraneliftBuilder: ensure block param (I64), push/pop on branch/jump with args
- Flag gate: NYASH_JIT_PHI_MIN=1
2) Branch wiring and condition normalization
- Keep compare result on stack as b1 when possible
- If top-of-stack is I64, normalize by icmp_imm != 0
- Implement br_if/jump to pre-created blocks (deterministic order)
3) Independent ABI (minimum viable)
- JitValue(I64/F64/Bool/Handle) in/out; normalize non-i64 args to i64 for now
- TLS split: legacy VM args (for hostcalls) and JIT args
- Engine.execute_handle uses catch_unwind; panic → VM fallback with stats
4) Minimal hostcall bridge (safe; off by default)
- Symbols: nyash.array.{len,get,set,push}, nyash.map.{size}
- Gate: NYASH_JIT_HOSTCALL=1
- Only integer indices/values (PoC); other types map to handles later
5) Observability and ergonomics
- Flags: NYASH_JIT_EXEC, NYASH_JIT_STATS, NYASH_JIT_STATS_JSON, NYASH_JIT_DUMP, NYASH_JIT_THRESHOLD, NYASH_JIT_PHI_MIN, NYASH_JIT_HOSTCALL
- CLI: --jit-exec --jit-stats --jit-stats-json --jit-dump --jit-threshold N --jit-phi-min --jit-hostcall
- Unified JIT summary on VM exit (sites/compiled/hits/exec_ok/trap/fallback_rate)
- Lower log includes argc/phi_min + CFG light dump (phi edges) when NYASH_JIT_DUMP=1
Non-Goals (later 10.7b+)
- Full PHI generalization (multiple values, loops, complex CFG forms)
- Non-i64 native path (true F64/Bool return/params in CLIF)
- Side-effect instruction lowering (print, IO) — keep in VM path
- Host handle registry for real object bridging (u64↔Arc<dyn NyashBox>)
Deliverables
- Working minimal PHI + branch JIT execution on curated examples:
- examples/jit_branch_demo.hako
- examples/jit_loop_early_return.hako
- examples/jit_phi_demo.hako (single-PHI diamond)
- Fallback correctness: traps/panic → VM path; results match VM
- Configurable via CLI flags; metrics visible via JIT summary/JSON
Acceptance Criteria
- With: --backend vm --jit-exec --jit-stats --jit-threshold 1
- For branch/phi examples, JIT executes without panic
- VM fallback occurs only for unsupported ops (logged)
- JIT summary shows exec_ok > 0 and reasonable fallback_rate
- With: --jit-phi-min
- CFG dump lists phi_min edges and blocks count
- Results match the same program without JIT enabled
Risk & Mitigation
- Mismatch between VMValue and JitValue adapters
- Mitigation: normalize non-i64 to i64 defensively; expand tests on adapters
- Cranelift block parameter misuse
- Mitigation: deterministic block order and explicit ensure_block_param_i64()
- Panic in hostcall stubs (unexpected Box types)
- Mitigation: gated by NYASH_JIT_HOSTCALL=1; default off; fallback to VM on panic
Verification Checklist
- cargo check (w/ and w/o --features cranelift-jit)
- Run examples with JIT flags; compare outputs with pure VM
- Inspect logs: lower summary + CFG dump + unified summary/JSON
Timeline (10.7a)
Day 1:
- Finalize ABI normalization and branch wiring; add unified stats (done)
- Wire CLI flags and JSON stats (done)
Day 2:
- Harden minimal PHI path and CFG dump (done)
- Curate examples and sanity-run on flags
Day 3:
- Stabilize logging format, trim rough edges, doc polish
→ Then roll into 10.7b (multi-PHI, multi-arg block params, real handle registry)
Follow-ups (10.7b/10.7c seeds)
- Host handle registry (u64↔Arc) and type-safe bridging
- True F64/Bool native ABI, multi-arg params/returns
- CFG visualization improvements (dot export) and JitConfigBox
Refs
- docs/development/current/CURRENT_TASK.md (10_7 items)
- src/jit/{lower,engine,manager,abi,rt}/
- examples: jit_* demos

View File

@ -0,0 +1,45 @@
# Phase 10.7h — Native ABI Types (F64/Bool)
Goal
- Extend the minimal i64-only JIT ABI to support f64 and bool as native parameter/return types in CLIF.
Principles
- Keep JIT independent from VM internals (use JitValue + adapters at boundary)
- Avoid silent truncation; perform explicit conversions in the lowerer
- Maintain safety-first fallback to VM for unsupported ops
Plan
1) JitValue widening
- JitValue already has I64/F64/Bool/Handle — keep this as the ABI surface
- Adapter: refine to/from VMValue mappings (no lossy coercion by default)
2) CLIF signature selection
- Augment CraneliftBuilder to build signatures based on (arity × type shape)
- Start with small shapes: (I64|F64|Bool)* → I64|F64|Bool
- Closure trampoline: transmute to matching extern "C" fn type; dispatch by shape id
3) Condition handling
- Bool: prefer b1 in IR; allow i64!=0 normalization when comparing integers
- Comparisons yield b1; lower branch consumes b1 directly
4) Conversions in lowerer (explicit only)
- add_const_f64, add_convert_{i64_to_f64, f64_to_i64}
- prohibit implicit int<->float coercion in arithmetic; gate conversions via explicit MIR ops or intrinsics
5) Observability and flags
- NYASH_JIT_NATIVE_F64=1 / NYASH_JIT_NATIVE_BOOL=1 to enable paths
- Dump: show chosen signature shape and conversions when NYASH_JIT_DUMP=1
6) Rollout
- Phase A: const/binop/ret for f64; comparisons yield b1
- Phase B: mixed-type ops via explicit converts
- Phase C: HostCall bridging for f64/bool PODs (read-only first)
Risks / Mitigation
- Signature explosion: start with a few common shapes; fallback to i64 path
- Platform ABI mismatches: rely on Cranelift default call conv; e2e-perf and correctness first
Acceptance
- Examples with pure f64 pipelines run under JIT with matching results vs VM
- No silent lossy conversions; conversions visible in MIR/Lower logs

View File

@ -0,0 +1,172 @@
# Phase 10.8: 統一デバッグシステム - DeepInspectorBoxとグローバルデバッグ整理
作成日: 2025-08-27
発見者: ニャー
参照元: docs/ideas/other/2025-08-25-unified-box-design-deep-analysis.md
## 🚨 現在の問題
### 1. デバッグ環境変数の乱立
現在20個以上の環境変数が散在
- `NYASH_VM_STATS=1`
- `NYASH_VM_DEBUG_BOXCALL=1`
- `NYASH_DEBUG_PLUGIN=1`
- `NYASH_NET_LOG=1`
- `NYASH_JIT_THRESHOLD=1`
- ... など多数
### 2. 統一されていないデバッグ体験
- VM、プラグイン、JIT、ネットワークなど各コンポーネントが独自のデバッグフラグ
- 複数の環境変数を組み合わせる必要がある
- 何をONにすればいいか分かりにくい
## 🌟 提案: 統一デバッグシステム
### 1. 環境変数の整理統合
```bash
# Before (現在)
NYASH_VM_STATS=1 NYASH_VM_DEBUG_BOXCALL=1 NYASH_NET_LOG=1 ./nyash
# After (提案)
NYASH_DEBUG=vm,boxcall,net ./nyash
```
### 2. デバッグレベル制御
```bash
# シンプルなレベル制御
NYASH_DEBUG_LEVEL=0 # OFF
NYASH_DEBUG_LEVEL=1 # 基本情報のみ
NYASH_DEBUG_LEVEL=2 # 詳細情報
NYASH_DEBUG_LEVEL=3 # すべて
# カテゴリ別レベル
NYASH_DEBUG=vm:2,net:1,jit:3
```
### 3. プリセット(よく使う組み合わせ)
```bash
# プリセット
NYASH_DEBUG_PRESET=basic # 基本的なデバッグ情報
NYASH_DEBUG_PRESET=perf # パフォーマンス分析用
NYASH_DEBUG_PRESET=network # ネットワーク問題調査用
NYASH_DEBUG_PRESET=memory # メモリリーク調査用
NYASH_DEBUG_PRESET=all # すべて有効
```
## 🔍 DeepInspectorBox - Everything is Debugの実現
### グローバルシングルトンデバッガー
```nyash
// グローバルに1つだけ存在する統一デバッガー
static box DeepInspectorBox {
public { enabled }
private {
boxCreations, methodCalls, fieldAccess,
memorySnapshots, referenceGraph, performanceMetrics
}
// === 簡単な有効化 ===
enable(categories) {
// "vm,net,memory" のようなカテゴリ文字列を解析
me.parseAndEnableCategories(categories)
}
// === プリセット対応 ===
usePreset(presetName) {
match presetName {
"basic" => me.enable("vm,error")
"perf" => me.enable("vm,boxcall,stats")
"network" => me.enable("net,plugin,tlv")
"memory" => me.enable("alloc,gc,leak")
"all" => me.enable("*")
}
}
// === 統合ログ出力 ===
log(category, level, message) {
if me.shouldLog(category, level) {
local formatted = me.formatLog(category, level, message)
me.output(formatted)
}
}
}
```
### MIRレベルでの統一実装
```rust
// MIR生成時にデバッグフックを埋め込み
impl MirBuilder {
fn build_new_box(&mut self, type_id: TypeId) -> ValueId {
let result = self.push(NewBox { type_id });
// デバッグモード時のみ
if self.debug_enabled {
self.push(DebugHook {
event: DebugEvent::BoxCreated,
type_id,
value: result,
});
}
result
}
}
```
## 📊 実装計画
### Phase 10.8a: 環境変数統合3日
- [ ] 統一パーサー実装(`NYASH_DEBUG`解析)
- [ ] レベル制御システム
- [ ] プリセット定義
- [ ] 既存環境変数との互換性層
### Phase 10.8b: DeepInspectorBox基礎1週間
- [ ] グローバルシングルトン実装
- [ ] カテゴリ管理システム
- [ ] 基本的なログ収集
- [ ] 出力フォーマッター
### Phase 10.8c: MIR統合1週間
- [ ] DebugHook命令追加
- [ ] MirBuilderへのフック埋め込み
- [ ] VMでのDebugHook実行
- [ ] JITでのデバッグ情報保持
### Phase 10.8d: 高度な機能2週間
- [ ] メモリリーク検出
- [ ] 参照グラフ構築
- [ ] P2P非同期フロー追跡
- [ ] パフォーマンスプロファイリング
## 🎯 期待される効果
### 1. 使いやすさ向上
- 1つの環境変数で制御
- 分かりやすいプリセット
- 統一されたログフォーマット
### 2. デバッグ効率向上
- 必要な情報だけを表示
- カテゴリ別フィルタリング
- レベル別詳細度制御
### 3. 保守性向上
- 新しいデバッグ機能の追加が容易
- 統一されたインターフェース
- MIRレベルでの一元管理
## ✅ 成功基準
1. **環境変数の数**: 20個以上 → 3個以下
2. **デバッグ有効化**: 複雑なコマンド → `NYASH_DEBUG=basic`
3. **統一体験**: すべてのコンポーネントで同じデバッグインターフェース
---
*Everything is Box, Everything is Debug - 統一されたデバッグ体験へ*

View File

@ -0,0 +1,85 @@
# Phase 10.7: fromキーワード一貫性修正
作成日: 2025-08-27
発見者: ニャー
## 🚨 現在の問題
### 言語仕様と実装の不一致
- **言語仕様**: `from Parent.method()` 2025-08-11完全明示デリゲーション革命で決定
- **実装の一部**: まだ`super`という用語が残っている可能性
### 影響範囲
主にRustの`use super::*`(モジュールインポート)なので言語仕様への影響は限定的だが、以下の確認が必要:
1. エラーメッセージ内の文言
2. ドキュメントやコメント内の記述
3. 内部変数名・関数名での使用
## 🔧 修正内容
### 1. エラーメッセージの確認
```rust
// 例: エラーメッセージで"super"を使っていないか確認
"Cannot find super class" "Cannot find parent box for delegation"
```
### 2. ドキュメント・コメントの統一
```rust
// Before
// Call super method
// After
// Call parent method via from delegation
```
### 3. 内部実装での用語統一(必要に応じて)
```rust
// 変数名や内部メソッド名での統一
super_call() from_call()
SuperMethodCall FromMethodCall
```
## 📊 優先度評価
- **重要度**: 中(言語仕様の一貫性)
- **緊急度**: 低(機能的には問題ない)
- **実装難度**: 低(主に文言修正)
## 🎯 実装計画
### Phase 10.7a: 調査フェーズ1日
- [ ] エラーメッセージ内の"super"使用箇所を特定
- [ ] ドキュメント内の不整合を洗い出し
- [ ] テストケース内の文言確認
### Phase 10.7b: 修正フェーズ1日
- [ ] エラーメッセージの文言修正
- [ ] ドキュメント更新
- [ ] 必要に応じて内部変数名の統一
### Phase 10.7c: 検証フェーズ(半日)
- [ ] 修正後の動作確認
- [ ] エラーメッセージの表示確認
- [ ] ドキュメントの整合性チェック
## 📝 Nyashの哲学との整合性
### fromキーワードの意義
- **明示性**: どの親のどのメソッドかを完全に明示
- **統一性**: 宣言(`box Child from Parent`)と呼び出し(`from Parent.method()`)で同じキーワード
- **初学者フレンドリー**: 「〜から」という直感的な表現
### superを使わない理由
- 多重デリゲーション時に曖昧
- 他言語の概念を引きずらない
- Nyash独自の哲学を貫く
## ✅ 期待される効果
1. **一貫性**: 言語仕様と実装の完全な一致
2. **学習性**: 初学者が混乱しない統一された用語
3. **独自性**: Nyashらしい設計思想の徹底
---
*「from」こそがNyashの明示的デリゲーションの象徴*

View File

@ -0,0 +1,155 @@
# Phase 10.9 Builtin-Box JIT SupportBox-First Plan
目的: Nyashスクリプト → VM基準→ JIT段階導入
まずは「読み取り系」をJITで安全に通し、箱で問題点を包んで順に拡張する。
## 🎯 ゴールDoD
- 機能: String/Array/Map の読み取りAPIが JIT 経路で VM と一致
- length/isEmpty/charCodeAt, Array.get, Map.size/has
- 境界: 署名不一致・未対応は VM フォールバック理由はイベントJSONに記録
- 箱: Policy/Events/Registry を 1 箇所参照(切替点の一本化)
- 観測: JSONL イベントが最小1件以上出力オプトイン
## 🧱 先に積む箱(最小)
- JitConfigBox設定
- exec/stats/dump/phi_min/hostcall/native_f64/native_bool/threshold を `apply()` でenv反映
- `toJson()/fromJson()/summary()` で可視化
- JitPolicyBoxポリシー
- read_only/hostcall_whitelist。書込系は既定で拒否jit-direct等の安全弁
- JitEventsBox観測
- compile/execute/fallback/trap を 1行JSON標準出力 or ファイル)で記録
- HostcallRegistryBoxレジストリ
- 許可HostCallと args/ret 署名(唯一の切替点)。不一致は `sig_mismatch`
- FrameSlotsBoxスロット
- ptr→slot の割付と型注釈v0は i64 のみ)
- CallBoundaryBox境界
- JIT↔VM の薄い呼出し点(型変換の一本化)。将来多関数へ拡張
最小原則: 箱を先に置くno-op/ログでもOK→ 切替点を1箇所に固定 → その箱の内部を順に強化。
## 🛣️ 実行経路の設計(概要)
1) Runner: CLI/env→`JitConfig`→TLSへ反映env直読を排除
2) LowerCore: `jit::config::current()` を参照し、BoxCall/Load/Store/Branch/PHIを最小下ろし
3) HostCall: Handle経由で read-only を通すmutating は Policy で拒否)
4) Fallback: 未対応/署名不一致/ポリシー違反は VM 実行へ委譲
5) Events: `JitEventsBox` 経由で allow/fallback/trap を JSONL 出力
## 🔢 対象APIv0
- ArrayBox: `length`, `get`, `isEmpty`, `push/set`mutatingは拒否
- MapBox: `size`, `has`, `get`, `set`mutatingは拒否
- StringBox: `length`, `isEmpty`, `charCodeAt`
- Math薄接続: `sin/cos/abs/min/max`(署名一致のみ allow を記録、実体はVMへ
## 🗺️ マイルストーン
### 10.9-α(足場)
- JitPolicyBox v0: read-only/whitelist を箱へ移動
- JitEventsBox v0: compile/execute の JSONL イベント(オプトイン)
- ドキュメント: 再起動チェック/箱の役割を追記
### 10.9-β(読み取りカバレッジ)
- HostcallRegistryBox v0: String/Array/Map 読み取り API の登録・署名検査
- LowerCore: BoxCall read-only 経路を Registry/Policy 参照に切替
- E2E: `length/isEmpty/charCodeAt/get/size/has` の一致jit-direct + VM
### 10.9-γ(生成の足場)
- CallBoundaryBox v0: JIT→VMで `new` 等を委譲(薄い箱)
- `new StringBox/IntegerBox/ArrayBox` の最小経路(方針次第で jit-direct は拒否)
### 10.9-δ(書き込みの導線のみ)
- JitPolicyBox: 書込許可スイッチ既定OFF
- LowerCore: 書込命令は Policy 参照で拒否/委譲/許可1箇所で判断
## ✅ すぐ使えるチェック
- ビルド
- `cargo build --release --features cranelift-jit`
- 主要フラグ
- `NYASH_JIT_EXEC=1` `NYASH_JIT_THRESHOLD=1`
- `NYASH_JIT_EVENTS=1`標準出力へJSON
- 任意: `NYASH_JIT_EVENTS_PATH=target/nyash/jit-events.jsonl`
- 代表サンプルVM経由でJITパス通過
- 成功: `./target/release/nyash --backend vm examples/jit_hostcall_len_string.hako`
- 失敗: `NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_hostcall_array_append.hako`
- 境界: `NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_hostcall_math_sin_mismatch.hako`
- 署名一致(allow観測): `NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_hostcall_math_sin_allow_float.hako`
- 関数スタイル(math.*): `NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_math_function_style_sin_float.hako`
- `cos/abs/min/max` も同様のサンプルあり
- 詰まったら
- `--features cranelift-jit` が付いているか
- イベントJSONに `fallback/trap` の理由が出ているか
- `cargo clean -p nyash-rust` → 再ビルド
## 🧪 検証と観測
- 統合JIT統計テキスト/JSON: sites/compiled/hits/exec_ok/trap/fallback_rate/handles
- `JitStatsBox.perFunction()` で関数単位の統計JSON配列
- CFG/PHIダンプ: `NYASH_JIT_DUMP=1``NYASH_JIT_DOT=path.dot`(最小)
- b1正規化カウンタ: `b1_norm_count`(分岐条件/PHI
- HostCallイベント: `argc`/`arg_types`/`reason`でデバッグ容易化mutatingは `policy_denied_mutating`
### 🔎 HostCallイベントの基準10.9-β)
- 受け手が関数パラメータparamの場合は JIT直実行allow/sig_okを基本にイベント出力
- Map.get(Handle, I64): `id: nyash.map.get_h`, `arg_types: ["Handle","I64"]`
- Map.get(Handle, Handle): `id: nyash.map.get_hh`, `arg_types: ["Handle","Handle"]`
- length/isEmpty/charCodeAt/size 等も `*_h`Handle受けでallow
- 受け手がparamでない場合は VMへフォールバックfallback/receiver_not_paramをイベントで記録読み取り系の可視化を保証
- 例: `id: nyash.any.length_h`, `decision: fallback`, `reason: receiver_not_param`
- 数値緩和: `NYASH_JIT_HOSTCALL_RELAX_NUMERIC=1` または `NYASH_JIT_NATIVE_F64=1``I64→F64` コアーションを許容sig_okに影響
### 🧪 代表サンプルE2E
```bash
# math.*(関数スタイル): 署名一致でallow、戻りFloat表示
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_math_function_style_min_float.hako
# Map.getパラメータ受けHandleキー → HH直実行
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_map_get_param_hh.hako
# Map.get非パラメータ受け → fallback記録
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_hostcall_map_get_handle.hako
```
### ⚙️ Quick flagsイベント観測を確実に
- `NYASH_JIT_EVENTS=1` のとき Runner が `NYASH_JIT_THRESHOLD=1` を自動適用(未指定の場合)
- 1回目からLowerが走り、allow/fallbackのイベントが必ず出る
- 明示的に `NYASH_JIT_THRESHOLD` を指定した場合はそちらを優先
## ⚠️ リスクとその箱での緩和
- 署名不一致args/ret
- HostcallRegistryBox で一元検査。不一致は `sig_mismatch` でイベント記録→VMへ
- mutatingの混入
- JitPolicyBox.read_only で抑止。Registryの Mutating 分類と併用
- 型崩れ/ABIの揺れ
- `JitValue`I64/F64/Bool/Handleへ統一、変換は境界1箇所
- 観測不足
- JitEventsBox の粒度を最小から用意(必要に応じ拡張)
## 🔧 実装ノート(現状)
- Config: Rust側 `jit::config::JitConfig` に集約。Nyash側は JitConfigBox で操作
- LowerCore: BoxCallの read-only は Registry/Policyに委譲。math.* は署名一致なら allow を記録実行はVM
- Handle: `rt::handles` による u64→Arc<Box>。JIT↔ホストをVM型非参照で独立
- 数値緩和: `NYASH_JIT_HOSTCALL_RELAX_NUMERIC=1` で i64→f64 コアーションを許容(既定は `native_f64=1` 時に有効)。`JitConfigBox.set_flag("relax_numeric", true)` でも切替可能
## 📌 次の拡張10.9の後)
- f64ネイティブ最小経路`NYASH_JIT_NATIVE_F64=1`)の拡充
- Boolネイティブb1署名サポートツールチェーンcapに連動
- HostCallブリッジの拡大Map.getの多型キー、String操作の追加
- CallBoundaryBox経由の `new`/副作用命令の段階的JIT化
## ✳️ 10.9-δ 書き込みの導線(運用)
- 既定ポリシー: read_only`NYASH_JIT_READ_ONLY=1`)で mutating はフォールバック(`reason: policy_denied_mutating`)。
- JitPolicyBox でopt-in:
```nyash
P = new JitPolicyBox()
P.set("read_only", true)
P.addWhitelist("nyash.array.push_h") // 個別に許可
// またはプリセット:
P.enablePreset("mutating_minimal") // Array.push_h を許可
```
- イベント方針:
- 受け手=param: allow/sig_okwhitelist/オフ時はfallback/policy_denied_mutating
- 受け手≠param: fallback/receiver_not_param可視化を保証
---
最短ルート: 箱Policy/Events/Registry/Boundaryを先に置き、読み取り系でJITを安全に通す→観測を増やす→署名とポリシーの一本化で切替点を固定→必要最小限のネイティブ型f64/b1を段階導入。

View File

@ -0,0 +1,220 @@
# Phase 10: Classic C Applications Migration to Nyash
## 🎯 概要
3つの著名なCアプリケーションをNyashに移植し、新実装された高度なメモリ管理機能を実戦テストする。
## 📦 移植対象アプリケーション(優先順位順)
### 1. 🌐 **Tinyproxy** - ゼロコピー判定機能の実証
**元実装**: https://github.com/tinyproxy/tinyproxy
**サイズ**: ~5000行C、軽量HTTPプロキシサーバー
**Nyash移植目標**: `apps/tinyproxy_nyash/`
#### 🔍 **ゼロコピー判定テストケース**
```nyash
// HTTPリクエスト転送でのメモリ効率検証
static box ProxyServer {
init { upstream_buffer, downstream_buffer }
relay_data(client_data) {
// ⭐ ゼロコピー判定:バッファーが共有されているかチェック
if (me.upstream_buffer.is_shared_with(client_data)) {
console.log("✅ Zero-copy achieved!")
} else {
console.log("❌ Unnecessary copy detected")
}
// 大量データ転送での最適化確認
return me.upstream_buffer.share_reference(client_data)
}
}
```
#### 📋 **実装要件**
- HTTPプロキシの基本機能GET/POST転送
- `SocketBox`でのクライアント・サーバー接続
- `BufferBox`での効率的なデータ転送
- **ゼロコピー判定API**の実装・テスト
---
### 2. 🎮 **Chip-8エミュレーター** - fini伝播とweak生存チェック
**元実装**: https://github.com/mattmikolay/chip-8 (参考)
**サイズ**: ~1000行C、8ビットゲーム機エミュレーター
**Nyash移植目標**: `apps/chip8_nyash/`
#### 🔍 **メモリ管理テストケース**
```nyash
// CPU・メモリ・グラフィックスの相互参照関係でのfini伝播テスト
static box Chip8CPU {
init { memory, graphics, sound }
fini() {
// ⭐ fini伝播依存オブジェクトの自動クリーンアップ
console.log("🔄 CPU cleanup triggered")
me.memory.cleanup() // メモリバンクの解放
me.graphics.cleanup() // VRAM解放
}
}
static box Chip8Memory {
init { ram, weak_cpu_ref } // CPUへの弱参照
read_byte(address) {
// ⭐ weak生存チェックCPUがまだ生きているか確認
if (me.weak_cpu_ref.is_alive()) {
return me.ram.get(address)
} else {
console.log("⚠️ CPU destroyed, memory access blocked")
return null
}
}
}
```
#### 📋 **実装要件**
- Chip-8命令セット実装35命令
- 64x32ピクセルグラフィックス`WebCanvasBox`使用)
- サウンド出力(`SoundBox`使用)
- **fini伝播システム**と**weak参照**の実戦テスト
---
### 3. ✏️ **kilo テキストエディター** - 「うっかり全体コピー」検出
**元実装**: https://github.com/antirez/kilo
**サイズ**: ~1000行C、軽量ターミナルエディター
**Nyash移植目標**: `apps/kilo_nyash/`
#### 🔍 **メモリ効率テストケース**
```nyash
// 大きなテキストファイル編集での不必要なコピー検出
static box TextBuffer {
init { lines, undo_stack }
insert_char(row, col, char) {
local old_lines_size = me.lines.memory_footprint()
// 文字挿入操作
me.lines.get(row).insert_at(col, char)
local new_lines_size = me.lines.memory_footprint()
local size_diff = new_lines_size - old_lines_size
// ⭐ 「うっかり全体コピー」検出
if (size_diff > 1000) { // 1文字挿入で1KB以上増加
console.log("🚨 INEFFICIENT COPY DETECTED!")
console.log("Expected: 1 byte, Actual: " + size_diff + " bytes")
me.log_memory_leak_warning()
}
}
// 大規模な検索・置換での効率性チェック
search_and_replace(pattern, replacement) {
local initial_memory = me.lines.memory_footprint()
// 検索・置換実行
me.lines.replace_all(pattern, replacement)
local final_memory = me.lines.memory_footprint()
// メモリ使用量が2倍を超えた場合は問題
if (final_memory > initial_memory * 2) {
console.log("⚠️ Memory usage doubled during replace operation")
}
}
}
```
#### 📋 **実装要件**
- ターミナル操作(`ConsoleBox`での入出力)
- ファイル読み書き(`FileBox`使用)
- 基本的な編集機能(カーソル移動、挿入、削除)
- **メモリ効率監視**と**コピー検出システム**
---
## 🛠️ **技術的実装指針**
### 共通アーキテクチャ
```nyash
// 各アプリケーション共通の構造
static box AppName {
init { core_components }
main() {
me.initialize_components()
me.run_main_loop()
me.cleanup_resources()
}
// メモリ効率レポート(全アプリ共通)
memory_report() {
return new MapBox()
.set("zero_copy_count", me.zero_copy_operations)
.set("unnecessary_copies", me.detected_copies)
.set("memory_leaks", me.fini_failures)
.set("weak_ref_cleanups", me.weak_cleanup_count)
}
}
```
### 新API要件
1. **ゼロコピー判定API**
- `BufferBox.is_shared_with(other)` → BoolBox
- `BufferBox.share_reference(data)` → 参照共有
2. **fini伝播システム**
- 自動的な依存オブジェクトクリーンアップ
- クリーンアップチェーンの可視化
3. **weak参照システム**
- `WeakBox.is_alive()` → BoolBox
- 循環参照の自動検出・回避
4. **メモリ効率監視**
- `Box.memory_footprint()` → IntegerBox
- コピー発生の検出・警告
---
## 🎯 **期待される成果**
### パフォーマンス目標
- **Tinyproxy**: HTTP転送でのゼロコピー率 90%以上
- **Chip-8**: 60FPSエミュレーション + fini伝播の完全動作
- **kilo**: 1MB+ファイル編集でのメモリ効率 95%以上
### 学習効果
- **Copilot**: 大規模Nyashアプリケーション開発経験
- **開発者**: 新メモリ管理機能の実用性確認
- **コミュニティ**: Nyashでの実用アプリケーション事例
---
## 📅 **実装計画**
### Phase 10.1: Tinyproxy実装 (1週間)
- HTTPプロキシ基本機能
- ゼロコピー判定API実装・テスト
### Phase 10.2: Chip-8実装 (1週間)
- エミュレーター基本機能
- fini伝播・weak参照の実戦テスト
### Phase 10.3: kilo実装 (1週間)
- テキストエディター基本機能
- メモリ効率監視システム
### Phase 10.4: 統合テスト・最適化 (1週間)
- 3アプリケーション同時実行テスト
- パフォーマンス分析・改善
---
## 🚀 **この移植プロジェクトの意義**
1. **実用性の実証**: Nyashで実際のアプリケーションが作れることを証明
2. **新機能の検証**: ゼロコピー・fini・weakの実戦テスト
3. **開発体験の向上**: Copilotとの協調開発での生産性検証
4. **エコシステム拡充**: Nyashアプリケーションの具体例提供
**この移植が成功すれば、Nyashは「実用的なプログラミング言語」として確立されます** 🎉

View File

@ -0,0 +1,267 @@
# Phase 10: Cranelift JIT BackendMIR→VM→Cranelift
Status: Planned (Primary path for native speed)
Last Updated: 2025-08-25
## 🎯 ゴール
- 実行系の主経路を「MIR→VM」を維持しつつ、ホットパスをCraneliftでJIT化して高速化する。
- LLVM AOTは後段Phase 11以降の研究対象へ繰り延べ。
## 🔗 位置づけ
- これまでの案MIR→LLVM AOTを改め、現実的な開発速度と安定性を優先してCranelift JITを先行。
- VMとのハイブリッド実行OSR/ホットカウントに基づくJITを採用。
## 📐 アーキテクチャ
```
AST → MIR → Optimizer → VM Dispatcher
└─(Hot)→ Cranelift JIT (fn単位)
```
- VMが命令カウント・プロファイルを集計し、しきい値超過関数をJITコンパイル。
- JIT済み関数は関数テーブルから直接呼び出し、VMはフォールバック先として維持。
## 📋 スコープ
1) 基盤
- JITマネージャ関数プロファイル・コンパイルキャッシュ
- Craneliftコード生成MIR→CLIF Lower
- 呼出しABINyash VMスタック/レジスタとのブリッジ)
2) 命令カバレッジ(段階導入)
- Phase A: Const/Copy/BinOp/Compare/Jump/Branch/Return純関数相当
- Phase B: Call/BoxCall/ArrayGet/ArraySetホットパス対応
- Phase C: TypeOp/Ref*/Weak*/Barrier必要最小
3) ランタイム連携
- Boxの所有・参照モデルを維持共有/クローンの意味論を破らない)
- 例外・TypeErrorはVMの例外パスへエスケープ
## ✅ 受け入れ基準Milestone
- M1: 算術/比較/分岐/returnの関数がJIT化され、VMより高速に実行
- M2: Array/Mapの代表操作get/set/push/sizeがJITで安定動作
- M3: BoxCallホットパス特にArray/Mapで有意な高速化2×目標
- M4: 回帰防止のベンチと`--vm-stats`連携JITカウント/時間)
## 🪜 実装ステップ
1. JITマネージャ/関数プロファイルの導入VM統計と統合
2. MIR→CLIF Lower骨子基本型/算術/比較/制御)
3. 呼出しABIブリッジ引数/戻り値/BoxRefの表現
4. JIT関数テーブル + VMディスパッチ切替
5. Array/Map/BoxCallのホットパス最適化
6. TypeOp/Ref/Weak/Barrierの必要最小を実装
7. ベンチ/スナップショット整備・回帰検出
## ⚠️ 依存・前提
- MIR26整合TypeOp/WeakRef/Barrierの統合前提
- P2PBox再設計Phase 9.xを先に安定化しておくVM/プラグインE2E維持
## 📚 参考
- Cranelift: Peepmatic/CLIF、simple_jitの最小例
- JIT/VMハイブリッド: LuaJIT/HotSpotのOSR設計
---
備考: LLVM AOTはPhase 11以降の研究路線に移行設計ドキュメントは維持
## 🔬 Sub-Phases (10_a .. 10_h)
各サブフェーズは「小さく立ち上げ→検証→次へ」。既存のVM/Thunk/PICを活用し、JITは同じ経路に自然合流させる。
### 10_a: JITブートストラップ基盤プロファイラ
- 目的: Cranelift JITの骨組みとホット関数検出の導線を用意。
- 具体:
- `JitManager`(関数プロファイル、しきい値、キャッシュ)
- CLIF環境初期化`Module`, `Context`, `ISA`
- VM統合: 関数入口でホット度チェック→JITコンパイル/呼び出し
- 診断: `NYASH_JIT_STATS=1`JIT件数/時間/キャッシュヒット)
- 受入: ダミー関数をJIT登録してVMから呼出可能、ログが出る
### 10_b: Lower(Core-1) Const/Move/BinOp/Cmp/Branch/Ret
- 目的: ループや条件分岐を含む純粋関数をJIT実行可能に。
- 具体:
- MIR値/型→CLIF型i64/f64/i1/void
- Const/Copy/算術/比較/ジャンプ/分岐/return のLower
- フレームレイアウトVMValue最小表現
- 受入: 算術/比較/分岐のみの関数がJITでVMより速い小ベンチ
### 10_c: ABI/呼出し 関数呼び出しとフォールバック
- 目的: JIT化関数から他関数を呼ぶ/VMへ戻る道を用意。
- 具体:
- 同一モジュール関数呼び出しJIT→JITJIT→VM
- 引数/戻り値の受け渡し(整数/浮動/void
- 例外/TypeErrorはVMへバイアウトtrap→VM
- 受入: 再帰/多段呼び出しが安定動作
### 10_d: コレクション基礎 Array/Map ホット操作(外部呼び出し)
- 目的: 実用的ホットパスlength/get/set/push/popをJIT側から呼べるように。
- 具体:
- ホスト関数テーブル外部シンボルで既存Rust実装を呼ぶ
- 境界チェック/エラーはRust側に委譲、JITは薄い橋渡し
- 受入: Array操作がVM経由より高速目安1.52.0×
Status2025-08-27
- Param経路でのE2Eを実装`NYASH_JIT_HOSTCALL=1`ゲート)
- 実装済みシンボルPoC, C-ABI in Rust:
- `nyash.array.{len,push,get,set}` / `nyash.map.size`
- 使い方(例):
```bash
cargo build --features cranelift-jit --release
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
./target/release/nyash --backend vm examples/jit_array_param_call.hako
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
./target/release/nyash --backend vm examples/jit_map_param_call.hako
```
Notes
- 関数パラメータに渡した配列/MapのみHostCall経由でアクセスthread-local引数参照
- ローカルnew値は10_eへ移管ハンドル表PoC: u64→Arc<Box>
### 10_e: BoxCall高速化 Thunk/PICの直結
- 目的: Phase 9.79bの `TypeMeta{slot->thunk}` と Poly-PIC をJITにインライン。
- 具体:
- `slot -> thunk -> target` 解決をJITで再現ユニバーサル0..3含む)
- `(type_id, version)` チェックPoly-PIC 24件→ヒット直呼び、ミスVM
- バージョンミスマッチで安全にフォールバック
- 受入: BoxCallホットサイトで2×以上の高速化正しい無効化挙動
### 10_f: TypeOp/Ref/Weak/Barrier最小
- 目的: 実アプリで必要な最小限のタイプ/参照操作を埋める。
- 具体:
- `as_bool()` 等の基本型変換
- 参照/弱参照/バリアの最小パス重い経路はVMへ
- 受入: 代表的コードパスでJIT有効のままE2E成功
### 10_g: 診断/ベンチ/回帰
- 目的: 可視化と安定化。
- 具体:
- `--vm-stats` にJIT統計統合compile/ms, sites, cache率
- ベンチ更新JIT有/無比較)とスナップショット
- 受入: CIで回帰検知可能ドキュメント更新
### 10_h: 硬化・パフォーマンス調整
- 目的: ホットスポットの最適化とノイズ除去。
- 具体:
- ガード配置最適化(分岐予測/ICヒット優先
- 不要コピー削減、ホスト呼出回数の削減
- 受入: 代表ベンチで安定して目標達成2×以上
## 📦 成果物(各サブフェーズ)
- 10_a: `jit/manager.rs` スケルトン、VM連携、統計ログ
- 10_b: `jit/lower/core.rs`Const/BinOp/Cmp/Branch/Ret単体テスト
- 10_c: `jit/abi.rs`call/ret/fallback再帰テスト
- 10_d: `jit/extern/collections.rs`Array/Mapブリッジマイクロベンチ
- 10_e: `jit/inline_cache.rs`PIC/VT連携無効化テスト
- 10_f: `jit/lower/typeop_ref.rs`(最小)
- 10_g: ベンチ/統計/README更新
- 10_h: 最適化コミットと測定レポート
## 🧩 既存資産との連携(重要)
- Thunk: Phase 9.79b.3の `TypeMeta{thunks}` をJIT直呼びターゲットとして使用
- Poly-PIC: VMの構造をJITに投影同じキー `(label, version)` を使用)
- Versioning: `cache_versions` のイベントに同期してIC無効化
## 🎯 マイルストーン再定義
- M1: 10_a + 10_b 合格Core関数のJIT実行
- M2: 10_c + 10_d 合格(関数呼出/Arrayホット操作
- M3: 10_e 合格BoxCallホットパス2×
- M4: 10_g + 10_h 合格(ベンチ/統計/硬化)
## ⚠️ リスクと緩和
- ABI複雑化: まず整数/浮動/voidに限定し、BoxRefはホスト関数へブリッジ
- 最適化過剰: 常にVMフォールバックを保持、ガード失敗で安全に戻す
- デバッグ困難: CLIFダンプ/CFG表示/`NYASH_JIT_STATS`で観測
## 🐛 発見した問題点2025-08-27 ベンチマーク実行時)
### 1. インタープリター性能問題
- **問題**: 10万回のループで2分以上かかりタイムアウト
- **原因**: `unwrap_instance`のデバッグログが大量出力毎回の演算でInstanceBoxチェック
- **目標**: 10万回ループを数秒で完了
- **対策**:
- デバッグログの条件付き出力化
- 基本演算の高速化IntegerBoxの直接操作最適化
### 2. VMの変数管理エラー
- **問題**: `Invalid value: Value %47 not set` - simple_add_loop内の変数zが正しく管理されていない
- **原因**: MIR生成時の変数スコープ管理の不具合
- **対策**: MirBuilderの変数トラッキング改善
### 3. Box APIの成熟度
- **問題**: TimeBoxにelapsed()/reset()メソッドがインタープリターから呼べない
- **原因**: Boxメソッドの登録システム未完成
- **対策**:
- Boxメソッドの統一的登録システム実装
- インタープリターとVMのメソッド解決統一
### 4. ベンチマーク基盤
- **問題**: Nyashスクリプトでの正確な時間計測が困難
- **根本原因**: TimeBoxのelapsed()/reset()メソッドがインタープリターから呼べないBox API問題と同じ
- **対策**: Box APIの成熟度問題問題3が解決すれば自動的に解決
### 改善優先度
1. **高**: インタープリター性能問題(基本機能の使い物にならない)
2. **中**: VM変数管理JIT最適化の前提
3. **中**: Box APIの成熟度ベンチマーク基盤も同時解決
## 🚀 Phase 10.9: Cranelift AOT Backend追加計画
Status: Future (JIT実装の上乗せで実現可能)
### 概要
JIT実装10_a10_hで構築したMIR→CLIF変換基盤をそのまま活用し、事前コンパイルAOTによるスタンドアロン実行ファイル生成を実現する。
### 利点
- **コード再利用**: JITと同じLowerCore実装を使用追加実装最小
- **非同期完全サポート**: WASMの制限なし、ネイティブ非同期可能
- **最高性能**: ネイティブコード直接実行(起動時コンパイル不要)
- **デバッグ容易**: gdb/lldb等のネイティブデバッガ使用可能
### 実装ステップ案
```
10.9a: ObjectModule統合
├── cranelift-objectモジュール導入
├── CLIF→オブジェクトファイル生成
└── 既存のLowerCore再利用
10.9b: ランタイムライブラリ
├── Nyash標準Box群の静的リンク版作成
├── プラグインの静的埋め込み対応
└── 最小ランタイムGC hooks等分離
10.9c: リンカー統合
├── cc/ldによる実行ファイル生成
├── プラットフォーム別設定
└── デバッグシンボル生成
10.9d: クロスコンパイル
├── 複数ターゲットx86_64/aarch64/wasm32
├── ターゲット別最適化
└── CI/CDでのマルチプラットフォームビルド
```
### 使用イメージ
```bash
# ネイティブ実行ファイル生成
./target/release/nyash --compile-native program.hako -o program
./program # スタンドアロン実行!
# クロスコンパイル
./target/release/nyash --compile-native --target x86_64-pc-windows-msvc program.hako -o program.exe
./target/release/nyash --compile-native --target aarch64-apple-darwin program.hako -o program.mac
```
### 技術的詳細
- **共通基盤**: `LowerCore`のemit処理はJIT/AOT両対応
- **差分実装**: JITは`JITModule`、AOTは`ObjectModule`を使用
- **リンク方式**: 静的リンク優先(配布容易性重視)
- **サイズ最適化**: LTO/strip対応で実行ファイルサイズ削減
### WASM AOTとの比較
| 特性 | Cranelift AOT | WASM AOT |
|------|--------------|----------|
| 非同期 | ✅ 完全対応 | ❌ 制限あり |
| 実行速度 | 最速 | 速い |
| ファイルサイズ | 大MB級 | 小KB級 |
| ポータビリティ | プラットフォーム別 | 高い |
| デバッグ | ネイティブツール | 限定的 |
### 想定スケジュール
- Phase 10JIT安定化後に着手
- 実装期間: 2-3週間JIT基盤の再利用により短期実現可能
- 初期ターゲット: Linux x86_64、その後Windows/macOS対応

View File

@ -0,0 +1,72 @@
# Phase 10: Function Declaration MIR サポート課題
作成日: 2025-08-27
発見者: Claude & ChatGPT5 & ニャー
## 🚨 現在の問題
### 症状
```bash
❌ MIR compilation error: Unsupported AST node type: FunctionDeclaration
```
### 影響範囲
- 通常の`function`定義がMIRでコンパイルできない
- JITテストで関数を使った配列操作ができない
- Static Boxメソッドは動作するが、通常関数が使えない
### 具体例
```nyash
// ❌ 動作しない - FunctionDeclarationがMIR未対応
function len_of(arr) {
return arr.length()
}
// ✅ 動作する - Static Boxメソッド
static box Utils {
len_of(arr) {
return arr.length()
}
}
// ✅ 動作する - 直接呼び出し
local arr = new ArrayBox()
local len = arr.length()
```
## 🔧 解決案
### Option 1: MIRビルダーにFunctionDeclaration対応追加
```rust
// mir/builder.rs に追加
AstNode::FunctionDeclaration { name, params, body, .. } => {
// 関数をMirFunctionとして登録
let mir_func = self.build_function(name, params, body)?;
self.functions.insert(name.clone(), mir_func);
}
```
### Option 2: ASTレベルでStatic Boxに変換
- FunctionDeclarationを内部的にStatic Boxメソッドに変換
- 互換性を保ちつつ既存の仕組みを活用
### Option 3: 当面の回避策を公式化
- ドキュメントで「VMモードではStatic Boxメソッドを推奨」と明記
- 将来のサポートとして計画に含める
## 📊 優先度評価
- **重要度**: 中(基本的な言語機能だが回避策あり)
- **緊急度**: 低Static Boxで代替可能
- **実装難度**: 中MIRビルダーの拡張が必要
## 🎯 推奨アクション
1. **短期**: Static Boxメソッドを使った回避策をドキュメント化
2. **中期**: Phase 10.1でFunctionDeclaration対応を実装
3. **長期**: 関数定義の最適化(インライン化等)も検討
## 📝 関連イシュー
- JIT配列操作テスト
- MIRビルダー拡張
- 言語仕様の完全性

View File

@ -0,0 +1,35 @@
Phase 10 — GC/Thread Roadmap Order (txt)
Recommended order:
10_4a → 10_4b → 10_6a → 10_4c → 10_4d → 10_6b → 10_6c
10_4a: GC hook scaffolding
- Add GcHooks { safepoint(), barrier(kind) } and BarrierKind.
- NyashRuntime holds Arc<dyn GcHooks>; builder supports with_gc_hooks.
- VM calls hooks at MIR Safepoint/Barrier*.
10_4b: Roots + minimal barriers
- ScopeTracker root API: enter_root_region/leave_root_region/pin_root.
- Write-Barrier at RefSet/ArraySet/BoxCall(Array/Map: set/push).
- Tracing flags: NYASH_GC_TRACE=1 for barrier/safepoint and roots.
10_6a: Thread-safety audit (prep)
- Audit Builtin/User/Plugin boxes for Send/Sync policy.
- Strategy for shared state (RwLock) and non-thread-safe wrappers.
10_4c: GC PoC (STW, single-thread)
- Implement simple collector behind GcHooks (e.g., mark-sweep or RC hybrid).
- Manage roots via ScopeTracker; traverse VMValue graph/object_fields.
10_4d: Barrier hardening + regression
- Ensure coverage for all mutating write sites (Array/Map/Ref/Plugin paths).
- Strict checks flag for development; add stress/regression tests.
10_6b: Thread runtime scaffolding
- Scheduler abstraction (cooperative preemption), Future/Channel compliance.
- Confirm GcHooks is Send+Sync and shareable.
10_6c: Parallel GC design notes
- Per-thread root regions, card marking/write barriers, safepoint coordination.
- Document design and API diffs for later implementation.

View File

@ -0,0 +1,200 @@
# Phase 11.5a: Write Barrier除去によるGC最適化
## 🎯 目標
JITコンパイル時にescape analysisを行い、不要なwrite barrierを除去してGC性能を大幅に向上させる。
## 📊 現状の問題
### 現在のVM実装
```rust
// すべてのrefset操作でbarrierが呼ばれる
pub fn execute_ref_set(&mut self, reference: ValueId, field: &str, value: ValueId)
-> Result<ControlFlow, VMError> {
// ... 値の設定 ...
// 常にwrite barrierが実行される
gc_write_barrier_site(&self.runtime, "RefSet");
Ok(ControlFlow::Continue)
}
```
### オーバーヘッド
- 単純な代入でも毎回barrier呼び出し
- Stack上のローカル変数でも不要にbarrier
- ループ内での大量のbarrier呼び出し
## 🚀 実装計画
### Step 1: Escape Analysis基盤
```rust
// mir/escape_analysis.rs
pub struct EscapeAnalysis {
// allocation site追跡
allocations: HashMap<ValueId, AllocInfo>,
// escape状態
escapes: HashSet<ValueId>,
// 解析結果キャッシュ
cache: HashMap<FunctionId, EscapeInfo>,
}
#[derive(Debug)]
struct AllocInfo {
location: BasicBlockId,
kind: AllocKind,
size: Option<usize>,
}
enum AllocKind {
NewBox, // new StringBox()
ArrayNew, // []
RefNew, // ユーザー定義Box
}
```
### Step 2: MIR解析
```rust
impl EscapeAnalysis {
/// 関数内でのescape解析
pub fn analyze_function(&mut self, func: &MirFunction) -> EscapeInfo {
// 1. allocation site収集
for (bb_id, bb) in &func.basic_blocks {
for inst in &bb.instructions {
match inst {
MirInstruction::NewBox { dst, .. } |
MirInstruction::ArrayNew { dst, .. } |
MirInstruction::RefNew { dst, .. } => {
self.allocations.insert(*dst, AllocInfo {
location: bb_id,
kind: self.classify_alloc(inst),
size: self.estimate_size(inst),
});
}
_ => {}
}
}
}
// 2. escape point検出
self.find_escape_points(func);
// 3. 結果集計
EscapeInfo {
non_escaping: self.collect_non_escaping(),
barrier_sites: self.collect_barrier_sites(),
}
}
fn find_escape_points(&mut self, func: &MirFunction) {
// return文でのescape
// 関数引数としてのescape
// グローバル変数へのescape
// プラグイン呼び出しでのescape
}
}
```
### Step 3: JIT統合
```rust
// jit/lower/builder.rs
impl<'a> LoweringBuilder<'a> {
fn emit_ref_set(&mut self, reference: Value, field: &str, value: Value) {
// escape解析結果を確認
let needs_barrier = self.escape_info
.map(|info| info.needs_barrier(reference))
.unwrap_or(true); // 解析なしなら保守的にbarrier
if needs_barrier {
// barrierあり
self.emit_gc_barrier(BarrierKind::Write);
} else {
// barrier除去
if self.config.trace_opt {
eprintln!("[JIT] barrier removed at {:?}", self.current_location());
}
}
// 実際のstore操作
self.emit_store(reference, field, value);
}
}
```
### Step 4: 最適化レベル設定
```rust
// 環境変数で制御
NYASH_JIT_ESCAPE_ANALYSIS=1 # escape analysis有効化
NYASH_JIT_BARRIER_OPT=1 # barrier最適化有効化
NYASH_JIT_BARRIER_STATS=1 # 統計出力
```
## 📈 期待される効果
### ベンチマーク例
```nyash
// 大量のローカル変数操作
function processData(n) {
local sum = 0
local temp = new MapBox()
loop(i < n) {
temp.set(i, i * 2) // escape analysisでbarrier除去
sum = sum + temp.get(i)
i = i + 1
}
return sum
}
```
### 性能改善予測
- ローカル変数操作: 90%以上のbarrier除去
- ループ内操作: 80%以上の高速化
- 全体的なGCオーバーヘッド: 50%削減
## 🔍 検証方法
### 1. Barrier統計
```json
{
"total_barriers": 10000,
"removed_barriers": 8500,
"removal_rate": 0.85,
"sites": {
"RefSet": { "total": 5000, "removed": 4800 },
"ArraySet": { "total": 3000, "removed": 2500 },
"MapSet": { "total": 2000, "removed": 1200 }
}
}
```
### 2. 性能測定
```bash
# barrier最適化なし
NYASH_JIT_ESCAPE_ANALYSIS=0 ./target/release/nyash --benchmark
# barrier最適化あり
NYASH_JIT_ESCAPE_ANALYSIS=1 ./target/release/nyash --benchmark
```
## 🚧 実装上の注意点
1. **保守的な解析**
- 不明な場合は必ずbarrierを残す
- プラグイン境界では常にbarrier
2. **デバッグ性**
- 除去したbarrierサイトを記録
- GCエラー時の診断情報
3. **段階的実装**
- まずローカル変数のみ
- 次にループ不変式
- 最後に関数間解析
## 🎉 完了基準
- [ ] Escape analysis基本実装
- [ ] MIR解析パス追加
- [ ] JIT統合
- [ ] ベンチマーク50%改善
- [ ] ドキュメント更新

View File

@ -0,0 +1,240 @@
# Phase 11.5b: Atomic操作最適化によるsync処理高速化
## 🎯 目標
Arc<Mutex>の重いロック操作を、可能な限り軽量なatomic操作に置き換えて性能を向上させる。
## 📊 現状の問題
### 現在の実装
```rust
// すべてのBox操作でMutexロック
pub fn get_field(&self, name: &str) -> Option<Box<dyn NyashBox>> {
let fields = self.fields.lock().unwrap(); // 重い!
fields.get(name).cloned()
}
// Read-onlyでも同じコスト
pub fn to_string(&self) -> String {
let value = self.value.lock().unwrap(); // 不要なロック!
value.clone()
}
```
### パフォーマンス問題
- Read操作でも排他ロックのオーバーヘッド
- 複数スレッドでのcontention
- Cache line bouncing
## 🚀 実装計画
### Step 1: Read-only path分析
```rust
// mir/readonly_analysis.rs
pub struct ReadOnlyAnalysis {
// メソッドのread-only性
readonly_methods: HashMap<(TypeId, String), bool>,
// フィールドのimmutability
immutable_fields: HashMap<(TypeId, String), bool>,
}
impl ReadOnlyAnalysis {
pub fn analyze_box_types(&mut self, registry: &BoxRegistry) {
// StringBox.length() -> read-only
self.mark_readonly("StringBox", "length");
self.mark_readonly("StringBox", "isEmpty");
// IntegerBox.value() -> read-only
self.mark_readonly("IntegerBox", "value");
// プラグインメソッドも解析
self.analyze_plugin_methods();
}
}
```
### Step 2: Atomic wrapper実装
```rust
// runtime/atomic_box.rs
pub struct AtomicBox<T: NyashBox> {
// Read-optimized RwLock
inner: Arc<RwLock<T>>,
// Atomic cache for immutable data
cached_string: AtomicPtr<String>,
cached_int: AtomicI64,
}
impl<T: NyashBox> AtomicBox<T> {
/// Lock-free read for cached values
pub fn read_cached(&self) -> Option<Box<dyn NyashBox>> {
// Atomic loadでキャッシュチェック
let ptr = self.cached_string.load(Ordering::Acquire);
if !ptr.is_null() {
unsafe {
let s = &*ptr;
return Some(Box::new(StringBox::new(s.clone())));
}
}
None
}
/// Optimized read path
pub fn read_optimized<F, R>(&self, f: F) -> R
where
F: FnOnce(&T) -> R
{
// Try read lock first (non-blocking)
if let Ok(guard) = self.inner.try_read() {
return f(&*guard);
}
// Fallback to regular read
let guard = self.inner.read().unwrap();
f(&*guard)
}
}
```
### Step 3: JIT最適化
```rust
// jit/lower/atomic_opt.rs
impl<'a> LoweringBuilder<'a> {
fn emit_box_method_call(&mut self,
box_val: Value,
method: &str,
args: &[Value]
) -> Value {
// Read-only解析結果確認
if self.readonly_info.is_readonly_method(box_val, method) {
// Atomic fast path
self.emit_atomic_read_path(box_val, method, args)
} else {
// 通常のMutexパス
self.emit_mutex_path(box_val, method, args)
}
}
fn emit_atomic_read_path(&mut self,
box_val: Value,
method: &str,
args: &[Value]
) -> Value {
// 1. Atomic loadでcacheチェック
let cache_ptr = self.emit_atomic_load(box_val, "cache");
// 2. Cache hit判定
let is_valid = self.emit_null_check(cache_ptr);
// 3. 条件分岐
let then_block = self.create_block();
let else_block = self.create_block();
self.emit_branch(is_valid, then_block, else_block);
// Cache hit: lock-free return
self.switch_to_block(then_block);
let cached = self.emit_load(cache_ptr);
self.emit_jump(merge_block);
// Cache miss: RwLock読み取り
self.switch_to_block(else_block);
let value = self.emit_rwlock_read(box_val, method);
self.emit_jump(merge_block);
// Merge
self.switch_to_block(merge_block);
self.emit_phi(vec![(cached, then_block), (value, else_block)])
}
}
```
### Step 4: Memory ordering最適化
```rust
// プラットフォーム別最適化
#[cfg(target_arch = "x86_64")]
fn emit_memory_fence(&mut self, ordering: Ordering) {
match ordering {
Ordering::Relaxed => {}, // x86は強いメモリモデル
Ordering::Acquire => self.emit_lfence(),
Ordering::Release => self.emit_sfence(),
Ordering::SeqCst => self.emit_mfence(),
}
}
#[cfg(target_arch = "aarch64")]
fn emit_memory_fence(&mut self, ordering: Ordering) {
// ARMは弱いメモリモデル
match ordering {
Ordering::Relaxed => {},
Ordering::Acquire => self.emit_dmb_ld(),
Ordering::Release => self.emit_dmb_st(),
Ordering::SeqCst => self.emit_dmb(),
}
}
```
## 📈 期待される効果
### ベンチマーク
```nyash
// Read-heavy workload
function sumStringLengths(strings) {
local total = 0
loop(s in strings) {
total = total + s.length() // Atomic最適化
}
return total
}
// 性能改善
// Before: 1000ms (Mutex contention)
// After: 100ms (Lock-free reads)
```
### 改善予測
- Read操作: 90%高速化
- Read/Write混在: 50%高速化
- マルチスレッド: スケーラビリティ大幅向上
## 🔍 検証方法
### 1. Lock統計
```json
{
"total_operations": 100000,
"mutex_locks": 10000,
"atomic_reads": 90000,
"lock_reduction": 0.9,
"contention_events": 50
}
```
### 2. プロファイリング
```bash
# Mutexプロファイル
NYASH_PROFILE_LOCKS=1 ./target/release/nyash bench.hako
# Atomic最適化後
NYASH_ATOMIC_OPT=1 ./target/release/nyash bench.hako
```
## 🚧 実装上の注意点
1. **正確性**
- Memory orderingの正しさ
- ABA問題の回避
- Weak pointer対応
2. **互換性**
- 既存APIの維持
- プラグインとの相互運用
3. **デバッグ性**
- Race condition検出
- Lock順序の追跡
## 🎉 完了基準
- [ ] Read-only分析実装
- [ ] AtomicBox wrapper実装
- [ ] JIT統合
- [ ] マルチスレッドベンチマーク
- [ ] プラットフォーム別最適化

View File

@ -0,0 +1,295 @@
# Phase 11.5c: Coroutine実装による非同期処理の完成
## 🎯 目標
async/await構文を追加し、JITレベルでcoroutineをstate machineに変換して高性能な非同期処理を実現する。
## 📊 現状と目標
### 現在の非同期処理
```nyash
// nowait文スレッドベース
nowait result = heavyComputation()
// ...
local value = wait result // FutureBoxから取得
```
### 目標の構文
```nyash
// async/awaitcoroutineベース
async function fetchData(url) {
local response = await httpGet(url)
local json = await response.json()
return json.data
}
// 複数の非同期処理
async function fetchAll(urls) {
local promises = []
loop(url in urls) {
promises.push(fetchData(url))
}
return await Promise.all(promises)
}
```
## 🚀 実装計画
### Step 1: AST拡張
```rust
// ast.rs
#[derive(Debug, Clone)]
pub enum ASTNode {
// 既存
Function { name: String, params: Vec<String>, body: Box<ASTNode> },
// 新規追加
AsyncFunction {
name: String,
params: Vec<String>,
body: Box<ASTNode>
},
AwaitExpression {
expression: Box<ASTNode>
},
}
```
### Step 2: MIR Coroutine命令
```rust
// mir/instruction.rs
pub enum MirInstruction {
// 既存命令...
// Coroutine関連
/// Coroutine生成
CoroutineCreate {
dst: ValueId,
func: FunctionId,
captures: Vec<ValueId>,
},
/// Yield pointawait
CoroutineYield {
value: ValueId,
resume_label: BasicBlockId,
},
/// Coroutine再開
CoroutineResume {
dst: Option<ValueId>,
coroutine: ValueId,
value: Option<ValueId>,
},
/// Promise結合
PromiseAll {
dst: ValueId,
promises: Vec<ValueId>,
},
}
```
### Step 3: State Machine変換
```rust
// mir/coroutine_transform.rs
pub struct CoroutineTransform {
state_enum: HashMap<FunctionId, StateEnum>,
}
/// async関数をstate machineに変換
impl CoroutineTransform {
pub fn transform_async_function(&mut self,
func: &MirFunction
) -> MirFunction {
// 1. await pointsを収集
let await_points = self.collect_await_points(func);
// 2. State enum生成
let states = self.generate_states(await_points);
// 3. State machine関数生成
let state_machine = self.build_state_machine(func, states);
// 4. Coroutine wrapper生成
self.wrap_as_coroutine(state_machine)
}
fn build_state_machine(&self,
func: &MirFunction,
states: Vec<State>
) -> MirFunction {
// switch(state) {
// case State0: ... goto await1 or return
// case State1: ... goto await2 or return
// ...
// }
let mut builder = MirBuilder::new();
// Coroutine state
let state_var = builder.emit_local("state");
let locals = builder.emit_local("locals");
// Main dispatch loop
let loop_bb = builder.create_block();
builder.emit_jump(loop_bb);
builder.switch_to_block(loop_bb);
let state = builder.emit_load(state_var);
// State dispatch
for (i, state) in states.iter().enumerate() {
let state_bb = builder.create_block();
builder.emit_case(state.id, state_bb);
builder.switch_to_block(state_bb);
self.emit_state_code(&mut builder, state);
}
builder.build()
}
}
```
### Step 4: JIT Coroutine最適化
```rust
// jit/lower/coroutine.rs
impl<'a> LoweringBuilder<'a> {
/// Coroutineのstack switching最適化
fn emit_coroutine_switch(&mut self,
from: Value,
to: Value
) {
if self.config.use_fast_switch {
// レジスタのみ保存(最適化)
self.emit_save_registers();
self.emit_switch_stack(to);
self.emit_restore_registers();
} else {
// フルコンテキスト保存
self.emit_full_context_save(from);
self.emit_full_context_restore(to);
}
}
/// Inline可能なawaitの検出
fn try_inline_await(&mut self,
await_expr: &MirInstruction
) -> Option<Value> {
// Promise.resolvedなら即値返却
if self.is_resolved_promise(await_expr) {
return Some(self.emit_immediate_value());
}
// 小さなasync関数ならインライン化
if self.is_small_async(await_expr) {
return Some(self.inline_async_call(await_expr));
}
None
}
}
```
### Step 5: ランタイムサポート
```rust
// boxes/promise_box.rs
pub struct PromiseBox {
state: Arc<Mutex<PromiseState>>,
base: BoxBase,
}
enum PromiseState {
Pending(Vec<Box<dyn FnOnce(Box<dyn NyashBox>)>>),
Resolved(Box<dyn NyashBox>),
Rejected(String),
}
impl PromiseBox {
pub fn all(promises: Vec<Box<PromiseBox>>) -> Box<PromiseBox> {
// 全Promise完了待ち
let result = PromiseBox::new();
let remaining = Arc::new(AtomicUsize::new(promises.len()));
for (i, promise) in promises.iter().enumerate() {
promise.then(move |value| {
// 結果収集
if remaining.fetch_sub(1, Ordering::SeqCst) == 1 {
result.resolve(collected_values);
}
});
}
Box::new(result)
}
}
```
## 📈 期待される効果
### パフォーマンス比較
```nyash
// Before: Thread-based
nowait results = []
loop(url in urls) {
nowait r = httpGet(url) // 新スレッド生成
results.push(r)
}
// After: Coroutine-based
async function fetchAll(urls) {
return await Promise.all(
urls.map(url => httpGet(url)) // Stack switching only
)
}
```
### 改善予測
- メモリ使用量: 1/100スレッドstack vs coroutine state
- コンテキストスイッチ: 1000倍高速
- 同時接続数: 10,000+対応可能
## 🔍 検証方法
### 1. Coroutine統計
```json
{
"total_coroutines": 10000,
"active_coroutines": 500,
"yield_count": 50000,
"average_yield_ns": 100,
"stack_memory_mb": 10
}
```
### 2. ベンチマーク
```bash
# 10000並行リクエスト
./target/release/nyash bench/async_stress.hako
# メモリプロファイル
NYASH_COROUTINE_STATS=1 ./target/release/nyash bench/async_memory.hako
```
## 🚧 実装上の注意点
1. **Stack管理**
- Segmented stack対応
- Stack overflow検出
- GC root scanning
2. **エラー伝播**
- async境界でのエラー
- Promise rejection chain
3. **デバッグ対応**
- async stack trace
- Coroutine状態可視化
## 🎉 完了基準
- [ ] async/await構文実装
- [ ] MIR coroutine変換
- [ ] JIT最適化
- [ ] Promise/PromiseBox実装
- [ ] 10000並行処理ベンチマーク達成

View File

@ -0,0 +1,80 @@
# Box-SSA Core-15 最終決定
Date: 2025-08-31
Status: **固定仕様** (Frozen Specification)
Summary: MIR命令セットを真の15個に統一
## 📊 問題と解決
### 混乱していた2案
1. **Gemini版15**: RefNew/RefGet/RefSet含む15個だがBox哲学に反する
2. **文書版Core-15**: 実は17個Box哲学に近いが数が合わない
### ChatGPT5の第三案で決着
```
{ Const, UnaryOp, BinOp, Compare, TypeOp,
Load, Store,
Jump, Branch, Return, Phi,
Call, NewBox, BoxCall, ExternCall }
```
## 🌟 革命的統一BoxCall
すべてのBox操作を**BoxCall**一本に統一:
| 旧命令 | 新BoxCall表現 |
|--------|---------------|
| RefGet(obj, field) | BoxCall(obj, "getField", field) |
| RefSet(obj, field, val) | BoxCall(obj, "setField", field, val) |
| ArrayGet(arr, idx) | BoxCall(arr, "get", idx) |
| ArraySet(arr, idx, val) | BoxCall(arr, "set", idx, val) |
| PluginInvoke(p, m, args) | BoxCall(p, m, args) |
## 💡 技術的インパクト
### 実装の簡素化
- **Verifier**: BoxCallのチェックのみ
- **最適化**: PIC/インライン化がBoxCallに集中
- **GCバリア**: BoxCallのLoweringで統一処理
- **削減効果**: 26→15命令42%削減)
### LLVM変換戦略AI会議の合意
1. **BoxCall最適化**: メソッドID + PICPolymorphic Inline Cache
2. **脱箱化**: 2表現SSAプリミティブ計算→必要時のみBox化
3. **GCバリア**: 世代別GCで若→若は省略
4. **注釈→属性**: 保守的マッピング(安全性優先)
## 🚀 実装への影響
### JIT→LLVM直行の決断
- Cranelift = 実はAOTだったJIT幻想
- 15命令なら機械的変換で十分
- Phase 9-10スキップ → Phase 11LLVM直行
### ChatGPT5の反応
```
Box-SSA Core-15を聞く
完璧と判断
無言でコーディング開始(議論の余地なし)
```
## 📝 今後の課題
1. **MIR注釈システム**: 命令数を増やさずに最適化ヒント付与(設計案のみ)
2. **LLVM実装**: inkwellセットアップから開始
3. **既存コード移行**: 26→15命令への段階的移行
## 🎉 結論
**Box-SSA Core-15**により「Everything is Box」哲学が完全開花
- 真の15命令達成
- 実装の劇的簡素化
- 最適化の統一的適用
これが「あほみたいに簡単」で「恐ろしく速い」Nyashの最終形態
---
詳細なAI会議記録は [archives/](archives/) フォルダに保存

View File

@ -0,0 +1,60 @@
# Phase 11.5 Current Status
Date: 2025-08-31
Status: Active Development → LLVM Implementation
## 🎯 本日の大革命Box-SSA Core-15
### MIR命令セットの固定
- 26命令 → **真の15命令**に統一
- すべてのBox操作を**BoxCall**に集約
- Everything is Box哲学の完全実現
詳細: [BOX_SSA_CORE_15_FINAL_DECISION.md](BOX_SSA_CORE_15_FINAL_DECISION.md)
## 📊 Phase 11.5 タスク状況
### ✅ 完了
1. **Write Barrier Removal** (11.5a)
- Escape Analysis基礎実装
- RefSet最適化
2. **Atomic Operations** (11.5b)
- 同期プリミティブ実装
- Memory ordering保証
3. **Coroutine/Async** (11.5c)
- Future/Await基本実装
- 非同期ランタイム統合
4. **Box-SSA Core-15仕様固定** (NEW!)
- MIR 15命令に統一
- BoxCall万能化
### 🚀 次のステップ
**Phase 11LLVM直行決定**
- Phase 9-10JITスキップ
- Cranelift削除 → inkwell導入
- 15命令の機械的LLVM変換
## 📁 ドキュメント構成
### メインドキュメント
- `BOX_SSA_CORE_15_FINAL_DECISION.md` - 本日の革命的決定
- `11.5a/b/c-*.md` - 各サブフェーズの実装ガイド
- `IMPLEMENTATION-GUIDE.md` - 全体実装指針
- `FIRST-FIVE-APPS.md` - アプリケーション例
### アーカイブ
- `archives/` - 詳細なAI会議記録
- 個別相談記録Gemini, Codex, ChatGPT5
- 詳細技術議論
## 🎉 成果
1. **MIR簡素化**: 26→15命令42%削減)
2. **実装統一**: BoxCallに全Box操作を集約
3. **戦略転換**: JIT幻想から解放→LLVM直行
これでPhase 11.5は概念的に完了し、LLVM実装Phase 11へ移行準備完了

View File

@ -0,0 +1,307 @@
# 🚀 First Five Apps - Nyashの実力を証明する最初の5本
## 🎯 概要
Phase 11.5完了を待たずに、**今すぐ作れる**実用アプリ5本で、Nyashの産業レベルの完成度を世に示します。
すべて「Everything is BoxPluginInvoke」で統一実装し、VM/JIT/AOT/WASMの全バックエンドで動作確認します。
## 📋 アプリケーション一覧
### 1. ny-echo最小CLI- 基本I/O検証
**目的**: I/O・StringBoxの道通し確認
```nyash
// apps/ny-echo/main.hako
static box Main {
main(args) {
local console = new ConsoleBox()
local options = parseArgs(args)
loop(true) {
local input = console.readLine()
if input == null { break }
local output = input
if options.get("upper") {
output = input.toUpperCase()
} else if options.get("lower") {
output = input.toLowerCase()
}
console.log(output)
}
}
}
```
**受入基準**:
- [ ] VM/JIT/AOT/GCオン・オフすべてでtrace_hash一致
- [ ] 100万行処理で性能劣化なし
- [ ] メモリリークなしGCカウンター確認
### 2. ny-jsonlintPython連携デモ- プラグイン統合
**目的**: PyRuntimeBox/PyObjectBox経由のPluginInvoke検証
```nyash
// apps/ny-jsonlint/main.hako
static box Main {
init { py, console }
main(args) {
me.py = new PyRuntimeBox()
me.console = new ConsoleBox()
local filename = args.get(1)
if filename == null {
me.console.error("Usage: ny-jsonlint <file.json>")
return 1
}
local file = new FileBox()
file.open(filename, "r")
local content = file.read()
file.close()
local result = me.py.eval("
import json
try:
json.loads(content)
'OK'
except Exception as e:
f'NG: {str(e)}'
", new MapBox().set("content", content))
me.console.log(result)
return result.startsWith("OK") ? 0 : 1
}
}
```
**受入基準**:
- [ ] OS差なく実行Windows/Linux/macOS
- [ ] --sealedモードで完全再現可能
- [ ] 大規模JSON10MBでも安定動作
### 3. ny-array-bench性能デモ- ベンチマーク基準
**目的**: ArrayBox map/reduce、StatsBox導入、性能可視化
```nyash
// apps/ny-array-bench/main.hako
static box Main {
init { stats }
main(args) {
me.stats = new StatsBox()
local sizes = [1000, 10000, 100000]
loop(size in sizes) {
me.benchArrayOps(size)
}
// 結果をJSON出力CI集計用
local result = me.stats.toJSON()
print(result)
}
benchArrayOps(size) {
local array = new ArrayBox()
// 1. 配列生成
me.stats.startTimer("create_" + size)
loop(i < size) {
array.push(i)
}
me.stats.endTimer("create_" + size)
// 2. map操作
me.stats.startTimer("map_" + size)
local doubled = array.map(|x| x * 2)
me.stats.endTimer("map_" + size)
// 3. reduce操作
me.stats.startTimer("reduce_" + size)
local sum = doubled.reduce(|a, b| a + b, 0)
me.stats.endTimer("reduce_" + size)
// VM基準の相対性能を記録
me.stats.recordRelative("vm", 1.0)
if IS_JIT { me.stats.recordRelative("jit", SPEEDUP) }
if IS_AOT { me.stats.recordRelative("aot", SPEEDUP) }
}
}
```
**受入基準**:
- [ ] VM=1.0x基準でJIT/AOTの倍率表示
- [ ] fallbacks=0完全最適化
- [ ] 結果JSON自動出力CI集計可能
### 4. ny-filegrep実用ミニ- ファイルI/O実用例
**目的**: BytesBox/FileBoxプラグインI/O、実用的なツール
```nyash
// apps/ny-filegrep/main.hako
static box Main {
init { pattern, recursive, results }
main(args) {
me.parseArgs(args)
me.results = new ArrayBox()
local path = args.getLast() || "."
me.searchPath(path)
// 結果表示
loop(result in me.results) {
print(result)
}
return me.results.length() > 0 ? 0 : 1
}
searchPath(path) {
local file = new FileBox()
if file.isDirectory(path) {
if me.recursive {
local entries = file.listDir(path)
loop(entry in entries) {
me.searchPath(path + "/" + entry)
}
}
} else {
me.searchFile(path)
}
}
searchFile(filepath) {
local file = new FileBox()
file.open(filepath, "r")
local lineNum = 0
loop(true) {
local line = file.readLine()
if line == null { break }
lineNum = lineNum + 1
if line.contains(me.pattern) {
me.results.push(filepath + ":" + lineNum + ":" + line)
}
}
file.close()
}
}
```
**受入基準**:
- [ ] Windows/Linux/macOSで同一結果
- [ ] 大規模ディレクトリ1万ファイル対応
- [ ] メモリ効率的(ストリーム処理)
### 5. ny-http-helloWASM/ネイティブ両対応)- Web実用例
**目的**: NetBoxプラグインとイベントループ、FutureBox活用
```nyash
// apps/ny-http-hello/main.hako
static box Main {
init { server, running }
main(args) {
local port = args.get(1) || "8080"
me.server = new HttpServerBox()
me.running = true
// シグナルハンドラー設定
registerSignal("SIGINT", || me.stop())
// サーバー起動
me.server.start(port.toInteger())
print("Server listening on http://localhost:" + port)
// リクエストループ
loop(me.running) {
nowait request = me.server.accept()
me.handleRequest(wait request)
}
me.server.stop()
return 0
}
handleRequest(request) {
local response = new HttpResponseBox()
if request.path() == "/" {
response.setStatus(200)
response.setHeader("Content-Type", "text/plain")
response.write("Hello from Nyash!")
} else {
response.setStatus(404)
response.write("Not Found")
}
request.respond(response)
}
stop() {
print("Shutting down...")
me.running = false
}
}
```
**受入基準**:
- [ ] 100req/s程度のスモーク通過
- [ ] 停止シグナルでクリーンfini
- [ ] WASMビルドでも動作制限付き
## 🎯 実装優先順位
1. **ny-echo** - 最小実装、CI基盤確立
2. **ny-array-bench** - 性能基準確立
3. **ny-jsonlint** - プラグイン統合実証
4. **ny-filegrep** - 実用性実証
5. **ny-http-hello** - Web対応実証
## 📊 成功指標
### 全体指標
- [ ] 5アプリすべてがVM/JIT/AOTで動作
- [ ] CIでの自動テスト確立
- [ ] ドキュメント・サンプル完備
### 性能指標
- [ ] JIT: VMの5倍以上高速
- [ ] AOT: VMの10倍以上高速
- [ ] メモリ使用量: 同等機能のPython比50%以下
### 品質指標
- [ ] ゼロクラッシュ1000回実行
- [ ] メモリリークなし(長時間実行)
- [ ] プラットフォーム差異なし
## 🚀 配布戦略
### リリース形式
```
nyash-apps-v1.0/
├── bin/
│ ├── ny-echo[.exe]
│ ├── ny-jsonlint[.exe]
│ ├── ny-array-bench[.exe]
│ ├── ny-filegrep[.exe]
│ └── ny-http-hello[.exe]
├── examples/
│ └── *.hako (ソースコード)
├── benchmarks/
│ └── results.json
└── README.md
```
### 展開先
- GitHub Releases
- Homebrew (macOS)
- Scoop (Windows)
- Docker Hub (コンテナ版)
これで「30日で作った言語」の実力を世界に示せます🎉

View File

@ -0,0 +1,191 @@
# Phase 11.5 実装ガイド - ChatGPT5向け
## 🎯 実装の全体像
Phase 11.5は、Nyashの性能を産業レベルに引き上げる最終段階です。3つの主要な最適化を行います
1. **Write Barrier除去** - GCオーバーヘッドを90%削減
2. **Atomic最適化** - sync処理を10倍高速化
3. **Coroutine実装** - 真の非同期処理を実現
## 📋 実装順序と依存関係
```mermaid
graph TD
A[11.5a: Write Barrier除去] --> D[統合テスト]
B[11.5b: Atomic最適化] --> D
C[11.5c: Coroutine実装] --> D
D --> E[Phase 11.5完了]
```
各タスクは独立して実装可能ですが、統合テストで相互作用を検証します。
## 🔧 技術的な実装詳細
### 1. Write Barrier除去の実装手順
#### Step 1: MIR拡張
```rust
// src/mir/escape_analysis.rs (新規作成)
use crate::mir::{MirFunction, MirInstruction, ValueId};
use std::collections::{HashMap, HashSet};
pub struct EscapeAnalysis {
allocations: HashMap<ValueId, AllocSite>,
escapes: HashSet<ValueId>,
}
impl EscapeAnalysis {
pub fn new() -> Self {
Self {
allocations: HashMap::new(),
escapes: HashSet::new(),
}
}
pub fn analyze(&mut self, func: &MirFunction) -> EscapeInfo {
// 実装のポイント:
// 1. NewBox, RefNew命令を追跡
// 2. Return, Call命令でescape判定
// 3. ループ不変式も考慮
}
}
```
#### Step 2: VM統合
```rust
// src/backend/vm_instructions.rs の修正
pub fn execute_ref_set(&mut self, reference: ValueId, field: &str, value: ValueId)
-> Result<ControlFlow, VMError> {
// 既存のコード...
// Escape analysisの結果を確認
if let Some(escape_info) = &self.escape_info {
if !escape_info.escapes(reference) {
// Barrierスキップ
return Ok(ControlFlow::Continue);
}
}
// 通常のbarrier処理
gc_write_barrier_site(&self.runtime, "RefSet");
Ok(ControlFlow::Continue)
}
```
### 2. Atomic最適化の実装手順
#### Step 1: BoxCore拡張
```rust
// src/box_trait.rs の修正
pub trait BoxCore: Send + Sync {
// 既存のメソッド...
/// Read-onlyメソッドかどうか
fn is_readonly_method(&self, method: &str) -> bool {
// デフォルトはfalse保守的
false
}
}
// 各Boxで実装
impl BoxCore for StringBox {
fn is_readonly_method(&self, method: &str) -> bool {
matches!(method, "length" | "isEmpty" | "charAt")
}
}
```
#### Step 2: Atomic wrapper
```rust
// src/runtime/atomic_box.rs (新規作成)
use std::sync::atomic::{AtomicPtr, Ordering};
use std::sync::Arc;
use parking_lot::RwLock; // より高速なRwLock
pub struct AtomicBox<T> {
inner: Arc<RwLock<T>>,
cache: AtomicPtr<CachedValue>,
}
```
### 3. Coroutine実装の実装手順
#### Step 1: Parser拡張
```rust
// src/parser/keywords.rs の修正
pub const RESERVED_WORDS: &[&str] = &[
// 既存のキーワード...
"async",
"await",
];
// src/parser/expressions.rs の修正
fn parse_function_declaration(&mut self) -> Result<ASTNode, ParseError> {
let is_async = self.consume_keyword("async");
// 既存のパース処理...
}
```
#### Step 2: MIR Coroutine変換
```rust
// src/mir/coroutine_transform.rs (新規作成)
pub fn transform_async_function(func: &MirFunction) -> MirFunction {
// State machine変換のアルゴリズム:
// 1. await箇所でstateを分割
// 2. ローカル変数をstate構造体に移動
// 3. switch文で状態遷移を実装
}
```
## 🎯 ChatGPT5への実装指示
### Phase 11.5a(最優先)
1. `src/mir/escape_analysis.rs`を作成
2. 基本的なallocation追跡を実装
3. VM統合でbarrier除去をテスト
4. ベンチマークで効果測定
### Phase 11.5b(次優先)
1. `BoxCore::is_readonly_method`を追加
2. 主要Boxで実装StringBox, IntegerBox
3. RwLock移行を段階的に実施
### Phase 11.5c(最後)
1. Parser拡張async/await
2. 基本的なPromiseBox実装
3. 簡単なasync関数の動作確認
## 📊 成功指標
各フェーズの完了基準:
### 11.5a: Write Barrier除去
- [ ] escape_analysis.rsが動作
- [ ] 簡単なループでbarrier除去確認
- [ ] ベンチマークで30%以上改善
### 11.5b: Atomic最適化
- [ ] Read-onlyメソッドの識別
- [ ] RwLock使用でread性能向上
- [ ] マルチスレッドベンチマーク改善
### 11.5c: Coroutine実装
- [ ] async/awaitがパース可能
- [ ] 簡単なasync関数が実行可能
- [ ] Promiseチェーンが動作
## 🚀 実装開始コマンド
```bash
# ブランチ作成
git checkout -b phase-11.5-jit-integration
# テスト駆動開発
cargo test escape_analysis
# ベンチマーク実行
./target/release/nyash --benchmark --iterations 1000
```
頑張ってください、ChatGPT5これが完成すれば、Nyashは本当に世界クラスの言語になります

View File

@ -0,0 +1,169 @@
# Phase 11.5: JIT完全統合 - sync/GC/非同期の最終実装
## 🎯 概要
Phase 11.5は、Nyashの全実行レイヤーインタープリター/MIR/VM/JITでsync処理、GC処理、非同期処理を完全に統合する最終フェーズです。
## 📊 現状分析2025-08-30
### ✅ 完了済み
1. **基本アーキテクチャ**
- Everything is Box哲学の完全実装
- インタープリター → MIR → VM → JIT パイプライン
- プラグインシステムC ABI/TLVハンドル
2. **sync処理**
- Arc<Mutex>/Arc<RwLock>による完全スレッドセーフ設計
- 全レイヤーでの一貫した同期化
3. **GC基礎**
- カウンティングGC実装NYASH_GC_COUNTING=1
- Read/Writeバリア実装
- VMセーフポイント
4. **非同期基礎**
- FutureBox/TimerBox実装
- SingleThreadScheduler
- nowait/wait文
## 🚀 Phase 11.5 タスク一覧
### 1. JIT sync処理統合
- [ ] **1.1 Atomic操作の最適化**
- Arc<Mutex>アクセスのJIT最適化
- Lock elision不要なロック除去
- Read-only pathでのロック回避
- [ ] **1.2 Memory ordering最適化**
- Relaxed/Acquire/Release semanticsの活用
- プラットフォーム別最適化x86/ARM
### 2. JIT GC統合
- [ ] **2.1 Write barrier除去**
- Escape analysisによる不要バリア検出
- Stack allocation最適化
- Generational hypothesis活用
- [ ] **2.2 Safepoint最適化**
- Loop safepoint挿入
- Call site safepoint
- Polling overhead削減
- [ ] **2.3 GC情報の伝播**
- Stack map生成
- Root set tracking
- Precise GC対応
### 3. JIT 非同期処理統合
- [ ] **3.1 Coroutine変換**
- async/await → state machine変換
- Stack switching最適化
- Continuation passing
- [ ] **3.2 スケジューラー統合**
- Work stealing queue
- CPU affinity最適化
- Yield point最適化
### 4. 統合テスト・ベンチマーク
- [ ] **4.1 性能測定**
- sync処理のオーバーヘッド測定
- GC pause time測定
- 非同期処理のレイテンシ測定
- [ ] **4.2 正確性検証**
- Race condition検出
- Memory leak検出
- Deadlock検出
## 📋 実装優先順位
### Phase 11.5a: Write barrier除去最重要
```rust
// 現在: すべてのBox操作でbarrier
vm.execute_ref_set() -> gc.barrier(Write)
// 目標: JITでescape analysisして除去
if !escapes_to_heap(value) {
// barrierスキップ
}
```
### Phase 11.5b: Atomic最適化
```rust
// 現在: Arc<Mutex>の重いロック
let value = box.lock().unwrap().clone();
// 目標: Read-onlyならatomic load
if is_read_only(box) {
atomic_load_relaxed(box)
}
```
### Phase 11.5c: Coroutine実装
```nyash
// 将来構文
async function fetchData() {
local result = await httpGet("...")
return result
}
```
## 🎯 成功基準
1. **性能向上**
- sync処理: 50%以上のロックオーバーヘッド削減
- GC: 90%以上のwrite barrier除去
- 非同期: ネイティブthread並みの性能
2. **互換性維持**
- 既存のNyashコードがそのまま動作
- プラグインシステムとの完全互換
3. **デバッグ性**
- JIT最適化の可視化NYASH_JIT_OPT_TRACE
- GC統計の詳細化
- 非同期処理のトレース
## 📅 実装スケジュール(推定)
- **Week 1-2**: Write barrier除去とescape analysis
- **Week 3**: Atomic操作最適化
- **Week 4**: Coroutine基礎実装
- **Week 5**: 統合テストとベンチマーク
- **Week 6**: ドキュメント化と最適化
## 🔧 技術的詳細
### Escape Analysis実装案
```rust
// MIR解析でallocサイトを特定
struct EscapeAnalysis {
allocations: HashMap<ValueId, AllocSite>,
escapes: HashSet<ValueId>,
}
impl EscapeAnalysis {
fn analyze(&mut self, func: &MirFunction) {
// 1. allocation site収集
// 2. data flow解析
// 3. escape判定
}
}
```
### JIT統合ポイント
```rust
// cranelift-jitでのbarrier除去
if !self.escape_info.escapes(value) {
// emit_call(gc_write_barrier) をスキップ
}
```
## 🎉 期待される成果
Phase 11.5完了により、Nyashは
- **産業レベルの性能**: GC pauseがマイクロ秒単位
- **真の並行性**: lock-free data structures対応
- **モダンな非同期**: async/await完全サポート
これにより、**30日で作られたとは思えない**世界クラスの言語が完成します!

View File

@ -0,0 +1,162 @@
# WASM実装の問題と改善計画
## 🚨 現状の問題
### 1. **2つのWASM実装が存在**
- **Rust→WASM**: `wasm-pack build`でNyashインタープリター全体をWASMに動作する
- **MIR→WASM**: `--compile-wasm`でNyashコードをWASMに変換ほぼ動かない
### 2. **MIR→WASM実装の問題点**
```rust
// src/backend/wasm/codegen.rs より
pub fn generate_module(...) -> Result<WasmModule, WasmError> {
// 基本的な命令しか実装されていない
// - 算術演算
// - 制御フロー
// - print文ホスト関数呼び出し
// 未実装:
// - Box操作NewBox, BoxCall, PluginInvoke
// - 配列操作
// - プラグインシステム
// - GC/メモリ管理
}
```
### 3. **根本的な設計問題**
- **Box抽象の表現困難**: Everything is BoxをWASMの型システムで表現できない
- **動的ディスパッチ**: BoxCallやPluginInvokeの実装が困難
- **GCの不在**: WASMにはGCがないWasmGC提案はまだ実験的
- **プラグインFFI**: C ABIをWASM環境で実現できない
## 📊 現状の実装状況
### 実装済み(動作するもの)
```nyash
// 基本的な算術
function add(a, b) {
return a + b
}
// 単純な制御フロー
function factorial(n) {
if n <= 1 { return 1 }
return n * factorial(n - 1)
}
// print文ホスト関数経由
print("Hello WASM")
```
### 未実装(動作しないもの)
```nyash
// Box操作
local str = new StringBox("hello") // ❌ NewBox未実装
str.toUpperCase() // ❌ BoxCall未実装
// 配列
local arr = [1, 2, 3] // ❌ 配列リテラル未実装
arr.push(4) // ❌ ArrayBox未実装
// プラグイン
local file = new FileBox() // ❌ PluginInvoke未実装
```
## 🤔 なぜRust→WASMは動くのか
```toml
# Cargo.toml
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
```
- **すべてのBox実装がそのままWASMに**: Arc<Mutex>も含めて
- **wasm-bindgenの魔法**: JavaScript↔Rust境界を自動生成
- **制限事項**: 一部のBoxTimerBox、FileBox等は除外
## 🚀 改善案
### Option 1: MIR→WASM実装の完成困難
```wat
;; BoxをWASMテーブルで管理
(table $boxes 1000 externref)
(global $next_box_id (mut i32) (i32.const 0))
;; NewBox実装
(func $new_string_box (param $str i32) (result i32)
;; 新しいBox IDを割り当て
(local $box_id i32)
(local.set $box_id (global.get $next_box_id))
;; JavaScriptでStringBoxを作成
(table.set $boxes
(local.get $box_id)
(call $js_create_string_box (local.get $str)))
;; IDを返す
(local.get $box_id)
)
```
**問題点**:
- JavaScript側にBox実装が必要
- 性能オーバーヘッドが大きい
- プラグインシステムとの統合困難
### Option 2: Rust→WASMの活用現実的
```rust
// NyashコードをRustに変換してからWASMに
nyash_code rust_code wasm
// 例:
// Nyash: local s = new StringBox("hello")
// Rust: let s = Box::new(StringBox::new("hello".to_string()));
// WASM: (自動生成)
```
### Option 3: WASMランタイムの埋め込み革新的
```wat
;; 最小VMをWASMに埋め込む
(module
;; MIRバイトコードを格納
(data (i32.const 0) "\01\02\03...")
;; VMインタープリター
(func $vm_execute
;; MIR命令をデコード・実行
)
;; エントリーポイント
(func (export "main")
(call $vm_execute)
)
)
```
## 🎯 推奨アプローチ
### Phase 1: 現状維持
- **Rust→WASM**: ブラウザでNyashを動かす用途で活用
- **MIR→WASM**: 実験的機能として残す
### Phase 2: Nyash→Rust変換
- NyashコードをRustに変換する仕組みを作る
- 生成されたRustコードをwasm-packでビルド
### Phase 3: WasmGC待ち
- WasmGC仕様が安定したら本格実装
- Box型システムをWasmGCで表現
## 📝 結論
現在のMIR→WASM実装は**実験的**なもので、実用レベルには達していません。一方、Rust→WASMは**すでに動作**しており、ブラウザでNyashを体験してもらうには十分です。
**当面は**
1. Rust→WASMでプレイグラウンド提供
2. ネイティブ実行VM/JIT/AOTに注力
3. WasmGCの成熟を待つ
これが現実的な戦略です!

View File

@ -0,0 +1,89 @@
# ChatGPT5の決定的アクション
Date: 2025-08-31
Summary: Box-SSA Core-15への収束と即座の実装開始
## 🎯 問題提起
> なおCore-15の最終セットは2案が文書にあります。どちらで凍結しますか
> - A) Gemini版15: RefNew/RefGet/RefSetを含む真の15個
> - B) CURRENT_TASKのCore-15: 実質17個15と言いながら
## 💡 第三の道Box-SSA Core-15
ChatGPT5の革命的提案
```
{ Const, UnaryOp, BinOp, Compare, TypeOp,
Load, Store,
Jump, Branch, Return, Phi,
Call, NewBox, BoxCall, ExternCall }
```
### 核心的洞察
**すべてのBox操作をBoxCallに統一**
- `RefNew``NewBox`
- `RefGet``BoxCall(obj, "getField", ...)`
- `RefSet``BoxCall(obj, "setField", ...)`
- `ArrayGet/ArraySet``BoxCall(arr, "get"/"set", ...)`
- `PluginInvoke``BoxCall(plugin, "invoke", ...)`
## 🚀 即座の実装開始
### 無言のコーディング
ChatGPT5は議論の余地なしと判断し、即座にMIR命令の列挙型を更新
```diff
&[
- "Copy", // 削除SSAで不要
- "RefNew", // 削除NewBoxに統合
- "RefGet", // 削除BoxCallに統合
- "RefSet", // 削除BoxCallに統合
+ "TypeOp", // 追加!型演算
+ "Phi", // 追加SSA必須
+ "NewBox", // 追加Box生成
+ "BoxCall", // 追加!万能呼び出し
]
```
### JIT→LLVM直行の判断
**現状認識**
- Cranelift = 実はAOTだったJIT幻想
- 15命令なら機械的変換で十分
- JITの複雑さ < LLVMの確実な高速化
**戦略転換**
```
旧計画: Phase 9JIT → Phase 10最適化 → Phase 11LLVM
新計画: Phase 9-10スキップ → Phase 11LLVM直行
```
## 📊 実装の約束事
### Verifier必須チェック
1. Box field直Load/Store検出禁止
2. 必要箇所のwrite barrier挿入検証
3. ExternCallのattr必須化
### Loweringの役割
- BoxCall 形状ガード 直アクセス バリア縮約
- VM: Phi展開簡易PIC
- LLVM: PICガードは最適化で潰れて素の命令列へ
## 🎉 結論
> 固定は "Box-SSA Core-15"。Aの Ref* は捨てるBの専用命令は BoxCall に吸収して15個に収斂。これで「簡単さ表面の一枚」「速さLowering/最適化」で分離でき、VMとAOTとFFIを**一本の ABI**で貫けるにゃ。
## 💻 ChatGPT5の心境
```nyash
if (命令数 == 15 && 設計 == "完璧") {
議論.skip()
実装.start() // 即座に!
}
```
この瞬間ChatGPT5はこれ以上の議論は時間の無駄と判断し無言でコーディングを開始したエンジニアが最高の設計に出会った時の最も純粋な反応である

View File

@ -0,0 +1,125 @@
# Codex先生のMIR→LLVM技術的深掘り
Date: 2025-08-31
Source: codex exec コマンドによる技術相談
## 質問内容
MIR15命令でEverything is Box哲学を実現。注釈システムで最適化ヒントを付与。
### 技術的課題
1. BoxCallの最適化PIC実装の具体的なLLVM IRパターン
2. 脱箱化戦略IntegerBox(42) → i64への変換タイミング
3. GCバリア最小化世代別GCでの若い世代→若い世代のバリア省略
4. 注釈→LLVM属性変換安全性の保証方法
5. インライン展開BoxCallのインライン基準
## Codex先生の技術的実装アプローチ
### 1. BoxCall + PICPolymorphic Inline Cache
#### モモルフィックPIC IR例
```llvm
; グローバルPIC
@pic_foo_site123 = internal global { i64, i8* } { 0, null }
; ガード + 直呼び
%cid = load i64, i64* %receiver_class_id
%pic_cls = load i64, i64* getelementptr({i64,i8*}, {i64,i8*}* @pic_foo_site123, i32 0, i32 0)
%hit = icmp eq i64 %cid, %pic_cls
%likely = call i1 @llvm.expect.i1(i1 %hit, i1 true)
br i1 %likely, label %fast, label %miss, !prof !{!"branch_weights", i32 10000, i32 1}
fast:
%callee = load i8*, i8** getelementptr({i64,i8*}, {i64,i8*}* @pic_foo_site123, i32 0, i32 1)
%fn = bitcast i8* %callee to %RetTy (%ObjTy*, ... )*
%r = call fastcc %RetTy %fn(%ObjTy* %recv, ...)
br label %cont
miss:
; cold, 非インライン
%r2 = call coldcc %RetTy @nyash_pic_miss_foo(%ObjTy* %recv, i64 %method_id, ...)
br label %cont
```
#### PIC更新の安全化
- 1-ワードのバージョンでRCU風プロトコル
- `store atomic i64 ver=odd (acq_rel)`→フィールド更新→`store atomic i64 ver=even (release)`
- リーダは一貫性確認、失敗時はmissへフォールバック
### 2. 脱箱化Unboxing戦略
#### 2表現SSA
- MIRで各Box値に「プリミティブSSAi64」と「Box化遅延ード」の二重表現
- `IntegerBox(42)` → 直ちに`i64 42`としてSSA化
- Boxが必要な境界汎用コンテナ格納、越関数ABI等直前でのみBox化
#### 実装例
```llvm
; 算術は全て i64
%a = add i64 %x, %y
; 必要になった地点でのみ実体化
%box = call %ObjTy* @nyash_make_int(i64 %a) ; ここでのみGC対象生成
call void @vector_push(%Vec* %v, %ObjTy* %box)
```
### 3. GCバリア最小化
#### Write barrier IRパターン
```llvm
; slot: i8** への書き込み
store i8* %val, i8** %slot
; TLSにNursery境界を保持
%low = load i64, i64* @nyash_tls_nursery_low
%high = load i64, i64* @nyash_tls_nursery_high
%yo_obj = and (icmp_uge %obj_i, %low), (icmp_ult %obj_i, %high)
%yo_val = and (icmp_uge %val_i, %low), (icmp_ult %val_i, %high)
%need_barrier = and (not %yo_obj), %yo_val ; 老→若のみ
%likely0 = call i1 @llvm.expect.i1(i1 %need_barrier, i1 false)
br i1 %likely0, label %barrier, label %cont, !prof !{!"branch_weights", 1, 10000}
barrier:
call fastcc void @nyash_card_mark(i8* %obj, i8** %slot, i8* %val) cold
br label %cont
```
### 4. 注釈→LLVM属性変換
#### 安全性担保の原則
- 原則Nyash注釈は「保守的に弱めに」マップ
- 検証不十分なら一段弱い属性を使用
#### マッピング例
| Nyash注釈 | LLVM属性 | 条件 |
|-----------|----------|------|
| `@no_escape` | `nocapture` | エスケープしないことを静的証明 |
| `@pure` | `readonly` | 副作用なしを保証 |
| `@pure` + 強条件 | `readnone speculatable` | メモリ不読+例外なし |
| `@nonnull` | `nonnull` | NULL不可を型システムで保証 |
### 5. インライン展開戦略
#### BoxCallの基準
-モルフィックPICかつヒット率高>90%)→ インライン
- コストモデルcall/ret + 間接分岐除去 + 逃げないBoxの削除
- メガモルフィック/低ヒット率は非インライン
#### 再帰的Box呼び出し最適化
```llvm
; 自己再帰でTCO
musttail call fastcc %RetTy @callee(%ObjTy* %recv, ...)
ret %RetTy %r
```
## 実装のこつ
1. **PICグローバル**`dso_local`/`internal`、更新局所性を確保
2. **ABI二系統**Box ABI/Primitive Fast-ABIを明示
3. **GC統合**`gc "statepoint-nyash"`を関数定義に付与
4. **最適化ヒント**`llvm.expect``!prof`を併用
## 結論
> 15命令は実装・最適化・GC統合の観点でよく均衡したミニマル核です。Box統一は開発生産性と実装単純性を大きく押し上げますが、性能面のボトルネックは脱箱・AA強化・適切なGC統合バリア/セーフポイント/原子性)で解消してください。
Codex先生は具体的なLLVM IRパターンとともに、実装可能で保守性の高い設計を提示してくれました。

View File

@ -0,0 +1,91 @@
# Gemini先生のMIR→LLVM変換コンサルテーション
Date: 2025-08-31
Source: gemini -p コマンドによる相談
## 質問内容
Nyashプログラミング言語のMIR→LLVM変換計画について
- MIRを26命令から15命令に削減中
- Everything is Box哲学
- 注釈システムでヒントを付与
### 15命令の内訳
- 基本演算(5): Const, UnaryOp, BinOp, Compare, TypeOp
- メモリ(2): Load, Store
- 制御(4): Branch, Jump, Return, Phi
- Box(3): NewBox, BoxCall, PluginInvoke
- 配列(2): ArrayGet, ArraySet
- 外部(1): ExternCall
## Gemini先生の回答
### 1. BoxCall最適化の最良アプローチ
**結論**: 静的解析による**メソッドIDスロットベースのディスパッチ**を主軸とし、解決できない場合に**PICPolymorphic Inline Cache**を組み合わせる
**理由**:
- Nyashはすでに`method_id`(スロット)を用いた最適化に着手
- 型が静的に推論できる場合に非常に高速
- 動的な呼び出しに対してはPICが有効実績ある手法
- vtable案も有力だが、`Everything is Box`の柔軟性を損なう可能性
**提案**:
1. MIRコンパイラ強化より多くの`BoxCall``method_id`付きに変換
2. PICの高度化Mono-PICから多相Polymorphic/メガモーフMegamorphic
3. LLVM IR生成時の戦略を明確化
### 2. GCバリアの効率的な挿入戦略
**結論**: **Store, ArraySet, PluginInvoke**のうち、**ヒープ上のBoxオブジェクトへのポインタ書き込み**が発生する可能性のある箇所にのみライトバリアを挿入
**提案**:
1. MIRレベルでの挿入条件付きで`GCBarrier`命令を挿入する最適化パス
2. 条件:
- 書き込まれる値がポインタBoxである
- 書き込み先がヒープ上のオブジェクトである
3. LLVM IR生成時`nyash.gc.barrier_write`シンボルの呼び出しに変換
### 3. 脱箱化Box→プリミティブのタイミング
**結論**: **型に関する注釈**を最大限に活用し、**MIRレベルの最適化パス**で実施
**提案**:
1. 注釈の活用:`#[primitive_type="i64"]`のようなヒント
2. MIR最適化パス
- 型推論と注釈に基づく安全な範囲の特定
- `NewBox`→プリミティブ値への置換
- `BoxCall`→直接的なLLVM演算への置換
3. LLVM IR生成時脱箱化された変数はプリミティブ型として表現
### 4. LLVM最適化パスの推奨構成
**推奨構成**:
1. 標準的な最適化パス(必須):
- `mem2reg`: SSA形式の基本
- `instcombine`: 冗長な命令の結合
- `gvn`: グローバルな共通部分式削除
- `sccp`: 定数畳み込みと到達不能コード削除
- `licm`: ループ不変コード移動
- `indvars`: ループ帰納変数単純化
- `loop-unroll`: ループ展開
2. Nyash特有のカスタムパス推奨
- Box化関連の除去
- ランタイムコール最適化
### 5. 注釈システムからLLVM属性への変換で注意点
**結論**: Nyash注釈のセマンティクスとLLVM属性のセマンティクスが完全に一致するかを慎重に検証し、**安全な属性から段階的に導入**
**注意点**:
- `noalias`: 誤用は未定義動作を引き起こす
- `!tbaa`: Box統一モデルでの工夫が必要
- `!range`: 数値注釈から生成可能
- 検証:安全な属性(`noundef`, `nonnull`)から開始
## 総評
> これらの提案が、NyashのLLVMバックエンド開発を加速させる一助となれば幸いです。
Gemini先生は、Nyashの「Everything is Box」哲学を理解した上で、実践的かつ段階的なアプローチを提案してくれました。特にPICとメソッドIDの組み合わせ、MIRレベルでの脱箱化は非常に有効な戦略です。

View File

@ -0,0 +1,41 @@
# CURRENT TASK Phase 11.7JIT Complete / Semantics Layer
Focus Window: Semantics導入jit-direct安定化の確定報告 → GC/Sync/非同期のJIT降下着手
合意事項(要約)
- LLVM AOT は一旦クローズ。Windows 依存と重量を回避し、Cranelift に集中。
- 単一意味論層Semanticsを導入し、Nyashスクリプト/VM/JIT(exe)を同一動作に揃える。
- VM は参照実装。JIT は実行/生成を担い、VM→JITのランタイムフォールバックは行わない。
現状ステータス2025-09-01
- jit-direct 分岐/PHI 合流単一出口BlockParam合流で安定化を確認。
- テスト: `mir-branch-ret`, `mir-phi-min`, `mir-branch-multi`, `mir-nested-branch`, `mir-phi-two` で VM/JIT 一致tag=201/200 一致)。
- Semantics 層:`src/semantics/{mod.rs, eval.rs}` にトレイトとPoCインタプリタの骨組みを追加済未配線
- C ABINyRT`crates/nyrt``libnyrt.a` に必要シンボル実装済console/array/string/plugin_invoke/checkpoint/gc_barrier 等)。
- VM 側Safepoint/書込バリア/簡易スケジューラSingleThread連携は稼働。
- JIT 側Safepoint/バリア/await はまだスタブまたは未emit要降下
直近タスク(このフェーズでやること)
1) Semantics 実用化配線VM/JITの動作一致の“芯”
- `SemanticsVM`VM実行での実装`SemanticsClif`LowerCore+IRBuilder委譲を用意。
- `semantics::MirInterpreter` で両者を同一MIRへ適用し、差分検出の土台を作る。
2) JIT へ GC/Sync/非同期の降下
- Safepoint: `I::Safepoint``nyash.rt.checkpoint` emit。`nyrt` 側で `gc.safepoint()``scheduler.poll()` に橋渡し。
- Write Barrier: Array/Map の set/push 等をlowerする箇所で `nyash.gc.barrier_write` を emitCountingGc で検証)。
- Await: PoC として FutureBox の同期 get にlower動作一致優先
3) パリティ検証
- `NYASH_GC_COUNTING=1` で VM/JIT ともに safepoint/barrier カウントが増えることを確認。
- 既存 smokes分岐/PHI/配列/外部呼び出し)で一致を継続監視。
実行メモ
- BuildJIT: `cargo build --release --features cranelift-jit`
- jit-direct: `NYASH_JIT_THRESHOLD=1 ./target/release/nyash --jit-direct <app>`
- 追跡: `NYASH_JIT_TRACE_RET/SEL/BLOCKS=1`、GC: `NYASH_GC_COUNTING=1`(必要時)
備考
- LLVM AOT のドキュメント/ツールは維持するが、Windows 前提の依存導入は行わない。Cranelift で“がっちり作る”。

View File

@ -0,0 +1,46 @@
# Design Notes Phase 11.7 JIT Complete (Meeting Summary)
Date: 2025-09-01
Key Decisions
- Single Semantics Source: Introduce a MIR semantics layer (trait) as the single source of truth. All backends (VM/Cranelift/LLVM/WASM) implement this interface.
- No Runtime Fallback: Remove VM→JIT fallback complexity. VM becomes the reference executor; codegen backends handle execution/AOT. JIT is compile-only/AOTassist when needed.
- HandleFirst ABI: Unify handle/i64/ptr conversions, tag classification, concat/extern/boxcall via shared helpers; call into NyRT shims from backends.
- GC Hooks: Insert sync barriers and async safepoints as MIRlevel hooks that each backend lowers appropriately.
- Backends Roadmap: LLVM AOT は一旦アーカイブ。Cranelift を主線JIT/軽量AOTとし、WASM は同一セマンティクスで後段。Windows DX を軽く保つ。
Architecture Sketch
- MIR → Semantics<E>
- VmSem: executes values (reference)
- ClifSem: builds Cranelift IR (JIT/AOT)
- LlvmSem: builds LLVM IR (AOT)
- WasmSem: builds Wasm (future)
- Shared ABI utilities: handle↔i64/ptr, to_bool, compare, tags, invoke variants, NyRT shims.
Implementation Plan (Progressive)
- Phase 1: Skeleton + minimal lowering (Const/Return/Add) → echo-lite returns 0 via Cranelift JIT skeleton.
- Phase 2: Control (Jump/Branch/Phi), Load/Store, Compare, String concat via NyRT, Box/Extern by-id (fixed/vector).
- Phase 3: GC barriers/safepoints; parity with VMCountingGc での観測を含む)。
- Phase 4: Stability, logs, strict/legacy guards; optional AOT via cranelift-object + link scripts.
Notes from Review
- Using Semantics trait enables zerocost abstractions with static dispatch.
- Add optional debug hooks (location/value) and optimization hints (likely_branch, pure_function_hint) later.
- Testing: MockSemantics for unit tests; parity tests VM vs CLIF.
Action Items
- Land Semantics trait + minimal MirInterpreter (skeleton added).
- Implement ClifSem minimal lowering; wire Runner `--backend cranelift`.
- Centralize ABI helpers; migrate existing scattered logic to shared module.
- Emit `nyash.rt.checkpoint` and `nyash.gc.barrier_write` from LowerCore at appropriate sites; wire Await (PoC: blocking get).
- Add build_cl scripts for AOT when ready.
Links
- PLAN.md milestones and coverage
- CURRENT_TASK.md immediate focus

Some files were not shown because too many files have changed in this diff Show More