docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)

This commit is contained in:
nyash-codex
2025-10-31 18:00:10 +09:00
parent 1d49e24bf0
commit 8fd3a2b509
433 changed files with 108935 additions and 0 deletions

View File

@ -0,0 +1,203 @@
# Phase 20 Python Integration - INDEX
## 📋 全体概要
**Phase 20: Python-Hakorune統合** - PythonのAST/木構造をHakoruneに落とし、Python-Hakorune間の相互運用を実現するフェーズです。
**出典**: 旧Phase 10.5Phase 10.1系)の内容を整理・再編成
## 🗂️ フォルダ構成
```
phase-20-python-integration/
├── README.md # ⭐ メインドキュメント
├── INDEX.md # このファイル
├── 📁 planning/ # 計画・設計
│ ├── README.md
│ ├── integrated-plan.md # ChatGPT5統合計画
│ ├── python-parser-plan-summary.md # パーサー計画サマリー
│ ├── python-parser-box-design.md # パーサーBox設計
│ └── expert-feedback.md # AI専門家フィードバック
├── 📁 parser-integration/ # パーサー統合
│ ├── README.md
│ ├── implementation-plan.md # 実装計画
│ └── builtin-box-flow.md # ビルトインBox実装フロー
├── 📁 core-implementation/ # コア実装
│ ├── README.md
│ └── implementation-roadmap.md # 実装ロードマップ
├── 📁 transpiler/ # トランスパイラー
│ ├── README.md
│ └── python-to-hakorune-spec.md # Python→Hakorune変換仕様
├── 📁 design/ # 設計ドキュメント
│ ├── README.md
│ ├── abi-design.md # ABI設計
│ ├── native-build-consolidation.md # ネイティブビルド
│ └── handle-first-plugininvoke-plan.md # Handle-First設計
├── 📁 testing/ # テスト計画
│ └── README.md
└── 📁 documentation/ # ドキュメント計画
└── README.md
```
## 🎯 クイックナビゲーション
### 🚀 初めての方へ
1. [メインREADME](README.md) - 全体概要を理解
2. **[強化版アーキテクチャv2](design/enhanced-architecture-v2.md)** - ChatGPT Pro最新設計推奨
3. [マイルストーン](planning/milestones.md) - M0〜M6実装計画
4. [Planning README](planning/README.md) - 計画の詳細を確認
5. [統合計画](planning/integrated-plan.md) - ChatGPT5による詳細計画
### 🏗️ 設計を知りたい
- **[強化版アーキテクチャv2](design/enhanced-architecture-v2.md)** ⭐ ChatGPT Pro最新設計2025-10-02
- [ABI設計](design/abi-design.md) - Python-Hakorune間のABI
- [Handle-First設計](design/handle-first-plugininvoke-plan.md) - プラグイン呼び出し設計
- [ネイティブビルド](design/native-build-consolidation.md) - AOT/EXE生成
- [メタ設定例](design/meta-config-examples.md) - hako.toml設定リファレンス
- [リスクと対策](design/risks-and-mitigations.md) - 既知のリスクと対策
### 💻 実装を見たい
- [パーサー実装計画](parser-integration/implementation-plan.md) - PythonパーサーBox
- [コア実装ロードマップ](core-implementation/implementation-roadmap.md) - PyRuntimeBox/PyObjectBox
- [トランスパイラー仕様](transpiler/python-to-hakorune-spec.md) - Python→Hakorune変換
### 🧪 テストについて
- [テスト計画](testing/README.md) - テスト戦略とチェックリスト
### 📚 ドキュメントについて
- [ドキュメント計画](documentation/README.md) - ドキュメント構成
## 📊 実装ステータス
| カテゴリ | コンポーネント | ステータス |
|---------|--------------|----------|
| **計画** | 設計・計画書 | ✅ 完了 |
| **計画** | 強化版アーキテクチャv2 | ✅ 完了2025-10-02|
| **計画** | マイルストーンM0-M6 | ✅ 完了2025-10-02|
| **設計** | ABI設計 | ✅ 完了 |
| **設計** | Handle-First | ✅ 完了 |
| **設計** | ネイティブビルド | ✅ 完了 |
| **設計** | メタ設定例 | ✅ 完了2025-10-02|
| **設計** | リスク管理 | ✅ 完了2025-10-02|
| **実装** | PyRuntimeBox | 📅 未実装M0予定|
| **実装** | PyObjectBox | 📅 未実装M0予定|
| **実装** | PythonパーサーBox | 📅 未実装M4予定|
| **実装** | トランスパイラー | 📅 未実装 |
| **テスト** | ユニットテスト | 📅 未実装 |
| **テスト** | 統合テスト | 📅 未実装 |
| **ドキュメント** | ユーザーガイド | 📅 未実装 |
| **ドキュメント** | APIリファレンス | 📅 未実装 |
## 🎯 主要コンポーネント
### 1. PyRuntimeBox
**目的**: Python実行環境の提供
```hakorune
box PyRuntimeBox {
eval(code: StringBox) -> PyObjectBox
import(name: StringBox) -> PyObjectBox
}
```
### 2. PyObjectBox
**目的**: Pythonオブジェクトの管理
```hakorune
box PyObjectBox {
getattr(name: StringBox) -> PyObjectBox
setattr(name: StringBox, value: PyObjectBox)
call(args: ArrayBox) -> PyObjectBox
to_string() -> StringBox
to_int() -> IntegerBox
}
```
### 3. PythonパーサーBox
**目的**: Python AST → Hakorune MIR変換
```hakorune
box PythonParserBox {
parse(code: StringBox) -> ASTBox
to_hakorune_ast(ast: ASTBox) -> HakoruneASTBox
to_mir(ast: ASTBox) -> MIRBox
}
```
### 4. トランスパイラー
**目的**: Python構文 → Hakorune構文変換
```hakorune
box PythonTranspiler {
transpile(python_code: StringBox) -> StringBox
}
```
## ⚠️ 現在のステータス
**保留中** - Phase 15Hakoruneセルフホスティング完了後に着手予定
### 保留理由
1. **優先度**: まずHakorune自身の基盤を固める
2. **依存関係**: セルフホスティング実現が先決
3. **リソース**: 段階的に実装する方が安全
### 再開条件
- ✅ Phase 15完了Rust VM + LLVM 2本柱体制確立
- ✅ セルフホスティング実現
- ✅ プラグインシステム安定化
## 🔗 関連Phase
### 前提Phase
- [Phase 15 - セルフホスティング](../phase-15/) - 現在進行中
- [Phase 12 - TypeBox統合](../phase-12/) - 完了
### 後続Phase予定
- Phase 21 - 箱データベース
- Phase 22+ - 未定
## 📚 元資料
このPhase 20は以下の旧資料を整理・統合したものです
- **元の場所**: `docs/archive/phases/phase-10.5/phase-10.5/`
- **旧Phase名**: Phase 10.5Phase 10.1系を再編成)
- **作成時期**: 2025年8月頃
- **主要貢献者**: ChatGPT5, Gemini, Codex
## 🎯 将来の展望
### 短期目標Phase 15後
1. PyRuntimeBox基本実装
2. PyObjectBox基本実装
3. 基本的なPython呼び出し動作
### 中期目標
1. PythonパーサーBox実装
2. Python AST → Hakorune MIR変換
3. トランスパイラー実装
### 長期目標
1. Python-Hakoruneシームレス統合
2. Pythonライブラリの完全活用
3. ハイブリッド開発の実現
## 📞 お問い合わせ
- **メインドキュメント**: [README.md](README.md)
- **マスタープラン**: [00_MASTER_ROADMAP.md](../00_MASTER_ROADMAP.md)
- **現在のフェーズ**: [Phase 15](../phase-15/)
---
**最終更新**: 2025-10-02
**整理者**: Claude Code
**ステータス**: 計画済み・実装待ち

View File

@ -0,0 +1,127 @@
# Phase 20: Python-Hakorune統合 - PythonのAST/木構造をHakoruneに落とす
## 📋 概要
PythonのAST抽象構文木をHakoruneの木構造MIR/ASTに変換し、Python-Hakorune間の相互運用を実現するフェーズです。
**出典**: 旧Phase 10.5Phase 10.1系)の内容を整理・再編成
## 🎯 目的
1. **PythonパーサーBox**: PythonコードをHakoruneで解析
2. **AST変換**: Python AST → Hakorune MIR/AST
3. **相互運用**: Python ⇄ Hakorune の双方向呼び出し
4. **トランスパイラー**: Python → Hakorune コード変換
## 📁 フォルダ構成
```
phase-20-python-integration/
├── README.md # このファイル
├── INDEX.md # 全体ナビゲーション ⭐推奨
├── planning/ # 計画・設計ドキュメント
│ ├── README.md
│ ├── milestones.md # ⭐M0-M6実装計画2025-10-02追加
│ ├── integrated-plan.md # 統合計画
│ ├── expert-feedback.md # AI専門家フィードバック
│ └── python-parser-box-design.md
├── parser-integration/ # パーサー統合
│ ├── README.md
│ ├── implementation-plan.md
│ └── builtin-box-flow.md
├── core-implementation/ # コア実装
│ ├── README.md
│ └── implementation-roadmap.md
├── transpiler/ # トランスパイラー
│ ├── README.md
│ └── python-to-hakorune-spec.md
├── testing/ # テスト計画
│ └── README.md
├── documentation/ # ドキュメント
│ └── README.md
└── design/ # 設計ドキュメント
├── README.md
├── enhanced-architecture-v2.md ⭐ChatGPT Pro最新設計2025-10-02追加
├── meta-config-examples.md ⭐hako.toml設定例2025-10-02追加
├── risks-and-mitigations.md ⭐リスク管理2025-10-02追加
├── abi-design.md # ABI設計
├── native-build-consolidation.md # ネイティブビルド
└── handle-first-plugininvoke-plan.md # Handle-First設計
```
## 🎯 主要コンポーネント
### 1. PythonパーサーBox
- PythonコードをHakorune内で解析
- `PyRuntimeBox`: Python実行環境
- `PyObjectBox`: Pythonオブジェクト管理
### 2. AST変換
- Python AST → Hakorune MIR
- 型情報の保持
- スコープ解決
### 3. 相互運用
- Hakorune → Python: BoxCall経由
- Python → Hakorune: FFI経由
- エラーハンドリング
### 4. トランスパイラー
- Python構文 → Hakorune構文
- イディオム変換
- 最適化
## 📊 実装ステータス
| コンポーネント | ステータス | 備考 |
|--------------|----------|------|
| 計画・設計 | ✅ 完了 | 詳細設計済み |
| パーサーBox | 📅 未実装 | Phase 15後に実装予定 |
| AST変換 | 📅 未実装 | - |
| 相互運用 | 📅 未実装 | - |
| トランスパイラー | 📅 未実装 | - |
## 🎯 重要ドキュメント2025-10-02追加
### 最新設計ChatGPT Pro UltraThink
1. **[強化版アーキテクチャv2](design/enhanced-architecture-v2.md)** ⭐必読 - Effect/Capability/Contract/Policy統合設計
2. **[マイルストーンM0-M6](planning/milestones.md)** - 段階的実装計画
3. **[メタ設定例](design/meta-config-examples.md)** - hako.toml設定リファレンス
4. **[リスクと対策](design/risks-and-mitigations.md)** - GILデッドロック・メモリリーク等
### ナビゲーション
- **[INDEX.md](INDEX.md)** - 全体ナビゲーション
## 🔗 関連ドキュメント
- **元資料**: `docs/archive/phases/phase-10.5/phase-10.5/`
- **現在のフェーズ**: [Phase 15 - セルフホスティング](../phase-15/)
- **マスタープラン**: [00_MASTER_ROADMAP.md](../00_MASTER_ROADMAP.md)
## ⚠️ 開発優先度
**現在は保留中** - Phase 15Hakoruneセルフホスティング完了後に着手予定
理由:
- まずHakorune自身の基盤Rust VM + LLVMを固める
- セルフホスティングの実現が優先
- Python統合は後段で段階的に実装
## 🚀 将来の展望
1. **短期**: Python FFI統合PyO3等
2. **中期**: Python AST → Hakorune MIR 変換
3. **長期**: Python-Hakorune シームレス統合
---
**最終更新**: 2025-10-02
**ステータス**: 計画済み・実装待ち
**優先度**: Phase 15完了後

View File

@ -0,0 +1,151 @@
# Core Implementation - コア実装
## 📋 概要
Python-Hakorune統合のコア実装計画です。
## 📁 ファイル一覧
- **[implementation-roadmap.md](implementation-roadmap.md)** - Python実装ロードマップ
## 🎯 実装コンポーネント
### 1. PyRuntimeBoxPython実行環境
```hakorune
box PyRuntimeBox {
// 初期化・終了
init()
shutdown()
// コード実行
eval(code: StringBox) -> PyObjectBox
exec(code: StringBox)
// モジュール
import(name: StringBox) -> PyObjectBox
}
```
### 2. PyObjectBoxPythonオブジェクト
```hakorune
box PyObjectBox {
// 属性アクセス
getattr(name: StringBox) -> PyObjectBox
setattr(name: StringBox, value: PyObjectBox)
// 呼び出し
call(args: ArrayBox) -> PyObjectBox
// 変換
to_string() -> StringBox
to_int() -> IntegerBox
to_bool() -> BoolBox
}
```
### 3. 相互運用レイヤー
#### Hakorune → Python
- BoxCall → CPython C API
- 型変換: Hakorune Box → PyObject*
- エラーハンドリング
#### Python → Hakorune
- CPython拡張モジュール`hakorunert`
- 型変換: PyObject* → Hakorune Box
- GIL管理
## 🏗️ アーキテクチャ
### レイヤー構造
```
┌─────────────────────────────┐
│ Hakorune Application │
├─────────────────────────────┤
│ PyRuntimeBox/PyObjectBox │
├─────────────────────────────┤
│ FFI/Plugin Interface │
├─────────────────────────────┤
│ CPython C API │
├─────────────────────────────┤
│ CPython Runtime │
└─────────────────────────────┘
```
### プラグイン化
- `hakorune-python-plugin` (cdylib/staticlib)
- `nyplug_python_invoke` FFI関数
- 動的ロード/静的リンク対応
## 🔧 技術的詳細
### 1. メモリ管理
#### Python側
- `Py_INCREF` / `Py_DECREF`
- Boxライフサイクルとの連携
- 循環参照の回避
#### Hakorune側
- Handle管理TLV tag=8
- Arc<PyObject> でのラップ
- Drop時の自動DECREF
### 2. GIL管理
```rust
// 基本パターン
{
let gil = Python::acquire_gil();
let py = gil.python();
// Python操作
let result = py.eval(code, None, None)?;
// GILは自動解放
}
```
### 3. エラーハンドリング
- Python例外 → Hakorune文字列エラーtag=6
- トレースバック情報の保持
- 双方向のエラー伝搬
## 📊 実装ステータス
| コンポーネント | ステータス | 備考 |
|--------------|----------|------|
| PyRuntimeBox設計 | ✅ 完了 | - |
| PyObjectBox設計 | ✅ 完了 | - |
| FFI統合 | 📅 未実装 | - |
| GIL管理 | 📅 未実装 | - |
| エラーハンドリング | 📅 未実装 | - |
| メモリ管理 | 📅 未実装 | - |
## ⚠️ リスク要因
### 1. GILデッドロック
- 入口/出口での厳格な管理
- ネスト呼び出し時の方針
- デッドロック検出機能
### 2. 参照カウントリーク
- BoxライフサイクルでのDECREF保証
- リークテストの追加
- デバッグツール整備
### 3. パフォーマンス
- FFIオーバーヘッド
- GIL待機時間
- 最適化戦略
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Planning](../planning/)
- [Design Documents](../design/)

View File

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

View File

@ -0,0 +1,193 @@
# Design - 設計ドキュメント
## 📋 概要
Python-Hakorune統合の設計ドキュメント集です。
## 📁 ファイル一覧
### 🌟 最新設計2025-10-02追加
- **[enhanced-architecture-v2.md](enhanced-architecture-v2.md)** ⭐必読 - ChatGPT Pro UltraThink強化版アーキテクチャ
- **[meta-config-examples.md](meta-config-examples.md)** - hako.toml設定リファレンス
- **[risks-and-mitigations.md](risks-and-mitigations.md)** - リスク管理ドキュメント
### ABI・FFI設計
- **[abi-design.md](abi-design.md)** - Python-Hakorune ABI設計
- **[handle-first-plugininvoke-plan.md](handle-first-plugininvoke-plan.md)** - Handle-First PluginInvoke設計
### ビルド・実行
- **[native-build-consolidation.md](native-build-consolidation.md)** - ネイティブビルド基盤設計
## 🎯 設計の核心
### 1. ABI設計方針
#### ハンドル管理
- **TLV tag=8**: Python object handle
- **type_id + instance_id**: 箱の識別
- **Arc<PyObject>**: Rust側での管理
#### 型変換
| Hakorune | Python | 備考 |
|---------|--------|------|
| BoolBox | bool | 真偽値 |
| IntegerBox | int | 整数 |
| StringBox | str | 文字列 |
| ArrayBox | list | 配列 |
| MapBox | dict | 辞書 |
| PyObjectBox | object | 任意のPythonオブジェクト |
### 2. Handle-First 設計
#### 原則
- 第一引数a0は常にハンドル
- `nyash.handle.of(receiver)` で変換
- TLV統一: String/Integer以外はHandletag=8
#### メリット
- 型安全性の向上
- 統一されたインターフェース
- デバッグの容易さ
### 3. GIL管理戦略
#### 基本方針
- **birth/invoke/decRef中はGIL確保**
- **AOTでも同等の処理**
- **ネスト呼び出しの安全性保証**
#### 実装パターン
```rust
pub fn invoke_python_method(handle: Handle, method: &str, args: &[Value]) -> Result<Value> {
// GIL獲得
let gil = Python::acquire_gil();
let py = gil.python();
// Pythonオブジェクト取得
let obj = get_pyobject_from_handle(handle)?;
// メソッド呼び出し
let result = obj.call_method(py, method, args, None)?;
// 結果を変換
let value = pyobject_to_value(result)?;
Ok(value)
// GILは自動解放
}
```
## 🏗️ アーキテクチャ概要
### レイヤー構造
```
┌─────────────────────────────────┐
│ Hakorune Application │
├─────────────────────────────────┤
│ Python Integration Layer │
│ - PyRuntimeBox │
│ - PyObjectBox │
├─────────────────────────────────┤
│ FFI/Plugin Interface │
│ - Handle-First design │
│ - TLV type system │
├─────────────────────────────────┤
│ CPython C API │
├─────────────────────────────────┤
│ CPython Runtime │
└─────────────────────────────────┘
```
### プラグイン構成
```
hakorune-python-plugin/
├── src/
│ ├── lib.rs # FFI entry point
│ ├── runtime.rs # PyRuntimeBox
│ ├── object.rs # PyObjectBox
│ ├── conversion.rs # 型変換
│ └── gil.rs # GIL管理
├── Cargo.toml
└── build.rs
```
## 🔧 ネイティブビルド戦略
### AOT/EXEパイプライン
```
Hakorune Source (.hkr)
↓ Parse
AST
↓ Lower
MIR
↓ JIT Compile
CLIF IR
↓ Object Generation
Object File (.o)
↓ Link (with libhakorunert.a + Python libs)
Native Executable
```
### クロスプラットフォーム対応
| Platform | Python Library | 備考 |
|----------|---------------|------|
| Linux | libpython3.X.so | 動的リンク |
| macOS | libpython3.X.dylib | 動的リンク |
| Windows | python3X.dll | 動的リンク |
## 📊 設計決定事項
### 1. Embedding vs Extending
**決定**: Embedding優先
理由:
- HakoruneからPythonを制御
- デプロイが簡単
- ユーザー体験が良い
### 2. 静的 vs 動的リンク
**決定**: 動的リンク優先、静的リンクはオプション
理由:
- Python標準の配布方法
- ライセンス問題の回避
- 柔軟性の確保
### 3. サポート対象Python
**決定**: Python 3.8以降
理由:
- 型ヒントの充実
- 十分な普及
- メンテナンス負荷
## ⚠️ リスク要因
### 1. CPython依存
- バージョン互換性
- プラットフォーム差異
- ビルド環境の複雑さ
### 2. パフォーマンス
- FFIオーバーヘッド
- GIL待機時間
- メモリコピーコスト
### 3. デバッグ困難性
- 言語境界を越えるエラー
- スタックトレースの複雑さ
- メモリリークの追跡
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Planning](../planning/)
- [Core Implementation](../core-implementation/)

View File

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

View File

@ -0,0 +1,543 @@
# Python-Hakorune統合 強化版アーキテクチャ v2
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**ステータス**: 設計提案
---
## 📋 概要
Phase 10.5の「Active」設計を踏まえつつ、**強化版Hakorune**Effect/Capability/Contract/Policy・PHI検証・BlockVMap等の上に載せる、**安全で境界に問題を閉じ込めたPythonブリッジ**の設計書です。
---
## 🎯 ねらいPhase 10.5の「Active」意図との整合
- 最小コアで **"箱Boxに閉じ込めたPython実行環境"** を提供
- VM/LLVM/AOTラインから同じ呼び出し規約で扱える
- **当面はVMハーネスllvmlite側を使って決定実行とスモークの安定性を優先**、AOT/EXEは段階導入
---
## 🏗️ 1. Box階層木構造の基本セット
### PyRuntimeBoxルート・単一 or 少数)
**役割**:
- PythonランタイムCPython埋め込み
- `import` 解決
- GIL管理
- モジュールキャッシュ
**ライフサイクル**:
- `init`: インタプリタ起動
- `fini`: 停止
- **Capability**で"import可能モジュールFS/NET/ENV"を限定
**実装指針**:
- まずは既存 **Plugin-First**C ABI・TLVでブリッジ
- 後段で **Hakorune ABIvtable** に段階移行
- `HAKO_ABI_VTABLE` 等のgateを活用
```hakorune
box PyRuntimeBox {
// 初期化・終了
init()
fini()
// モジュール
import(name: StringBox) -> PyModuleBox
reflect(module_name: StringBox) -> PyModuleBox
// 実行
eval(code: StringBox) -> PyObjectBox
exec(code: StringBox)
}
```
---
### PyModuleBox
**役割**:
- `import "pkg.mod"` の結果をBoxとして公開
- 属性 = フィールド
- 関数 = MethodBox
**ライフサイクル**:
- `PyRuntimeBox` が所有
- `fini` で参照解除refcnt を減らす)
```hakorune
box PyModuleBox {
// 属性アクセス
get(name: StringBox) -> PyObjectBox
set(name: StringBox, value: PyObjectBox)
// 列挙
list_attributes() -> ArrayBox
}
```
---
### PyTypeBox / PyInstanceBox
**役割**:
- Pythonのクラス定義とインスタンスをBox化
- `get/setField``call_method` を統一導線に
**所有権タグ**:
- **shared**CPython RC前提
- `unique` が必要な場合は"借用トークン"で一時的に排他操作を許可
```hakorune
box PyTypeBox {
// クラス情報
get_name() -> StringBox
get_bases() -> ArrayBox
get_methods() -> ArrayBox
// インスタンス化
new_instance(args: ArrayBox) -> PyInstanceBox
}
box PyInstanceBox {
// フィールドアクセス
get_field(name: StringBox) -> PyObjectBox
set_field(name: StringBox, value: PyObjectBox)
// メソッド呼び出し
call_method(name: StringBox, args: ArrayBox) -> PyObjectBox
}
```
---
### PyFunctionBox / PyCallableBox
**役割**:
- 呼出しを `exec(args)->result`Pulse的に落として**最小ライフサイクル**で扱える
```hakorune
box PyFunctionBox {
// Pulse: 完全な一発実行
exec(args: ArrayBox) -> PyObjectBox
// メタ情報
get_name() -> StringBox
get_signature() -> StringBox
}
```
---
### PyIteratorBox / PyGeneratorBox必要に応じて
**役割**:
- `__iter__`/`__next__` をBox化
- flow実行と相性を取る
```hakorune
box PyIteratorBox {
next() -> PyObjectBox
has_next() -> BoolBox
}
box PyGeneratorBox {
send(value: PyObjectBox) -> PyObjectBox
throw(error: ErrorBox)
}
```
> **Phase 10.5の設計メモと整合**"最小の箱から着手 → 後から拡張"
---
## 🔄 2. ライフサイクル対応Hakorune流
### init/fini
**PyRuntimeBox.init()**:
```rust
fn init() {
Py_Initialize();
// import policyのロード
// キャッシュ構築
}
```
**PyRuntimeBox.fini()**:
```rust
fn fini() {
// weakref.finalize併用で安全解放循環対策
Py_Finalize();
}
```
### Pulse
**PyFunctionBox.exec** は完全Pulseinit/fini不要:
- **作用範囲はmetaのCapabilityに閉じ込め**
- 副作用は明示的にEffect宣言
### 所有権タグ
- 既定: **shared**RC準拠
- **unique** が必要な経路: `BorrowMutToken` を発行して**単発処理中のみ**排他
> これらは **管理棟のトグル**とも親和性が高いdev: 緩める / prod: 厳格)
---
## 🎭 3. Effect / Capability / Contract の外付けmeta
### Effect論理的効果名
```toml
[box.PyRuntimeBox.effects]
available = [
"py.import",
"py.fs",
"py.net",
"py.env",
"py.time",
"py.random",
"py.subprocess"
]
```
### Capability許可リスト
```toml
[box.PyRuntimeBox.capabilities]
allow = [
"py.import:math",
"py.import:json",
"py.time:monotonic"
]
deny = [
"py.subprocess",
"py.net"
]
enforce = true # devではfalse→観測のみ
```
### Contract
**Pre条件**:
```toml
[contracts.PyFunctionBox.exec]
pre = [
"args.len <= 8",
"bytes_total <= 1_000_000"
]
```
**Post条件**:
```toml
[contracts.PyFunctionBox.exec]
post = [
"result.size <= 1_000_000",
"no_exception",
"allow_none = true"
]
```
### 監査トグル
```bash
# Dev/CI
HAKO_PLUGIN_CAPS_ENFORCE=1
HAKO_CHECK_CONTRACTS=1
# Prod
HAKO_PLUGIN_CAPS_ENFORCE=1
HAKO_CHECK_CONTRACTS=0 # 警告のみ
```
---
## 🔁 4. Deterministic / Repro の扱い
### Deterministic モード
**問題**:
- `random`, `time`, `os.urandom` 等は非決定的
**解決策**:
- **Capability トークン経由**で提供するshimsを使用
**実装例**:
```python
# py.random shim
class DeterministicRandom:
def __init__(self, seed):
self._rng = random.Random(seed)
def random(self):
return self._rng.random()
# py.time shim
class LogicalClock:
def __init__(self):
self._tick = 0
def monotonic(self):
self._tick += 1
return float(self._tick)
```
**トグル**:
```bash
# Deterministic モード有効化
HAKO_DETERMINISTIC=1
HAKO_TRACE_EFFECTS=1 # 効果ログ収集
```
**メリット**:
- **flow Main.main** 実行のスナップショット再現が可能
- デバッグ容易性向上
- テストの再現性保証
---
## 🌳 5. 木構造への「落とし方」(反射 → Box化
### ビルダー(反射)
**PyRuntimeBox.reflect(module_name: String) -> PyModuleBox**:
1. `dir(module)``inspect` で**属性ツリーを走査**
2. **Box**を生成
3. **規約**:
- 公開対象は `__all__` 優先
- ない場合は `_` 先頭を除外
- `@hako_export` デコレータがあれば優先で `FunctionBox`
**実装擬似コード**:
```python
# Python側リフレクションヘルパー
def reflect_module(module_name):
mod = importlib.import_module(module_name)
# 属性リスト取得
if hasattr(mod, '__all__'):
attrs = mod.__all__
else:
attrs = [a for a in dir(mod) if not a.startswith('_')]
# Box化
boxes = {}
for attr_name in attrs:
attr = getattr(mod, attr_name)
if callable(attr):
boxes[attr_name] = create_function_box(attr)
elif inspect.isclass(attr):
boxes[attr_name] = create_type_box(attr)
else:
boxes[attr_name] = create_object_box(attr)
return boxes
```
### 使用例
```hakorune
using "python"
box Main {
flow main() {
// init: CPython起動
let py = PyRuntimeBox();
// PyModuleBox
let m = py.reflect("math");
// PyFunctionBox
let sqrt = m.get("sqrt");
// 実行
let r = sqrt.exec([2.0]);
print(r); // -> 1.4142...
// 正常停止
py.fini();
}
}
```
> 反射で"木"を作り、**Box統一APIget/set/callで走る** — Phase 10.5の「Activeは最小の箱から導入」を踏襲
---
## ⚠️ 6. 例外とエラー境界
### Python例外 → ErrorBox
```hakorune
box ErrorBox {
type: StringBox // "ZeroDivisionError"
message: StringBox // "division by zero"
traceback: StringBox // フルトレースバック
}
```
**変換例**:
```python
# Python側
try:
result = some_function()
except Exception as e:
return ErrorBox(
type=type(e).__name__,
message=str(e),
traceback=traceback.format_exc()
)
```
### Contract違反
**Strict モード**:
```bash
HAKO_EXTERN_STRICT=1 # fail-fast
```
**通常モード**:
```bash
HAKO_EXTERN_STRICT=0 # 警告 + ErrorBox返却
```
---
## 🎛️ 7. 実行ポリシーとトグル(管理棟)
### ハーネス
```bash
# 既定でPythonハーネス使用
HAKO_LLVM_USE_HARNESS=1 # デフォルトON
```
### PHIオプション
**ブリッジ互換**PHI-off:
```bash
HAKO_VERIFY_ALLOW_NO_PHI=1 # 互換用途のみ
```
**統一**PHI-on:
```bash
HAKO_VERIFY_ALLOW_NO_PHI=0 # 推奨
# Verifierを**PHI直後に常時実行**
```
**モード設定**:
- Dev: fail-fast
- Prod: 警告
### ABI
**初期**C ABI - TLV:
```bash
HAKO_ABI_VTABLE=0 # C ABI使用
```
**段階移行**Hakorune ABI - vtable:
```bash
HAKO_ABI_VTABLE=1
HAKO_ABI_STRICT=1 # フォールバック禁止
```
### Plugin観測
```bash
# CI/Dev
HAKO_TRACE_EFFECTS=1
HAKO_PLUGIN_META=1
HAKO_PLUGIN_CAPS_ENFORCE=1
```
---
## 🚀 強化版Hakoruneでの設計図アップデート
### 1. 境界検証を"必須フェーズ"に
**実装**:
- `finalize_phis()` の直後で **SSA/支配関係/到達性**を検証
- Dev: 例外
- Prod: 警告+トレース保全
**効果**:
- Pythonブリッジ有無に関わらず**毎回**回る
- IR品質を境界に閉じ込める
### 2. BlockVMap型でvmap/_current_vmapを統合
**実装**:
- 参照は必ず `BlockVMap::at(block)` 経由
- 呼び出し側から**どの視点が"真"か**を隠蔽
**効果**:
- Python連携でもブロック境界で値がぶれない
- 事故防止
### 3. InstructionContextを必須引数化
**実装**:
- すべての `lower_*` に統一コンテキストを渡す
- **ログ/例外に命令位置・BB名を強制添付**
**効果**:
- 原因追跡が一気に楽に
### 4. flow Main.main を"仕様"として固定
**実装**:
- Phase 10.5のActive方針と揃えて **flow優先**
- staticを覚える必要なし
**効果**:
- 入口の一意化
- セルフホストの再現ビルド検証にも効く
### 5. 開発→本番の昇格パスを明確化
**Dev**:
```bash
HAKO_*_ENFORCE=0
HAKO_TRACE=1
# fail-fast ON
```
**Prod**:
```bash
HAKO_*_ENFORCE=1
HAKO_TRACE=0
# fail-fast OFFErrorBox警告
```
**効果**:
- **管理棟env**にすでに集約されている設計
- 運用で迷わない
---
## 🔗 関連ドキュメント
- [マイルストーン](../planning/milestones.md) - M0〜M6の詳細計画
- [メタ設定例](meta-config-examples.md) - hako.toml設定例
- [リスクと対策](risks-and-mitigations.md) - 既知のリスクと対策
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**レビュー**: 未実施
**ステータス**: 設計提案・Phase 15完了後に実装予定

View File

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

View File

@ -0,0 +1,531 @@
# hako.toml メタ設定例
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**用途**: Python統合のメタデータ設定リファレンス
---
## 📋 概要
Python-Hakorune統合における`hako.toml`の設定例集です。
Effect/Capability/Contract/Policyの具体的な設定方法を示します。
---
## 🎯 基本設定
### 最小構成
```toml
# hako.toml (minimal)
[box.PyRuntimeBox]
effects.allow = ["py.import:math"]
```
### 標準構成
```toml
# hako.toml (standard)
[box.PyRuntimeBox]
effects.allow = [
"py.import:math",
"py.import:json",
"py.time:monotonic"
]
capabilities.enforce = true
```
---
## 🎭 Effect設定
### 利用可能なEffect一覧
```toml
[box.PyRuntimeBox.effects]
available = [
# モジュールインポート
"py.import",
# ファイルシステム
"py.fs.read",
"py.fs.write",
# ネットワーク
"py.net.http",
"py.net.socket",
# 環境変数
"py.env.read",
"py.env.write",
# 時刻
"py.time.monotonic",
"py.time.real",
# ランダム
"py.random",
# プロセス
"py.subprocess"
]
```
### Effect許可例
```toml
[box.PyRuntimeBox.effects]
allow = [
"py.import:math",
"py.import:json",
"py.import:re",
"py.time:monotonic",
"py.fs.read:/tmp/**"
]
```
---
## 🛡️ Capability設定
### 基本Capability
```toml
[box.PyRuntimeBox.capabilities]
# 許可リスト
allow = [
"py.import:math",
"py.import:json"
]
# 拒否リスト
deny = [
"py.subprocess",
"py.net"
]
# 厳格モード
enforce = true
```
### 詳細Capabilityモジュール別
```toml
[box.PyRuntimeBox.capabilities.import]
# 標準ライブラリ
stdlib = [
"math",
"json",
"re",
"datetime",
"collections"
]
# サードパーティ(ホワイトリスト)
allow_third_party = [
"numpy",
"pandas"
]
# 拒否(ブラックリスト)
deny = [
"os",
"subprocess",
"socket"
]
```
### ファイルシステムCapability
```toml
[box.PyRuntimeBox.capabilities.fs]
# 読み取り許可
read_paths = [
"/tmp/**",
"/data/input/**",
"~/.config/app/**"
]
# 書き込み許可
write_paths = [
"/tmp/**",
"/data/output/**"
]
# 拒否
deny_paths = [
"/etc/**",
"/sys/**",
"~/.ssh/**"
]
```
### ネットワークCapability
```toml
[box.PyRuntimeBox.capabilities.net]
# HTTP許可
http_allow = [
"https://api.example.com/**",
"https://data.example.org/api/**"
]
# Socket許可ホスト:ポート)
socket_allow = [
"localhost:8080",
"127.0.0.1:5432"
]
# 拒否
deny = [
"0.0.0.0:*", # すべてのインターフェース
"*:22", # SSH
"*:3389" # RDP
]
```
---
## ✅ Contract設定
### PyFunctionBox Contract
```toml
[contracts.PyFunctionBox.exec]
# Pre条件引数チェック
pre = [
"args.len <= 8", # 引数は8個まで
"bytes_total <= 1_000_000", # 合計1MB以下
"no_file_descriptors" # ファイルディスクリプタ禁止
]
# Post条件返り値チェック
post = [
"result.size <= 1_000_000", # 返り値1MB以下
"no_exception", # 例外禁止
"allow_none = true", # None許可
"execution_time <= 5.0" # 5秒以内
]
# 違反時の挙動
on_violation = "error" # "error" | "warn" | "ignore"
```
### PyModuleBox Contract
```toml
[contracts.PyModuleBox.import]
pre = [
"module_name.len <= 100", # モジュール名100文字以内
"no_relative_import" # 相対インポート禁止
]
post = [
"module_size <= 10_000_000", # モジュールサイズ10MB以下
"no_native_code" # ネイティブコード禁止(オプション)
]
```
### PyInstanceBox Contract
```toml
[contracts.PyInstanceBox.call_method]
pre = [
"method_name.len <= 50", # メソッド名50文字以内
"args.len <= 16" # 引数16個まで
]
post = [
"result.size <= 1_000_000", # 返り値1MB以下
"no_side_effects" # 副作用禁止Pure
]
```
---
## 🎛️ Policy設定
### 開発モードDev
```toml
[policy.dev]
# Capability
capabilities.enforce = false # 観測のみ
capabilities.log = true # ログ記録
# Contract
contracts.enforce = true # 厳格チェック
contracts.on_violation = "error" # 違反時エラー
# Deterministic
deterministic = false # 非決定的許可
# Trace
trace.effects = true # 効果トレース
trace.calls = true # 呼び出しトレース
trace.errors = true # エラートレース
# Verifier
verify.phi = true # PHI検証
verify.ssa = true # SSA検証
verify.on_fail = "error" # 検証失敗時エラー
```
### 本番モードProd
```toml
[policy.prod]
# Capability
capabilities.enforce = true # 厳格適用
capabilities.log = false # ログなし
# Contract
contracts.enforce = true # 厳格チェック
contracts.on_violation = "warn" # 違反時警告
# Deterministic
deterministic = true # 決定的実行
# Trace
trace.effects = false # トレースなし
trace.calls = false
trace.errors = true # エラーのみ
# Verifier
verify.phi = true # PHI検証
verify.ssa = true # SSA検証
verify.on_fail = "warn" # 検証失敗時警告
```
### テストモードTest
```toml
[policy.test]
# Capability
capabilities.enforce = true # 厳格適用
capabilities.log = true # ログ記録
# Contract
contracts.enforce = true # 厳格チェック
contracts.on_violation = "error" # 違反時エラー
# Deterministic
deterministic = true # 決定的実行(再現性)
# Trace
trace.effects = true # 全トレース
trace.calls = true
trace.errors = true
# Verifier
verify.phi = true # 全検証
verify.ssa = true
verify.on_fail = "error" # 検証失敗時エラー
```
---
## 🔧 環境変数によるオーバーライド
### 優先順位
1. 環境変数(最優先)
2. hako.toml
3. hakorune.toml
4. デフォルト値
### 環境変数例
```bash
# Capability
export HAKO_PLUGIN_CAPS_ENFORCE=1
export HAKO_TRACE_EFFECTS=1
# Contract
export HAKO_CHECK_CONTRACTS=1
export HAKO_CONTRACT_VIOLATION=error
# Deterministic
export HAKO_DETERMINISTIC=1
# ABI
export HAKO_ABI_VTABLE=1
export HAKO_ABI_STRICT=1
# Verifier
export HAKO_VERIFY_ALLOW_NO_PHI=0
export HAKO_VERIFY_ON_FAIL=error
# LLVM
export HAKO_LLVM_USE_HARNESS=1
```
---
## 📊 実用例
### 例1: 数学計算のみ許可
```toml
# hako.toml
[box.PyRuntimeBox]
effects.allow = ["py.import:math"]
capabilities.enforce = true
[contracts.PyFunctionBox.exec]
pre = ["args.len <= 4"]
post = ["no_exception", "execution_time <= 1.0"]
```
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let math = py.import("math");
let sqrt = math.get("sqrt");
let r = sqrt.exec([2.0]);
print(r); // OK
py.fini();
}
}
```
### 例2: データ処理(ファイル読み取り)
```toml
# hako.toml
[box.PyRuntimeBox]
effects.allow = [
"py.import:json",
"py.fs.read:/data/input/**"
]
[box.PyRuntimeBox.capabilities.fs]
read_paths = ["/data/input/**"]
write_paths = [] # 書き込み禁止
```
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let json = py.import("json");
// ファイル読み取り(許可)
let data = py.eval("open('/data/input/test.json').read()");
let parsed = json.get("loads").exec([data]);
print(parsed);
py.fini();
}
}
```
### 例3: API呼び出しネットワーク
```toml
# hako.toml
[box.PyRuntimeBox]
effects.allow = [
"py.import:urllib",
"py.net.http"
]
[box.PyRuntimeBox.capabilities.net]
http_allow = [
"https://api.example.com/**"
]
[contracts.PyFunctionBox.exec]
pre = ["args.len <= 2"]
post = [
"result.size <= 1_000_000",
"execution_time <= 10.0"
]
```
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let code = "
import urllib.request
def fetch(url):
with urllib.request.urlopen(url) as r:
return r.read()
";
py.exec(code);
let fetch = py.get("fetch");
// API呼び出し許可
let result = fetch.exec(["https://api.example.com/data"]);
print(result);
py.fini();
}
}
```
---
## 🔍 デバッグ設定
### 詳細ログ
```toml
[debug]
# すべてのトレース有効化
trace.all = true
# 個別トレース
trace.effects = true
trace.capabilities = true
trace.contracts = true
trace.python_calls = true
trace.gil = true
# ログレベル
log_level = "debug"
# ログ出力先
log_file = "/tmp/hakorune-python-debug.log"
```
### パフォーマンスプロファイル
```toml
[profile]
# タイミング記録
timing.enabled = true
timing.threshold = 0.1 # 100ms以上
# メモリ使用量
memory.track = true
memory.threshold = 10_000_000 # 10MB以上
# GC統計
gc.enabled = true
```
---
## 🔗 関連ドキュメント
- [強化版アーキテクチャv2](enhanced-architecture-v2.md) - 設計詳細
- [マイルストーン](../planning/milestones.md) - 実装計画
- [リスクと対策](risks-and-mitigations.md) - リスク管理
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**ステータス**: 設定リファレンス

View File

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

View File

@ -0,0 +1,441 @@
# リスクと対策
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**用途**: Python統合における既知のリスクと対策
---
## 📋 概要
Python-Hakorune統合における技術的リスク、運用リスク、およびその対策をまとめます。
---
## 🔥 高リスク項目
### 1. GILデッドロック
#### リスク詳細
- **問題**: Hakorune並列実行とPython GILのズレ
- **発生条件**: Hakorune側マルチスレッド + Python呼び出しのネスト
- **影響**: プログラム全体がハング、デバッグ困難
#### 対策
**アーキテクチャレベル**:
```rust
// PyRuntimeBoxを専用スレッドで実行
pub struct PyRuntimeBox {
thread: JoinHandle<()>,
tx: Sender<PyCommand>,
rx: Receiver<PyResult>,
}
impl PyRuntimeBox {
pub fn init() -> Self {
let (tx, rx_cmd) = channel();
let (tx_result, rx) = channel();
let thread = thread::spawn(move || {
// このスレッドでGILを保持
let gil = Python::acquire_gil();
let py = gil.python();
loop {
match rx_cmd.recv() {
Ok(PyCommand::Import(name)) => {
let result = py.import(&name);
tx_result.send(PyResult::Module(result)).unwrap();
}
Ok(PyCommand::Shutdown) => break,
Err(_) => break,
}
}
});
PyRuntimeBox { thread, tx, rx }
}
}
```
**ガードレール**:
```toml
[debug.gil]
# GIL獲得・解放のログ
trace = true
# タイムアウト検出
timeout = 5.0 # 5秒
# デッドロック検出
detect_deadlock = true
```
**モニタリング**:
```bash
# GILトレース有効化
export HAKO_TRACE_GIL=1
# タイムアウト設定
export HAKO_GIL_TIMEOUT=5.0
```
#### 回避策
1. **専用スレッド**でPython実行を隔離
2. **メッセージパッシング**でHakorune-Python間通信
3. **タイムアウト**で異常検出
4. **ログ**で原因追跡
---
### 2. メモリリーク
#### リスク詳細
- **問題**: Python参照カウント管理ミス
- **発生条件**: `Py_INCREF`/`Py_DECREF`の不一致
- **影響**: メモリ使用量増大、最悪OOM
#### 対策
**Arc管理**:
```rust
// PythonオブジェクトをArcでラップ
pub struct PyObjectBox {
inner: Arc<PyObjectInner>,
}
struct PyObjectInner {
py_obj: Py<PyAny>,
}
impl Drop for PyObjectInner {
fn drop(&mut self) {
// 確実にDECREF
Python::with_gil(|py| {
self.py_obj.as_ref(py);
});
}
}
```
**weakref.finalize**:
```python
# Python側で自動クリーンアップ
import weakref
def create_hakorune_object(obj):
# finalizer登録
finalizer = weakref.finalize(obj, cleanup_callback, obj_id)
return obj
```
**リーク検出**:
```toml
[debug.memory]
# メモリトラッキング
track = true
# リーク検出
detect_leaks = true
# 定期チェック
check_interval = 10.0 # 10秒
```
**ツール**:
```bash
# Valgrind
valgrind --leak-check=full ./hakorune script.hkr
# AddressSanitizer
RUSTFLAGS="-Z sanitizer=address" cargo build
# Python memory profiler
export PYTHONTRACEMALLOC=1
```
#### 回避策
1. **Arc/Drop**で自動管理
2. **weakref.finalize**で循環参照対策
3. **定期チェック**で早期発見
4. **テスト**で継続監視
---
### 3. C拡張モジュールの扱い
#### リスク詳細
- **問題**: numpy等のC拡張は特殊な扱いが必要
- **発生条件**: ネイティブコードの直接呼び出し
- **影響**: セグフォ、未定義動作
#### 対策
**Capability制御**:
```toml
[box.PyRuntimeBox.capabilities.native]
# C拡張の許可
allow_native = true
# ホワイトリスト
allow_modules = [
"numpy",
"pandas",
"_ctypes"
]
# ブラックリスト
deny_modules = [
"ctypes", # 任意ネイティブコード実行
"cffi"
]
```
**サンドボックス**(将来):
```toml
[sandbox]
# ネイティブコードをサンドボックスで実行
enable = true
mode = "seccomp" # Linux
```
**検証**:
```rust
// ロード前に検証
fn verify_module_safety(module_name: &str) -> Result<()> {
// シグネチャ確認
// 既知の安全なモジュールか
// ブラックリスト確認
}
```
#### 回避策
1. **ホワイトリスト**で既知の安全なモジュールのみ許可
2. **サンドボックス**で隔離実行(将来)
3. **検証**でロード前チェック
---
## ⚠️ 中リスク項目
### 4. パフォーマンスオーバーヘッド
#### リスク詳細
- **問題**: FFI境界・GIL・型変換のコスト
- **影響**: 性能劣化
#### 対策
**最適化**:
```rust
// 型変換キャッシュ
struct TypeCache {
string_to_pyobject: HashMap<String, Py<PyString>>,
int_to_pyobject: HashMap<i64, Py<PyLong>>,
}
impl TypeCache {
fn get_or_create_string(&mut self, py: Python, s: &str) -> Py<PyString> {
self.string_to_pyobject
.entry(s.to_string())
.or_insert_with(|| PyString::new(py, s).into())
.clone()
}
}
```
**バッチ処理**:
```rust
// 複数呼び出しをまとめる
fn batch_call(funcs: Vec<PyFunctionBox>, args: Vec<Vec<Value>>) -> Vec<Value> {
Python::with_gil(|py| {
funcs.iter().zip(args.iter())
.map(|(f, a)| f.exec_with_gil(py, a))
.collect()
})
}
```
**ベンチマーク**:
```bash
# パフォーマンステスト
cargo bench --features python-integration
```
---
### 5. プラットフォーム固有問題
#### リスク詳細
- **問題**: Python配布形態の違いLinux/macOS/Windows
- **影響**: ビルド・実行時エラー
#### 対策
**プラットフォーム別設定**:
```toml
# Linux
[target.x86_64-unknown-linux-gnu]
python-lib = "python3.11"
python-path = "/usr/lib/python3.11"
# macOS
[target.x86_64-apple-darwin]
python-lib = "python3.11"
python-path = "/usr/local/opt/python@3.11"
# Windows
[target.x86_64-pc-windows-msvc]
python-lib = "python311"
python-path = "C:/Python311"
```
**CI/CD**:
```yaml
# .github/workflows/python-integration.yml
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.8', '3.9', '3.10', '3.11']
```
---
### 6. 例外伝播の複雑さ
#### リスク詳細
- **問題**: Python例外とHakoruneエラーの境界
- **影響**: エラーハンドリングの困難さ
#### 対策
**統一ErrorBox**:
```hakorune
box ErrorBox {
type: StringBox // "ZeroDivisionError"
message: StringBox // "division by zero"
traceback: StringBox // フルスタックトレース
source: StringBox // "python" | "hakorune"
}
```
**変換層**:
```rust
fn convert_py_exception(py_err: &PyErr) -> ErrorBox {
ErrorBox {
type_: py_err.get_type().name().to_string(),
message: py_err.to_string(),
traceback: format_traceback(py_err),
source: "python".to_string(),
}
}
```
---
## 📊 低リスク項目
### 7. ドキュメント不足
#### 対策
- 段階的にドキュメント整備
- コードサンプル充実
- チュートリアル作成
### 8. テストカバレッジ
#### 対策
- ユニットテスト追加
- 統合テスト充実
- E2Eテスト自動化
---
## 🛡️ リスク管理マトリックス
| リスク | 深刻度 | 発生確率 | 優先度 | 対策状況 |
|-------|-------|---------|-------|---------|
| GILデッドロック | 高 | 中 | 最優先 | 設計段階で対策 |
| メモリリーク | 高 | 中 | 最優先 | Arc/Drop自動化 |
| C拡張問題 | 高 | 低 | 高 | ホワイトリスト |
| パフォーマンス | 中 | 高 | 中 | 最適化計画 |
| プラットフォーム | 中 | 中 | 中 | CI/CD網羅 |
| 例外伝播 | 中 | 低 | 低 | ErrorBox統一 |
| ドキュメント | 低 | 高 | 低 | 段階的整備 |
| テストカバレッジ | 低 | 中 | 低 | 継続改善 |
---
## 🔍 監視・検出
### 自動検出
```toml
[monitoring]
# GIL監視
gil.timeout = 5.0
gil.alert_on_timeout = true
# メモリ監視
memory.threshold = 100_000_000 # 100MB
memory.alert_on_threshold = true
# パフォーマンス監視
performance.slow_call_threshold = 1.0 # 1秒
performance.alert_on_slow = true
```
### ログ
```bash
# すべての監視ログ
export HAKO_TRACE_GIL=1
export HAKO_TRACE_MEMORY=1
export HAKO_TRACE_PERFORMANCE=1
```
---
## 📝 インシデント対応
### 1. GILデッドロック発生時
```bash
# 1. ログ確認
cat /tmp/hakorune-debug.log | grep GIL
# 2. スタックトレース取得
kill -QUIT <pid>
# 3. デバッガー接続
gdb -p <pid>
```
### 2. メモリリーク発生時
```bash
# 1. メモリ使用量確認
ps aux | grep hakorune
# 2. Valgrind実行
valgrind --leak-check=full ./hakorune script.hkr
# 3. Python側確認
export PYTHONTRACEMALLOC=1
```
---
## 🔗 関連ドキュメント
- [強化版アーキテクチャv2](enhanced-architecture-v2.md) - 設計詳細
- [マイルストーン](../planning/milestones.md) - 実装計画
- [メタ設定例](meta-config-examples.md) - 設定例
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**ステータス**: リスク管理ドキュメント

View File

@ -0,0 +1,270 @@
# Documentation - ドキュメント
## 📋 概要
Python-Hakorune統合のドキュメント計画です。
## 📚 ドキュメント構成
### 1. ユーザーガイド
#### クイックスタート
```markdown
# Python統合クイックスタート
## インストール
hakorune-pythonプラグインをインストール:
```bash
cargo build --release --features python-integration
```
## 基本的な使い方
```hakorune
// Pythonコードを実行
local py = new PyRuntimeBox()
local result = py.eval("2 + 3")
console.log(result.to_string()) // "5"
// モジュールをインポート
local math = py.import("math")
local pi = math.getattr("pi")
console.log(pi.to_string()) // "3.14159..."
```
```
#### チュートリアル
- Python基本操作
- モジュールインポート
- オブジェクト操作
- エラーハンドリング
- パフォーマンス最適化
### 2. リファレンス
#### PyRuntimeBox API
```markdown
# PyRuntimeBox
Python実行環境を提供するBox。
## メソッド
### eval(code: StringBox) -> PyObjectBox
Pythonコードを評価し、結果を返す。
**引数:**
- `code`: 実行するPythonコード
**戻り値:**
- `PyObjectBox`: 実行結果
**例:**
```hakorune
local py = new PyRuntimeBox()
local result = py.eval("2 + 3")
```
### import(name: StringBox) -> PyObjectBox
Pythonモジュールをインポート。
**引数:**
- `name`: モジュール名
**戻り値:**
- `PyObjectBox`: インポートされたモジュール
**例:**
```hakorune
local math = py.import("math")
```
```
#### PyObjectBox API
```markdown
# PyObjectBox
Pythonオブジェクトを表すBox。
## メソッド
### getattr(name: StringBox) -> PyObjectBox
オブジェクトの属性を取得。
### setattr(name: StringBox, value: PyObjectBox)
オブジェクトの属性を設定。
### call(args: ArrayBox) -> PyObjectBox
オブジェクトを関数として呼び出し。
### to_string() -> StringBox
Pythonオブジェクトを文字列に変換。
### to_int() -> IntegerBox
Pythonオブジェクトを整数に変換。
### to_bool() -> BoolBox
Pythonオブジェクトを真偽値に変換。
```
### 3. 設計ドキュメント
#### アーキテクチャ
- 全体構成
- レイヤー構造
- データフロー
#### ABI仕様
- ハンドル管理
- 型変換ルール
- エラーハンドリング
#### GIL管理
- 獲得・解放ルール
- ネスト呼び出し
- マルチスレッド対応
### 4. 開発者ガイド
#### プラグイン開発
```markdown
# Python統合プラグイン開発ガイド
## プラグインの構造
```rust
// src/lib.rs
use hakorune_plugin_api::*;
#[no_mangle]
pub extern "C" fn nyplug_python_invoke(
method_id: u32,
args: *const TLV,
args_len: usize,
ret: *mut TLV,
) -> i32 {
// 実装
}
```
## ビルド
```bash
cargo build --release --crate-type cdylib
```
```
#### コントリビューション
- コーディング規約
- テストガイドライン
- プルリクエストプロセス
### 5. トラブルシューティング
#### よくある問題
**Q: Pythonモジュールが見つからない**
```
A: PYTHONPATHを設定してください:
export PYTHONPATH=/path/to/modules:$PYTHONPATH
```
**Q: GILデッドロックが発生する**
```
A: ネスト呼び出しを避けるか、GILを明示的に解放してください。
```
**Q: メモリリークが発生する**
```
A: PyObjectBoxを適切にdropしているか確認してください。
```
## 📝 ドキュメント作成タスク
### Phase 1: 基本ドキュメント
- [ ] README.md概要
- [ ] QUICKSTART.mdクイックスタート
- [ ] INSTALLATION.mdインストール
### Phase 2: API リファレンス
- [ ] PyRuntimeBox API
- [ ] PyObjectBox API
- [ ] 型変換ルール
### Phase 3: チュートリアル
- [ ] 基本操作
- [ ] モジュールインポート
- [ ] オブジェクト操作
- [ ] エラーハンドリング
### Phase 4: 開発者向け
- [ ] アーキテクチャ設計
- [ ] プラグイン開発ガイド
- [ ] コントリビューションガイド
### Phase 5: その他
- [ ] トラブルシューティング
- [ ] パフォーマンスガイド
- [ ] ベストプラクティス
## 🎯 ドキュメント品質基準
### 必須要件
- [ ] コードサンプルが動作する
- [ ] 用語が一貫している
- [ ] エラーメッセージが明確
- [ ] プラットフォーム差異を記載
### 推奨要件
- [ ] 図表を含む
- [ ] ビデオチュートリアル
- [ ] 多言語対応(日本語・英語)
- [ ] 検索可能
## 📊 ドキュメント構成図
```
docs/
├── guides/
│ ├── python-integration/
│ │ ├── README.md # 概要
│ │ ├── quickstart.md # クイックスタート
│ │ ├── installation.md # インストール
│ │ ├── tutorial/ # チュートリアル
│ │ │ ├── 01-basics.md
│ │ │ ├── 02-modules.md
│ │ │ ├── 03-objects.md
│ │ │ └── 04-errors.md
│ │ └── troubleshooting.md # トラブルシューティング
│ └── ...
├── reference/
│ ├── python-integration/
│ │ ├── pyruntimebox-api.md # PyRuntimeBox API
│ │ ├── pyobjectbox-api.md # PyObjectBox API
│ │ ├── type-conversion.md # 型変換ルール
│ │ └── error-handling.md # エラーハンドリング
│ └── ...
└── development/
└── python-integration/
├── architecture.md # アーキテクチャ
├── plugin-dev.md # プラグイン開発
└── contributing.md # コントリビューション
```
## 🔗 関連リソース
### 公式ドキュメント
- [Python C API](https://docs.python.org/3/c-api/)
- [PyO3 Guide](https://pyo3.rs/)
### 参考実装
- Rust PyO3
- Node.js Python bindings
- Julia Python interop
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Planning](../planning/)
- [Core Implementation](../core-implementation/)

View File

@ -0,0 +1,121 @@
# Parser Integration - Pythonパーサー統合
## 📋 概要
PythonのAST抽象構文木をHakoruneで扱うためのパーサー統合設計です。
## 📁 ファイル一覧
### 実装計画
- **[implementation-plan.md](implementation-plan.md)** - PythonパーサーBox実装計画
- **[builtin-box-flow.md](builtin-box-flow.md)** - ビルトインBox実装フロー
## 🎯 目的
### PythonパーサーBoxの役割
1. **Python AST解析**
- Pythonコードをパース
- AST抽象構文木を生成
- Hakorune内で操作可能な形式に変換
2. **型推論・スコープ解決**
- Python動的型の静的解析
- スコープ情報の抽出
- 型アノテーション活用
3. **Hakorune MIRへの変換**
- Python AST → Hakorune AST
- Hakorune AST → MIR
- 最適化情報の付与
## 🏗️ アーキテクチャ
### PythonParserBox計画
```hakorune
box PythonParserBox {
// パース
parse(code: StringBox) -> ASTBox
// AST操作
visit_nodes(ast: ASTBox, visitor: FunctionBox)
get_node_type(node: ASTBox) -> StringBox
// 変換
to_hakorune_ast(ast: ASTBox) -> HakoruneASTBox
to_mir(ast: ASTBox) -> MIRBox
}
```
### ビルトインBox統合フロー
1. **パーサー初期化**
- CPython APIの初期化
- パーサーモジュールのロード
2. **パース実行**
- コード文字列を受け取り
- Python ASTを生成
- エラーハンドリング
3. **AST変換**
- Python AST → Hakorune AST
- 型情報の付与
- スコープ情報の追加
4. **MIR生成**
- Hakorune AST → MIR
- 最適化パスの適用
## 🔧 技術的課題
### 1. Python AST API統合
- CPython C API使用
- `ast` モジュールとの連携
- メモリ管理(参照カウント)
### 2. 型推論
- Python動的型の静的解析
- 型アノテーション活用
- 型推論アルゴリズム
### 3. スコープ解決
- PythonのスコープルールLEGB
- Hakoruneスコープへのマッピング
- クロージャ・ネストスコープ対応
### 4. 構文マッピング
- Python構文 → Hakorune構文
- イディオム変換
- サポートする機能範囲の決定
## 📊 実装ステータス
| コンポーネント | ステータス | 備考 |
|--------------|----------|------|
| パーサーBox設計 | ✅ 完了 | 設計書完成 |
| CPython API統合 | 📅 未実装 | - |
| AST変換 | 📅 未実装 | - |
| 型推論 | 📅 未実装 | - |
| MIR生成 | 📅 未実装 | - |
## ⚠️ リスク要因
1. **CPython依存**
- CPythonバージョン互換性
- プラットフォーム固有の問題
2. **型推論の精度**
- Python動的型の限界
- 型アノテーションの不完全性
3. **パフォーマンス**
- パース・変換のオーバーヘッド
- 大規模コードベースでの性能
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Planning](../planning/)
- [Core Implementation](../core-implementation/)

View File

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

View File

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

View File

@ -0,0 +1,65 @@
# Planning - Python-Hakorune統合計画
## 📋 概要
Python-Hakorune統合の計画・設計ドキュメント集です。
## 📁 ファイル一覧
### 🌟 最新計画2025-10-02追加
- **[milestones.md](milestones.md)** ⭐必読 - M0〜M6段階的実装計画ChatGPT Pro UltraThink
### 主要計画書
- **[integrated-plan.md](integrated-plan.md)** - ChatGPT5による統合計画旧Phase 10.5全体計画)
- **[python-parser-plan-summary.md](python-parser-plan-summary.md)** - Pythonパーサー統合計画サマリー
### 設計ドキュメント
- **[python-parser-box-design.md](python-parser-box-design.md)** - PythonパーサーBox設計
- **[expert-feedback.md](expert-feedback.md)** - GeminiとCodexによるAI専門家フィードバック
## 🎯 計画の核心
### Phase 10.5の目的(旧計画)
1. **ネイティブ基盤固め**
- VM/JIT分離VM=実行、JIT=コンパイル)
- AOT/EXEパイプライン確立
- クロスプラットフォーム対応
2. **Python統合**
- PyRuntimeBox: Python実行環境
- PyObjectBox: Pythonオブジェクト管理
- Hakorune ⇄ Python 双方向呼び出し
### 設計方針
#### Embedding vs Extending
- **Embedding**: HakoruneプロセスにCPythonを埋め込み
- **Extending**: Python拡張モジュールとして提供
#### ABI設計
- ハンドル: TLV tag=8type_id+instance_id
- Pythonオブジェクト: `PyObjectBox` として格納
- 変換: Bool/I64/String/Bytes/Handle の相互変換
- GIL: birth/invoke/decRef中はGIL確保
## 📊 実装フェーズ旧10.5計画)
| フェーズ | 期間 | 内容 |
|---------|------|------|
| 10.5a | 1-2日 | Python設計・ABI整合 |
| 10.5b | 2-4日 | ネイティブビルド基盤 |
| 10.5c | 3-5日 | PyRuntimeBox/PyObjectBox実装 |
| 10.5d | 3-5日 | JIT/AOT統合 |
| 10.5e | 1週間 | サンプル/テスト/ドキュメント |
## ⚠️ 現在のステータス
**保留中** - Phase 15Hakoruneセルフホスティング完了後に再開予定
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Parser Integration](../parser-integration/)
- [Core Implementation](../core-implementation/)
- [Design Documents](../design/)

View File

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

View File

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

View File

@ -0,0 +1,602 @@
# Python統合マイルストーンM0〜M6
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**ステータス**: 計画・Phase 15完了後に実装
---
## 📋 概要
Python-Hakorune統合を**段階的に**進めるためのマイルストーン定義です。
最小から始めて、機能を段階的に追加していきます。
---
## 🎯 M0: PyRuntimeBox の最小化
### 目的
`import("math")/call("sqrt")` が走る最小実装
### 成果物
- [ ] PyRuntimeBoxの基本実装
- [ ] PyFunctionBoxの基本実装
- [ ] math.sqrtの実行確認
### 実装内容
#### PyRuntimeBox最小版
```rust
pub struct PyRuntimeBox {
py: GILGuard,
modules: HashMap<String, Py<PyModule>>,
}
impl PyRuntimeBox {
pub fn init() -> Self {
pyo3::prepare_freethreaded_python();
let gil = Python::acquire_gil();
PyRuntimeBox {
py: gil,
modules: HashMap::new(),
}
}
pub fn import(&mut self, name: &str) -> PyModuleBox {
let py = self.py.python();
let module = PyModule::import(py, name).unwrap();
self.modules.insert(name.to_string(), module.into());
PyModuleBox::new(module)
}
}
```
#### テストケース
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let math = py.import("math");
let sqrt = math.get("sqrt");
let result = sqrt.exec([2.0]);
assert(result.to_float() == 1.4142135623730951);
py.fini();
}
}
```
### Capability/Contract
- Capability/Contractは**ログのみ**(観測)
- `HAKO_TRACE_EFFECTS=1` で呼び出しログ記録
### DoD完了定義
- ✅ math.sqrt(2.0)が正常実行
- ✅ 結果が正しい値を返す
- ✅ メモリリークなし
- ✅ スモークテスト追加
### 期間
**1週間**
---
## 🛡️ M1: Capability ゲート
### 目的
**ホワイトリスト**運用開始
### 成果物
- [ ] Capability管理機構
- [ ] hako.toml設定サポート
- [ ] 違反時のエラーハンドリング
### 実装内容
#### hako.toml設定
```toml
[box.PyRuntimeBox.capabilities]
allow = [
"py.import:math",
"py.import:json",
"py.time:monotonic"
]
deny = [
"py.subprocess",
"py.net"
]
enforce = true
```
#### Capability検証
```rust
impl PyRuntimeBox {
pub fn import(&mut self, name: &str) -> Result<PyModuleBox> {
// Capability確認
if !self.capabilities.allows_import(name) {
return Err(CapabilityError::ImportDenied(name.to_string()));
}
// 通常のimport処理
// ...
}
}
```
#### テストケース
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
// OK: 許可されたモジュール
let math = py.import("math");
// ERROR: 拒否されたモジュール
try {
let subprocess = py.import("subprocess");
} catch(e) {
assert(e.type == "CapabilityError");
}
py.fini();
}
}
```
### トグル
```bash
# Dev: 違反時fail-fast
HAKO_PLUGIN_CAPS_ENFORCE=1
# Prod: 違反時警告(継続)
HAKO_PLUGIN_CAPS_ENFORCE=0
```
### DoD完了定義
- ✅ allow/denyリスト動作確認
- ✅ 違反時の適切なエラー
- ✅ hako.toml読み込み動作
- ✅ トグル切り替え動作
### 期間
**1-2週間**
---
## ✅ M2: Contract 検証
### 目的
`pre/post` 条件検証の実装
### 成果物
- [ ] Contract検証機構
- [ ] pre条件検証引数チェック
- [ ] post条件検証返り値チェック
### 実装内容
#### Contract定義
```toml
[contracts.PyFunctionBox.exec]
pre = [
"args.len <= 8",
"bytes_total <= 1_000_000"
]
post = [
"result.size <= 1_000_000",
"no_exception",
"allow_none = true"
]
```
#### Contract検証Python側wrapper
```python
# hakorune_contract.py
def verify_contract(func, pre_conditions, post_conditions):
def wrapper(*args, **kwargs):
# Pre条件検証
if len(args) > 8:
raise ContractViolation("args.len > 8")
total_bytes = sum(sys.getsizeof(a) for a in args)
if total_bytes > 1_000_000:
raise ContractViolation("bytes_total > 1_000_000")
# 実行
result = func(*args, **kwargs)
# Post条件検証
if sys.getsizeof(result) > 1_000_000:
raise ContractViolation("result.size > 1_000_000")
return result
return wrapper
```
#### テストケース
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
// OK: Contract満たす
let math = py.import("math");
let sqrt = math.get("sqrt");
let r1 = sqrt.exec([2.0]);
// ERROR: 引数多すぎ
try {
let r2 = sqrt.exec([1,2,3,4,5,6,7,8,9]);
} catch(e) {
assert(e.type == "ContractViolation");
}
py.fini();
}
}
```
### DoD完了定義
- ✅ pre条件違反検出
- ✅ post条件違反検出
- ✅ ErrorBox化
- ✅ トグル切り替えstrict/warn
### 期間
**2週間**
---
## 🎲 M3: Deterministic
### 目的
`random/time/os.urandom` に shims を適用
### 成果物
- [ ] Deterministic shims実装
- [ ] random固定化
- [ ] time論理クロック化
- [ ] スモーク再現性確認
### 実装内容
#### Deterministic Random
```python
# hakorune_deterministic.py
class DeterministicRandom:
def __init__(self, seed=42):
self._rng = random.Random(seed)
def random(self):
return self._rng.random()
def randint(self, a, b):
return self._rng.randint(a, b)
# モンキーパッチ
if os.getenv('HAKO_DETERMINISTIC') == '1':
random.random = DeterministicRandom().random
```
#### Logical Clock
```python
class LogicalClock:
def __init__(self):
self._tick = 0
def monotonic(self):
self._tick += 1
return float(self._tick)
def time(self):
return self.monotonic()
# モンキーパッチ
if os.getenv('HAKO_DETERMINISTIC') == '1':
time.monotonic = LogicalClock().monotonic
```
#### テストケース
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
// Deterministic mode
let random = py.import("random");
// 同じseedなら同じ結果
let r1 = random.get("random").exec([]);
let r2 = random.get("random").exec([]);
assert(r1 == r2); // Deterministic!
py.fini();
}
}
```
### トグル
```bash
# Deterministic モード有効化
HAKO_DETERMINISTIC=1
HAKO_TRACE_EFFECTS=1 # 効果ログ収集
```
### DoD完了定義
- ✅ random固定化動作
- ✅ time論理クロック動作
- ✅ スモーク再現性100%
- ✅ トレースログ記録
### 期間
**1-2週間**
---
## 🏗️ M4: Type/Instance 反射
### 目的
クラス→`PyTypeBox`、インスタンス→`PyInstanceBox`
### 成果物
- [ ] PyTypeBox実装
- [ ] PyInstanceBox実装
- [ ] get/setField統一
- [ ] call_method統一
### 実装内容
#### PyTypeBox
```rust
pub struct PyTypeBox {
py_type: Py<PyType>,
}
impl PyTypeBox {
pub fn get_name(&self) -> String {
// クラス名取得
}
pub fn get_bases(&self) -> Vec<PyTypeBox> {
// 基底クラスリスト
}
pub fn new_instance(&self, args: Vec<Value>) -> PyInstanceBox {
// インスタンス化
}
}
```
#### PyInstanceBox
```rust
pub struct PyInstanceBox {
py_obj: Py<PyAny>,
}
impl PyInstanceBox {
pub fn get_field(&self, name: &str) -> Value {
// フィールド取得
}
pub fn set_field(&self, name: &str, value: Value) {
// フィールド設定
}
pub fn call_method(&self, name: &str, args: Vec<Value>) -> Value {
// メソッド呼び出し
}
}
```
#### テストケース
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
// クラス取得
let code = "
class Player:
def __init__(self, name):
self.name = name
self.health = 100
def heal(self, amount):
self.health += amount
";
py.exec(code);
let PlayerClass = py.get("Player"); // PyTypeBox
// インスタンス化
let player = PlayerClass.new_instance(["Alice"]); // PyInstanceBox
// フィールドアクセス
let name = player.get_field("name");
assert(name == "Alice");
// メソッド呼び出し
player.call_method("heal", [20]);
let health = player.get_field("health");
assert(health == 120);
py.fini();
}
}
```
### DoD完了定義
- ✅ PyTypeBox動作確認
- ✅ PyInstanceBox動作確認
- ✅ get/setField統一動作
- ✅ call_method統一動作
### 期間
**2-3週間**
---
## 🔄 M5: ABI 昇格
### 目的
C ABI→Hakorune ABIvtableへPoC
### 成果物
- [ ] Hakorune ABI実装
- [ ] vtable生成
- [ ] C ABI互換レイヤー
- [ ] 段階切り替え確認
### 実装内容
#### Hakorune ABIvtable
```rust
#[repr(C)]
pub struct HakoruneABI {
vtable: *const VTable,
data: *mut c_void,
}
#[repr(C)]
pub struct VTable {
init: extern "C" fn(*mut c_void),
fini: extern "C" fn(*mut c_void),
invoke: extern "C" fn(*mut c_void, method_id: u32, args: *const TLV) -> TLV,
}
```
#### トグル切り替え
```bash
# C ABI使用
HAKO_ABI_VTABLE=0
# Hakorune ABI使用
HAKO_ABI_VTABLE=1
HAKO_ABI_STRICT=1 # フォールバック禁止
```
#### テストケース
```hakorune
using "python"
box Main {
flow main() {
// どちらのABIでも同じコードが動く
let py = PyRuntimeBox();
let math = py.import("math");
let sqrt = math.get("sqrt");
let result = sqrt.exec([2.0]);
assert(result.to_float() == 1.4142135623730951);
py.fini();
}
}
```
### DoD完了定義
- ✅ Hakorune ABI動作確認
- ✅ C ABI互換性維持
- ✅ トグル切り替え動作
- ✅ パフォーマンス劣化なし
### 期間
**3-4週間**
---
## 📦 M6: AOT/EXE の包み込み10.5b連動)
### 目的
Python依存を**スタティック or 埋め込み**方針で詰め、`hako` EXE生成ラインに統合
### 成果物
- [ ] スタティックリンク対応
- [ ] 埋め込みPython対応
- [ ] EXE生成パイプライン統合
- [ ] クロスプラットフォーム確認
### 実装内容
#### スタティックリンク
```toml
# Cargo.toml
[dependencies]
pyo3 = { version = "0.20", features = ["auto-initialize", "extension-module"] }
[build-dependencies]
pyo3-build-config = "0.20"
```
#### 埋め込みPython
```rust
// Python標準ライブラリを埋め込み
#[cfg(feature = "embed-python")]
const PYTHON_STDLIB: &[u8] = include_bytes!("python3.11.zip");
```
#### EXE生成
```bash
# AOTコンパイル
hakorune --backend llvm --embed-python script.hkr -o app
# 生成されたEXE
./app # Python依存なしで実行可能
```
### プラットフォーム対応
| Platform | Python | 方式 |
|----------|--------|------|
| Linux | 3.8+ | 動的/静的両対応 |
| macOS | 3.8+ | 動的優先 |
| Windows | 3.8+ | 埋め込み推奨 |
### DoD完了定義
- ✅ Linux EXE生成
- ✅ macOS EXE生成
- ✅ Windows EXE生成
- ✅ Python依存最小化
- ✅ サイズ最適化
### 期間
**4-6週間**
---
## 📊 全体スケジュール
| マイルストーン | 期間 | 開始条件 |
|--------------|------|---------|
| M0: PyRuntimeBox最小化 | 1週間 | Phase 15完了 |
| M1: Capabilityゲート | 1-2週間 | M0完了 |
| M2: Contract検証 | 2週間 | M1完了 |
| M3: Deterministic | 1-2週間 | M2完了 |
| M4: Type/Instance反射 | 2-3週間 | M3完了 |
| M5: ABI昇格 | 3-4週間 | M4完了 |
| M6: AOT/EXE統合 | 4-6週間 | M5完了 |
**合計**: 約3-5ヶ月
---
## 🔗 関連ドキュメント
- [強化版アーキテクチャv2](../design/enhanced-architecture-v2.md) - 設計詳細
- [メタ設定例](../design/meta-config-examples.md) - hako.toml設定例
- [リスクと対策](../design/risks-and-mitigations.md) - 既知のリスク
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**ステータス**: 計画・Phase 15完了後に実装

View File

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

View File

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

View File

@ -0,0 +1,263 @@
# Testing - テスト計画
## 📋 概要
Python-Hakorune統合のテスト計画です。
## 🎯 テスト戦略
### テストレベル
1. **ユニットテスト**
- 個別コンポーネントのテスト
- 型変換のテスト
- エラーハンドリングのテスト
2. **統合テスト**
- Python-Hakorune連携テスト
- FFI境界のテスト
- GIL管理のテスト
3. **E2Eテスト**
- 実用的なユースケーステスト
- パフォーマンステスト
- 互換性テスト
## 🧪 テストケース
### 1. 基本機能テスト
#### Python実行
```hakorune
// test_python_eval.hkr
local py = new PyRuntimeBox()
local result = py.eval("2 + 3")
assert(result.to_int() == 5)
```
#### モジュールインポート
```hakorune
// test_python_import.hkr
local py = new PyRuntimeBox()
local math = py.import("math")
local pi = math.getattr("pi")
assert(pi.to_string() == "3.14159...")
```
#### オブジェクト操作
```hakorune
// test_python_object.hkr
local py = new PyRuntimeBox()
local obj = py.eval("{'x': 10, 'y': 20}")
local x = obj.getattr("x")
assert(x.to_int() == 10)
```
### 2. 型変換テスト
```hakorune
// test_type_conversion.hkr
local py = new PyRuntimeBox()
// Bool変換
local py_true = py.eval("True")
assert(py_true.to_bool() == true)
// Int変換
local py_int = py.eval("42")
assert(py_int.to_int() == 42)
// String変換
local py_str = py.eval("'hello'")
assert(py_str.to_string() == "hello")
// List変換
local py_list = py.eval("[1, 2, 3]")
// ... ArrayBox への変換テスト
```
### 3. エラーハンドリングテスト
```hakorune
// test_python_error.hkr
local py = new PyRuntimeBox()
// Python例外のキャッチ
try {
py.eval("1 / 0") // ZeroDivisionError
} catch(e) {
assert(e.contains("ZeroDivisionError"))
}
```
### 4. GIL管理テスト
```rust
// tests/gil_management.rs
#[test]
fn test_gil_acquisition() {
// GILの正しい獲得・解放
}
#[test]
fn test_nested_gil_calls() {
// ネストしたPython呼び出し
}
#[test]
fn test_concurrent_access() {
// 複数スレッドからのアクセス
}
```
### 5. メモリ管理テスト
```rust
// tests/memory_management.rs
#[test]
fn test_no_memory_leak() {
// メモリリークがないことを確認
for _ in 0..1000 {
let obj = create_python_object();
drop(obj);
}
// メモリ使用量が増加していないことを確認
}
#[test]
fn test_reference_counting() {
// Pythonオブジェクトの参照カウント
}
```
### 6. パフォーマンステスト
```rust
// benches/python_integration.rs
#[bench]
fn bench_python_call_overhead(b: &mut Bencher) {
// Python呼び出しのオーバーヘッド測定
}
#[bench]
fn bench_type_conversion(b: &mut Bencher) {
// 型変換のパフォーマンス測定
}
```
## 📊 テスト環境
### サポート対象
| 環境 | Python | Platform | 備考 |
|------|--------|----------|------|
| Linux | 3.8+ | x86_64 | 優先 |
| macOS | 3.8+ | x86_64, arm64 | 優先 |
| Windows | 3.8+ | x86_64 | 後段 |
### CI/CD統合
```yaml
# .github/workflows/python-integration.yml
name: Python Integration Tests
on: [push, pull_request]
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Run tests
run: cargo test --features python-integration
```
## 🔧 テストツール
### 1. ユニットテスト
- Cargo test framework
- `#[test]` アトリビュート
- アサーションマクロ
### 2. 統合テスト
- `tests/` ディレクトリ
- E2Eシナリオ
### 3. ベンチマーク
- Criterion.rs
- パフォーマンス回帰検出
### 4. メモリリークチェック
- Valgrind
- AddressSanitizer
- Python memory profiler
## 📋 テストチェックリスト
### 基本機能
- [ ] Python eval実行
- [ ] モジュールインポート
- [ ] オブジェクト属性アクセス
- [ ] メソッド呼び出し
- [ ] 例外ハンドリング
### 型変換
- [ ] bool変換
- [ ] int変換
- [ ] string変換
- [ ] list変換
- [ ] dict変換
- [ ] None処理
### FFI境界
- [ ] Handle管理
- [ ] TLV型変換
- [ ] エラー伝搬
### GIL管理
- [ ] GIL獲得・解放
- [ ] ネスト呼び出し
- [ ] マルチスレッド
### メモリ管理
- [ ] 参照カウント
- [ ] リーク検出
- [ ] 循環参照処理
### パフォーマンス
- [ ] 呼び出しオーバーヘッド
- [ ] 型変換コスト
- [ ] メモリ使用量
### プラットフォーム
- [ ] Linux (x86_64)
- [ ] macOS (x86_64)
- [ ] macOS (arm64)
- [ ] Windows (x86_64)
## ⚠️ 既知の課題
### 1. GILデッドロック
- **問題**: ネスト呼び出しでデッドロックの可能性
- **対策**: GIL獲得・解放のログ、タイムアウト検出
### 2. メモリリーク
- **問題**: 参照カウントの管理ミス
- **対策**: 定期的なリークチェック、自動テスト
### 3. プラットフォーム固有問題
- **問題**: Python配布形態の違い
- **対策**: CI環境での網羅的テスト
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Core Implementation](../core-implementation/)
- [Design Documents](../design/)

View File

@ -0,0 +1,201 @@
# Transpiler - Python→Hakorune トランスパイラー
## 📋 概要
PythonコードをHakoruneコードに変換するトランスパイラーの設計・仕様です。
## 📁 ファイル一覧
- **[python-to-hakorune-spec.md](python-to-hakorune-spec.md)** - Python→Hakorune変換仕様
## 🎯 目的
### トランスパイラーの役割
1. **構文変換**
- Python構文 → Hakorune構文
- イディオム変換
- スタイル変換
2. **型注釈の活用**
- Pythonの型ヒント → Hakorune型
- 型推論の補助
- 型安全性の向上
3. **最適化**
- Hakorune向け最適化
- 不要なコードの削除
- パフォーマンス改善
## 🔄 変換例
### 基本構文
```python
# Python
class Player:
def __init__(self, name: str):
self.name = name
self.health = 100
def heal(self, amount: int):
self.health += amount
```
```hakorune
// Hakorune
box Player {
name: StringBox
health: IntegerBox
birth(name: StringBox) {
me.name = name
me.health = integer.create(100)
}
heal(amount: IntegerBox) {
me.health = me.health.add(amount)
}
}
```
### 制御構文
```python
# Python
for i in range(10):
print(i)
```
```hakorune
// Hakorune
local i = integer.create(0)
loop(i.compare("<", 10)) {
console.log(i.to_string())
i = i.add(1)
}
```
### リスト操作
```python
# Python
items = [1, 2, 3]
items.append(4)
```
```hakorune
// Hakorune
local items = array.create()
items.push(integer.create(1))
items.push(integer.create(2))
items.push(integer.create(3))
items.push(integer.create(4))
```
## 🏗️ アーキテクチャ
### トランスパイラーのフェーズ
1. **パース**
- Pythonコードをパース
- AST生成
2. **型推論**
- 型ヒントの解析
- 型推論の実行
- 型情報の付与
3. **変換**
- Python AST → Hakorune AST
- イディオム変換
- 最適化
4. **コード生成**
- Hakorune ASTからコード生成
- フォーマット適用
- 出力
### 変換ルール
| Python構文 | Hakorune構文 | 備考 |
|-----------|-------------|------|
| `class` | `box` | クラス→Box |
| `__init__` | `birth` | コンストラクタ |
| `self` | `me` | 自己参照 |
| `for ... in range()` | `loop(...)` | ループ |
| `if ... elif ... else` | `if ... elif ... else` | 条件分岐 |
| `def func()` | `func()` | 関数定義 |
| `x = y` | `local x = y` | 変数宣言 |
| `list[index]` | `list.get(index)` | 配列アクセス |
| `dict[key]` | `dict.get(key)` | 辞書アクセス |
## 🔧 技術的課題
### 1. Python固有機能の扱い
#### サポートする機能
- 基本データ型int, str, list, dict
- クラス・メソッド
- 制御構文if, for, while
- 関数定義
#### サポートしない/制限する機能
- メタクラス
- デコレーター(一部のみ)
- ジェネレーター
- 内包表記(将来対応)
- async/awaitPhase 15以降
### 2. 型推論
- 型ヒントを優先使用
- 未注釈の場合は推論
- 推論不可能な場合は`AnyBox`
### 3. ネーミング変換
- snake_case → camelCaseオプション
- Python予約語の回避
- Hakorune予約語との衝突回避
## 📊 実装ステータス
| コンポーネント | ステータス | 備考 |
|--------------|----------|------|
| 変換仕様 | ✅ 完了 | 設計書完成 |
| パーサー統合 | 📅 未実装 | - |
| 型推論 | 📅 未実装 | - |
| AST変換 | 📅 未実装 | - |
| コード生成 | 📅 未実装 | - |
## 🎯 使用例
```bash
# コマンドライン(将来)
hakorune transpile script.py -o script.hkr
# プログラマティック(将来)
local transpiler = new PythonTranspiler()
local hakorune_code = transpiler.transpile(python_code)
```
## ⚠️ 制限事項
1. **完全互換性は保証しない**
- Pythonのすべての機能はサポートしない
- 一部機能は手動移植が必要
2. **実行時動的機能**
- `eval()`, `exec()` は変換不可
- 動的属性追加は制限
3. **標準ライブラリ**
- Python標準ライブラリは自動変換しない
- Hakorune equivalent への手動マッピング必要
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Parser Integration](../parser-integration/)
- [Core Implementation](../core-implementation/)

View File

@ -0,0 +1,225 @@
# Python → Nyashトランスパイラー機能
PythonParserBoxの応用による自動変換
## 🎯 概要
PythonParserBoxでPython AST → Nyash ASTの変換ができるなら、それを**Nyashソースコードとして出力**できる!
## 🚀 実現可能な機能
### 1. Python → Nyashファイル変換
```python
# input.py
def calculate(x, y):
result = x * 2 + y
return result
for i in range(10):
print(calculate(i, 5))
```
↓ 変換
```nyash
# output.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の価値をさらに高める**素晴らしい応用です!