📚 Phase 12: Nyashスクリプトプラグインシステム設計と埋め込みVM構想

## 主な成果
- Nyashスクリプトでプラグイン作成可能という革命的発見
- C ABI制約の分析と埋め込みVMによる解決策
- MIR/VM/JIT層での箱引数サポートの詳細分析

## ドキュメント作成
- Phase 12基本構想(README.md)
- Gemini/Codex先生の技術分析
- C ABIとの整合性問題と解決策
- 埋め込みVM実装ロードマップ
- 箱引数サポートの技術詳細

## 重要な洞察
- 制約は「リンク時にC ABI必要」のみ
- 埋め込みVMでMIRバイトコード実行により解決可能
- Nyashスクリプト→C ABIプラグイン変換が実現可能

Everything is Box → Everything is Plugin → Everything is Possible!
This commit is contained in:
Moe Charm
2025-08-30 22:52:16 +09:00
parent 7a0f9bd432
commit c13d9c045e
82 changed files with 5842 additions and 138 deletions

View File

@ -80,6 +80,55 @@
6) ドキュメント/サンプル更新
- Handle-First のガイドと最小AOT手順の追記。
### 10.5c ドキュメント/サンプル 追加(本スナップショット)
- FFI最小仕様a0/a1/a2, 戻りTLVを短文化: `docs/reference/abi/ffi_calling_convention_min.md`
- birth引数の一般化メモ可変長TLV/例外伝搬): `docs/ideas/new-features/2025-08-30-birth-args-tlv-generalization.md`
- Python最小チェーンの追加:
- VM: `examples/py_min_chain_vm.nyash`
- AOT: `examples/aot_py_min_chain.nyash`
### 10.5d AOT統合 仕上げ(今回)
- ガイド追加: `docs/guides/build/aot_quickstart.md`CLI/スクリプト/内部フロー/FAQ
- by-nameシム整理: nyrtの `nyash_plugin_invoke_name_{getattr,call}_i64` をFFI要約へ反映
- スモーク更新: `tools/smoke_aot_vs_vm.sh` に Python最小チェーンを追加VM側は `NYASH_PY_AUTODECODE=1`
- 今後: nyrtシムのTLV拡充bytes/N引数、Windowsのプラグイン探索微調整
### 10.5e 小仕上げ(今回)
- nyrtシム TLV拡充: BufferBox→bytes(tag=7) 自動エンコード、3引数目以降はレガシー引数からTLVに詰める暫定N引数対応
- Windows探索調整: EXE起動時に PATHへexe/`plugins/`を追加、`PYTHONHOME` 未設定時は `exe\python` を自動採用存在時。相対PYTHONHOMEはexe基準に正規化
### 次フェーズ: 10.6Thread-Safety / Scheduler
- 計画: docs/development/roadmap/phases/phase-10.6/PLAN.txt新規
- 10.6a 監査: Array/Map/Buffer/NyashRuntime/Scheduler の共有戦略Arc+RwLock/Mutexを確認し、未整備箇所をTODO化
- 10.6b スケジューラ: SingleThreadScheduler を Safepoint で `poll()` 連携(観測: `NYASH_SCHED_DEMO/TRACE/POLL_BUDGET`
- 10.6c 並列GC設計: per-thread roots / safepoint協調 / カードマーキングの段階導入メモ確定
### 橋渡し: 10.7 Python Nativeトランスパイル / All-or-Nothing
- 方針と計画: docs/development/roadmap/phases/phase-10.7/PLAN.txt新規
- 二本立て明確化: 実行系現行PyRuntimeBoxと トランスパイル系Python→Nyash→MIR→AOTを併走。自動フォールバック無し
- サブフェーズ: C1 Parser1週→ C2 Compiler Core2週→ C3 CLI配線3日→ C4 テスト(並行)
- 既存導線の活用: 生成Nyashは既存 `--compile-native` でAOT化Strict
### Nyash-only パイプライン(作業場 / 最小導線)
- 目的: すべてNyashで書き、即実行・即修正できる足場を先に用意
- 追加ファイル: tools/pyc/
- PythonParserNy.nyashPyRuntimeBox経由で ast.parse/dump。NYASH_PY_CODE を参照)
- PyIR.nyashIR最小ヘルパ/ PyCompiler.nyashNyash側コンパイラ骨組み/ pyc.nyashエントリ
- Parser/Compiler Rustプラグインは雛形として併存将来削減。当面はNyash実装を優先
### 次の順番(小粒で進める)
1) Parser JSON→IR 変換の最小実装def/return。tools/pyc/PyCompiler.nyash に追加env NYASH_PY_CODE を Pythonで解析→IR生成
2) IR→Nyash 生成の最小拡張Return定数→Return文字列/数値に対応、If/Assignは後続
3) All-or-NothingのStrictスイッチunsupported_nodes 非空ならErr。開閉はenvで制御
4) CLI隠しフラグ `--pyc/--pyc-native` を追加し、Parser→Compiler→AOT を一本化内部で現行AOTを使用
5) サンプル/回帰: tools/pyc の最小ケースをVM/AOTで回し、差分を記録
### Python AOTサンプルの追加最小
- `examples/aot_py_min_chain.nyash`import→getattr→call
- `examples/aot_py_result_ok.nyash`returns_result: Ok
- `examples/aot_py_result_err.nyash`returns_result: Err
- kwargs暫定ブリッジenv eval + **dict: `examples/aot_py_eval_kwargs_env.nyash`
## 🔧 実行方法(再起動手順)
```bash
cargo build --release --features cranelift-jit

View File

@ -6,9 +6,9 @@ Purpose: Claude×Copilot×ChatGPT協調開発の総合ロードマップ
## 📍 現在位置
- **現在フェーズ**: Phase 8.6 VM性能改善進行中
- **次フェーズ**: Phase 9 JIT実装
- **詳細タスク**: [CURRENT_TASK.md](../../current/CURRENT_TASK.md)
- 現在フェーズ: Phase 10.5b ネイティブビルド基盤の固めMIR→VM→AOTの足固め
- 次フェーズ: Phase 10.5c Handle-First PluginInvokePython統合の実装着手
- 備考: 旧10.1系10.1c/dは「PythonをNyashで動かすフェーズ」の設計資料Archived。順番を入れ替え、先にネイティブビルド基盤を完成させています。
## 🗺️ フェーズ概要
@ -219,4 +219,4 @@ nyash bid gen --target llvm bid.yaml # AOT用declare生成LLVM実装時
- 🔄 **Phase 8.6 VM性能改善を最優先** (進行中)
- 📦 **Phase 9.8 BIDレジストリ** (Phase 8.6完了後の次期重点)
- 🔍 **Phase 10 Cranelift JIT** (主経路として確定)
- 🌟 **統一ロードマップ化** (phasesフォルダに集約)
- 🌟 **統一ロードマップ化** (phasesフォルダに集約)

View File

@ -1,5 +1,7 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
Note: 本来は「PythonをNyashで動かすフェーズパーサー統合」の位置づけでしたが、現在は順番を変更し、先に 10.5bMIR→VM→ネイティブビルド基盤を進めています。
# Phase 10.1c - パーサー統合実装
## 🎯 このフェーズの目的
@ -60,4 +62,4 @@ print(json_ast) // JSON ASTが表示される
```
## ⏭️ 次のフェーズ
→ Phase 10.1d (Core実装)
→ Phase 10.1d (Core実装)

View File

@ -1,5 +1,7 @@
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
Note: 本来は「PythonをNyashで動かすフェーズCore実装」の位置づけでしたが、現在は順番を変更し、先に 10.5bMIR→VM→ネイティブビルド基盤を進めています。
# Phase 10.1d - Core実装Phase 1機能
## 🎯 このフェーズの目的
@ -71,4 +73,4 @@ def append_to_list(item, lst=[]): # 定義時に評価!
```
## ⏭️ 次のフェーズ
→ Phase 10.1e (トランスパイラー)
→ Phase 10.1e (トランスパイラー)

View File

@ -6,15 +6,16 @@
- 10.5 README全体像: ./README.md
- 10.5a Python ABI 設計: ./10.5a-ABI-DESIGN.md
- 10.5b ネイティブビルド基盤: ./10.5b-native-build-consolidation.md
- 10.5c PyRuntimeBox / PyObjectBox 実装(予定)
- 現在フォーカス: 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

@ -56,6 +56,12 @@
- 参照管理: `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)` を提供
@ -72,6 +78,10 @@
- テスト: GILの再入・参照カウントリーク検知・例外伝搬・多プラットフォーム
- ドキュメント: 使用例、制約GIL/スレッド、AOT時のリンク・ランタイム要件
追加済みサンプル(最小チェーン)
- VM: `examples/py_min_chain_vm.nyash`import→getattr→call→println
- AOT: `examples/aot_py_min_chain.nyash`import→getattr→call→return
## 🎯 DoD定義
- NyashからPythonコードを評価し、PyObjectをHandleで往復できる
- 代表的なプロパティ取得/呼び出しROがJIT/VMで動作

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/development/roadmap/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.nyash` → `Result: 4`math.sqrt(16)
- VM: `examples/py_min_chain_vm.nyash` → 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.nyash`, `examples/py_min_chain_vm.nyash`(既存)
- ツール: `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,67 @@
# Phase 10.7 Python Native 再スタート計画(合意版 / txt
目的: 現行の Plugin-FirstPyRuntimeBox/PyObjectBox, Handle-First/TLVを維持しつつ、トランスパイル路線Python→Nyashを“All or Nothing”原則で段階導入。10.6の足場Thread-Safety/Scheduler上で、AOT配布体験に直結する最短ラインを構築する。
====================
A) 方針(判断)
====================
- 二本立てを明確化:
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に対して適用

View File

@ -0,0 +1,148 @@
# Phase 10.7 - True Python Native via Plugin Boxes
## 🎯 概要
PythonコードをNyashで**本当にネイティブ実行**する。CPythonへの依存なしに、Pythonコードが完全にNyash MIR/JIT経由で機械語として実行される。
### 現状 vs 理想
**現状Phase 10.6**: PyRuntimeBox → libpython呼び出し
**理想Phase 10.7**: Python → Nyashスクリプト → MIR → ネイティブ
## 🏗️ アーキテクチャ:トランスパイル方式
```
Python AST → CorePy IR → Nyash AST → Nyashスクリプト
```
### なぜトランスパイル?
1. **透明性**: 生成コードが見える・デバッグできる・手を加えられる
2. **既存資産活用**: Nyashコンパイラの最適化を自動享受
3. **教育的価値**: PythonとNyashの対応が学習価値を持つ
4. **段階的改善**: 生成コードの品質を徐々に向上
### プラグインBox群
- **PythonParserBox**: Python → AST変換
- **PythonCompilerBox**: AST → Nyashスクリプト生成
- **py_runtime.ny**: Pythonセマンティクス保持ライブラリ
## ⚠️ 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 10.7a - Parser Plugin1週間
- PythonParserBoxの実装
- Python AST → ASTBox変換
- テレメトリー基盤
### Phase 10.7b - Compiler Core2週間
**Phase 1機能必須**
- 関数定義、条件分岐、ループ
- 演算子、関数呼び出し
- Python固有LEGB、デフォルト引数、for/else
### Phase 10.7c - Validation & Testing1週間
- コンパイル可能性の事前検証
- Differential testingCPythonと比較
- 明確なエラーメッセージ
### Phase 10.7d - Coverage拡大3-4週間
**Phase 2**: 例外処理、with文、comprehensions
**Phase 3**: 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完了時
```
Compilable files: 15/100 (15%)
Performance (numeric): 10x faster than CPython
Correctness: 100% (differential testing)
```
### 最終目標Phase 3
```
Coverage: 95%+ of common patterns
Performance: 5-20x faster
Distribution: Single binary, no CPython
```
## 🚀 クイックスタート
```bash
# プラグイン作成
cd plugins/
cargo new nyash-python-parser-plugin --lib
# 最小実装
[dependencies]
pyo3 = { version = "0.22", features = ["auto-initialize"] }
nyash-plugin-sdk = { path = "../../crates/plugin-sdk" }
# テスト実行
cargo build --release
../../target/release/nyash test_parser.nyash
```
## 💡 創造的可能性
### ハイブリッドプログラミング
```python
@nyash.vectorize # PythonデコレータがNyashのSIMD生成
def matrix_multiply(a, b):
return a @ b
```
### 言語の共進化
- Nyashが「Pythonで最も使われるイディオム」から学習
- Pythonに「Nyash-aware」コーディングスタイル誕生
### 教育的インパクト
左にPython、右にリアルタイムNyash変換のPlayground
## 📚 参考資料
- **archive/gemini-analysis-transpile-beauty.md** - 創造性分析
- **archive/codex-analysis-technical-implementation.md** - 技術分析

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,295 @@
# Python Native実装例
## 🎯 実装イメージ
### 使用例1: 基本的な関数のネイティブ化
```nyash
// example1_basic.nyash
// 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.nyash
// コンパイルできるかどうか事前に判定
// 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.nyash
// 実行しながら徐々に最適化
// 型推論付きコンパイラー
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.nyash
// 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.nyash
// 開発時のデバッグ支援
// デバッグモード有効
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,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.nyash
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.nyash
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,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

@ -5,6 +5,7 @@ Whats added
- 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:

View File

@ -0,0 +1,142 @@
# 埋め込みVMでの箱引数サポート
## 🎯 結論:完全にサポート可能
現在のMIR/VM/JIT/プラグインすべてで**箱は箱を引数にできる**仕組みが確立されており、埋め込みVMでも同じパターンで実装可能です。
## 📊 各層での箱引数の扱い
### 1. Nyashスクリプトレベル
```nyash
// 箱を引数に取るメソッド
box Processor {
process(inputBox, configBox) {
// inputBoxもconfigBoxも箱インスタンス
local data = inputBox.getData()
local settings = configBox.getSettings()
return me.transform(data, settings)
}
}
```
### 2. MIRレベル
```
; box1.process(box2, box3)
%4 = BoxCall %1.process(%2, %3)
```
### 3. 埋め込みVMでの実装
#### バイトコード表現
```c
// BoxCall命令: [op][dst][recv][method_id:2][argc][args...]
// 例: box1.process(box2, box3)
0x20 // OP_BOXCALL
0x04 // dst: %4
0x01 // recv: %1 (box1)
0x00 0x10 // method_id: 16 (process)
0x02 // argc: 2
0x02 // arg[0]: %2 (box2)
0x03 // arg[1]: %3 (box3)
```
#### 実行時処理
```c
// 埋め込みVMでの箱引数処理
int nyvm_execute_boxcall(NyashEmbeddedVM* vm, ...) {
// レシーバー取得
NyVMValue* recv = &vm->values[recv_idx];
// 引数をTLVエンコード
for (int i = 0; i < argc; i++) {
NyVMValue* arg = &vm->values[args[i]];
if (arg->type == NYVM_TYPE_HANDLE) {
// 箱引数はハンドルとしてエンコード
uint32_t type_id = get_type_id_from_handle(arg->value.h);
uint32_t inst_id = get_instance_id_from_handle(arg->value.h);
encode_handle(&tlv, type_id, inst_id);
} else {
// プリミティブ値
encode_primitive(&tlv, arg);
}
}
// C ABIプラグイン呼び出し
return nyash_plugin_invoke(...);
}
```
## 🔄 ハンドル管理の詳細
### 1. ハンドルレジストリ
```c
// グローバルハンドルテーブル
typedef struct {
uint32_t type_id; // Box型ID
uint32_t instance_id; // インスタンスID
uint8_t flags; // GC/所有権フラグ
} HandleEntry;
static HandleEntry g_handles[MAX_HANDLES];
// 新しい箱インスタンスの登録
uint64_t register_box_handle(uint32_t type_id, uint32_t instance_id) {
uint64_t handle = allocate_handle();
g_handles[handle] = (HandleEntry){
.type_id = type_id,
.instance_id = instance_id,
.flags = HANDLE_OWNED
};
return handle;
}
```
### 2. プラグイン間の箱共有
```c
// プラグインAが箱を返す
int plugin_a_create_box(uint8_t* result, size_t* result_len) {
// 新しい箱を作成
uint32_t type_id = 100; // CustomBox
uint32_t inst_id = create_instance();
// TLVエンコード
encode_handle(result, type_id, inst_id);
return 0;
}
// プラグインBが箱を受け取る
int plugin_b_process(const uint8_t* args, size_t args_len) {
// TLVデコード
uint32_t type_id, inst_id;
decode_handle(args, &type_id, &inst_id);
// 箱を使用
process_box(type_id, inst_id);
return 0;
}
```
## 💡 重要なポイント
### 1. 型安全性
- ハンドルには型情報type_idが含まれる
- 実行時の型チェックが可能
### 2. 所有権管理
- ハンドルは参照カウント or GC管理
- プラグイン間で安全に共有
### 3. 相互運用性
- ネイティブBox ↔ スクリプトBox間で透過的
- 同じハンドル機構を使用
## 🎯 結論
埋め込みVMでも
1. **箱は箱を引数に取れる**(ハンドル経由)
2. **型情報を保持**type_id
3. **プラグイン間で共有可能**instance_id
4. **C ABIと完全互換**TLVエンコード
これにより、Nyashスクリプトで書いた高度なBoxコンポジションも、C ABIプラグインとして動作します

View File

@ -0,0 +1,106 @@
# 🚨 重大な設計問題スクリプトプラグインとMIR/EXEの非互換性
## 問題の本質
**MIR/JIT/AOTEXEは、C ABIの関数しか呼び出せない。**
```
現実のフロー:
MIR → JIT → C関数呼び出し固定アドレス→ ネイティブコード実行
MIR → AOT → EXE内のC関数静的リンク→ ネイティブコード実行
不可能なフロー:
MIR → ??? → Nyashスクリプト実行インタープリター必要
```
## なぜスクリプトプラグインは動作しないのか
### 1. インタープリター依存
```nyash
// スクリプトプラグイン
export box CustomMath {
sin(x) { return me._math.sin(x) }
}
```
**実行にはNyash VMが必要** → EXEに埋め込めない
### 2. 動的型システム
- C ABI: 静的型i32, i64, double等
- Nyashスクリプト: 動的型Box
- 型変換にはランタイムが必要
### 3. メモリ管理
- C ABI: 手動管理またはシンプルなGC
- Nyashスクリプト: Arc<Mutex<dyn NyashBox>>
- GC/参照カウント管理にランタイムが必要
## 実例なぜFileBoxはC ABIなのか
```rust
// FileBoxプラグインネイティブ
#[no_mangle]
pub extern "C" fn nyash_plugin_invoke(...) -> i32 {
// 直接システムコール可能
// VMなしで動作
// EXEに静的リンク可能
}
```
対して、Nyashスクリプトは
- VM必須
- 動的評価
- EXEに埋め込み不可
## 結論Phase 12の方向転換が必要
### ❌ 不可能なこと
- スクリプトプラグインをJIT/AOTから直接呼び出し
- スクリプトプラグインをEXEに埋め込み
- ネイティブプラグインと完全に透過的な利用
### ✅ 可能なこと
1. **インタープリターモード限定**
- スクリプトプラグインはインタープリター実行時のみ
- 開発/プロトタイピング用途
2. **トランスパイル方式**
- Nyashスクリプト → C/Rust → ネイティブプラグイン
- ビルドステップが必要
3. **ハイブリッド実行**
- 開発時: スクリプトプラグイン(高速イテレーション)
- 本番時: ネイティブプラグイン(高性能)
## 修正された価値提案
### 開発フローの改善
```
1. アイデア → Nyashスクリプトでプロトタイプ
2. 動作確認 → インタープリターでテスト
3. 性能要求 → Rust/Cで再実装
4. 配布 → ネイティブプラグインとして
```
### 制限事項の明確化
- **JIT/AOT**: ネイティブプラグインのみ
- **インタープリター**: スクリプトプラグインも可
- **EXE生成**: ネイティブプラグインのみ含む
## 推奨アクション
1. **Phase 12の再定義**
- 「開発支援ツール」として位置づけ
- JIT/AOT統合は諦める
2. **ドキュメント修正**
- 制限事項を明確に記載
- 誤解を招く「透過的利用」を削除
3. **代替案の検討**
- Nyash→Rustトランスパイラー
- プラグインテンプレート生成ツール
---
**重要な教訓C ABIの制約は、システムプログラミングの本質的な制約である。**

View File

@ -0,0 +1,207 @@
# 埋め込みVMでのBox処理設計
## 🎯 核心MIRレベルでのBox処理を再現
### 現在のMIR/VMでのBox処理フロー
```
1. MIR: BoxCall/PluginInvoke命令
2. VM: ValueId → VMValue変換
3. VMValue → Box<dyn NyashBox> or TLVエンコード
4. メソッド実行
5. 結果をVMValueに戻す
```
## 📊 埋め込みVMの設計
### 1. 軽量VMValue定義
```c
// 埋め込みVM用の値表現
typedef enum {
NYVM_TYPE_INT,
NYVM_TYPE_FLOAT,
NYVM_TYPE_BOOL,
NYVM_TYPE_STRING,
NYVM_TYPE_HANDLE, // Box参照ハンドル
NYVM_TYPE_VOID
} NyVMType;
typedef struct {
NyVMType type;
union {
int64_t i;
double f;
uint8_t b;
struct { const char* data; size_t len; } s;
uint64_t h; // ハンドルBox参照
} value;
} NyVMValue;
```
### 2. MIRバイトコード形式
```c
// BoxCall命令のエンコード
enum {
OP_BOXCALL = 0x20,
OP_PLUGIN_INVOKE = 0x21,
// ...
};
// BoxCall: [op:1] [dst:1] [box_val:1] [method_id:2] [argc:1] [args...]
// 例: BoxCall %2 = %1.toString()
// → 0x20 0x02 0x01 0x00 0x00 0x00
```
### 3. 埋め込みVMでのBoxCall実行
```c
int nyvm_execute_boxcall(
NyashEmbeddedVM* vm,
uint8_t dst,
uint8_t box_val,
uint16_t method_id,
uint8_t argc,
uint8_t* args
) {
// 1. レシーバー取得
NyVMValue* recv = &vm->values[box_val];
// 2. プリミティブ型の場合
if (recv->type != NYVM_TYPE_HANDLE) {
// プリミティブ→TLV変換
uint8_t tlv_buf[256];
size_t tlv_len = encode_primitive_to_tlv(recv, tlv_buf);
// 組み込み実装を呼び出し
return call_builtin_method(recv->type, method_id, tlv_buf, tlv_len);
}
// 3. Boxハンドルの場合
uint64_t handle = recv->value.h;
// 引数をTLVエンコード
uint8_t args_tlv[1024];
size_t args_len = 0;
for (int i = 0; i < argc; i++) {
NyVMValue* arg = &vm->values[args[i]];
args_len += encode_value_to_tlv(arg, &args_tlv[args_len]);
}
// 4. プラグイン呼び出しC ABI
uint8_t result[4096];
size_t result_len = sizeof(result);
int rc = nyash_plugin_invoke(
get_type_id_from_handle(handle),
method_id,
get_instance_id_from_handle(handle),
args_tlv, args_len,
result, &result_len
);
// 5. 結果をVMValueに変換
if (rc == 0) {
decode_tlv_to_value(result, result_len, &vm->values[dst]);
}
return rc;
}
```
## 🔄 Box引数の処理
### 現在のVMRust
```rust
// VMValue → Box<dyn NyashBox>変換
let val = self.get_value(*arg)?;
Ok(val.to_nyash_box())
```
### 埋め込みVMC
```c
// NyVMValue → TLVエンコード
switch (value->type) {
case NYVM_TYPE_INT:
encode_i64(tlv, value->value.i);
break;
case NYVM_TYPE_HANDLE:
encode_handle(tlv,
get_type_id_from_handle(value->value.h),
get_instance_id_from_handle(value->value.h)
);
break;
// ...
}
```
## 💡 実装のポイント
### 1. ハンドル管理
```c
// グローバルハンドルテーブル
typedef struct {
uint32_t type_id;
uint32_t instance_id;
void* native_ptr; // 実際のBoxポインタ必要な場合
} HandleEntry;
static HandleEntry g_handles[MAX_HANDLES];
static uint64_t g_next_handle = 1;
uint64_t register_handle(uint32_t type_id, uint32_t instance_id) {
uint64_t h = g_next_handle++;
g_handles[h].type_id = type_id;
g_handles[h].instance_id = instance_id;
return h;
}
```
### 2. 組み込みメソッド
```c
// 頻出メソッドは埋め込みVMに直接実装
int call_builtin_method(NyVMType type, uint16_t method_id, ...) {
switch (type) {
case NYVM_TYPE_INT:
if (method_id == 0) { // toString
// 整数→文字列変換
}
break;
// ...
}
}
```
### 3. プラグインとの統合
```c
// 生成されるCコード
extern "C" int32_t nyplug_mybox_invoke(...) {
// MIRバイトコード実行
NyashEmbeddedVM vm;
nyvm_init(&vm, BYTECODE, sizeof(BYTECODE));
// 引数をVMスタックに設定
nyvm_decode_args(&vm, args, args_len);
// メソッド実行
nyvm_execute_method(&vm, method_id);
// 結果をTLVエンコード
return nyvm_encode_result(&vm, result, result_len);
}
```
## 🎯 結論
埋め込みVMは
1. **MIRのBoxCall/PluginInvoke命令を忠実に実装**
2. **TLVエンコード/デコードでC ABIと通信**
3. **ハンドルでBox参照を管理**
4. **頻出処理は最適化実装**
これにより、Nyashスクリプトで書いたプラグインも、ネイティブプラグインと同じC ABIで動作します

View File

@ -0,0 +1,195 @@
# 埋め込みVM実装ロードマップ
## 🎯 目標スクリプトプラグインのC ABI化
**Nyashスクリプト → C ABIプラグイン変換の完全自動化**
## 📊 技術スタック
```
[Nyashスクリプト]
↓ パース・型チェック
[MIR (中間表現)]
↓ 最適化・定数畳み込み
[MIRバイトコード]
↓ 埋め込み
[Cソースコード] ← nyash-to-c ツール
↓ コンパイル (cc/clang/gcc)
[.so/.dll/.a] ← 通常のプラグイン!
```
## 🚀 実装フェーズ
### Phase 12.1: 最小埋め込みVM2-3週間
#### 1. MIRバイトコード設計
```rust
// mir_bytecode.rs
pub enum CompactInstruction {
// 1バイト命令頻出
LoadLocal(u8), // 0x00-0x7F
StoreLocal(u8), // 0x80-0xFF
// 2バイト命令
LoadConst(u8), // 0x01 XX
Call(u8), // 0x02 XX
// 可変長
LoadString, // 0x03 [len:u16] [data]
Jump, // 0x04 [offset:i16]
}
```
#### 2. 埋め込みVMコア
```c
// nyash_embedded_vm.h
typedef struct {
const uint8_t* bytecode;
size_t bytecode_len;
// 実行時状態(最小)
void* stack[256];
int sp;
void* locals[16];
} NyashEmbeddedVM;
int32_t nyash_embedded_execute(
const uint8_t* bytecode,
size_t bytecode_len,
uint32_t method_id,
const uint8_t* args,
size_t args_len,
uint8_t* result,
size_t* result_len
);
```
### Phase 12.2: Nyash→Cトランスパイラー3-4週間
#### 1. 基本変換
```bash
$ nyash-to-c math_plugin.ny -o math_plugin.c
Generating C plugin from Nyash script...
- Parsing... OK
- Type checking... OK
- MIR generation... OK
- Bytecode emission... OK
- C code generation... OK
Output: math_plugin.c (2.3KB)
```
#### 2. 生成コード例
```c
// Generated from: math_plugin.ny
#include <nyash_embedded.h>
// MIRバイトコード最適化済み
static const uint8_t BYTECODE[] = {
0x01, 0x00, // Version 1.0
0x01, 0x00, // 1 function
// Function: cached_sin
0x00, 0x08, // Function header
0x80, 0x00, // StoreLocal 0 (x)
0x02, 0x10, // Call sin
0x90, // Return
};
// プラグインエントリポイント
extern "C" int32_t nyplug_math_plugin_invoke(
uint32_t type_id,
uint32_t method_id,
uint32_t instance_id,
const uint8_t* args,
size_t args_len,
uint8_t* result,
size_t* result_len
) {
return nyash_embedded_execute(
BYTECODE, sizeof(BYTECODE),
method_id,
args, args_len,
result, result_len
);
}
```
### Phase 12.3: 最適化とツールチェーン4-6週間
#### 1. ビルドシステム統合
```toml
# nyash.toml
[[plugins]]
name = "math_plugin"
source = "plugins/math_plugin.ny" # Nyashソース
type = "script" # 自動的にC変換
[[plugins]]
name = "file_plugin"
source = "plugins/file_plugin/Cargo.toml"
type = "native" # 従来のRustプラグイン
```
#### 2. 自動ビルドパイプライン
```bash
$ nyash build --plugins
Building plugins...
[1/2] math_plugin (script)
- Transpiling to C... OK
- Compiling... OK
- Output: target/plugins/libmath_plugin.so
[2/2] file_plugin (native)
- Building with cargo... OK
- Output: target/plugins/libfile_plugin.so
Done!
```
## 📈 パフォーマンス目標
| 操作 | ネイティブ | 埋め込みVM | 目標比率 |
|------|-----------|------------|----------|
| 単純計算 | 10ns | 50ns | 5x |
| メソッド呼び出し | 20ns | 100ns | 5x |
| 文字列操作 | 100ns | 200ns | 2x |
| I/O操作 | 10μs | 10.1μs | 1.01x |
## 🔧 開発ツール
### 1. デバッガ
```bash
$ nyash-debug math_plugin.ny --method cached_sin --args "[3.14]"
Executing cached_sin(3.14)...
[PC:0000] LoadLocal 0 ; x = 3.14
[PC:0002] Call sin ; sin(3.14)
[PC:0004] Return ; 0.0015926...
Result: 0.0015926
```
### 2. プロファイラ
```bash
$ nyash-profile math_plugin.so
Method statistics:
- cached_sin: 1000 calls, avg 120ns
- cached_cos: 500 calls, avg 115ns
Bottlenecks: None detected
```
## 🎉 最終形
```bash
# 開発者の体験
$ cat my_plugin.ny
export box MyPlugin {
init { cache = new MapBox() }
process(x) { return x * 2 }
}
$ nyash build my_plugin.ny
✓ Generated: my_plugin.so
$ nyash run --plugin my_plugin.so test.ny
✓ Plugin loaded (C ABI)
✓ Result: 42
```
**Nyashで書いて、どこでも動く**

View File

@ -0,0 +1,115 @@
# Phase 12: Nyashスクリプトプラグインシステム革命
## 🚀 概要
Nyashスクリプト自体でプラグインを作成できる革命的発見ビルド不要で、既存のネイティブプラグインを組み合わせて新機能を作成可能。
## 💡 発見の経緯
include/export仕様の検討中に、以下の重要な気づきが
```nyash
# custom_math_plugin.ny
export box CustomMathPlugin {
init {
_math = new MathBox() # 既存プラグイン活用
_cache = new MapBox() # 結果キャッシュ
}
// カスタム拡張
cached_sin(x) {
local key = x.toString()
if me._cache.has(key) {
return me._cache.get(key)
}
local result = me._math.sin(x)
me._cache.set(key, result)
return result
}
}
```
これにより、Rust/C++のビルドなしでプラグイン開発が可能に!
## 🎯 統一Box ABI設計
### 基本インターフェース
```rust
// Rust側の統一インターフェース
trait BoxInterface {
fn invoke(&self, method_id: u32, args: NyashValue) -> NyashValue;
fn get_methods(&self) -> Vec<MethodInfo>;
fn init(&mut self, ctx: Context);
fn drop(&mut self);
}
```
### Nyashスクリプトプラグインの要件
```nyash
export box MyPlugin {
// 必須:初期化
init { ... }
// 推奨FFI互換インターフェース
invoke(method_id, args) {
// method_idに基づいてディスパッチ
}
// オプション:メソッド情報
get_methods() {
return [
{ name: "method1", id: 1 },
{ name: "method2", id: 2 }
]
}
}
```
## 📊 エコシステムへの影響
### 開発の民主化
- **参入障壁の劇的低下**: Rust/C++環境不要
- **即座の開発**: ビルド待ち時間ゼロ
- **コミュニティ拡大**: より多くの開発者が参加可能
### 新しい開発パターン
1. **プラグインの合成**: 複数のネイティブプラグインを組み合わせ
2. **ラピッドプロトタイピング**: アイデアを即座に実装
3. **ホットリロード**: 実行中の更新が可能
## 🛣️ 実装ロードマップ
### Phase 12.1: 基盤構築
- [ ] Box ABI仕様の最終決定
- [ ] export box構文のパーサー実装
- [ ] 基本的なPluginRegistry実装
### Phase 12.2: 統一インターフェース
- [ ] FFIプラグインのBoxInterface対応
- [ ] NyashスクリプトのBoxInterface実装
- [ ] 相互運用テスト
### Phase 12.3: 動的機能
- [ ] 動的ロード/アンロード機能
- [ ] ホットリロード対応
- [ ] プラグイン間依存関係管理
### Phase 12.4: セキュリティと最適化
- [ ] サンドボックス実装
- [ ] ケイパビリティベース権限
- [ ] パフォーマンス最適化
## 📚 関連ドキュメント
- [Gemini先生の分析](./gemini-analysis-script-plugins.md)
- [Codex先生の技術提案](./codex-technical-proposal.md)
- [統合分析まとめ](./synthesis-script-plugin-revolution.md)
## 🎯 次のアクション
1. Box ABI仕様書の作成
2. export box構文の実装開始
3. 既存FFIプラグイン1つを統一インターフェースに移行
---
*Everything is Box - そしてプラグインもBoxになる*

View File

@ -0,0 +1,147 @@
# Phase 12改訂版Nyashスクリプトプラグイン - 開発支援ツールとして
## 🎯 現実的な位置づけ
**スクリプトプラグインは、JIT/AOT/EXEとは独立した開発支援機能として実装する。**
## 📊 制約と可能性の整理
### ❌ できないこと(技術的制約)
- MIR/VM/JIT/AOTからのスクリプトプラグイン呼び出し
- スクリプトプラグインのEXE埋め込み
- ネイティブプラグインとの完全な相互運用性
### ✅ できること(現実的な価値)
- インタープリターモードでの高速プロトタイピング
- 既存プラグインの組み合わせによる新機能開発
- ビルド不要な機能拡張(開発時のみ)
## 🔄 修正された開発フロー
```
┌─────────────────┐
│ アイデア/要件 │
└────────┬────────┘
┌─────────────────┐
│ Nyashスクリプト │ ← 高速イテレーション
│ プラグイン作成 │ ビルド不要
└────────┬────────┘
┌─────────────────┐
│ インタープリター│
│ でテスト/検証 │
└────────┬────────┘
性能要求?
↙ ↘
No Yes
↓ ↓
そのまま Rust/Cで
使用 再実装
ネイティブ
プラグイン
JIT/AOT/EXE
```
## 📝 実装方針
### 1. インタープリター専用機能として実装
```nyash
// script_plugin.ny
export box CustomLogic {
init {
_math = new MathBox() // ネイティブプラグイン利用
_cache = new MapBox()
}
process(data) {
// 複雑なビジネスロジック
// インタープリターでのみ実行
}
}
```
### 2. 明確な使用場面の区別
```nyash
// development.ny開発時
local plugin = include("custom_logic.ny") // ✅ OK
// production.ny本番時
local plugin = new CustomLogicBox() // ネイティブ版を使用
```
### 3. トランスパイル支援ツール(将来)
```bash
# Nyashスクリプト → Rustテンプレート生成
nyash-to-rust custom_logic.ny > custom_logic_plugin/src/lib.rs
```
## 🎯 価値提案(修正版)
### 開発者にとっての価値
1. **探索的プログラミング** - アイデアを即座に試せる
2. **プロトタイピング** - ビルドなしで機能検証
3. **学習曲線の緩和** - Rust/C知識不要で拡張開発
### エコシステムへの貢献
1. **アイデアの具現化** - スクリプトで検証→ネイティブで実装
2. **コミュニティ参加** - より多くの開発者が貢献可能
3. **ベストプラクティス** - 成功パターンの蓄積
## 🚀 実装計画(現実的版)
### Phase 12.1: 基盤構築2週間
- [ ] export box構文インタープリター専用
- [ ] include()関数の拡張
- [ ] 基本的なプラグインレジストリ
### Phase 12.2: 開発体験向上3週間
- [ ] ホットリロード(開発モード)
- [ ] エラーメッセージ改善
- [ ] デバッグ支援機能
### Phase 12.3: 移行支援4週間
- [ ] パフォーマンス分析ツール
- [ ] Rust変換テンプレート
- [ ] 移行ガイドライン
## 📚 ドキュメント戦略
### 明確な制約の説明
```markdown
# Nyashスクリプトプラグイン
⚠️ **重要な制約**
- インタープリターモードでのみ動作
- JIT/AOT/EXEでは使用不可
- 本番環境ではネイティブプラグインへの移行推奨
```
### 使用例の充実
- プロトタイピング例
- ネイティブ移行例
- パフォーマンス比較
## 🎉 期待される成果(現実的版)
### 短期3ヶ月
- 開発効率の向上プロトタイピング時間80%削減)
- 新規開発者の参入Rust不要
- アイデア検証の高速化
### 中期1年
- 成功パターンの確立
- ネイティブプラグインの品質向上
- コミュニティ主導の機能提案増加
## 結論
**スクリプトプラグインは、C ABIの制約を認識した上で、開発支援ツールとして大きな価値を提供できる。**
「Everything is Box」の哲学は、実行時の制約はあれど、開発時の自由度として実現される。

View File

@ -0,0 +1,164 @@
# 解決策埋め込みVMによるスクリプトプラグイン実現
## 💡 発想の転換
**制約は「リンク時にC ABIが必要」だけ。つまり、C ABI関数の中でVMを動かせばいい**
## 🎯 アーキテクチャ
```c
// C ABI関数静的リンク可能
extern "C" int32_t nyplug_custom_math_invoke(
uint32_t method_id,
const uint8_t* args,
size_t args_len,
uint8_t* result,
size_t* result_len
) {
// 埋め込みVM起動
static NyashVM* embedded_vm = NULL;
if (!embedded_vm) {
embedded_vm = nyash_vm_create_minimal();
nyash_vm_load_script(embedded_vm, EMBEDDED_SCRIPT);
}
// スクリプト実行
return nyash_vm_invoke(embedded_vm, method_id, args, args_len, result, result_len);
}
// スクリプトは文字列リテラルとして埋め込み
static const char* EMBEDDED_SCRIPT = R"(
export box CustomMath {
cached_sin(x) {
// Nyashコード
}
}
)";
```
## 🔄 実現方法
### 1. Nyash→C トランスパイラー
```bash
# Nyashスクリプト → C関数
nyash-to-c custom_math.ny > custom_math_plugin.c
# 生成されるC
// custom_math_plugin.c
#include "nyash_embedded_vm.h"
static const char* SCRIPT = "..."; // Nyashコード埋め込み
extern "C" int32_t nyplug_custom_math_invoke(...) {
return nyash_embedded_invoke(SCRIPT, method_id, ...);
}
```
### 2. 最小VM実装
```rust
// crates/nyash-embedded-vm
pub struct EmbeddedVM {
// 最小限の実行環境
values: Vec<VMValue>,
// スクリプトはプリコンパイル済みMIR
mir: MirModule,
}
#[no_mangle]
pub extern "C" fn nyash_embedded_invoke(
script: *const c_char,
method_id: u32,
// ... TLV args/result
) -> i32 {
// MIR実行インタープリター
}
```
## 📊 利点と制約
### ✅ 可能になること
- **スクリプトプラグインがEXEに埋め込み可能**
- **JIT/AOTから呼び出し可能**C ABI経由
- **既存のプラグインシステムと完全互換**
### ⚠️ 制約
- **パフォーマンス**: 埋め込みVMのオーバーヘッド
- **サイズ**: 最小VMランタイムが必要~500KB?
- **機能制限**: フルVMの一部機能のみ
## 🚀 段階的実装
### Phase 1: 最小埋め込みVM
```rust
// 必要最小限の機能
- MIR実行(インタープリター)
- 基本型(Integer, String, Bool
- メソッド呼び出し
- TLVエンコード/デコード
```
### Phase 2: Nyash→Cトランスパイラー
```nyash
// input: custom_math.ny
export box CustomMath {
sin(x) { ... }
}
// output: custom_math_plugin.c
extern "C" int32_t nyplug_custom_math_invoke(...) {
static const uint8_t MIR_BYTECODE[] = { ... };
return nyash_embedded_execute(MIR_BYTECODE, ...);
}
```
### Phase 3: 最適化
- MIRプリコンパイル
- 頻出パスのネイティブ化
- 選択的JITコンパイル
## 💡 実装例
```c
// 生成されたプラグイン
#include <nyash_embedded.h>
// MIRバイトコード事前コンパイル
static const uint8_t CUSTOM_MATH_MIR[] = {
0x01, 0x00, // version
0x10, 0x00, // function count
// ... MIR instructions
};
extern "C" int32_t nyplug_custom_math_abi_version() {
return 1;
}
extern "C" int32_t nyplug_custom_math_invoke(
uint32_t method_id,
const uint8_t* args,
size_t args_len,
uint8_t* result,
size_t* result_len
) {
// 埋め込みVM実行
return nyash_mir_execute(
CUSTOM_MATH_MIR,
sizeof(CUSTOM_MATH_MIR),
method_id,
args, args_len,
result, result_len
);
}
```
## 🎯 結論
**「リンク時にC ABI」という制約は、埋め込みVMで解決可能**
- Nyashスクリプト → MIR → Cコード → ネイティブプラグイン
- 開発の容易さNyashと配布の利便性C ABIを両立
- 既存のプラグインエコシステムと完全互換
これで「Everything is Box」が真に実現する

View File

@ -0,0 +1,175 @@
# C ABIとの整合性Phase 12スクリプトプラグインシステム
## 🚨 重要な発見
Phase 10.1で既に**C ABI v0**が定義されており、これとPhase 12の提案を整合させる必要があります。
## 📊 現状のC ABIPhase 10.1
### 既存のBID-FFIプラグイン用
```c
// 現在のプラグインFFITLVベース
extern "C" fn nyash_plugin_invoke(
type_id: u32,
method_id: u32,
instance_id: u32,
args: *const u8, // TLVエンコード
args_len: usize,
result: *mut u8, // TLVエンコード
result_len: *mut usize,
) -> i32
```
### 新しいNyRT C ABI v0
```c
// コア関数
int32_t nyrt_abi_version(void);
NyBox nyrt_box_new(uint64_t typeid, uint64_t size);
void nyrt_box_free(NyBox b);
// プラグイン関数Array
int32_t nyplug_array_abi_version(void);
NyBox nyplug_array_new(void);
int32_t nyplug_array_get(NyBox arr, uint64_t i, NyBox* out);
```
## 🎯 Phase 12の修正案
### 問題点
- Gemini/Codexの提案した`BoxInterface`トレイトは**Rust専用**
- C ABIとの相互運用性が考慮されていない
- TLVエンコーディングとの整合性が不明
### 解決策C ABIラッパー戦略
```rust
// ❌ 元の提案Rust専用
trait BoxInterface {
fn invoke(&self, method_id: u32, args: NyashValue) -> NyashValue;
}
// ✅ 修正案C ABI互換
pub struct ScriptPluginWrapper {
// Nyashスクリプトインスタンス
script_box: NyashValue,
// C ABI互換性のためのFFI関数
ffi_invoke: extern "C" fn(
type_id: u32,
method_id: u32,
instance_id: u32,
args: *const u8,
args_len: usize,
result: *mut u8,
result_len: *mut usize,
) -> i32,
}
impl ScriptPluginWrapper {
// 既存のBID-FFIと完全互換
pub extern "C" fn invoke_ffi(
&self,
type_id: u32,
method_id: u32,
instance_id: u32,
args: *const u8,
args_len: usize,
result: *mut u8,
result_len: *mut usize,
) -> i32 {
// 1. TLVデコード
let nyash_args = decode_tlv(args, args_len);
// 2. Nyashスクリプト呼び出し
let result_value = self.script_box.invoke(method_id, nyash_args);
// 3. TLVエンコード
encode_tlv(result_value, result, result_len)
}
}
```
## 🔄 統合アーキテクチャ
```
[JIT/AOT] ---> C ABI (nyrt_*/nyplug_*) --+--> [ネイティブプラグイン]
|
+--> [ScriptPluginWrapper] --> [Nyashスクリプト]
```
### 利点
1. **完全な後方互換性** - 既存のプラグインがそのまま動作
2. **統一されたFFI** - JIT/AOT/プラグインすべて同じC ABI
3. **透過的な利用** - 呼び出し側はネイティブ/スクリプトを区別しない
## 📝 実装修正案
### Phase 12.1(修正版)
1. **ScriptPluginWrapperの実装**
- BID-FFI互換のC関数エクスポート
- TLVエンコード/デコード処理
- Nyashスクリプトへの橋渡し
2. **プラグインレジストリ拡張**
```rust
pub struct PluginRegistry {
// 既存のネイティブプラグインC ABI
native_plugins: HashMap<u32, PluginHandle>,
// スクリプトプラグインC ABIラッパー経由
script_plugins: HashMap<u32, ScriptPluginWrapper>,
}
```
3. **export box構文の実装**
```nyash
export box CustomMathPlugin {
// BID-FFI互換のためのメタ情報
__type_id__ = 100 // 動的割り当てor設定ファイル
__methods__ = {
"cached_sin": 1,
"cached_cos": 2
}
// 通常のNyashコード
init { ... }
cached_sin(x) { ... }
}
```
## 🚀 移行パス
### 段階1既存プラグインの動作確認
- FileBox、NetBox等がC ABI経由で正常動作
- パフォーマンステスト
### 段階2簡単なスクリプトプラグイン
- MathBoxの一部機能をNyashで再実装
- C ABIラッパー経由での動作確認
### 段階3高度な統合
- ネイティブとスクリプトの混在
- 動的ロード/アンロード
## ⚡ パフォーマンス影響
```
呼び出しチェーン:
1. JIT → C ABI関数呼び出し既存
2. C ABI → ScriptPluginWrapper追加
3. Wrapper → TLVデコード追加
4. Wrapper → Nyashスクリプト実行追加
5. Wrapper → TLVエンコード追加
予想オーバーヘッド: 100-500ns/呼び出し
```
## 🎯 結論
Phase 12のスクリプトプラグインシステムは、**C ABIを尊重**しつつ実装可能です。
- BoxInterfaceトレイトは内部実装詳細に留める
- 外部インターフェースは既存のC ABIBID-FFIを維持
- ScriptPluginWrapperがブリッジとして機能
これにより、**「Everything is Plugin」**の哲学を保ちながら、スクリプトプラグインを実現できます。

View File

@ -0,0 +1,334 @@
# Codex先生の技術提案Nyashスクリプトプラグインシステム実装
## エグゼクティブサマリー
Nyashスクリプトをプラグインとして使用する提案は、技術的に極めて実現可能であり、Nyashエコシステムに革命的な価値をもたらします。「Everything is Box」哲学の究極の実現として、実装言語に依存しない統一インターフェースを提供することで、開発の民主化とエコシステムの爆発的成長が期待できます。
## 技術アーキテクチャ提案
### 1. 統一Box ABIの詳細設計
```rust
// コアインターフェース定義
pub trait UnifiedBoxInterface: Send + Sync {
// 基本メソッド
fn invoke(&self, ctx: &mut Context, method_id: u32, args: &[NyashValue]) -> Result<NyashValue, BoxError>;
fn get_metadata(&self) -> BoxMetadata;
// ライフサイクル管理
fn initialize(&mut self, config: &BoxConfig) -> Result<(), BoxError>;
fn shutdown(&mut self) -> Result<(), BoxError>;
// 動的機能(オプション)
fn hot_reload(&mut self, new_code: &str) -> Result<(), BoxError> {
Err(BoxError::NotSupported)
}
}
// メタデータ構造
pub struct BoxMetadata {
pub name: String,
pub version: String,
pub methods: Vec<MethodInfo>,
pub capabilities: Vec<Capability>,
pub dependencies: Vec<Dependency>,
}
```
### 2. プラグインレジストリアーキテクチャ
```rust
pub struct PluginRegistry {
// ネイティブプラグイン
native_plugins: HashMap<u32, Arc<dyn UnifiedBoxInterface>>,
// スクリプトプラグイン
script_plugins: HashMap<u32, ScriptPlugin>,
// 動的ID管理
id_allocator: IdAllocator,
// 依存関係グラフ
dependency_graph: DependencyGraph,
}
impl PluginRegistry {
pub fn register_native(&mut self, plugin: impl UnifiedBoxInterface + 'static) -> u32 {
let id = self.id_allocator.allocate();
self.native_plugins.insert(id, Arc::new(plugin));
id
}
pub fn register_script(&mut self, source: &str) -> Result<u32, RegistryError> {
let plugin = ScriptPlugin::compile(source)?;
let id = self.id_allocator.allocate();
self.script_plugins.insert(id, plugin);
Ok(id)
}
}
```
### 3. スクリプトプラグインラッパー実装
```rust
pub struct ScriptPlugin {
vm: NyashVM,
box_instance: NyashValue,
method_cache: HashMap<u32, MethodHandle>,
}
impl UnifiedBoxInterface for ScriptPlugin {
fn invoke(&self, ctx: &mut Context, method_id: u32, args: &[NyashValue]) -> Result<NyashValue, BoxError> {
// メソッドキャッシュから高速検索
if let Some(handle) = self.method_cache.get(&method_id) {
return self.vm.call_cached(handle, args);
}
// 動的メソッド解決
let method = self.resolve_method(method_id)?;
self.vm.call_method(&self.box_instance, &method, args)
}
}
```
## 実装戦略
### Phase 1: MVP実装2-3週間
1. **基本インターフェース実装**
- UnifiedBoxInterfaceトレイトの実装
- 既存FFIプラグイン1つを移行MathBox推奨
- ScriptPluginラッパーの基本実装
2. **export box構文の実装**
```nyash
export box MyPlugin {
init { _version = "1.0.0" }
// 必須:プラグインメタデータ
get_metadata() {
return {
name: "MyPlugin",
version: me._version,
methods: ["process", "transform"]
}
}
// ビジネスロジック
process(data) { ... }
transform(input) { ... }
}
```
3. **基本的なレジストリ**
- 静的登録のみ
- 依存関係解決なし
### Phase 2: 動的機能3-4週間
1. **動的ロード/アンロード**
```nyash
local registry = new PluginRegistry()
local id = registry.load_script("path/to/plugin.ny")
registry.unload(id)
```
2. **ホットリロード**
```nyash
registry.enable_hot_reload("path/to/plugin.ny")
// ファイル変更時に自動リロード
```
3. **依存関係管理**
- 循環依存検出
- バージョン互換性チェック
### Phase 3: 最適化とセキュリティ4-6週間
1. **パフォーマンス最適化**
- メソッドキャッシング
- JITコンパイル統合
- プリコンパイルオプション
2. **セキュリティサンドボックス**
```rust
pub struct Sandbox {
memory_limit: usize,
cpu_quota: Duration,
allowed_capabilities: HashSet<Capability>,
}
```
3. **ケイパビリティベースセキュリティ**
- ファイルアクセス制限
- ネットワーク制限
- システムコール制限
## パフォーマンス考察
### ベンチマーク予測
```
操作 | ネイティブ | スクリプト | 比率
--------------------|-----------|-----------|-----
単純メソッド呼び出し | 10ns | 100ns | 10x
複雑な計算1000ops | 1μs | 5μs | 5x
I/O操作 | 100μs | 102μs | 1.02x
```
### 最適化戦略
1. **ホットパスの識別**
- 頻繁に呼ばれるメソッドを自動検出
- JITコンパイル優先度付け
2. **ハイブリッドアプローチ**
- コア機能:ネイティブ実装
- カスタマイズ層:スクリプト実装
## エコシステムへの影響
### 開発者体験の革新
1. **即座のフィードバックループ**
```bash
# 編集
vim my_plugin.ny
# 即座にテスト(ビルド不要)
nyash test_plugin.ny
```
2. **プラグインマーケットプレイス**
- GitHubから直接インストール
- バージョン管理統合
- 自動更新機能
### コミュニティ成長予測
- **現在**: 10-20人のコアコントリビューターRust必須
- **1年後**: 100-500人のプラグイン開発者Nyashのみ
- **3年後**: 1000+のプラグインエコシステム
## リスクと緩和策
### 技術的リスク
1. **パフォーマンス劣化**
- 緩和策:重要部分のネイティブ実装維持
- プロファイリングツール提供
2. **セキュリティ脆弱性**
- 緩和策:デフォルトサンドボックス
- 署名付きプラグイン
### エコシステムリスク
1. **品質のばらつき**
- 緩和策:公式プラグインガイドライン
- 自動品質チェックツール
2. **互換性問題**
- 緩和策:セマンティックバージョニング強制
- 自動互換性テスト
## 結論と推奨事項
### 即時実行すべきアクション
1. **Box ABI仕様書の作成**1週間
2. **export box構文の実装**2週間
3. **MathBoxの統一インターフェース移行**1週間
### 長期ビジョン
Nyashスクリプトプラグインシステムは、単なる機能追加ではなく、Nyashを**プログラミング言語**から**拡張可能なプラットフォーム**へと進化させる革命的な一歩です。
「Everything is Box」の哲学が、実装言語の壁を超えて真に実現される時、Nyashは次世代のプログラミングエコシステムのモデルケースとなるでしょう。
## 付録:実装例
### A. 完全なスクリプトプラグイン例
```nyash
# advanced_math_plugin.ny
export box AdvancedMathPlugin {
init {
_math = new MathBox()
_cache = new MapBox()
_stats = new MapBox()
}
// プラグインメタデータ(必須)
get_metadata() {
return {
name: "AdvancedMathPlugin",
version: "1.0.0",
methods: ["cached_sin", "cached_cos", "fibonacci", "factorial"],
capabilities: ["compute"],
dependencies: [{
name: "MathBox",
version: ">=1.0.0"
}]
}
}
// キャッシュ付き三角関数
cached_sin(x) {
local key = "sin:" + x.toString()
if me._cache.has(key) {
me._update_stats("cache_hit")
return me._cache.get(key)
}
local result = me._math.sin(x)
me._cache.set(key, result)
me._update_stats("cache_miss")
return result
}
// 再帰的フィボナッチ(メモ化)
fibonacci(n) {
if n <= 1 { return n }
local key = "fib:" + n.toString()
if me._cache.has(key) {
return me._cache.get(key)
}
local result = me.fibonacci(n-1) + me.fibonacci(n-2)
me._cache.set(key, result)
return result
}
// 統計情報
get_stats() {
return me._stats
}
// プライベートメソッド
_update_stats(event) {
local count = me._stats.get(event) or 0
me._stats.set(event, count + 1)
}
}
```
### B. ネイティブとスクリプトの透過的利用
```nyash
// 使用側のコード(プラグインの実装言語を意識しない)
local math1 = new MathBox() // ネイティブプラグイン
local math2 = include("advanced_math_plugin.ny") // スクリプトプラグイン
// 同じインターフェースで利用
print(math1.sin(3.14)) // ネイティブ実装
print(math2.cached_sin(3.14)) // スクリプト実装
// 動的に切り替え可能
local math = get_config("use_cached") ? math2 : math1
print(math.sin(1.57))
```
---
*"Write plugins in Nyash, for Nyash, by Nyash!"*

View File

@ -0,0 +1,90 @@
# Gemini先生の分析Nyashスクリプトプラグインシステム
## 技術的妥当性評価
### 結論:極めて実現可能性は高く、技術的にも非常に妥当
このアプローチは、多くのモダンな言語やエンジンLua, JavaScript/Node.js, Pythonなどで採用されている「ネイティブコアとスクリプト拡張」という実績あるモデルを踏襲しています。
### 「Everything is Box」哲学との整合性
このアプローチは、Boxを「外部から観測可能なインターフェースを持つオブジェクト」と定義するならば、その実装がネイティブRust/C++であろうとスクリプトNyashであろうと区別しない、という哲学の究極的な現れです。
## 統一インターフェース設計
### BoxInterface Traitの提案
```rust
// Rust側に、すべてのプラグインが実装すべきtraitを定義
trait BoxInterface {
fn invoke(&self, method_id: u32, args: NyashValue) -> NyashValue;
// その他、初期化やメタデータ取得などの共通メソッド
}
```
### アーキテクチャ
```
[Nyashコード] -> [BoxInterface Trait] --+--> [FFIラッパー] -> [ネイティブコード]
|
+--> [Nyashスクリプトラッパー] -> [Nyash VM実行]
```
これにより、Nyashのコードからプラグインを利用する側は、相手がネイティブかスクリプトかを一切意識する必要がなくなります。
## エコシステムへの影響
### 開発の民主化
- **参入障壁の劇的な低下**: Rust/C++の環境構築やビルドプロセスが不要
- **迅速なプロトタイピング**: アイデアをすぐにNyashスクリプトで形にし、テスト可能
### 新しいプラグインの形態
- **プラグインの合成**: 複数の既存プラグインを組み合わせて新しい機能を持つ「メタプラグイン」
- **アプリケーションの「設定」としてのプラグイン**: ユーザーが自身のアプリケーションの動作をカスタマイズ
### 動的性の向上
アプリケーションの実行中に、Nyashスクリプトプラグインをリロードしたり、新しいものを追加したりすることが容易になります。
## 実装ロードマップ
### フェーズ1コアランタイムの実現MVP
1. `BoxInterface` Traitの設計と実装Rust側
2. 既存FFIの`BoxInterface`への対応
3. Nyashオブジェクトの`BoxInterface`対応
4. `import` / `export` の実装
### フェーズ2動的機能と管理
1. プラグインレジストリの実装
2. 動的ロード/アンロードAPIの提供
3. ID管理の洗練
### フェーズ3セキュリティと堅牢性
1. サンドボックスの導入
2. パフォーマンス分析ツールの提供
### フェーズ4開発者体験DXの向上
1. ドキュメントの整備
2. LSP/静的解析の対応
## 他言語からの学び
### Lua
- C APIが非常にクリーンで、Cの関数をLuaから、Luaの関数をCから呼び出すのが容易
- **学ぶべき点**: ネイティブとスクリプト間の境界APIをいかにシンプルで強力に保つか
### Node.js (JavaScript)
- `require()`システムが、C++で書かれたネイティブアドオンも、JavaScriptで書かれたモジュールも、全く同じように読み込む
- **学ぶべき点**: 統一されたモジュール解決システムとインターフェースの重要性
### Python
- Cで書かれた拡張モジュールと、Pure Pythonで書かれたモジュールが共存
- **学ぶべき点**: パフォーマンスが重要な部分はCで、それ以外は柔軟なPythonで書くという、実用的な使い分け
## 総括
この発見はNyashの方向性を決定づける重要なマイルストーンです。パフォーマンスが最重要視されるコアな機能はRust/C++のFFIプラグインで、それ以外の大部分の機能、ビジネスロジック、UI、ユーザーカスタマイズなどはNyashスクリプトプラグインで開発する、という美しい棲み分けが実現します。
これはNyashを単なるプログラミング言語から、**拡張可能なプラットフォーム**へと昇華させる可能性を秘めています。

View File

@ -0,0 +1,172 @@
# Nyashスクリプトプラグイン革命統合分析まとめ
## 🚀 革命的発見の本質
Nyashスクリプト自体でプラグインを作成できるという発見は、単なる機能追加ではなく、**Nyashの本質的な進化**を意味します。
### Everything is Boxの究極形
```
従来: Box = Rust/C++実装のオブジェクト
革命: Box = 実装言語を問わないインターフェース
```
この発見により、「Everything is Box」哲学が実装レイヤーの制約から解放され、真の意味で実現されます。
## 🎯 両先生の分析の統合
### 共通の評価ポイント
1. **技術的妥当性**: 極めて高い実現可能性
2. **エコシステムへの影響**: 開発者数の爆発的増加が期待
3. **実装アプローチ**: 統一インターフェースによる透過的利用
### 相補的な視点
| 観点 | Gemini先生 | Codex先生 |
|------|-----------|-----------|
| 焦点 | 哲学的整合性・他言語事例 | 具体的実装・パフォーマンス |
| 強み | エコシステム影響分析 | 技術アーキテクチャ設計 |
| 提案 | 段階的ロードマップ | 詳細な実装戦略 |
## 📊 統合実装計画
### 即時着手1-2週間
1. **Box ABI仕様策定**
- Gemini案のBoxInterfaceトレイト
- Codex案のUnifiedBoxInterface
- 両案を統合した最終仕様
2. **export box構文実装**
```nyash
export box PluginName {
// 必須:メタデータ提供
get_metadata() { ... }
// ビジネスロジック
method1() { ... }
method2() { ... }
}
```
3. **プロトタイプ実装**
- MathBoxを統一インターフェースに移行
- 簡単なNyashスクリプトプラグイン作成
### 中期目標1-2ヶ月
1. **動的プラグインシステム**
- ホットリロード機能
- 依存関係管理
- バージョン互換性
2. **開発ツール整備**
- プラグインテンプレート
- デバッグツール
- パフォーマンスプロファイラ
3. **セキュリティ基盤**
- サンドボックス実装
- ケイパビリティベース権限
### 長期ビジョン6ヶ月-1年
1. **プラグインエコシステム**
- マーケットプレイス構築
- 自動品質チェック
- コミュニティガイドライン
2. **高度な最適化**
- JIT統合
- プリコンパイル機能
- ネイティブ/スクリプトハイブリッド
## 🔑 成功の鍵
### 技術的成功要因
1. **シンプルな統一インターフェース**
- 学習コストを最小化
- 既存プラグインの移行を容易に
2. **段階的移行パス**
- 既存のFFIプラグインと共存
- 破壊的変更を避ける
3. **パフォーマンス配慮**
- ホットパスはネイティブ維持
- I/O boundタスクから適用
### エコシステム成功要因
1. **開発体験の劇的改善**
- ビルド不要
- 即座のフィードバック
- 豊富なサンプル
2. **コミュニティ形成**
- 初心者に優しいドキュメント
- アクティブなサポート
- 貢献への明確なパス
## 🎊 期待される成果
### 短期3-6ヶ月
- プラグイン開発者: 10→100人
- プラグイン数: 20→200個
- 開発速度: 10倍向上
### 中期1年
- 主要機能の8割がプラグイン化
- サードパーティエコシステム確立
- 企業採用事例の出現
### 長期3年
- デファクトスタンダード化
- 1000+のプラグイン
- 自立的エコシステム
## 🏁 結論
Nyashスクリプトプラグインシステムは、**技術的に実現可能**であり、**戦略的に必須**の進化です。
「Everything is Box」哲学の真の実現により、Nyashは単なるプログラミング言語から、**次世代の拡張可能プラットフォーム**へと進化します。
### 合言葉
> **"Write plugins in Nyash, for Nyash, by Nyash!"**
この革命により、Nyashコミュニティは爆発的な成長を遂げ、真に民主的なプログラミングエコシステムが誕生するでしょう。
---
## 📎 付録:クイックスタートガイド
### 最初のスクリプトプラグイン5分で作成
```nyash
# my_first_plugin.ny
export box MyFirstPlugin {
init {
_name = "My First Plugin"
_count = 0
}
greet(name) {
me._count = me._count + 1
return "Hello, " + name + "! (call #" + me._count.toString() + ")"
}
}
```
### 使用例
```nyash
# main.ny
local plugin = include("my_first_plugin.ny")
print(plugin.greet("World")) // "Hello, World! (call #1)"
print(plugin.greet("Nyash")) // "Hello, Nyash! (call #2)"
```
**ビルド不要、即実行!** これがNyashスクリプトプラグインの力です。