📚 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:
@ -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.6(Thread-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 Parser(1週)→ C2 Compiler Core(2週)→ C3 CLI配線(3日)→ C4 テスト(並行)
|
||||
- 既存導線の活用: 生成Nyashは既存 `--compile-native` でAOT化(Strict)
|
||||
|
||||
### Nyash-only パイプライン(作業場 / 最小導線)
|
||||
- 目的: すべてNyashで書き、即実行・即修正できる足場を先に用意
|
||||
- 追加ファイル: tools/pyc/
|
||||
- PythonParserNy.nyash(PyRuntimeBox経由で ast.parse/dump。NYASH_PY_CODE を参照)
|
||||
- PyIR.nyash(IR最小ヘルパ)/ PyCompiler.nyash(Nyash側コンパイラ骨組み)/ 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
|
||||
|
||||
@ -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 PluginInvoke(Python統合の実装着手)
|
||||
- 備考: 旧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フォルダに集約)
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
|
||||
|
||||
Note: 本来は「PythonをNyashで動かすフェーズ(パーサー統合)」の位置づけでしたが、現在は順番を変更し、先に 10.5b(MIR→VM→ネイティブビルド基盤)を進めています。
|
||||
|
||||
# Phase 10.1c - パーサー統合実装
|
||||
|
||||
## 🎯 このフェーズの目的
|
||||
@ -60,4 +62,4 @@ print(json_ast) // JSON ASTが表示される
|
||||
```
|
||||
|
||||
## ⏭️ 次のフェーズ
|
||||
→ Phase 10.1d (Core実装)
|
||||
→ Phase 10.1d (Core実装)
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
[Archived] 旧10.1系ドキュメントです。最新は ../INDEX.md を参照してください。
|
||||
|
||||
Note: 本来は「PythonをNyashで動かすフェーズ(Core実装)」の位置づけでしたが、現在は順番を変更し、先に 10.5b(MIR→VM→ネイティブビルド基盤)を進めています。
|
||||
|
||||
# Phase 10.1d - Core実装(Phase 1機能)
|
||||
|
||||
## 🎯 このフェーズの目的
|
||||
@ -71,4 +73,4 @@ def append_to_list(item, lst=[]): # 定義時に評価!
|
||||
```
|
||||
|
||||
## ⏭️ 次のフェーズ
|
||||
→ Phase 10.1e (トランスパイラー)
|
||||
→ Phase 10.1e (トランスパイラー)
|
||||
|
||||
@ -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)」→ 後から最適化。
|
||||
|
||||
|
||||
@ -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 境界の双方向化(3–5日)
|
||||
- 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で動作
|
||||
|
||||
87
docs/development/roadmap/phases/phase-10.6/PLAN.txt
Normal file
87
docs/development/roadmap/phases/phase-10.6/PLAN.txt
Normal 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: 協調スケジューラの足場
|
||||
- SingleThreadScheduler(queue + 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 Audit(1–2日)
|
||||
- ドキュメント: 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 Prep(1–2日)
|
||||
- 仕様固定: poll() を MIR Safepoint で呼ぶ(既実装の確認)
|
||||
- 観測: NYASH_SCHED_DEMO=1 / NYASH_SCHED_TRACE=1 / NYASH_SCHED_POLL_BUDGET で動作確認
|
||||
- 最小API: spawn/spawn_after/poll/yield_now(SingleThreadScheduler)
|
||||
- ドキュメント: phase-10/phase_10_6b_scheduler_prep.txt 更新(Trace/観測例追加済)
|
||||
|
||||
3.3) 10.6c Parallel GC Design(2–3日)
|
||||
- 設計メモ: 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.txt(Trace/デモ手順)
|
||||
- 10.6c 並列GC設計: phase-10/phase_10_6c_parallel_gc_design.txt(確定版)
|
||||
- Code
|
||||
- src/runtime/scheduler.rs(SingleThreadScheduler / Send+Sync)
|
||||
- MIR Safepoint → VM Runtime.scheduler.poll()(済)
|
||||
|
||||
====================
|
||||
5) リスクと緩和
|
||||
====================
|
||||
- 共有の粒度: 競合を避けるため、Box内部は最小限のロックで運用(RwLock優先)。
|
||||
- 並列前倒しの誘惑: 10.6では並列化を“設計と足場”に限定、実実装は次フェーズ(feature)
|
||||
- Plugin/FFI: クロススレッド呼出しは明示的に非対応(ドキュメントで制約明記)。
|
||||
|
||||
====================
|
||||
6) タイムライン(目安)
|
||||
====================
|
||||
- 10.6a: 1–2日
|
||||
- 10.6b: 1–2日
|
||||
- 10.6c: 2–3日
|
||||
|
||||
====================
|
||||
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)
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
# Phase 10.6 → Pythonネイティブ接続プラン(整理版 / txt)
|
||||
|
||||
目的: 10.6で整えたThread-Safety/Schedulerの最小足場の上に、Pythonプラグイン(PyRuntimeBox/PyObjectBox)をネイティブEXE(AOT)まで安定接続する。
|
||||
|
||||
====================
|
||||
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_result(Ok/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日(確認/微修正)
|
||||
- M2(TLV拡充): 1–2日(kwargsは暫定・bytes/JSON)
|
||||
- M3(Lowerer整流): 0.5–1日
|
||||
- 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(並列化前の足場)
|
||||
|
||||
67
docs/development/roadmap/phases/phase-10.7/PLAN.txt
Normal file
67
docs/development/roadmap/phases/phase-10.7/PLAN.txt
Normal file
@ -0,0 +1,67 @@
|
||||
# Phase 10.7 – Python Native 再スタート計画(合意版 / txt)
|
||||
|
||||
目的: 現行の Plugin-First(PyRuntimeBox/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)
|
||||
====================
|
||||
- サンプルpy(Phase 1 範囲内)を `pythonc`(仮)で Nyashスクリプトへ生成 → `--compile-native` で EXE 生成 → 実行。
|
||||
- 機能カバレッジ(Phase 1): def/if/for/while/return/bool/算術/比較/関数呼び出し/LEGB/デフォルト引数/for-else。
|
||||
- Differential(限定): Phase 1 サンプル群で CPython と一致(出力/戻り/例外の有無)。
|
||||
|
||||
====================
|
||||
C) サブフェーズとタスク
|
||||
====================
|
||||
C1) Parser Plugin(1週)
|
||||
- `plugins/nyash-python-parser-plugin`: Python→AST(pyo3)。
|
||||
- AST→CorePy IR(JSON): 構文の正規化(with→try/finally などはPhase 2)。
|
||||
- Telemetry: ノード統計/未対応ノードを列挙。
|
||||
|
||||
C2) Compiler Core(2週)
|
||||
- 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に対して適用)。
|
||||
|
||||
148
docs/development/roadmap/phases/phase-10.7/README.md
Normal file
148
docs/development/roadmap/phases/phase-10.7/README.md
Normal 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 Plugin(1週間)
|
||||
- PythonParserBoxの実装
|
||||
- Python AST → ASTBox変換
|
||||
- テレメトリー基盤
|
||||
|
||||
### Phase 10.7b - Compiler Core(2週間)
|
||||
**Phase 1機能(必須)**
|
||||
- 関数定義、条件分岐、ループ
|
||||
- 演算子、関数呼び出し
|
||||
- Python固有:LEGB、デフォルト引数、for/else
|
||||
|
||||
### Phase 10.7c - Validation & Testing(1週間)
|
||||
- コンパイル可能性の事前検証
|
||||
- Differential testing(CPythonと比較)
|
||||
- 明確なエラーメッセージ
|
||||
|
||||
### 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** - 技術分析
|
||||
@ -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.
|
||||
@ -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プロジェクトの成功に大きく貢献する戦略的な一手だと確信します。
|
||||
295
docs/development/roadmap/phases/phase-10.7/examples.md
Normal file
295
docs/development/roadmap/phases/phase-10.7/examples.md
Normal 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に匹敵!)
|
||||
```
|
||||
249
docs/development/roadmap/phases/phase-10.7/implementation.md
Normal file
249
docs/development/roadmap/phases/phase-10.7/implementation.md
Normal 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文
|
||||
285
docs/development/roadmap/phases/phase-10.7/testing-plan.md
Normal file
285
docs/development/roadmap/phases/phase-10.7/testing-plan.md
Normal 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ケース追加
|
||||
- [ ] ベンチマーク結果(該当する場合)
|
||||
- [ ] カバレッジ低下なし
|
||||
@ -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の最小拡張が必要になる場合あり。
|
||||
@ -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化する)。
|
||||
@ -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 に隔離(本流に混ぜない)
|
||||
|
||||
13
docs/development/roadmap/phases/phase-10.7/workbench/TODO.md
Normal file
13
docs/development/roadmap/phases/phase-10.7/workbench/TODO.md
Normal 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)を commit(with/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)
|
||||
@ -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
|
||||
|
||||
未確認/注意:
|
||||
- プラグインBox(PluginBoxV2)の内部FFIハンドルはVM/EXE側で共有参照のみ(実体はFFI側)。クロススレッド呼出しは未サポート運用(明記要)。
|
||||
- 一部のBoxで外部資源(ファイル/ネット)を扱う場合、スレッド越境のI/O同期設計は別途(Phase 10.6d+)。
|
||||
|
||||
## 次の一手(提案)
|
||||
- マーカーTraits(例: `ThreadSafeBox`)の導入は保留(破壊的)。現時点は監査+ドキュメントで運用。
|
||||
- 並列スケジューラ(M:N)の実装は `feature` フラグで段階導入。
|
||||
@ -5,6 +5,7 @@ What’s 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:
|
||||
|
||||
@ -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プラグインとして動作します!
|
||||
106
docs/development/roadmap/phases/phase-12/CRITICAL-ISSUE.md
Normal file
106
docs/development/roadmap/phases/phase-12/CRITICAL-ISSUE.md
Normal file
@ -0,0 +1,106 @@
|
||||
# 🚨 重大な設計問題:スクリプトプラグインとMIR/EXEの非互換性
|
||||
|
||||
## 問題の本質
|
||||
|
||||
**MIR/JIT/AOT(EXE)は、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の制約は、システムプログラミングの本質的な制約である。**
|
||||
@ -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引数の処理
|
||||
|
||||
### 現在のVM(Rust)
|
||||
```rust
|
||||
// VMValue → Box<dyn NyashBox>変換
|
||||
let val = self.get_value(*arg)?;
|
||||
Ok(val.to_nyash_box())
|
||||
```
|
||||
|
||||
### 埋め込みVM(C)
|
||||
```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で動作します!
|
||||
@ -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: 最小埋め込みVM(2-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で書いて、どこでも動く!**
|
||||
115
docs/development/roadmap/phases/phase-12/README.md
Normal file
115
docs/development/roadmap/phases/phase-12/README.md
Normal 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になる!*
|
||||
147
docs/development/roadmap/phases/phase-12/REVISED-PROPOSAL.md
Normal file
147
docs/development/roadmap/phases/phase-12/REVISED-PROPOSAL.md
Normal 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」の哲学は、実行時の制約はあれど、開発時の自由度として実現される。
|
||||
164
docs/development/roadmap/phases/phase-12/SOLUTION-EMBEDDED-VM.md
Normal file
164
docs/development/roadmap/phases/phase-12/SOLUTION-EMBEDDED-VM.md
Normal 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」が真に実現する!
|
||||
175
docs/development/roadmap/phases/phase-12/c-abi-compatibility.md
Normal file
175
docs/development/roadmap/phases/phase-12/c-abi-compatibility.md
Normal file
@ -0,0 +1,175 @@
|
||||
# C ABIとの整合性:Phase 12スクリプトプラグインシステム
|
||||
|
||||
## 🚨 重要な発見
|
||||
|
||||
Phase 10.1で既に**C ABI v0**が定義されており、これとPhase 12の提案を整合させる必要があります。
|
||||
|
||||
## 📊 現状のC ABI(Phase 10.1)
|
||||
|
||||
### 既存のBID-FFI(プラグイン用)
|
||||
```c
|
||||
// 現在のプラグインFFI(TLVベース)
|
||||
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 ABI(BID-FFI)を維持
|
||||
- ScriptPluginWrapperがブリッジとして機能
|
||||
|
||||
これにより、**「Everything is Plugin」**の哲学を保ちながら、スクリプトプラグインを実現できます。
|
||||
@ -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!"*
|
||||
@ -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を単なるプログラミング言語から、**拡張可能なプラットフォーム**へと昇華させる可能性を秘めています。
|
||||
@ -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スクリプトプラグインの力です。
|
||||
Reference in New Issue
Block a user