JIT cond path: keep compare result as b1; br_if accepts b1 or i64 (!=0); add branch_return to benchmark suite.
This commit is contained in:
@ -0,0 +1,197 @@
|
|||||||
|
# PythonParserBox実装計画 - エキスパートフィードバック
|
||||||
|
日付: 2025-08-27
|
||||||
|
|
||||||
|
## Gemini先生のフィードバック
|
||||||
|
|
||||||
|
### 総評
|
||||||
|
これは非常に野心的で、言語の成熟度を飛躍的に高める可能性を秘めた素晴らしい計画です。Nyashの「Everything is a Box」哲学とPythonエコシステムを融合させるという着眼点に大変興奮しました。
|
||||||
|
|
||||||
|
### 1. 実装計画は技術的に健全か?落とし穴は?
|
||||||
|
|
||||||
|
**技術的健全性:**
|
||||||
|
はい、計画は全体として技術的に非常に健全です。
|
||||||
|
|
||||||
|
* **CPythonパーサーの利用:** `pyo3`経由で`ast.parse()`を利用するのは、Python構文との互換性を100%保証するための最も確実で賢明なアプローチです。
|
||||||
|
* **JSON中間表現(IR):** Python AST (Pythonメモリ空間) と Nyash AST (Rustメモリ空間) の間にJSONを挟むのは、言語間の境界を明確に分離する良い設計です。
|
||||||
|
* **段階的実装とフォールバック:** 未実装機能を`exec()`にフォールバックする戦略は、実用性を保ちながら段階的に実装を進めるための極めて現実的なアプローチです。
|
||||||
|
|
||||||
|
**潜在的な落とし穴:**
|
||||||
|
* **パフォーマンス:** `Python AST → JSON → Nyash AST → Nyash実行`というパイプラインは、特に初期段階では非常に低速になります。
|
||||||
|
* **ASTの複雑性の爆発:** PythonのASTは非常に巨大で、言語バージョンの更新も速いです。
|
||||||
|
* **標準ライブラリの壁:** Pythonの真の力は広範な標準/サードパーティライブラリにあります。`import`文をどう扱うかは最重要課題です。
|
||||||
|
|
||||||
|
### 2. Python AST → Nyash AST変換で注意すべき意味論の違いは?
|
||||||
|
|
||||||
|
* **型システム:** Pythonは動的型付け、Nyashは静的型付けまたはより厳格な型システムを持つと推測
|
||||||
|
* **オブジェクトモデルと可変性:** Pythonのオブジェクトは基本的に可変(mutable)
|
||||||
|
* **スコープとクロージャ:** Pythonの`global`や`nonlocal`の挙動は独特
|
||||||
|
* **特殊メソッド (`__dunder__`):** Pythonの挙動は特殊メソッドで定義される
|
||||||
|
* **組み込み関数:** `len()`, `print()`, `range()`などをどう扱うか
|
||||||
|
|
||||||
|
### 3. Nyashパーサーのバグ検証戦略として効果的か?
|
||||||
|
|
||||||
|
**非常に効果的です。** これは「Differential Testing(差分テスト)」と呼ばれる強力な手法です。
|
||||||
|
* **巨大なテストスイート:** 事実上、世の中にある無数のPythonコードがNyashのテストケースになります。
|
||||||
|
* **微妙なバグの発見:** 手書きの単体テストでは見逃しがちなセマンティクスのバグを発見するのに絶大な効果を発揮します。
|
||||||
|
|
||||||
|
### 4. pyo3統合でのGIL管理のベストプラクティスは?
|
||||||
|
|
||||||
|
* **基本原則:** Pythonオブジェクトに触れるコードは、必ずGILを獲得した状態で実行
|
||||||
|
* **GILの必要期間を最小化する**
|
||||||
|
* **`py.allow_threads`の活用:** 時間がかかり、かつPythonオブジェクトに触れない処理で使用
|
||||||
|
|
||||||
|
### 5. 段階的実装(Phase 1-4)の優先順位は適切か?
|
||||||
|
|
||||||
|
はい、提案されている優先順位は非常に適切です。
|
||||||
|
1. Phase 1: 基本構文 + 変数束縛 + 基本的な式 + プリミティブ型
|
||||||
|
2. Phase 2: list, dict, tuple
|
||||||
|
3. Phase 3: 関数とスコープ
|
||||||
|
4. Phase 4: モジュールとクラス
|
||||||
|
|
||||||
|
**最優先で並行すべきこと:** `exec()`へのフォールバック機構
|
||||||
|
|
||||||
|
### 6. 言語成熟度向上への貢献度をどう評価する?
|
||||||
|
|
||||||
|
**定量的指標:**
|
||||||
|
* ライブラリ互換性カバレッジ
|
||||||
|
* パフォーマンステスト
|
||||||
|
* 発見バグ数
|
||||||
|
|
||||||
|
**定性的指標:**
|
||||||
|
* 表現力の向上
|
||||||
|
* 開発者体験
|
||||||
|
* エコシステムのマイルストーン
|
||||||
|
|
||||||
|
### 結論
|
||||||
|
|
||||||
|
この`PythonParserBox`計画は、単なる機能追加ではなく、**Nyash言語のテスト、デバッグ、そしてエコシステム獲得を同時に加速させる、極めて戦略的な一手**です。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Codex先生のフィードバック
|
||||||
|
|
||||||
|
### Overall Verdict
|
||||||
|
- Sound approach: Using CPython's parser via pyo3, lowering via a JSON IR, and gradually replacing exec() with Nyash MIR/JIT is feasible and strategically strong.
|
||||||
|
- Biggest risks: Semantic mismatches at statement/expression boundaries, version skew of Python AST, and boundary-costs between CPython and Nyash during phased rollout.
|
||||||
|
|
||||||
|
### Architectural Pitfalls
|
||||||
|
- **Python version skew:** `ast` schema changes across minors. Pin and encode `py_version` + `ast_format` in the JSON.
|
||||||
|
- **AST stability vs syntax fidelity:** `ast` loses comments and some token distinctions
|
||||||
|
- **Boundary granularity:** Whole-file fallback wastes partial coverage; per-node fallback is unsafe. **The practical unit is per-function.**
|
||||||
|
- **Import system and environment:** Python imports pull arbitrary code
|
||||||
|
- **Error mapping:** Propagate Python exceptions with full traceback
|
||||||
|
- **Performance overhead:** Python AST→JSON→Nyash→MIR is heavy
|
||||||
|
- **Object model mismatch:** Identity (`is`), mutability, truthiness, numeric tower
|
||||||
|
- **Concurrency:** GIL limits parallel parse/exec
|
||||||
|
|
||||||
|
### AST→Nyash Semantics: High-Risk Differences
|
||||||
|
- **Names and scope:**
|
||||||
|
- LEGB resolution; `global`/`nonlocal` behavior; closures and cell variables
|
||||||
|
- Comprehension scopes (separate scope in Python 3)
|
||||||
|
- **Control flow:**
|
||||||
|
- `for` iterates via iterator protocol; `for/else`, `while/else` semantics
|
||||||
|
- Short-circuit truthiness uses Python rules; `__bool__` then `__len__`
|
||||||
|
- **Functions:**
|
||||||
|
- Defaults evaluated at definition time; `*args/**kwargs`
|
||||||
|
- Decorators transform functions at definition time
|
||||||
|
- **Operators and numbers:**
|
||||||
|
- `/` true division; `//` floor division; big integers by default
|
||||||
|
- Operator dispatch via dunder methods; `is` vs `==`
|
||||||
|
|
||||||
|
For Phase 1, the must-haves are: LEGB + locals/freevars, default args timing, iterator-based `for`, `for/else` + `while/else`, Python truthiness and short-circuiting.
|
||||||
|
|
||||||
|
### Fallback Strategy
|
||||||
|
- **Fallback unit: Per-function.** If a function body contains unsupported nodes, compile a "PyThunk" that calls into CPython.
|
||||||
|
- **Boundary types:** Define canonical bridges: `PyAnyBox` in Nyash wrapping `Py<PyAny>`
|
||||||
|
- **Imports and globals:** Execute module top-level in Python; then selectively replace functions
|
||||||
|
|
||||||
|
### pyo3/GIL Best Practices
|
||||||
|
- **Initialization:** Call `pyo3::prepare_freethreaded_python()` once
|
||||||
|
- **GIL usage:**
|
||||||
|
- Use `Python::with_gil(|py| { ... })` for all Python calls
|
||||||
|
- Minimize time under GIL; copy data out promptly
|
||||||
|
- For heavy Rust work, drop GIL: `py.allow_threads(|| { ... })`
|
||||||
|
- **Data transfer:** Prefer building JSON on the Python side
|
||||||
|
- **Versioning:** Pin Python minor version; embed version string in the IR
|
||||||
|
|
||||||
|
### Phasing and Priorities (Refined)
|
||||||
|
- **Phase 1 (Parser + Minimal Semantics):**
|
||||||
|
- Python→JSON exporter with location info
|
||||||
|
- Nyash IR for expressions and basic statements
|
||||||
|
- Semantics fidelity for: iterator protocol, truthiness, scoping
|
||||||
|
- **Fallback per-function for anything else**
|
||||||
|
- **Phase 2-4:** Coverage expansion → Objects/Runtime → MIR/JIT
|
||||||
|
|
||||||
|
### Parser Bug Validation Strategy
|
||||||
|
- **Differential execution:** Curate pairs of semantically equivalent snippets
|
||||||
|
- **Oracle testing:** Run CPython as oracle and compare
|
||||||
|
- **Fuzzing:** Grammar-based fuzzers
|
||||||
|
- **Coverage and gating:** Track node-kind coverage
|
||||||
|
|
||||||
|
### IR/JSON Design Tips
|
||||||
|
- Include: `node_type`, children, `lineno/col_offset`, `py_version`, `ast_format`, `support_level`
|
||||||
|
- Canonicalize: normalize forms, operator names
|
||||||
|
- Determinism: maintain stable field ordering
|
||||||
|
|
||||||
|
### Concrete Recommendations
|
||||||
|
- **Pin to one Python minor (e.g., 3.11 or 3.12)**
|
||||||
|
- **Choose per-function fallback as the core boundary**
|
||||||
|
- **Implement Python truthiness, iterator protocol, and scoping correctly before optimizing**
|
||||||
|
- **Keep the GIL minimal: build the JSON in Python; parse in Rust**
|
||||||
|
- **Telemetry from day one: log unsupported node kinds and fallback counts**
|
||||||
|
- **Start with JSON; plan migration to a compact binary once stable**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 統合された重要ポイント
|
||||||
|
|
||||||
|
### 🎯 両エキスパートが一致した最重要事項
|
||||||
|
|
||||||
|
1. **関数単位のフォールバック戦略**
|
||||||
|
- ファイル全体でなく関数レベルでコンパイル/フォールバックを切り替え
|
||||||
|
- 未対応機能を含む関数はCPython exec、対応済み関数はNyash MIR/JIT
|
||||||
|
|
||||||
|
2. **Python バージョン固定**
|
||||||
|
- Python 3.11または3.12に固定
|
||||||
|
- AST安定性の確保とバージョン間の差異回避
|
||||||
|
|
||||||
|
3. **意味論の正確な実装が最優先**
|
||||||
|
- 最適化より先にPython互換性を確保
|
||||||
|
- 特に: イテレータプロトコル、真偽値判定、スコーピング規則
|
||||||
|
|
||||||
|
4. **GIL管理の最小化**
|
||||||
|
- Python側でJSON生成、Rust側で解析
|
||||||
|
- 重い処理はGIL外で実行
|
||||||
|
|
||||||
|
5. **テレメトリーの重要性**
|
||||||
|
- 未対応ノードの記録
|
||||||
|
- フォールバック率の計測
|
||||||
|
- 実行時の統計情報収集
|
||||||
|
|
||||||
|
### 🚨 特に注意すべき意味論の違い
|
||||||
|
|
||||||
|
1. **制御フロー**
|
||||||
|
- for/else, while/else の独特な挙動
|
||||||
|
- forループのイテレータプロトコル
|
||||||
|
|
||||||
|
2. **スコープ規則**
|
||||||
|
- LEGB(Local, Enclosing, Global, Builtins)
|
||||||
|
- global/nonlocal宣言
|
||||||
|
- 内包表記の独立スコープ(Python 3)
|
||||||
|
|
||||||
|
3. **数値演算**
|
||||||
|
- / (true division) vs // (floor division)
|
||||||
|
- デフォルトで大整数
|
||||||
|
- NaN の扱い
|
||||||
|
|
||||||
|
4. **関数定義**
|
||||||
|
- デフォルト引数は定義時に評価
|
||||||
|
- *args/**kwargs の扱い
|
||||||
|
- デコレータの実行順序
|
||||||
|
|
||||||
|
### 📊 成功の測定指標
|
||||||
|
|
||||||
|
1. **カバレッジ**: コンパイル済み vs フォールバック関数の比率
|
||||||
|
2. **性能向上**: 数値計算ベンチマークでの改善率
|
||||||
|
3. **バグ発見数**: Differential Testingで発見されたバグ数
|
||||||
|
4. **エコシステム**: 動作する有名Pythonライブラリの数
|
||||||
@ -0,0 +1,148 @@
|
|||||||
|
# PythonParserBox統合実装計画 - エキスパート評価後の最終版
|
||||||
|
作成日: 2025-08-27
|
||||||
|
|
||||||
|
## 🎯 革命的な3つの価値
|
||||||
|
|
||||||
|
### 1. Pythonエコシステムの即座活用
|
||||||
|
- 既存のPythonライブラリをNyashから直接利用可能
|
||||||
|
- 段階的な移行パスの提供
|
||||||
|
|
||||||
|
### 2. Nyashパーサーのバグ自動検証(Differential Testing)
|
||||||
|
- **世界中のPythonコードがNyashのテストケースに!**
|
||||||
|
- CPythonをオラクルとして使用、出力・戻り値・例外を自動比較
|
||||||
|
- 微妙なセマンティクスバグを大量に発見可能
|
||||||
|
|
||||||
|
### 3. 言語成熟度の飛躍的向上
|
||||||
|
- 実用的なPythonコードでNyashをストレステスト
|
||||||
|
- 発見されたバグ数が成熟度向上の定量的指標
|
||||||
|
|
||||||
|
## 🏆 エキスパート評価サマリー
|
||||||
|
|
||||||
|
### Gemini先生の評価
|
||||||
|
**「非常に野心的で、言語の成熟度を飛躍的に高める可能性を秘めた素晴らしい計画」**
|
||||||
|
|
||||||
|
- 技術的に健全なアプローチ
|
||||||
|
- pyo3経由のCPythonパーサー利用は最も確実
|
||||||
|
- Differential Testingは極めて強力な手法
|
||||||
|
|
||||||
|
### Codex先生の評価
|
||||||
|
**「Sound approach with strategic strength」**
|
||||||
|
|
||||||
|
- 関数単位フォールバックが実用的かつ効果的
|
||||||
|
- Python 3.11固定でAST安定性確保
|
||||||
|
- テレメトリー重視で継続的改善可能
|
||||||
|
|
||||||
|
## 🔑 統合された5つの核心戦略
|
||||||
|
|
||||||
|
### 1. 関数単位フォールバック(両エキスパート一致)
|
||||||
|
```python
|
||||||
|
def supported_function(): # → Nyash MIR/JIT
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
def unsupported_function(): # → CPython exec
|
||||||
|
yield from generator # Phase 1では未対応
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Python 3.11固定
|
||||||
|
- AST安定性確保(3.8 Constant統一、3.10 match/case、3.12位置情報)
|
||||||
|
- `py_version`と`ast_format`をJSON IRに埋め込む
|
||||||
|
|
||||||
|
### 3. 意味論の正確な実装優先
|
||||||
|
Phase 1必須要素(Codex先生強調):
|
||||||
|
- LEGB + locals/freevars(スコーピング)
|
||||||
|
- デフォルト引数の評価タイミング(定義時)
|
||||||
|
- イテレータベースのfor文
|
||||||
|
- for/else + while/else(Python独特)
|
||||||
|
- Python真偽値判定(`__bool__` → `__len__`)
|
||||||
|
- 短絡評価(and/or)
|
||||||
|
|
||||||
|
### 4. GIL管理の最小化
|
||||||
|
```rust
|
||||||
|
// GILは最小限に!
|
||||||
|
let json_ast = Python::with_gil(|py| {
|
||||||
|
py_helper.parse_to_json(py, code) // Python側でJSON生成
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// GIL外でRust処理
|
||||||
|
let nyash_ast = py.allow_threads(|| {
|
||||||
|
convert_json_to_nyash(json_ast)
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. テレメトリー基盤
|
||||||
|
```bash
|
||||||
|
[PythonParser] Module: example.py (Python 3.11)
|
||||||
|
Functions: 10 total
|
||||||
|
Compiled: 7 (70%)
|
||||||
|
Fallback: 3 (30%)
|
||||||
|
- async_function: unsupported node 'AsyncFunctionDef' at line 23
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 実装フェーズ(詳細版)
|
||||||
|
|
||||||
|
### Phase 0: 準備(1週間)
|
||||||
|
- [ ] Python 3.11.9環境固定
|
||||||
|
- [ ] テレメトリー基盤構築
|
||||||
|
- [ ] Differential Testingフレームワーク
|
||||||
|
- [ ] JSON IR仕様策定
|
||||||
|
|
||||||
|
### Phase 1: Core Subset(2週間)
|
||||||
|
- [ ] pyo3統合(prepare_freethreaded_python)
|
||||||
|
- [ ] 関数単位コンパイル判定器
|
||||||
|
- [ ] 基本構文(def/if/for/while/return)
|
||||||
|
- [ ] 意味論必須要素の実装
|
||||||
|
- [ ] CPythonとの出力比較テスト
|
||||||
|
|
||||||
|
### Phase 2: Data Model(3週間)
|
||||||
|
- [ ] 特殊メソッドマッピング
|
||||||
|
- [ ] list/dict/tuple実装
|
||||||
|
- [ ] 演算子オーバーロード
|
||||||
|
|
||||||
|
### Phase 3: Advanced Features(1ヶ月)
|
||||||
|
- [ ] 例外処理(try/except)
|
||||||
|
- [ ] with文、ジェネレータ
|
||||||
|
- [ ] 内包表記、デコレータ
|
||||||
|
|
||||||
|
## 📊 成功の測定基準
|
||||||
|
|
||||||
|
### 定量的指標
|
||||||
|
| 指標 | 目標 | 測定方法 |
|
||||||
|
|------|------|----------|
|
||||||
|
| カバレッジ率 | 70%以上 | コンパイル済み vs フォールバック関数 |
|
||||||
|
| 性能向上 | 2-10倍 | 純Pythonループのベンチマーク |
|
||||||
|
| バグ発見数 | 10+件/Phase | Differential Testing |
|
||||||
|
| エコシステム | 1以上 | 動作する有名ライブラリ数 |
|
||||||
|
|
||||||
|
### マイルストーン
|
||||||
|
- Phase 1: "Hello from Python in Nyash"が動作
|
||||||
|
- Phase 2: scikit-learnの基本アルゴリズムが動作
|
||||||
|
- Phase 3: FlaskのHello Worldが動作
|
||||||
|
- Phase 4: PyPIトップ100の30%が基本動作
|
||||||
|
|
||||||
|
## 🚨 注意すべき意味論の違い(トップ5)
|
||||||
|
|
||||||
|
1. **制御フロー**: for/else, while/else
|
||||||
|
2. **スコープ規則**: LEGB、global/nonlocal
|
||||||
|
3. **数値演算**: / (true division) vs //
|
||||||
|
4. **関数定義**: デフォルト引数は定義時評価
|
||||||
|
5. **真偽値判定**: Pythonの__bool__/__len__ルール
|
||||||
|
|
||||||
|
## 🎉 期待されるインパクト
|
||||||
|
|
||||||
|
### 技術的成果
|
||||||
|
- Pythonエコシステムの活用
|
||||||
|
- Nyashパーサーの品質向上
|
||||||
|
- 性能最適化の実証
|
||||||
|
|
||||||
|
### 戦略的価値
|
||||||
|
- 言語成熟度の飛躍的向上
|
||||||
|
- 開発者コミュニティの拡大
|
||||||
|
- 実用アプリケーション開発の加速
|
||||||
|
|
||||||
|
## 📝 結論
|
||||||
|
|
||||||
|
PythonParserBoxは、単なる機能追加ではなく、**Nyash言語のテスト、デバッグ、エコシステム獲得を同時に加速させる極めて戦略的なプロジェクト**。
|
||||||
|
|
||||||
|
両エキスパートの技術的評価と具体的な実装指針により、実現可能性が確認され、明確な実装パスが定まった。
|
||||||
|
|
||||||
|
**「Everything is Box」哲学を、言語の壁を超えて実現する革命的な一歩。**
|
||||||
@ -1,30 +1,50 @@
|
|||||||
# PythonParserBox ビルトインBox実装フロー
|
# PythonParserBox ビルトインBox実装フロー(エキスパート統合版)
|
||||||
~CPythonパーサー統合とPhase 1実装の具体的な流れ~
|
~CPythonパーサー統合とPhase 1実装の具体的な流れ~
|
||||||
|
更新日: 2025-08-27
|
||||||
|
|
||||||
## 🎯 全体の実装フロー
|
## 🎯 全体の実装フロー
|
||||||
|
|
||||||
### Step 1: ビルトインBoxとしての基盤作成
|
### Step 0: Python 3.11固定(エキスパート推奨)
|
||||||
|
```
|
||||||
|
- Python 3.11.9を使用(AST安定性確保)
|
||||||
|
- pyenvまたはpython3.11コマンドで固定
|
||||||
|
- py_versionとast_formatをJSON IRに必ず含める
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 1: ビルトインBoxとしての基盤作成
|
||||||
```
|
```
|
||||||
1. src/boxes/python_parser_box/mod.rs を作成
|
1. src/boxes/python_parser_box/mod.rs を作成
|
||||||
2. BoxBase + BoxCore統一アーキテクチャに準拠
|
2. BoxBase + BoxCore統一アーキテクチャに準拠
|
||||||
3. PythonParserBoxの基本構造を定義
|
3. PythonParserBoxの基本構造を定義
|
||||||
4. src/boxes/mod.rs に登録
|
4. src/boxes/mod.rs に登録
|
||||||
|
5. テレメトリー基盤を初期から組み込む
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: pyo3統合とCPythonパーサー接続
|
### Step 2: pyo3統合とCPythonパーサー接続
|
||||||
```
|
```
|
||||||
1. Cargo.tomlに pyo3依存関係追加
|
1. Cargo.tomlに pyo3依存関係追加
|
||||||
2. Python環境の自動初期化設定
|
2. pyo3::prepare_freethreaded_python()で一度だけ初期化
|
||||||
3. ast.parse()へのFFIブリッジ実装
|
3. ast.parse()へのFFIブリッジ実装
|
||||||
4. JSON中間表現への変換
|
4. JSON中間表現への変換(Python側でJSON生成)
|
||||||
|
5. GILは最小限に、py.allow_threads()でRust処理
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Phase 1機能の実装
|
### Step 3: Phase 1機能の実装(必須意味論要素)
|
||||||
```
|
```
|
||||||
1. 最小限のAST変換(def, if, for, return)
|
必須要素(Codex先生強調):
|
||||||
2. 基本的な式の変換(演算子、関数呼び出し)
|
- LEGBスコーピング + locals/freevars
|
||||||
3. Nyash ASTへのマッピング
|
- デフォルト引数の定義時評価
|
||||||
4. テストケースの作成
|
- イテレータプロトコル(for文)
|
||||||
|
- for/else + while/else
|
||||||
|
- Python真偽値判定
|
||||||
|
- 短絡評価(and/or)
|
||||||
|
|
||||||
|
実装手順:
|
||||||
|
1. 関数単位フォールバック戦略の実装
|
||||||
|
2. 基本的なAST変換(def, if, for, while, return)
|
||||||
|
3. 式の変換(算術/比較/論理演算子、関数呼び出し)
|
||||||
|
4. Nyash ASTへの意味論を保ったマッピング
|
||||||
|
5. Differential Testingフレームワーク
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📝 具体的な実装コード
|
## 📝 具体的な実装コード
|
||||||
@ -79,11 +99,32 @@ impl NyashBox for PythonParserBox {
|
|||||||
|
|
||||||
### 2. メソッド実装(Phase 1対応)
|
### 2. メソッド実装(Phase 1対応)
|
||||||
```rust
|
```rust
|
||||||
|
// テレメトリー用構造体
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CompilationTelemetry {
|
||||||
|
compiled_functions: Vec<String>,
|
||||||
|
fallback_functions: Vec<(String, String, usize)>, // (name, reason, lineno)
|
||||||
|
unsupported_nodes: HashMap<String, usize>, // node_type -> count
|
||||||
|
}
|
||||||
|
|
||||||
impl PythonParserBox {
|
impl PythonParserBox {
|
||||||
// コンストラクタ
|
// コンストラクタ
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> Result<Self, String> {
|
||||||
|
// 一度だけ初期化
|
||||||
|
static INIT: std::sync::Once = std::sync::Once::new();
|
||||||
|
INIT.call_once(|| {
|
||||||
|
pyo3::prepare_freethreaded_python();
|
||||||
|
});
|
||||||
|
|
||||||
// Python環境の初期化
|
// Python環境の初期化
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
|
// Python 3.11確認
|
||||||
|
let version = py.version_info();
|
||||||
|
if version.major != 3 || version.minor != 11 {
|
||||||
|
return Err(format!("Python 3.11 required, got {}.{}",
|
||||||
|
version.major, version.minor));
|
||||||
|
}
|
||||||
|
|
||||||
let helper = PyHelper::new(py)?;
|
let helper = PyHelper::new(py)?;
|
||||||
Ok(PythonParserBox {
|
Ok(PythonParserBox {
|
||||||
base: BoxBase::new(),
|
base: BoxBase::new(),
|
||||||
@ -109,13 +150,23 @@ impl PythonParserBox {
|
|||||||
converter.convert(py_ast)
|
converter.convert(py_ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 直接実行(最初はCPython exec、段階的にMIR実行へ)
|
// 直接実行(関数単位フォールバック)
|
||||||
pub fn run(&self, code: &str) -> Result<Box<dyn NyashBox>, String> {
|
pub fn run(&self, code: &str) -> Result<Box<dyn NyashBox>, String> {
|
||||||
// Phase 1: CPython exec経由
|
// まずJSON ASTを取得
|
||||||
let helper = self.py_helper.lock().unwrap();
|
let json_ast = self.parse_to_json(code)?;
|
||||||
Python::with_gil(|py| {
|
let py_ast: serde_json::Value = serde_json::from_str(&json_ast)?;
|
||||||
helper.exec_code(py, code)
|
|
||||||
})
|
// モジュール内の各関数をチェック
|
||||||
|
let compiler = FunctionCompiler::new();
|
||||||
|
let module_result = compiler.compile_module(&py_ast)?;
|
||||||
|
|
||||||
|
// テレメトリー出力(環境変数で制御)
|
||||||
|
if std::env::var("NYASH_PYTHONPARSER_TELEMETRY").is_ok() {
|
||||||
|
compiler.print_telemetry();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 実行(コンパイル済み関数はMIR、他はCPython)
|
||||||
|
module_result.execute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -126,21 +177,48 @@ impl PythonParserBox {
|
|||||||
const PYTHON_HELPER_CODE: &str = r#"
|
const PYTHON_HELPER_CODE: &str = r#"
|
||||||
import ast
|
import ast
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Python 3.11固定チェック
|
||||||
|
assert sys.version_info[:2] == (3, 11), f"Python 3.11 required, got {sys.version}"
|
||||||
|
|
||||||
def ast_to_dict(node):
|
def ast_to_dict(node):
|
||||||
"""Phase 1: 基本的なAST要素のみ変換"""
|
"""Phase 1: 基本的なAST要素のみ変換(エキスパート推奨JSON IR)"""
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"node_type": node.__class__.__name__,
|
||||||
|
"py_version": "3.11",
|
||||||
|
"ast_format": "v1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 位置情報(エラー診断用)
|
||||||
|
if hasattr(node, 'lineno'):
|
||||||
|
result['lineno'] = node.lineno
|
||||||
|
result['col_offset'] = node.col_offset
|
||||||
|
if hasattr(node, 'end_lineno'):
|
||||||
|
result['end_lineno'] = node.end_lineno
|
||||||
|
result['end_col_offset'] = node.end_col_offset
|
||||||
if isinstance(node, ast.Module):
|
if isinstance(node, ast.Module):
|
||||||
return {
|
return {
|
||||||
"type": "Module",
|
"type": "Module",
|
||||||
"body": [ast_to_dict(stmt) for stmt in node.body]
|
"body": [ast_to_dict(stmt) for stmt in node.body]
|
||||||
}
|
}
|
||||||
elif isinstance(node, ast.FunctionDef):
|
elif isinstance(node, ast.FunctionDef):
|
||||||
return {
|
# 意味論上重要:デフォルト引数情報を保存
|
||||||
"type": "FunctionDef",
|
args_info = {
|
||||||
"name": node.name,
|
|
||||||
"args": [arg.arg for arg in node.args.args],
|
"args": [arg.arg for arg in node.args.args],
|
||||||
"body": [ast_to_dict(stmt) for stmt in node.body]
|
"defaults": [ast_to_dict(default) for default in node.args.defaults],
|
||||||
|
"kwonlyargs": [arg.arg for arg in node.args.kwonlyargs],
|
||||||
|
"kw_defaults": [ast_to_dict(d) if d else None for d in node.args.kw_defaults]
|
||||||
}
|
}
|
||||||
|
result.update({
|
||||||
|
"name": node.name,
|
||||||
|
"args": args_info,
|
||||||
|
"body": [ast_to_dict(stmt) for stmt in node.body],
|
||||||
|
"decorator_list": [], # Phase 1では未対応
|
||||||
|
"support_level": "full" # コンパイル可能
|
||||||
|
})
|
||||||
|
return result
|
||||||
elif isinstance(node, ast.Return):
|
elif isinstance(node, ast.Return):
|
||||||
return {
|
return {
|
||||||
"type": "Return",
|
"type": "Return",
|
||||||
@ -177,21 +255,42 @@ def ast_to_dict(node):
|
|||||||
"orelse": [ast_to_dict(stmt) for stmt in node.orelse]
|
"orelse": [ast_to_dict(stmt) for stmt in node.orelse]
|
||||||
}
|
}
|
||||||
elif isinstance(node, ast.For):
|
elif isinstance(node, ast.For):
|
||||||
return {
|
# 意味論上重要:for/else構文
|
||||||
"type": "For",
|
result.update({
|
||||||
"target": ast_to_dict(node.target),
|
"target": ast_to_dict(node.target),
|
||||||
"iter": ast_to_dict(node.iter),
|
"iter": ast_to_dict(node.iter),
|
||||||
"body": [ast_to_dict(stmt) for stmt in node.body]
|
"body": [ast_to_dict(stmt) for stmt in node.body],
|
||||||
}
|
"orelse": [ast_to_dict(stmt) for stmt in node.orelse], # else節
|
||||||
|
"support_level": "full"
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
elif isinstance(node, ast.While):
|
elif isinstance(node, ast.While):
|
||||||
return {
|
# 意味論上重要:while/else構文
|
||||||
"type": "While",
|
result.update({
|
||||||
"test": ast_to_dict(node.test),
|
"test": ast_to_dict(node.test),
|
||||||
"body": [ast_to_dict(stmt) for stmt in node.body]
|
"body": [ast_to_dict(stmt) for stmt in node.body],
|
||||||
}
|
"orelse": [ast_to_dict(stmt) for stmt in node.orelse], # else節
|
||||||
|
"support_level": "full"
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
elif isinstance(node, ast.BoolOp):
|
||||||
|
# 意味論上重要:短絡評価
|
||||||
|
result.update({
|
||||||
|
"op": node.op.__class__.__name__, # And, Or
|
||||||
|
"values": [ast_to_dict(v) for v in node.values],
|
||||||
|
"support_level": "full"
|
||||||
|
})
|
||||||
|
return result
|
||||||
else:
|
else:
|
||||||
# Phase 1では未対応
|
# Phase 1では未対応(テレメトリー用)
|
||||||
return {"type": "Unsupported", "node": str(type(node))}
|
return {
|
||||||
|
"node_type": "Unsupported",
|
||||||
|
"original_type": type(node).__name__,
|
||||||
|
"support_level": "fallback",
|
||||||
|
"lineno": getattr(node, 'lineno', -1)
|
||||||
|
}
|
||||||
|
|
||||||
def parse_to_json(code):
|
def parse_to_json(code):
|
||||||
try:
|
try:
|
||||||
@ -405,6 +504,50 @@ local result = py.run(code + "\nprint(calculate(10, 5))")
|
|||||||
4. **性能測定基盤**
|
4. **性能測定基盤**
|
||||||
- CPython実行 vs Nyash実行の比較
|
- CPython実行 vs Nyash実行の比較
|
||||||
|
|
||||||
|
## 📡 テレメトリー出力例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 環境変数で制御
|
||||||
|
export NYASH_PYTHONPARSER_TELEMETRY=1 # 基本統計
|
||||||
|
export NYASH_PYTHONPARSER_TELEMETRY=2 # 詳細ログ
|
||||||
|
export NYASH_PYTHONPARSER_STRICT=1 # フォールバック時にパニック
|
||||||
|
|
||||||
|
# 実行例
|
||||||
|
./target/release/nyash test_python_parser.nyash
|
||||||
|
|
||||||
|
# 出力
|
||||||
|
[PythonParser] Module: test.py (Python 3.11)
|
||||||
|
Functions: 10 total
|
||||||
|
Compiled: 7 (70%) → Nyash MIR/JIT
|
||||||
|
Fallback: 3 (30%) → CPython exec
|
||||||
|
- async_function: unsupported node 'AsyncFunctionDef' at line 23
|
||||||
|
- generator_func: unsupported node 'Yield' at line 45
|
||||||
|
- decorator_func: unsupported node 'decorator_list' at line 67
|
||||||
|
|
||||||
|
Unsupported Nodes Summary:
|
||||||
|
AsyncFunctionDef: 1
|
||||||
|
Yield: 2
|
||||||
|
ClassDef: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Differential Testingフレームワーク
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// CPythonとNyashの出力比較
|
||||||
|
pub fn differential_test(code: &str) -> TestResult {
|
||||||
|
// CPythonで実行(オラクル)
|
||||||
|
let python_result = Python::with_gil(|py| {
|
||||||
|
capture_python_execution(py, code)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Nyashで実行
|
||||||
|
let nyash_result = execute_with_pythonparser(code)?;
|
||||||
|
|
||||||
|
// 結果比較
|
||||||
|
compare_results(python_result, nyash_result)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
作成日: 2025-08-27
|
作成日: 2025-08-27
|
||||||
Phase 1実装の具体的な手順とコード例
|
Phase 1実装の具体的な手順とエキスパートフィードバック統合
|
||||||
@ -0,0 +1,361 @@
|
|||||||
|
# PythonParserBox実装計画(統合版)
|
||||||
|
更新日: 2025-08-27
|
||||||
|
|
||||||
|
## 🎯 エキスパートからの統合フィードバック
|
||||||
|
|
||||||
|
### 最重要ポイント(両エキスパートが一致)
|
||||||
|
1. **関数単位のフォールバック戦略**
|
||||||
|
- ファイル全体でなく関数レベルでコンパイル/フォールバックを切り替え
|
||||||
|
- 未対応機能を含む関数はCPython exec、対応済み関数はNyash MIR/JIT
|
||||||
|
|
||||||
|
2. **Python 3.11固定**
|
||||||
|
- AST安定性の確保(3.8 Constant統一、3.10 match/case、3.12位置情報)
|
||||||
|
- `py_version`と`ast_format`をJSON IRに埋め込む
|
||||||
|
|
||||||
|
3. **意味論の正確な実装が最優先**
|
||||||
|
- 最適化より先にPython互換性を確保
|
||||||
|
- 特に: イテレータプロトコル、真偽値判定、スコーピング規則(LEGB)
|
||||||
|
|
||||||
|
4. **GIL管理の最小化**
|
||||||
|
- Python側でJSON生成(`ast.NodeVisitor` + `json.dumps`)
|
||||||
|
- Rust側で解析(GIL外で実行)
|
||||||
|
- `py.allow_threads(|| { ... })`で重い処理をGIL外実行
|
||||||
|
|
||||||
|
5. **テレメトリー重視**
|
||||||
|
- 未対応ノードの記録(`support_level`フィールド)
|
||||||
|
- フォールバック率の計測
|
||||||
|
- ソース位置情報の保持(`lineno/col_offset/end_*`)
|
||||||
|
|
||||||
|
### Differential Testing戦略
|
||||||
|
- **世界中のPythonコードがNyashのテストケース**
|
||||||
|
- CPythonを「オラクル」として使用
|
||||||
|
- 出力、戻り値、例外を比較
|
||||||
|
- Grammar-based fuzzing(Hypothesis活用)
|
||||||
|
|
||||||
|
## 技術的実装方針
|
||||||
|
|
||||||
|
### 1. CPythonパーサー統合(pyo3使用)
|
||||||
|
```rust
|
||||||
|
// Cargo.toml
|
||||||
|
[dependencies]
|
||||||
|
pyo3 = { version = "0.22", features = ["auto-initialize"] }
|
||||||
|
pyo3-numpy = "0.22" // NumPy連携用
|
||||||
|
|
||||||
|
// 初期化(一度だけ)
|
||||||
|
pyo3::prepare_freethreaded_python();
|
||||||
|
|
||||||
|
// Python側ヘルパー(embedded)
|
||||||
|
const PYTHON_HELPER: &str = r#"
|
||||||
|
import ast
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def parse_to_json(code, filename="<string>", mode="exec"):
|
||||||
|
tree = ast.parse(code, filename, mode)
|
||||||
|
return json.dumps(ast_to_dict(tree))
|
||||||
|
|
||||||
|
def ast_to_dict(node):
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
# 必須フィールド
|
||||||
|
result['node_type'] = node.__class__.__name__
|
||||||
|
result['py_version'] = f"{sys.version_info.major}.{sys.version_info.minor}"
|
||||||
|
|
||||||
|
# 位置情報(エラー診断用)
|
||||||
|
if hasattr(node, 'lineno'):
|
||||||
|
result['lineno'] = node.lineno
|
||||||
|
result['col_offset'] = node.col_offset
|
||||||
|
if hasattr(node, 'end_lineno'): # Python 3.8+
|
||||||
|
result['end_lineno'] = node.end_lineno
|
||||||
|
result['end_col_offset'] = node.end_col_offset
|
||||||
|
|
||||||
|
# サポートレベル(Nyash側で設定)
|
||||||
|
result['support_level'] = 'unknown'
|
||||||
|
|
||||||
|
# ASTフィールド
|
||||||
|
if isinstance(node, ast.AST):
|
||||||
|
for field in node._fields:
|
||||||
|
value = getattr(node, field)
|
||||||
|
result[field] = ast_to_dict(value)
|
||||||
|
elif isinstance(node, list):
|
||||||
|
return [ast_to_dict(x) for x in node]
|
||||||
|
else:
|
||||||
|
return node
|
||||||
|
|
||||||
|
return result
|
||||||
|
"#;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 最小実装セット(Phase 1: Must-Have)
|
||||||
|
```
|
||||||
|
Phase 1 意味論の必須要素(Codex先生強調):
|
||||||
|
- LEGB + locals/freevars(スコーピング)
|
||||||
|
- デフォルト引数の評価タイミング(定義時)
|
||||||
|
- イテレータベースのfor文
|
||||||
|
- for/else + while/else(Python独特)
|
||||||
|
- Python真偽値判定(__bool__ → __len__)
|
||||||
|
- 短絡評価(and/or)
|
||||||
|
|
||||||
|
Phase 1 AST構造:
|
||||||
|
├─ Module (py_version, ast_format)
|
||||||
|
├─ FunctionDef (name, args, body, decorator_list=[])
|
||||||
|
│ └─ arguments (args, defaults, kwonlyargs=[], kw_defaults=[])
|
||||||
|
├─ Return (value)
|
||||||
|
├─ Assign (targets, value)
|
||||||
|
├─ AugAssign (target, op, value) # +=, -=等
|
||||||
|
└─ Expr (value)
|
||||||
|
|
||||||
|
Phase 1 式:
|
||||||
|
├─ BinOp (left, op, right)
|
||||||
|
│ └─ ops: Add, Sub, Mult, Div, FloorDiv, Mod, Pow
|
||||||
|
├─ Compare (left, ops, comparators)
|
||||||
|
│ └─ ops: Eq, NotEq, Lt, LtE, Gt, GtE, Is, IsNot
|
||||||
|
├─ BoolOp (op, values) # and/or
|
||||||
|
├─ UnaryOp (op, operand) # not, -, +
|
||||||
|
├─ Call (func, args, keywords=[])
|
||||||
|
├─ Name (id, ctx=Load/Store/Del)
|
||||||
|
├─ Constant (value) # Python 3.8+統一
|
||||||
|
└─ IfExp (test, body, orelse) # 三項演算子
|
||||||
|
|
||||||
|
Phase 1 制御フロー:
|
||||||
|
├─ If (test, body, orelse)
|
||||||
|
├─ While (test, body, orelse) # else節対応必須
|
||||||
|
├─ For (target, iter, body, orelse) # else節対応必須
|
||||||
|
├─ Break
|
||||||
|
└─ Continue
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 関数単位フォールバック戦略
|
||||||
|
```rust
|
||||||
|
// 関数単位のコンパイル判定
|
||||||
|
pub struct FunctionCompiler {
|
||||||
|
supported_nodes: HashSet<&'static str>,
|
||||||
|
telemetry: CompilationTelemetry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FunctionCompiler {
|
||||||
|
pub fn can_compile(&self, func_def: &PythonAst) -> CompileResult {
|
||||||
|
let mut visitor = SupportChecker::new(&self.supported_nodes);
|
||||||
|
visitor.visit(func_def);
|
||||||
|
|
||||||
|
if visitor.has_unsupported() {
|
||||||
|
// CPython execへフォールバック
|
||||||
|
CompileResult::Fallback {
|
||||||
|
reason: visitor.unsupported_nodes(),
|
||||||
|
location: func_def.location(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Nyash MIR/JITへコンパイル
|
||||||
|
CompileResult::Compile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compile_module(&mut self, module: &PythonAst) -> ModuleUnit {
|
||||||
|
let mut units = vec![];
|
||||||
|
|
||||||
|
// モジュールトップレベルはPythonで実行(globals設定)
|
||||||
|
units.push(ExecutionUnit::PythonExec(module.top_level));
|
||||||
|
|
||||||
|
// 各関数を判定
|
||||||
|
for func in module.functions() {
|
||||||
|
match self.can_compile(func) {
|
||||||
|
CompileResult::Compile => {
|
||||||
|
let mir = self.compile_to_mir(func);
|
||||||
|
units.push(ExecutionUnit::NyashFunction(mir));
|
||||||
|
self.telemetry.record_compiled(func.name);
|
||||||
|
}
|
||||||
|
CompileResult::Fallback { reason, location } => {
|
||||||
|
units.push(ExecutionUnit::PythonThunk(func));
|
||||||
|
self.telemetry.record_fallback(func.name, reason, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleUnit { units }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. データ共有戦略
|
||||||
|
```rust
|
||||||
|
// NdArrayBox定義
|
||||||
|
pub struct NdArrayBox {
|
||||||
|
base: BoxBase,
|
||||||
|
py_array: Py<PyArray<f64, Dim<[usize; 2]>>>, // Python側の参照保持
|
||||||
|
// 操作時のみGIL取得してArrayViewを取る
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NdArrayBox {
|
||||||
|
pub fn to_view(&self) -> PyResult<ArrayView2<f64>> {
|
||||||
|
Python::with_gil(|py| {
|
||||||
|
let array = self.py_array.as_ref(py);
|
||||||
|
Ok(array.readonly())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 実装ロードマップ
|
||||||
|
|
||||||
|
#### Phase 1: パーサー統合(1-2週間)
|
||||||
|
- [ ] pyo3セットアップとPythonParserBox骨格
|
||||||
|
- [ ] Python側parse_to_jsonヘルパー実装
|
||||||
|
- [ ] JSON→Nyash AST最小変換
|
||||||
|
- [ ] run()メソッド(CPython exec委譲)
|
||||||
|
- [ ] 例外変換(PyErr → NyashError)
|
||||||
|
|
||||||
|
#### Phase 2: MIR変換(2-4週間)
|
||||||
|
- [ ] AST→MIR変換器(最小セット)
|
||||||
|
- [ ] 数値演算プリミティブ実装
|
||||||
|
- [ ] スコープ解決(関数ローカル/グローバル)
|
||||||
|
- [ ] 基本的な制御フロー(If/While)
|
||||||
|
|
||||||
|
#### Phase 3: NumPy統合(並行可能)
|
||||||
|
- [ ] pyo3-numpy統合
|
||||||
|
- [ ] NdArrayBox実装
|
||||||
|
- [ ] ゼロコピーベンチマーク
|
||||||
|
- [ ] バッファプロトコル対応
|
||||||
|
|
||||||
|
#### Phase 4: 最適化と拡張
|
||||||
|
- [ ] 型特化とガード最適化
|
||||||
|
- [ ] 例外処理(try/except)
|
||||||
|
- [ ] クラス/メソッド対応
|
||||||
|
- [ ] import統合
|
||||||
|
|
||||||
|
## 性能目標(現実的な見積もり)
|
||||||
|
|
||||||
|
| コードタイプ | 期待される高速化 | 備考 |
|
||||||
|
|------------|----------------|------|
|
||||||
|
| 純Pythonループ | 2-10倍 | 型安定なホットパス |
|
||||||
|
| 関数呼び出し多 | 1.5-3倍 | インライン化効果 |
|
||||||
|
| NumPy処理中心 | 1.0-1.2倍 | 既に最適化済み |
|
||||||
|
| 動的特性多用 | 1.2-3倍 | ガード頻発で限定的 |
|
||||||
|
|
||||||
|
## 実装上の注意点(エキスパート推奨)
|
||||||
|
|
||||||
|
### 意味論の重要な違い(Phase 1で対応必須)
|
||||||
|
|
||||||
|
1. **制御フロー**
|
||||||
|
- `for`文: イテレータプロトコル必須(`__iter__`/`__next__`)
|
||||||
|
- `for/else`, `while/else`: breakしなかった場合のelse実行
|
||||||
|
- 短絡評価: `and`は左がFalseなら右を評価しない
|
||||||
|
|
||||||
|
2. **スコープ規則(LEGB)**
|
||||||
|
```python
|
||||||
|
# Local → Enclosing → Global → Builtins
|
||||||
|
global_var = 1
|
||||||
|
|
||||||
|
def outer():
|
||||||
|
enclosing_var = 2
|
||||||
|
|
||||||
|
def inner():
|
||||||
|
local_var = 3
|
||||||
|
nonlocal enclosing_var # 明示的な宣言
|
||||||
|
global global_var # 明示的な宣言
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **数値演算の違い**
|
||||||
|
- `/`: Python 3では常にfloat(true division)
|
||||||
|
- `//`: floor division(整数除算)
|
||||||
|
- 大整数: デフォルトで無限精度
|
||||||
|
- `is` vs `==`: オブジェクト同一性 vs 値の等価性
|
||||||
|
|
||||||
|
4. **関数定義の罠**
|
||||||
|
```python
|
||||||
|
def f(x, y=[]): # デフォルト引数は定義時に1度だけ評価!
|
||||||
|
y.append(x) # 全呼び出しで同じリストを共有
|
||||||
|
return y
|
||||||
|
```
|
||||||
|
|
||||||
|
### GIL管理のベストプラクティス
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ❌ 悪い例: GILを長時間保持
|
||||||
|
let result = Python::with_gil(|py| {
|
||||||
|
let ast = parse_python(py, code)?;
|
||||||
|
let json = convert_to_json(py, ast)?; // ここまでGIL必要
|
||||||
|
let nyash_ast = parse_json(&json)?; // GIL不要なのに保持
|
||||||
|
compile_to_mir(nyash_ast)? // GIL不要なのに保持
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ 良い例: GILを最小限に
|
||||||
|
let json = Python::with_gil(|py| {
|
||||||
|
let ast = parse_python(py, code)?;
|
||||||
|
convert_to_json(py, ast) // JSON生成まで
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// GIL外で重い処理
|
||||||
|
let nyash_ast = parse_json(&json)?;
|
||||||
|
let mir = compile_to_mir(nyash_ast)?;
|
||||||
|
|
||||||
|
// 必要時のみ再取得
|
||||||
|
Python::with_gil(|py| {
|
||||||
|
py.allow_threads(|| {
|
||||||
|
// 時間のかかるRust処理
|
||||||
|
optimize_mir(mir)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### テレメトリーとデバッグ
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// 環境変数で制御
|
||||||
|
NYASH_PYTHONPARSER_TELEMETRY=1 # 基本統計
|
||||||
|
NYASH_PYTHONPARSER_TELEMETRY=2 # 詳細ログ
|
||||||
|
NYASH_PYTHONPARSER_STRICT=1 # フォールバック時にパニック(CI用)
|
||||||
|
|
||||||
|
// 出力例
|
||||||
|
[PythonParser] Module: example.py
|
||||||
|
Functions: 10 total
|
||||||
|
Compiled: 7 (70%)
|
||||||
|
Fallback: 3 (30%)
|
||||||
|
- async_function: unsupported node 'AsyncFunctionDef' at line 23
|
||||||
|
- generator_func: unsupported node 'Yield' at line 45
|
||||||
|
- class_method: unsupported node 'ClassDef' at line 67
|
||||||
|
```
|
||||||
|
|
||||||
|
## 次のステップ
|
||||||
|
|
||||||
|
### 即座に開始すべきこと
|
||||||
|
|
||||||
|
1. **Python 3.11環境固定**
|
||||||
|
```bash
|
||||||
|
pyenv install 3.11.9
|
||||||
|
pyenv local 3.11.9
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **最小動作確認**
|
||||||
|
```python
|
||||||
|
# test_minimal.py
|
||||||
|
def add(x, y):
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
result = add(10, 5)
|
||||||
|
print(f"Result: {result}") # → Nyashで15が出力されれば成功!
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **テレメトリー基盤構築**
|
||||||
|
- 未対応ノードの記録システム
|
||||||
|
- フォールバック率の可視化
|
||||||
|
- ソース位置情報の保持
|
||||||
|
|
||||||
|
4. **Differential Testingの準備**
|
||||||
|
- CPythonとの出力比較フレームワーク
|
||||||
|
- 標準出力、戻り値、例外のキャプチャ
|
||||||
|
- テストコーパスの選定
|
||||||
|
|
||||||
|
### 成功の測定基準
|
||||||
|
|
||||||
|
| フェーズ | 目標 | 測定指標 |
|
||||||
|
|---------|------|----------|
|
||||||
|
| Phase 1 | 基本動作 | 簡単な数値計算の70%がコンパイル可能 |
|
||||||
|
| Phase 2 | 実用性 | scikit-learnの基本アルゴリズムが動作 |
|
||||||
|
| Phase 3 | 性能 | 純Pythonループで5倍以上の高速化 |
|
||||||
|
| Phase 4 | 成熟度 | PyPIトップ100の30%が基本動作 |
|
||||||
|
|
||||||
|
## まとめ
|
||||||
|
|
||||||
|
このPythonParserBox実装は、単なる機能追加ではなく、Nyash言語の成熟度を飛躍的に高める戦略的プロジェクト。
|
||||||
|
エキスパートの指摘を踏まえ、関数単位のフォールバック、Python 3.11固定、意味論の正確な実装、
|
||||||
|
GIL最小化、テレメトリー重視で着実に実装を進める。
|
||||||
@ -1,42 +1,73 @@
|
|||||||
# PythonParserBox 実装ロードマップ
|
# PythonParserBox 実装ロードマップ(エキスパート統合版)
|
||||||
Based on ChatGPT5's Python Language Feature Surface Map
|
Based on ChatGPT5's Python Language Feature Surface Map + Expert Feedback
|
||||||
|
更新日: 2025-08-27
|
||||||
|
|
||||||
## 🎯 実装優先順位の考え方
|
## 🎯 実装優先順位の考え方(エキスパート統合)
|
||||||
|
|
||||||
### 1. 最小限の価値を早く提供
|
### 🏯 核心戦略:関数単位フォールバック
|
||||||
- まずPythonコードが「動く」状態を作る
|
**両エキスパートが強調:** ファイル全体ではなく、**関数単位**でコンパイル/フォールバックを判断
|
||||||
- 完璧な言語機能カバレッジより、実用的なサブセットを優先
|
```python
|
||||||
|
def supported_function(): # → Nyash MIR/JIT
|
||||||
|
return x + y
|
||||||
|
|
||||||
### 2. Nyashの強みを活かせる部分から
|
def unsupported_function(): # → CPython exec
|
||||||
- ループ最適化(for/while → MIR/JIT高速化)
|
yield from generator # Phase 1では未対応
|
||||||
- 関数呼び出し(def → BoxCall高速化)
|
```
|
||||||
- 数値計算(BinOp → ネイティブ性能)
|
|
||||||
|
|
||||||
### 3. 段階的な拡張を可能にする設計
|
### 🔧 Python 3.11固定
|
||||||
- 未実装機能はCPython execへフォールバック
|
- AST安定性確保(3.8 Constant統一、3.10 match/case、3.12位置情報)
|
||||||
- 実装済み機能から徐々にMIR変換を拡大
|
- `py_version`と`ast_format`をJSON IRに埋め込む
|
||||||
|
|
||||||
|
### 🌟 Differential Testing戦略
|
||||||
|
- **世界中のPythonコードがNyashのテストケースに**
|
||||||
|
- CPythonをオラクルとして使用、出力・戻り値・例外を比較
|
||||||
|
- 微妙なセマンティクスバグを自動発見
|
||||||
|
|
||||||
|
### 📊 テレメトリー重視
|
||||||
|
- 未対応ノードの記録(`support_level`フィールド)
|
||||||
|
- フォールバック率の計測
|
||||||
|
- ソース位置情報保持(`lineno/col_offset/end_*`)
|
||||||
|
|
||||||
## 📋 Phase 1: Core Subset(1-2週間)
|
## 📋 Phase 1: Core Subset(1-2週間)
|
||||||
**目標**: 基本的なPythonコードをNyashで実行可能にする
|
**目標**: 基本的なPythonコードをNyashで実行可能にする
|
||||||
|
|
||||||
|
### ❌ Phase 1での必須意味論要素(Codex先生強調)
|
||||||
|
- **LEGB + locals/freevars**: スコーピング規則
|
||||||
|
- **デフォルト引数の評価タイミング**: 定義時に一度だけ
|
||||||
|
- **イテレータベースのfor文**: `__iter__`/`__next__`プロトコル
|
||||||
|
- **for/else + while/else**: Python独特のelse節
|
||||||
|
- **Python真偽値判定**: `__bool__` → `__len__`
|
||||||
|
- **短絡評価**: and/orの正確な挙動
|
||||||
|
|
||||||
### 文(Statement)
|
### 文(Statement)
|
||||||
- [x] def - 関数定義 → Nyash関数/Box
|
- [x] def - 関数定義 → Nyash関数/Box
|
||||||
|
- デフォルト引数の定義時評価
|
||||||
|
- argumentsオブジェクトの完全解析
|
||||||
- [x] if/elif/else - 条件分岐 → CondBr
|
- [x] if/elif/else - 条件分岐 → CondBr
|
||||||
- [x] for - ループ → Loop + Iterator
|
- [x] for - ループ → Loop + Iterator
|
||||||
- [x] while - ループ → Loop
|
- **else節対応必須**
|
||||||
|
- [x] while - ループ → Loop
|
||||||
|
- **else節対応必須**
|
||||||
|
- [x] break/continue - ループ制御
|
||||||
- [x] return - 戻り値 → Return
|
- [x] return - 戻り値 → Return
|
||||||
- [ ] import(最小限) - 標準モジュールは後回し
|
- [ ] pass - 空文
|
||||||
|
- [ ] import(Phase 3へ延期)
|
||||||
|
|
||||||
### 式(Expression)
|
### 式(Expression)
|
||||||
- [x] 関数呼び出し - Call → BoxCall
|
- [x] 関数呼び出し - Call → BoxCall
|
||||||
- [x] 演算子(算術) - +,-,*,/,% → BinOp
|
- [x] 算術演算子 - +,-,*,/,//,% → BinOp
|
||||||
- [x] 比較演算子 - ==,!=,<,>,<=,>= → Compare
|
- `/`: true division(常にfloat)
|
||||||
|
- `//`: floor division
|
||||||
|
- [x] 比較演算子 - ==,!=,<,>,<=,>=,is,is not → Compare
|
||||||
|
- [x] 論理演算子 - and,or,not → BoolOp/UnaryOp
|
||||||
|
- 短絡評価の正確な実装
|
||||||
- [x] 変数参照/代入 - Name → Load/Store
|
- [x] 変数参照/代入 - Name → Load/Store
|
||||||
- [x] リテラル - 数値/文字列/bool → Const
|
- [x] リテラル - 数値/文字列/bool → Constant
|
||||||
|
- [x] 三項演算子 - IfExp
|
||||||
|
|
||||||
### データ型(最小限)
|
### データ型(最小限)
|
||||||
- [x] int → IntegerBox
|
- [x] int → IntegerBox(大整数対応)
|
||||||
- [x] float → FloatBox
|
- [x] float → FloatBox(NaNの扱い注意)
|
||||||
- [x] str → StringBox
|
- [x] str → StringBox
|
||||||
- [x] bool → BoolBox
|
- [x] bool → BoolBox
|
||||||
- [x] list(基本) → ArrayBox
|
- [x] list(基本) → ArrayBox
|
||||||
@ -179,6 +210,55 @@ def hello():
|
|||||||
# これがNyashで動けば成功!
|
# これがNyashで動けば成功!
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 📊 成功の測定基準(エキスパート推奨)
|
||||||
|
|
||||||
|
### 定量的指標
|
||||||
|
| 指標 | 目標 | 測定方法 |
|
||||||
|
|------|-------|----------|
|
||||||
|
| カバレッジ率 | 70%以上 | コンパイル済み vs フォールバック関数の比率 |
|
||||||
|
| 性能向上 | 2-10倍 | 純Pythonループのベンチマーク |
|
||||||
|
| バグ発見数 | 10+件/Phase | Differential Testingで発見されたNyashバグ |
|
||||||
|
| エコシステム | 1以上 | 動作する有名Pythonライブラリ |
|
||||||
|
|
||||||
|
### マイルストーン
|
||||||
|
- Phase 1: "Hello from Python in Nyash"が動作
|
||||||
|
- Phase 2: scikit-learnの基本アルゴリズムが動作
|
||||||
|
- Phase 3: FlaskのHello Worldが動作
|
||||||
|
- Phase 4: PyPIトップ100の30%が基本動作
|
||||||
|
|
||||||
|
## 🔧 GIL管理の黄金律
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// GILは最小限に!
|
||||||
|
let json_ast = Python::with_gil(|py| {
|
||||||
|
// Python側でJSON生成(高速)
|
||||||
|
py_helper.parse_to_json(py, code)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// GIL外でRust処理(並列可能)
|
||||||
|
let nyash_ast = py.allow_threads(|| {
|
||||||
|
convert_json_to_nyash(json_ast)
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 JSON IR設計(Codex先生推奨)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"node_type": "FunctionDef",
|
||||||
|
"py_version": "3.11",
|
||||||
|
"ast_format": "v2",
|
||||||
|
"support_level": "full", // "partial", "fallback"
|
||||||
|
"lineno": 1,
|
||||||
|
"col_offset": 0,
|
||||||
|
"end_lineno": 3,
|
||||||
|
"end_col_offset": 15,
|
||||||
|
"name": "hello",
|
||||||
|
"args": {...},
|
||||||
|
"body": [...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
作成日: 2025-08-27
|
作成日: 2025-08-27
|
||||||
ChatGPT5のサーフェスマップを基に優先順位付けしたロードマップ
|
ChatGPT5のサーフェスマップ + Gemini/Codex先生のエキスパートフィードバックを統合
|
||||||
52
docs/development/roadmap/phases/phase-10.1/README.md
Normal file
52
docs/development/roadmap/phases/phase-10.1/README.md
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Phase 10.1 - PythonParserBox実装計画
|
||||||
|
|
||||||
|
このフォルダには、NyashとPythonの相互運用を実現するPythonParserBoxの実装計画が含まれています。
|
||||||
|
|
||||||
|
## 📁 フォルダ構造
|
||||||
|
|
||||||
|
### メイン実装ドキュメント(最新版)
|
||||||
|
- **`pythonparser_integrated_plan_summary.txt`** - 統合実装計画サマリー(最重要)
|
||||||
|
- **`python_implementation_roadmap.txt`** - 実装ロードマップ(エキスパート統合版)
|
||||||
|
- **`python_parser_box_implementation_plan.txt`** - 技術的実装計画(統合版)
|
||||||
|
- **`builtin_box_implementation_flow.txt`** - ビルトインBox実装フロー(統合版)
|
||||||
|
- **`python_to_nyash_transpiler.txt`** - Python→Nyashトランスパイラー機能
|
||||||
|
|
||||||
|
### エキスパート評価
|
||||||
|
- **`expert_feedback_gemini_codex.txt`** - Gemini先生とCodex先生のフィードバック全文
|
||||||
|
|
||||||
|
### アーカイブ(参考資料)
|
||||||
|
- **`archive/`** フォルダ
|
||||||
|
- `python_parser_box_design.txt` - 初期設計案
|
||||||
|
- `chatgpt5_original_idea.txt` - ChatGPT5の元アイデア
|
||||||
|
- `summary_2025_08_27.txt` - 当日の議論まとめ
|
||||||
|
|
||||||
|
## 🎯 Phase 10.1の目標
|
||||||
|
|
||||||
|
1. **Pythonエコシステムの即座活用** - 既存Pythonライブラリの利用
|
||||||
|
2. **Differential Testing** - Nyashパーサーのバグ自動検証
|
||||||
|
3. **言語成熟度の向上** - 実用的なPythonコードでのストレステスト
|
||||||
|
|
||||||
|
## 🔑 核心戦略(エキスパート推奨)
|
||||||
|
|
||||||
|
1. **関数単位フォールバック** - ファイル全体でなく関数レベルで切り替え
|
||||||
|
2. **Python 3.11固定** - AST安定性の確保
|
||||||
|
3. **意味論の正確な実装** - 最適化より互換性優先
|
||||||
|
4. **GIL管理の最小化** - Python側でJSON生成、Rust側で処理
|
||||||
|
5. **テレメトリー重視** - 継続的な改善のための計測
|
||||||
|
|
||||||
|
## 📋 実装フェーズ
|
||||||
|
|
||||||
|
- **Phase 1**: Core Subset(基本構文)- 2週間
|
||||||
|
- **Phase 2**: Data Model(特殊メソッド)- 3週間
|
||||||
|
- **Phase 3**: Advanced Features(高度な機能)- 1ヶ月
|
||||||
|
- **Phase 4**: Modern Python(最新機能)- 将来
|
||||||
|
|
||||||
|
## 🚀 期待される成果
|
||||||
|
|
||||||
|
- 純Pythonループの2-10倍高速化
|
||||||
|
- Nyashパーサーのバグ発見と改善
|
||||||
|
- PythonからNyashへの段階的移行パス
|
||||||
|
- Python→Nyashスクリプト変換機能
|
||||||
|
|
||||||
|
---
|
||||||
|
作成日: 2025-08-27
|
||||||
@ -1,43 +0,0 @@
|
|||||||
# Phase 10.1 - 言語間相互運用と革命的統合
|
|
||||||
|
|
||||||
このフォルダには、Nyashと他言語(特にPython)との相互運用に関する設計と実装計画が含まれています。
|
|
||||||
|
|
||||||
## 📁 ファイル一覧
|
|
||||||
|
|
||||||
### 1. python_parser_box_design.txt
|
|
||||||
- PythonParserBoxの基本設計提案
|
|
||||||
- CPythonパーサーを使ったPython→Nyash変換の革命的アプローチ
|
|
||||||
- AST/MIR変換の概要
|
|
||||||
- 使用例と期待される効果
|
|
||||||
|
|
||||||
### 2. python_parser_box_implementation_plan.txt
|
|
||||||
- Gemini先生とCodex先生からのフィードバックを統合した実装計画
|
|
||||||
- 技術的な実装方針(pyo3使用)
|
|
||||||
- 最小実装セットの定義
|
|
||||||
- Phase別の実装ロードマップ
|
|
||||||
- 現実的な性能目標
|
|
||||||
|
|
||||||
### 3. chatgpt5_original_idea.txt(この後作成)
|
|
||||||
- ChatGPT5さんの最初のアイデア
|
|
||||||
- ForeignBox/ProxyBoxの概念
|
|
||||||
- 多言語統合の全体像
|
|
||||||
|
|
||||||
## 🎯 Phase 10.1の目標
|
|
||||||
|
|
||||||
1. **Pythonエコシステムの活用**: 既存のPythonライブラリをNyashから直接使用可能に
|
|
||||||
2. **性能向上**: PythonコードをMIR経由でJIT/AOTコンパイル
|
|
||||||
3. **段階的移行**: PythonプロジェクトをNyashへ徐々に移行可能
|
|
||||||
4. **統一実行環境**: Python/Nyash/Rust/JS等を自由に組み合わせ
|
|
||||||
|
|
||||||
## 🚀 次のステップ
|
|
||||||
|
|
||||||
1. Phase 1の基本実装開始(pyo3統合)
|
|
||||||
2. 最小限のPython AST→Nyash AST変換
|
|
||||||
3. 小さなベンチマークで性能測定
|
|
||||||
4. フィードバックに基づく改善
|
|
||||||
|
|
||||||
## 📝 関連ドキュメント
|
|
||||||
|
|
||||||
- 元の発想: `/mnt/c/git/nyash-project/nyash/docs/development/roadmap/native-plan/chatgpt5との会話.txt`
|
|
||||||
- Phase 10全体計画: `../phase-10/phase_10_cranelift_jit_backend.md`
|
|
||||||
- MIR仕様: `/mnt/c/git/nyash-project/nyash/docs/reference/mir/INSTRUCTION_SET.md`
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
# PythonParserBox実装計画(技術検証版)
|
|
||||||
|
|
||||||
## エキスパートからのフィードバック統合
|
|
||||||
|
|
||||||
### Gemini先生の主要指摘
|
|
||||||
1. **FFI課題**: pyo3の活用で解決可能(参照カウント管理、エラーハンドリング自動化)
|
|
||||||
2. **意味論的ギャップ**: 最初は科学計算など特定ドメインのサブセットから開始
|
|
||||||
3. **GIL管理**: Boxレベルでの隠蔽は現実的かつ一般的
|
|
||||||
4. **ボトルネック**: FFI境界とデータ変換コスト → MIR変換で解決
|
|
||||||
5. **他言語展開**: 設計思想は汎用的、Ruby/JSにも応用可能
|
|
||||||
|
|
||||||
### Codex先生の実装提案
|
|
||||||
1. **安定API使用**: CPython内部APIではなく、Python `ast`モジュール→JSON経由
|
|
||||||
2. **段階的実装**: Phase 1でパーサー統合、Phase 2でMIR変換
|
|
||||||
3. **ゼロコピー戦略**: pyo3-numpy + PEP 3118バッファプロトコル
|
|
||||||
4. **現実的な性能目標**: 純Pythonループで2-10倍、NumPyは1.0-1.2倍
|
|
||||||
5. **最小実装セット**: 基本構造+演算+制御フローから開始
|
|
||||||
|
|
||||||
## 技術的実装方針
|
|
||||||
|
|
||||||
### 1. CPythonパーサー統合(pyo3使用)
|
|
||||||
```rust
|
|
||||||
// Cargo.toml
|
|
||||||
[dependencies]
|
|
||||||
pyo3 = { version = "0.22", features = ["auto-initialize"] }
|
|
||||||
pyo3-numpy = "0.22" // NumPy連携用
|
|
||||||
|
|
||||||
// Python側ヘルパー(embedded)
|
|
||||||
const PYTHON_HELPER: &str = r#"
|
|
||||||
import ast
|
|
||||||
import json
|
|
||||||
|
|
||||||
def parse_to_json(code, filename="<string>", mode="exec"):
|
|
||||||
tree = ast.parse(code, filename, mode)
|
|
||||||
return json.dumps(ast_to_dict(tree))
|
|
||||||
|
|
||||||
def ast_to_dict(node):
|
|
||||||
if isinstance(node, ast.AST):
|
|
||||||
fields = {f: ast_to_dict(getattr(node, f))
|
|
||||||
for f in node._fields}
|
|
||||||
fields['_type'] = node.__class__.__name__
|
|
||||||
return fields
|
|
||||||
elif isinstance(node, list):
|
|
||||||
return [ast_to_dict(x) for x in node]
|
|
||||||
else:
|
|
||||||
return node
|
|
||||||
"#;
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 最小実装セット(Phase 1-2)
|
|
||||||
```
|
|
||||||
Phase 1 構造:
|
|
||||||
├─ Module
|
|
||||||
├─ FunctionDef (name, args, body)
|
|
||||||
├─ Return (value)
|
|
||||||
├─ Assign (targets, value)
|
|
||||||
└─ Expr (value)
|
|
||||||
|
|
||||||
Phase 1 式:
|
|
||||||
├─ BinOp (left, op, right)
|
|
||||||
├─ Compare (left, ops, comparators)
|
|
||||||
├─ Call (func, args)
|
|
||||||
├─ Name (id, ctx=Load/Store)
|
|
||||||
└─ Constant (value)
|
|
||||||
|
|
||||||
Phase 2 追加:
|
|
||||||
├─ If (test, body, orelse)
|
|
||||||
├─ While (test, body, orelse)
|
|
||||||
├─ UnaryOp (op, operand)
|
|
||||||
└─ Attribute (value, attr, ctx)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. データ共有戦略
|
|
||||||
```rust
|
|
||||||
// NdArrayBox定義
|
|
||||||
pub struct NdArrayBox {
|
|
||||||
base: BoxBase,
|
|
||||||
py_array: Py<PyArray<f64, Dim<[usize; 2]>>>, // Python側の参照保持
|
|
||||||
// 操作時のみGIL取得してArrayViewを取る
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NdArrayBox {
|
|
||||||
pub fn to_view(&self) -> PyResult<ArrayView2<f64>> {
|
|
||||||
Python::with_gil(|py| {
|
|
||||||
let array = self.py_array.as_ref(py);
|
|
||||||
Ok(array.readonly())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 実装ロードマップ
|
|
||||||
|
|
||||||
#### Phase 1: パーサー統合(1-2週間)
|
|
||||||
- [ ] pyo3セットアップとPythonParserBox骨格
|
|
||||||
- [ ] Python側parse_to_jsonヘルパー実装
|
|
||||||
- [ ] JSON→Nyash AST最小変換
|
|
||||||
- [ ] run()メソッド(CPython exec委譲)
|
|
||||||
- [ ] 例外変換(PyErr → NyashError)
|
|
||||||
|
|
||||||
#### Phase 2: MIR変換(2-4週間)
|
|
||||||
- [ ] AST→MIR変換器(最小セット)
|
|
||||||
- [ ] 数値演算プリミティブ実装
|
|
||||||
- [ ] スコープ解決(関数ローカル/グローバル)
|
|
||||||
- [ ] 基本的な制御フロー(If/While)
|
|
||||||
|
|
||||||
#### Phase 3: NumPy統合(並行可能)
|
|
||||||
- [ ] pyo3-numpy統合
|
|
||||||
- [ ] NdArrayBox実装
|
|
||||||
- [ ] ゼロコピーベンチマーク
|
|
||||||
- [ ] バッファプロトコル対応
|
|
||||||
|
|
||||||
#### Phase 4: 最適化と拡張
|
|
||||||
- [ ] 型特化とガード最適化
|
|
||||||
- [ ] 例外処理(try/except)
|
|
||||||
- [ ] クラス/メソッド対応
|
|
||||||
- [ ] import統合
|
|
||||||
|
|
||||||
## 性能目標(現実的な見積もり)
|
|
||||||
|
|
||||||
| コードタイプ | 期待される高速化 | 備考 |
|
|
||||||
|------------|----------------|------|
|
|
||||||
| 純Pythonループ | 2-10倍 | 型安定なホットパス |
|
|
||||||
| 関数呼び出し多 | 1.5-3倍 | インライン化効果 |
|
|
||||||
| NumPy処理中心 | 1.0-1.2倍 | 既に最適化済み |
|
|
||||||
| 動的特性多用 | 1.2-3倍 | ガード頻発で限定的 |
|
|
||||||
|
|
||||||
## 実装上の注意点
|
|
||||||
|
|
||||||
1. **GIL管理**: 境界で短く、操作時のみwith_gil
|
|
||||||
2. **バージョン互換**: Python 3.10-3.12で検証
|
|
||||||
3. **エラー処理**: すべてのPython例外を適切にキャッチ
|
|
||||||
4. **メモリ管理**: Py<PyAny>で参照保持、GC連携
|
|
||||||
5. **段階的アプローチ**: 完璧を求めず、動くものから改善
|
|
||||||
|
|
||||||
## 次のステップ
|
|
||||||
|
|
||||||
1. Phase 1の基本実装を開始
|
|
||||||
2. 小さなPythonコードで動作確認
|
|
||||||
3. ベンチマークで性能測定
|
|
||||||
4. フィードバックを元に改善
|
|
||||||
|
|
||||||
この計画により、PythonエコシステムとNyashの高性能実行エンジンを段階的に統合できる。
|
|
||||||
@ -0,0 +1,225 @@
|
|||||||
|
# Python → Nyashトランスパイラー機能
|
||||||
|
~PythonParserBoxの応用による自動変換~
|
||||||
|
|
||||||
|
## 🎯 概要
|
||||||
|
|
||||||
|
PythonParserBoxでPython AST → Nyash ASTの変換ができるなら、それを**Nyashソースコードとして出力**できる!
|
||||||
|
|
||||||
|
## 🚀 実現可能な機能
|
||||||
|
|
||||||
|
### 1. Python → Nyashファイル変換
|
||||||
|
```python
|
||||||
|
# input.py
|
||||||
|
def calculate(x, y):
|
||||||
|
result = x * 2 + y
|
||||||
|
return result
|
||||||
|
|
||||||
|
for i in range(10):
|
||||||
|
print(calculate(i, 5))
|
||||||
|
```
|
||||||
|
|
||||||
|
↓ 変換
|
||||||
|
|
||||||
|
```nyash
|
||||||
|
# output.nyash
|
||||||
|
function calculate(x, y) {
|
||||||
|
local result
|
||||||
|
result = x * 2 + y
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
local i
|
||||||
|
for i in range(0, 10) {
|
||||||
|
print(calculate(i, 5))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 実装方法
|
||||||
|
|
||||||
|
```rust
|
||||||
|
impl PythonParserBox {
|
||||||
|
// Python → Nyashファイル出力
|
||||||
|
pub fn transpile_to_file(&self, python_code: &str, output_path: &str) -> Result<(), String> {
|
||||||
|
// 1. Python → JSON AST
|
||||||
|
let json_ast = self.parse_to_json(python_code)?;
|
||||||
|
|
||||||
|
// 2. JSON AST → Nyash AST
|
||||||
|
let nyash_ast = self.json_to_nyash_ast(&json_ast)?;
|
||||||
|
|
||||||
|
// 3. Nyash AST → Nyashソースコード
|
||||||
|
let nyash_code = self.ast_to_nyash_source(&nyash_ast)?;
|
||||||
|
|
||||||
|
// 4. ファイルに出力
|
||||||
|
std::fs::write(output_path, nyash_code)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AST → Nyashソースコード生成
|
||||||
|
fn ast_to_nyash_source(&self, ast: &NyashAst) -> Result<String, String> {
|
||||||
|
let mut output = String::new();
|
||||||
|
let formatter = NyashFormatter::new();
|
||||||
|
|
||||||
|
for item in &ast.items {
|
||||||
|
formatter.format_item(item, &mut output)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 使用例
|
||||||
|
|
||||||
|
### コマンドライン版
|
||||||
|
```bash
|
||||||
|
# PythonファイルをNyashに変換
|
||||||
|
nyash-transpile input.py -o output.nyash
|
||||||
|
|
||||||
|
# 標準出力に出力
|
||||||
|
nyash-transpile script.py
|
||||||
|
|
||||||
|
# 部分変換(サポートされる構文のみ)
|
||||||
|
nyash-transpile --partial complex_script.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nyashスクリプト内での使用
|
||||||
|
```nyash
|
||||||
|
local transpiler = new PythonParserBox()
|
||||||
|
|
||||||
|
// Pythonコードを読み込み
|
||||||
|
local python_code = FileBox.read("algorithm.py")
|
||||||
|
|
||||||
|
// Nyashに変換
|
||||||
|
local nyash_code = transpiler.to_nyash_source(python_code)
|
||||||
|
|
||||||
|
// ファイルに保存
|
||||||
|
FileBox.write("algorithm.nyash", nyash_code)
|
||||||
|
|
||||||
|
// または直接実行
|
||||||
|
eval(nyash_code)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 変換マッピング例
|
||||||
|
|
||||||
|
### 基本構文
|
||||||
|
| Python | Nyash |
|
||||||
|
|--------|-------|
|
||||||
|
| `def func():` | `function func() {` |
|
||||||
|
| `if x > 0:` | `if (x > 0) {` |
|
||||||
|
| `for i in range(10):` | `for i in range(0, 10) {` |
|
||||||
|
| `while x < 10:` | `while (x < 10) {` |
|
||||||
|
| `x = 5` | `local x; x = 5` または `x = 5`(スコープによる)|
|
||||||
|
|
||||||
|
### データ型
|
||||||
|
| Python | Nyash |
|
||||||
|
|--------|-------|
|
||||||
|
| `x = 42` | `x = 42` |
|
||||||
|
| `s = "hello"` | `s = "hello"` |
|
||||||
|
| `lst = [1, 2, 3]` | `lst = new ArrayBox([1, 2, 3])` |
|
||||||
|
| `d = {"a": 1}` | `d = new MapBox(); d.set("a", 1)` |
|
||||||
|
|
||||||
|
### 特殊なケース
|
||||||
|
```python
|
||||||
|
# Pythonのfor/else
|
||||||
|
for i in items:
|
||||||
|
if condition:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("No break")
|
||||||
|
```
|
||||||
|
|
||||||
|
```nyash
|
||||||
|
# Nyashでの実装(フラグを使用)
|
||||||
|
local broke = false
|
||||||
|
for i in items {
|
||||||
|
if (condition) {
|
||||||
|
broke = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (not broke) {
|
||||||
|
print("No break")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🌟 利点
|
||||||
|
|
||||||
|
### 1. 段階的移行支援
|
||||||
|
- 既存のPythonプロジェクトを段階的にNyashに移行
|
||||||
|
- 変換されたコードを手動で最適化可能
|
||||||
|
|
||||||
|
### 2. 学習ツールとして
|
||||||
|
- PythonユーザーがNyash構文を学ぶ
|
||||||
|
- 両言語の違いを理解
|
||||||
|
|
||||||
|
### 3. コード生成
|
||||||
|
- Pythonで書いたアルゴリズムをNyashネイティブコードに
|
||||||
|
- より高速な実行のための前処理
|
||||||
|
|
||||||
|
### 4. 逆方向変換の可能性
|
||||||
|
- Nyash → Pythonも将来的に可能
|
||||||
|
- 真のバイリンガル環境
|
||||||
|
|
||||||
|
## ⚠️ 制限事項と課題
|
||||||
|
|
||||||
|
### 1. 完全な互換性は不可能
|
||||||
|
- Pythonの動的機能すべては変換できない
|
||||||
|
- 一部の構文は手動調整が必要
|
||||||
|
|
||||||
|
### 2. 意味論の違い
|
||||||
|
```python
|
||||||
|
# Pythonのデフォルト引数(定義時評価)
|
||||||
|
def f(x, lst=[]):
|
||||||
|
lst.append(x)
|
||||||
|
return lst
|
||||||
|
```
|
||||||
|
|
||||||
|
```nyash
|
||||||
|
// Nyashでは毎回新しいリスト(異なる挙動)
|
||||||
|
function f(x, lst) {
|
||||||
|
if (lst == null) {
|
||||||
|
lst = new ArrayBox()
|
||||||
|
}
|
||||||
|
lst.push(x)
|
||||||
|
return lst
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. サポートレベルの明示
|
||||||
|
```nyash
|
||||||
|
// 生成されたファイルのヘッダー
|
||||||
|
// Generated from Python by Nyash Transpiler v1.0
|
||||||
|
// Original file: script.py
|
||||||
|
// Conversion rate: 85% (15/17 functions transpiled)
|
||||||
|
// Manual review recommended for: async_func, generator_func
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 実装フェーズ
|
||||||
|
|
||||||
|
### Phase 1.5: 基本トランスパイラ(Phase 1と並行)
|
||||||
|
- [ ] NyashFormatter実装(AST → ソースコード)
|
||||||
|
- [ ] 基本構文の出力(def, if, for, while)
|
||||||
|
- [ ] インデント管理
|
||||||
|
- [ ] コメント保持(可能な範囲で)
|
||||||
|
|
||||||
|
### Phase 2.5: 高度な変換
|
||||||
|
- [ ] クラス → Box変換
|
||||||
|
- [ ] 特殊メソッド → Nyashメソッド
|
||||||
|
- [ ] import文の処理
|
||||||
|
|
||||||
|
### Phase 3.5: ツール化
|
||||||
|
- [ ] コマンドラインツール
|
||||||
|
- [ ] VSCode拡張機能
|
||||||
|
- [ ] オンライン変換ツール
|
||||||
|
|
||||||
|
## 🎉 期待される効果
|
||||||
|
|
||||||
|
1. **Pythonエコシステムの資産をNyashネイティブ化**
|
||||||
|
2. **パフォーマンスクリティカルな部分をNyash/MIR/JITで高速化**
|
||||||
|
3. **両言語間のシームレスな相互運用**
|
||||||
|
4. **Nyashの採用障壁を大幅に下げる**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
これは**PythonParserBoxの価値をさらに高める**素晴らしい応用です!
|
||||||
@ -288,7 +288,7 @@ impl IRBuilder for CraneliftBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit_compare(&mut self, op: CmpKind) {
|
fn emit_compare(&mut self, op: CmpKind) {
|
||||||
use cranelift_codegen::ir::{types, condcodes::IntCC};
|
use cranelift_codegen::ir::{condcodes::IntCC};
|
||||||
use cranelift_frontend::FunctionBuilder;
|
use cranelift_frontend::FunctionBuilder;
|
||||||
if self.value_stack.len() < 2 { return; }
|
if self.value_stack.len() < 2 { return; }
|
||||||
let rhs = self.value_stack.pop().unwrap();
|
let rhs = self.value_stack.pop().unwrap();
|
||||||
@ -305,8 +305,8 @@ impl IRBuilder for CraneliftBuilder {
|
|||||||
CmpKind::Ge => IntCC::SignedGreaterThanOrEqual,
|
CmpKind::Ge => IntCC::SignedGreaterThanOrEqual,
|
||||||
};
|
};
|
||||||
let b1 = fb.ins().icmp(cc, lhs, rhs);
|
let b1 = fb.ins().icmp(cc, lhs, rhs);
|
||||||
let as_i64 = fb.ins().uextend(types::I64, b1);
|
// Keep b1 on the stack; users (branch) can consume directly, arithmetic should not assume compare value as i64
|
||||||
self.value_stack.push(as_i64);
|
self.value_stack.push(b1);
|
||||||
self.stats.2 += 1;
|
self.stats.2 += 1;
|
||||||
fb.finalize();
|
fb.finalize();
|
||||||
}
|
}
|
||||||
@ -402,7 +402,13 @@ impl IRBuilder for CraneliftBuilder {
|
|||||||
else if let Some(b) = self.entry_block { fb.switch_to_block(b); }
|
else if let Some(b) = self.entry_block { fb.switch_to_block(b); }
|
||||||
// Take top-of-stack as cond; if it's i64, normalize to b1 via icmp_imm != 0
|
// Take top-of-stack as cond; if it's i64, normalize to b1 via icmp_imm != 0
|
||||||
let cond_b1 = if let Some(v) = self.value_stack.pop() {
|
let cond_b1 = if let Some(v) = self.value_stack.pop() {
|
||||||
fb.ins().icmp_imm(IntCC::NotEqual, v, 0)
|
let ty = fb.func.dfg.value_type(v);
|
||||||
|
if ty == types::I64 {
|
||||||
|
fb.ins().icmp_imm(IntCC::NotEqual, v, 0)
|
||||||
|
} else {
|
||||||
|
// assume already b1
|
||||||
|
v
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let zero = fb.ins().iconst(types::I64, 0);
|
let zero = fb.ins().iconst(types::I64, 0);
|
||||||
fb.ins().icmp_imm(IntCC::NotEqual, zero, 0)
|
fb.ins().icmp_imm(IntCC::NotEqual, zero, 0)
|
||||||
|
|||||||
@ -30,6 +30,19 @@ impl NyashRunner {
|
|||||||
return sum
|
return sum
|
||||||
"#,
|
"#,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"branch_return",
|
||||||
|
r#"
|
||||||
|
local a, b
|
||||||
|
a = 3
|
||||||
|
b = 5
|
||||||
|
if (a < b) {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
for (name, code) in tests {
|
for (name, code) in tests {
|
||||||
|
|||||||
Reference in New Issue
Block a user