fix(joinir): Phase 241-EX - Remove hardcoded 'sum' check from Pattern3
Remove legacy hardcoded 'sum' carrier validation that was blocking array_filter patterns with different accumulator names (e.g., 'out'). Before: Pattern3 required carrier named 'sum' to exist After: Pattern3 uses carrier_info generically (any carrier name works) Test results: - phase49_joinir_array_filter_smoke: PASS ✅ - phase49_joinir_array_filter_fallback: PASS ✅ - phase49_joinir_array_filter_ab_comparison: PASS ✅ - Full suite: 909/909 PASS, 0 FAIL Also: Archive old roadmap documentation (67k lines moved to docs/archive/) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
114
docs/archive/roadmap/phases/phase-10.7/PLAN.txt
Normal file
114
docs/archive/roadmap/phases/phase-10.7/PLAN.txt
Normal file
@ -0,0 +1,114 @@
|
||||
# Phase 10.7 – Python Native 再スタート計画(合意版 / txt)
|
||||
|
||||
目的: 現行の Plugin-First(PyRuntimeBox/PyObjectBox, Handle-First/TLV)を維持しつつ、トランスパイル路線(Python→Nyash)を“All or Nothing”原則で段階導入。10.6の足場(Thread-Safety/Scheduler)上で、AOT配布体験に直結する最短ラインを構築する。
|
||||
|
||||
====================
|
||||
A) 方針(判断)+ Property System革命統合(2025-09-18追加)
|
||||
====================
|
||||
- 二本立てを明確化:
|
||||
1) 実行系(現行): PyRuntimeBox 経由(VM=仕様、JIT=AOT生成のみ)。配布/運用の実用ライン。
|
||||
2) トランスパイル系(10.7): Python→Nyash→MIR→AOT。コンパイル成功/失敗の二択(フォールバック自動無し)。
|
||||
- 役割分担:未対応Pythonはユーザーが明示的に PyRuntimeBox を使う。トランスパイルはコンパイル成功率を段階的に拡大。
|
||||
- Plugin-Firstは維持(Parser/CompilerもプラグインBox化)。CLI/VMから統一呼び出し。
|
||||
|
||||
====================
|
||||
B) 最小成功像(Phase 1 / DoD)
|
||||
====================
|
||||
- サンプルpy(Phase 1 範囲内)を `pythonc`(仮)で Nyashスクリプトへ生成 → `--compile-native` で EXE 生成 → 実行。
|
||||
- 機能カバレッジ(Phase 1): def/if/for/while/return/bool/算術/比較/関数呼び出し/LEGB/デフォルト引数/for-else。
|
||||
- Differential(限定): Phase 1 サンプル群で CPython と一致(出力/戻り/例外の有無)。
|
||||
|
||||
====================
|
||||
C) サブフェーズとタスク
|
||||
====================
|
||||
C1) Parser Plugin(1週)
|
||||
- `plugins/nyash-python-parser-plugin`: Python→AST(pyo3)。
|
||||
- AST→CorePy IR(JSON): 構文の正規化(with→try/finally などはPhase 2)。
|
||||
- Telemetry: ノード統計/未対応ノードを列挙。
|
||||
|
||||
C2) Compiler Core(2週)
|
||||
- IR→Nyash AST 生成(Box化/クロージャ/LEGB/デフォ引数の再現)。
|
||||
- peephole最小(定数畳み込み)。
|
||||
- 生成NyashのPretty-print + 簡易ソースマップ。
|
||||
|
||||
C3) 配線/CLI/実行(3日)
|
||||
- `nyash --pyc file.py -o out.ny`(Nyash出力)/ `--pyc-native file.py -o app`(EXE直行)を追加(内部で既存 `--compile-native` を利用)。
|
||||
- 生成Nyashは既存コンパイラ経由で MIR→AOT を通す(Strict)。
|
||||
|
||||
C4) テスト/観測(1週並行)
|
||||
- `phase-10.7/testing-plan.md` の Phase 1 部分を小粒に実装。
|
||||
- VM vs AOT の「Result:」比較ラインを流用(既存スモークベース)。
|
||||
|
||||
====================
|
||||
D) インターフェース / 成果物
|
||||
====================
|
||||
- ParserBox: `parse(code: String) -> AstBox/CorePyBox`(内部JSON保持 or to_json)
|
||||
- CompilerBox: `compile(ir: CorePyBox) -> Result<NyashSourceBox, ErrorBox>`
|
||||
- CLI: `--pyc/--pyc-native`(初期は隠しフラグでも可)
|
||||
- Docs: README/implementation/testing-plan を PLAN に沿って更新。
|
||||
|
||||
====================
|
||||
E) リスク/緩和
|
||||
====================
|
||||
- 範囲膨張: Phase 1 の構文/意味論を固定し、Beyondは即Err。PyRuntimeBoxは明示利用。
|
||||
- 例外/with/comp/async: Phase 2/3の対象。IR設計時に将来ノードを予約(後方互換)。
|
||||
- Windows配布: 10.5で整えた PATH/PYTHONHOME 補助はPyRuntime向け。トランスパイル後はCPython依存なし。
|
||||
|
||||
====================
|
||||
F) タイムライン(目安)
|
||||
====================
|
||||
- C1: 1週 / C2: 2週 / C3: 3日 / C4: 1週(並行)。
|
||||
|
||||
====================
|
||||
G) 現行との接続
|
||||
====================
|
||||
- 10.6の足場(Thread-Safety/Scheduler)は維持。トランスパイル系は単一スレッド/VM基準で十分。
|
||||
- 10.5のAOT導線/nyrtシムはそのまま活用(生成Nyashに対して適用)。
|
||||
|
||||
====================
|
||||
H) Property System革命統合(2025-09-18 ブレイクスルー)
|
||||
====================
|
||||
|
||||
### 🌟 Python → Nyash Property マッピング革命
|
||||
|
||||
今日完成したProperty System(stored/computed/once/birth_once)により、Python transpilationが飛躍的に向上:
|
||||
|
||||
**Pythonプロパティの完全対応**:
|
||||
```python
|
||||
# Python側
|
||||
class PyClass:
|
||||
def __init__(self):
|
||||
self._value = 42
|
||||
|
||||
@property
|
||||
def computed_prop(self):
|
||||
return self._value * 2
|
||||
|
||||
@functools.cached_property
|
||||
def expensive_prop(self):
|
||||
return heavy_computation()
|
||||
```
|
||||
|
||||
**自動生成Nyash(革命的シンプル)**:
|
||||
```nyash
|
||||
box PyClass {
|
||||
_value: IntegerBox // stored: 通常フィールド
|
||||
computed_prop: IntegerBox { me._value * 2 } // computed: @property
|
||||
once expensive_prop: ResultBox { heavy_computation() } // once: @cached_property
|
||||
|
||||
birth() { me._value = 42 }
|
||||
}
|
||||
```
|
||||
|
||||
### 🎯 実装戦略更新
|
||||
- **C2フェーズ拡張**: PythonCompilerBoxにProperty System生成機能追加
|
||||
- **descriptor protocol**: Python property/method → Nyash property 4分類自動判定
|
||||
- **poison-on-throw**: cached_property例外時の安全性保証
|
||||
|
||||
### 📊 成功指標追加
|
||||
```
|
||||
Property coverage: @property(100%), @cached_property(100%), descriptors(80%)
|
||||
Performance boost: cached property 10-50x faster (LLVM最適化)
|
||||
Code generation: Python class → 50%短いNyashコード
|
||||
```
|
||||
|
||||
286
docs/archive/roadmap/phases/phase-10.7/README.md
Normal file
286
docs/archive/roadmap/phases/phase-10.7/README.md
Normal file
@ -0,0 +1,286 @@
|
||||
# Phase 10.7 - Python→Nyash革命(Phase 16マクロ統合版)
|
||||
|
||||
## 🚀 **Phase 16マクロ革命による劇的変化**
|
||||
|
||||
**Before Phase 16**: 手動transpiler(2-3ヶ月)
|
||||
**After Phase 16**: マクロボックス自動変換(1-2週間)⚡
|
||||
|
||||
### 🎯 新戦略:MacroBox-Driven Python Transpilation
|
||||
|
||||
```
|
||||
Python AST → MacroBox Pattern Match → Nyash AST (自動生成)
|
||||
```
|
||||
|
||||
**革命的変化**:
|
||||
- ❌ **旧**: 手動コード変換地獄(2000行実装)
|
||||
- ✅ **新**: マクロパターンで自動変換(200行実装)
|
||||
|
||||
## 🧠 **核心アイデア:Everything is Box + Macro = 言語統合**
|
||||
|
||||
### **マクロボックス群(新設計)**
|
||||
|
||||
```rust
|
||||
// src/macro/python_transpiler.rs(新規)
|
||||
@macro_box("python_dataclass")
|
||||
@macro_box("python_property")
|
||||
@macro_box("python_listcomp")
|
||||
@macro_box("python_contextmgr")
|
||||
@macro_box("python_decorator")
|
||||
```
|
||||
|
||||
### **実装例:Python @dataclass**
|
||||
|
||||
#### **Before(手動地獄)**:
|
||||
```python
|
||||
@dataclass
|
||||
class User:
|
||||
name: str
|
||||
age: int
|
||||
```
|
||||
→ 手動変換(数時間) → Nyashコード
|
||||
|
||||
#### **After(マクロ天国)**:
|
||||
```nyash
|
||||
// @python_dataclass マクロが自動処理!
|
||||
@python_dataclass
|
||||
box UserBox {
|
||||
name: StringBox
|
||||
age: IntegerBox
|
||||
}
|
||||
// ↓ 自動展開 ↓
|
||||
@derive(Equals, ToString, Clone)
|
||||
box UserBox {
|
||||
name: StringBox
|
||||
age: IntegerBox
|
||||
}
|
||||
```
|
||||
|
||||
### **実装例:Python List Comprehension**
|
||||
|
||||
#### **Python**:
|
||||
```python
|
||||
result = [x * 2 for x in numbers if x > 0]
|
||||
```
|
||||
|
||||
#### **マクロ展開Nyash**:
|
||||
```nyash
|
||||
// @python_listcomp マクロが自動生成
|
||||
local result = numbers
|
||||
.filter(|x| x > 0)
|
||||
.map(|x| x * 2)
|
||||
.toArray()
|
||||
```
|
||||
|
||||
## ⚠️ All or Nothing設計(フォールバックなし)
|
||||
|
||||
**コンパイルできる or できない の2択のみ**
|
||||
|
||||
```nyash
|
||||
compiler = new PythonCompilerBox()
|
||||
result = compiler.compile(ast)
|
||||
|
||||
if result.isOk() {
|
||||
// 100%コンパイル成功 → ネイティブ実行
|
||||
print("Success! Native execution ready.")
|
||||
} else {
|
||||
// 未対応機能あり → 完全拒否
|
||||
print("Cannot compile: " + result.getError())
|
||||
print("Use PyRuntimeBox instead.")
|
||||
}
|
||||
```
|
||||
|
||||
理由:開発時と本番時で挙動が変わるのは最悪の設計
|
||||
|
||||
## 📋 **新実装フェーズ(Phase 16統合版)**
|
||||
|
||||
### **Phase 10.7-A: MacroBox基盤(3日)**
|
||||
```rust
|
||||
// src/macro/python_transpiler.rs 作成
|
||||
pub fn register_python_macros() {
|
||||
register_macro_box("python_dataclass", PythonDataclassTranspiler);
|
||||
register_macro_box("python_property", PythonPropertyTranspiler);
|
||||
register_macro_box("python_listcomp", PythonListCompTranspiler);
|
||||
}
|
||||
```
|
||||
|
||||
### **Phase 10.7-B: コア変換パターン(1週間)**
|
||||
**必須マクロ(Phase 1)**:
|
||||
- `@python_dataclass` → `@derive(Equals,ToString)`
|
||||
- `@python_property` → `computed property`
|
||||
- `@python_listcomp` → `.filter().map()`
|
||||
- `@python_function` → Nyash関数+LEGB
|
||||
|
||||
### **Phase 10.7-C: テスト・検証(3日)**
|
||||
- マクロ展開結果の差分テスト
|
||||
- `nyash --expand` でPython→Nyash変換可視化
|
||||
- エラー時の明確な診断メッセージ
|
||||
|
||||
### **Phase 10.7-D: 高度パターン(1週間)**
|
||||
**拡張マクロ(Phase 2)**:
|
||||
- `@python_contextmgr` → try/finally自動展開
|
||||
- `@python_decorator` → マクロ適用チェーン
|
||||
- `@python_async` → async/await変換
|
||||
|
||||
## 🧪 py_runtime設計
|
||||
|
||||
```nyash
|
||||
// Pythonセマンティクスを忠実に再現
|
||||
box PyRuntime {
|
||||
py_truthy(x) {
|
||||
// Python的真偽値判定
|
||||
if x == null or x == false { return false }
|
||||
if x.hasMethod("__bool__") { return x.__bool__() }
|
||||
if x.hasMethod("__len__") { return x.__len__() != 0 }
|
||||
return true
|
||||
}
|
||||
|
||||
py_getattr(obj, name) {
|
||||
// ディスクリプタプロトコル、MRO探索
|
||||
}
|
||||
|
||||
py_call(f, args, kwargs) {
|
||||
// デフォルト引数、*args/**kwargs処理
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 **新成功指標(マクロ革命版)**
|
||||
|
||||
### **Phase 1完了時(2週間後)**
|
||||
```
|
||||
実装コスト: 2000行 → 200行 (90%削減)
|
||||
開発時間: 2-3ヶ月 → 1-2週間 (85%短縮)
|
||||
マクロパターン: 5個実装完了
|
||||
Python→Nyash変換率: 80%+ (基本構文)
|
||||
```
|
||||
|
||||
### **最終目標(1ヶ月後)**
|
||||
```
|
||||
マクロパターン: 15個+ (全主要Python構文)
|
||||
変換精度: 95%+ (property/dataclass/listcomp)
|
||||
パフォーマンス: 10-50x faster (LLVM最適化)
|
||||
統合性: Property System完全対応
|
||||
```
|
||||
|
||||
## 🚀 **クイックスタート(マクロ版)**
|
||||
|
||||
```bash
|
||||
# Phase 16マクロ基盤活用
|
||||
cd src/macro/
|
||||
touch python_transpiler.rs
|
||||
|
||||
# 最小マクロボックス実装
|
||||
[dependencies]
|
||||
nyash-rust = { path = "../../" }
|
||||
serde_json = "1.0"
|
||||
|
||||
# テスト実行(マクロ展開確認)
|
||||
NYASH_MACRO_ENABLE=1 ./target/release/nyash --expand python_test.ny
|
||||
```
|
||||
|
||||
## 🎯 **Property System統合戦略**
|
||||
|
||||
### **Python @property → Nyash computed**
|
||||
```python
|
||||
class Circle:
|
||||
@property
|
||||
def area(self):
|
||||
return 3.14 * self.radius ** 2
|
||||
```
|
||||
|
||||
**マクロ自動変換**:
|
||||
```nyash
|
||||
@python_property // マクロが自動処理
|
||||
box CircleBox {
|
||||
radius: FloatBox
|
||||
|
||||
// computed property自動生成
|
||||
area: FloatBox { 3.14 * me.radius * me.radius }
|
||||
}
|
||||
```
|
||||
|
||||
### **Python @cached_property → Nyash once**
|
||||
```python
|
||||
@cached_property
|
||||
def expensive_calculation(self):
|
||||
return heavy_computation()
|
||||
```
|
||||
|
||||
**マクロ自動変換**:
|
||||
```nyash
|
||||
// once property自動生成
|
||||
once expensive_calculation: ResultBox {
|
||||
heavyComputation()
|
||||
}
|
||||
```
|
||||
|
||||
## 💡 **創造的可能性(マクロ革命版)**
|
||||
|
||||
### **🎪 ハイブリッドプログラミング**
|
||||
```python
|
||||
@nyash.vectorize # PythonデコレータがNyashマクロ展開!
|
||||
@nyash.config_schema # 環境変数自動読み込み
|
||||
@nyash.api_client("https://api.example.com/swagger.json")
|
||||
class DataProcessor:
|
||||
def process(self, data):
|
||||
return self.api.process_batch(data)
|
||||
```
|
||||
|
||||
**マクロ展開後**:
|
||||
```nyash
|
||||
@vectorize @config_schema @api_client("...")
|
||||
box DataProcessorBox {
|
||||
// 全てマクロで自動生成!
|
||||
api_client: HttpBox { /* 自動生成 */ }
|
||||
config: ConfigBox { /* 環境変数から自動読み込み */ }
|
||||
|
||||
method process(data: ArrayBox) -> ResultBox {
|
||||
me.api.processBatch(data) // SIMD最適化済み
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **🌍 言語統合プラットフォーム**
|
||||
**Phase 16マクロシステムにより実現**:
|
||||
- 🐍 **Python** → 🦀 **Nyash**: 自動変換
|
||||
- ☕ **Java** → 🦀 **Nyash**: `@java_class`マクロで
|
||||
- 🟦 **TypeScript** → 🦀 **Nyash**: `@ts_interface`マクロで
|
||||
- 🔷 **C#** → 🦀 **Nyash**: `@csharp_property`マクロで
|
||||
|
||||
### **🎓 教育革命**
|
||||
**リアルタイム変換Playground**:
|
||||
```
|
||||
┌─ Python Input ─────┐ ┌─ Nyash Output ────┐
|
||||
│ @dataclass │ → │ @derive(...) │
|
||||
│ class User: │ │ box UserBox { │
|
||||
│ name: str │ │ name: StringBox │
|
||||
│ age: int │ │ age: IntegerBox │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
```
|
||||
|
||||
**学習効果**:
|
||||
- プログラミング学習時間: **10分の1**
|
||||
- 言語間移植理解: **瞬時**
|
||||
- 最適化理解: **可視化**
|
||||
|
||||
## 📚 **参考資料(更新版)**
|
||||
|
||||
### **Phase 16統合ドキュメント**
|
||||
- **[Phase 16 Macro Revolution](../phase-16-macro-revolution/README.md)** - マクロシステム全体
|
||||
- **[docs/guides/macro-system.md](../../../../guides/macro-system.md)** - マクロ使用方法
|
||||
- **[Macro Examples](../phase-16-macro-revolution/macro-examples.md)** - 実装例集
|
||||
|
||||
### **従来資料**
|
||||
- **archive/gemini-analysis-transpile-beauty.md** - 創造性分析
|
||||
- **archive/codex-analysis-technical-implementation.md** - 技術分析
|
||||
|
||||
---
|
||||
|
||||
## 🏆 **結論:Phase 10.7の革命的変化**
|
||||
|
||||
**Before Phase 16**: Python実装 = 地獄の手動transpiler
|
||||
**After Phase 16**: Python実装 = 楽しいマクロパターン作成
|
||||
|
||||
**Phase 16マクロシステムにより、Phase 10.7は「Python実装」から「言語統合革命」へと進化した!**
|
||||
|
||||
**実装コスト90%削減、開発時間85%短縮で、10倍の表現力を実現する新時代の到来!** 🚀✨
|
||||
@ -0,0 +1,252 @@
|
||||
# Codex (GPT-5)の技術分析:Python→Nyashトランスパイルの実装詳細
|
||||
|
||||
2025-08-30 - OpenAI Codex v0.25.0による技術的深掘り
|
||||
|
||||
## Big Picture
|
||||
|
||||
- **Purpose**: Generate Nyash source from Python to leverage Nyash's optimizer, keep debugging simple, and "think in Nyash" early without locking into MIR details.
|
||||
- **Core idea**: Normalize Python to a small CorePy IR, then lower to idiomatic Nyash with a thin "Py runtime shim" in Nyash that preserves Python's dynamic semantics where required.
|
||||
|
||||
## AST Conversion
|
||||
|
||||
### Two-stage lowering
|
||||
```
|
||||
Python AST → CorePy IR → Nyash AST
|
||||
```
|
||||
|
||||
CorePy should be expression-friendly, desugared, and semantics-explicit (e.g., with→try/finally, for→iterator loop, boolean ops→if/else).
|
||||
|
||||
### Visitor + environment
|
||||
Implement a node visitor that carries scope info (locals/free/globals), evaluation order, and source spans. Use Python's `symtable` to seed symbol kinds; validate against your own pass.
|
||||
|
||||
### Semantic shims
|
||||
Lower Python ops to Nyash intrinsics that preserve semantics:
|
||||
- `py_truthy(x)`
|
||||
- `py_getattr(o,"a")`
|
||||
- `py_setattr(o,"a",v)`
|
||||
- `py_binop("add", a, b)`
|
||||
- `py_cmp("lt", a, b)`
|
||||
- `py_iter(x)`
|
||||
- `py_call(f, args, kwargs)`
|
||||
- `py_slice(x, i, j, k)`
|
||||
|
||||
### Boxes and cells
|
||||
Model Python variables and closures with Box/Cell objects. Rule of thumb: locals are unboxed unless captured or aliased; promote to Box when needed. Everything-is-Box in Nyash aligns well with Python's mutability/aliasing.
|
||||
|
||||
### Control flow
|
||||
Normalize to a small set: `if`, `block`, `loop`, `break`, `continue`, `try/catch/finally`, `throw`. Lower `and`/`or` with short-circuit temp; turn comprehensions into explicit loops with dedicated inner scope.
|
||||
|
||||
## Transpile Quality
|
||||
|
||||
### Readability vs optimize
|
||||
Offer modes. Default emits idiomatic Nyash constructs and meaningful identifiers, comments with source spans, and simple temporaries. "Optimize" mode switches to `py_*` intrinsics fusion and fewer temps.
|
||||
|
||||
### Idiomatic Nyash
|
||||
Prefer Nyash control constructs over procedural labels. Use native blocks for `if/else`, `match` if Nyash has it; only fall back to runtime calls where semantics demand.
|
||||
|
||||
### Stable pretty-printer
|
||||
Round-trip friendly formatter with consistent whitespace, trailing comma rules, and deterministic temp naming (`_t1`, `_t2…`). Keep def/class emitted in declaration-order.
|
||||
|
||||
### Debug info
|
||||
Attach `span(file, line, col)` to every IR node, carry through to Nyash AST, then emit a sidecar source map. Optionally embed lightweight `#line` directives or inline comments per statement in debug builds.
|
||||
|
||||
## Python Feature Mapping
|
||||
|
||||
### Default args
|
||||
Evaluate at def-time; store tuple/dict on the function object. At call-time, fill missing with stored defaults. Beware mutable defaults: do not clone; reuse exact object.
|
||||
|
||||
### LEGB scoping
|
||||
Build symbol table with flags for `global`/`nonlocal`. Emit closure "cells" (Boxes) for free vars; functions capture a vector of cells. Globals map to the module dict; builtins fallback when name miss in global.
|
||||
|
||||
### for/else, while/else
|
||||
Introduce `broken=false`. On `break`, set and exit; after loop, `if !broken { else_block }`.
|
||||
|
||||
### Comprehensions
|
||||
Create inner function/scope per comprehension (Python 3 semantics). Assignment targets exist only in that scope. Preserve evaluation order and late binding behavior.
|
||||
|
||||
### With statement
|
||||
Desugar to try/finally per Python spec: evaluate context expr, call `__enter__`, bind target, run body, always call `__exit__`, and suppress exception only if `__exit__` returns truthy.
|
||||
|
||||
### Decorators
|
||||
Evaluate bottom-up at def-time: `fn = decoN(...(deco1(fn)))` then assign back. Keep evaluation order of decorator expressions.
|
||||
|
||||
### Generators
|
||||
Lower to a state machine object implementing Nyash's iterator protocol, with saved instruction pointer, stack slots, and exception injection (`throw`, `close`). Support `yield from` by delegation trampoline.
|
||||
|
||||
### Pattern matching (PEP 634)
|
||||
If supported by Nyash, map directly; else lower to nested guards and extractor calls in a `py_match` helper library.
|
||||
|
||||
### Data model
|
||||
Attribute access honors descriptors; method binding creates bound objects; arithmetic and comparisons dispatch to `__op__`/`__rop__` and rich comparisons; truthiness via `__bool__`/`__len__`.
|
||||
|
||||
## Performance Opportunities
|
||||
|
||||
### At transpile-time
|
||||
- Constant fold literals, f-strings (format plan precomputation), simple arithmetic if types are literal.
|
||||
- Invariant hoisting for loop-invariant comprehensions and attribute chains when no side-effects (guarded).
|
||||
- Direct calls to Nyash intrinsics for selected builtins (`len`, `isinstance`, `range`) only if not shadowed (prove via symbol table).
|
||||
- Peephole: collapse nested `py_truthy(py_truthy(x))`, merge adjacent `if` with literal conditions, drop dead temporaries.
|
||||
|
||||
### Defer to Nyash compiler
|
||||
- Inlining across Nyash functions, register allocation, loop unrolling, vectorization, constant propagation at MIR level.
|
||||
- DCE/CSE once `py_*` helpers are inlined or annotated as pure/idempotent where legal.
|
||||
|
||||
### Types as hints
|
||||
- Consume Python annotations/`typing` to emit specialized fast paths: e.g., `int` → direct Nyash integer ops, else fallback to `py_binop`. Plumb types through IR as optional metadata for MIR to exploit.
|
||||
- Profile-guided guards: optional mode emits guards around hot calls to enable Nyash JIT/AOT to speculate and deopt to generic `py_*`.
|
||||
|
||||
## Error Handling & Debug
|
||||
|
||||
### Source maps
|
||||
Emit a compact mapping (e.g., VLQ JSON) from Nyash line/col → Python original; include segment mappings per expression for precise stepping.
|
||||
|
||||
### Exception rewriting
|
||||
Wrap Nyash runtime entrypoints to translate stack frames via the source map, hiding frames from helpers (`py_*`) unless verbose mode is on.
|
||||
|
||||
### Stage diagnostics
|
||||
- CorePy dump: toggle to print normalized IR with spans.
|
||||
- Nyash preview: post-format preview with original Python line hints.
|
||||
- Trace toggles: selective tracing of `py_call`, `py_getattr`, iteration; throttle to avoid noise.
|
||||
|
||||
### Friendly messages
|
||||
On unsupported nodes or ambiguous semantics, show minimal repro, Python snippet, and link to a doc page. Include symbol table excerpt when scoping fails.
|
||||
|
||||
## Architecture & DX
|
||||
|
||||
### Pass pipeline
|
||||
```
|
||||
Parse Python AST → Symbol table → Normalize to CorePy →
|
||||
Scope/closure analysis → Type/meta attach → Lower to Nyash AST →
|
||||
Optimize (peephole/simplify) → Pretty-print + source map
|
||||
```
|
||||
|
||||
### Runtime shim (`nyash/lib/py_runtime.ny`)
|
||||
Core APIs:
|
||||
- `py_call(f, pos, kw, star, dstar)`
|
||||
- `py_truthy(x)`
|
||||
- `py_getattr/py_setattr`
|
||||
- `py_binop(op, a, b)`
|
||||
- `py_cmp(op,a,b)`
|
||||
- `py_iter(x)`
|
||||
- `py_next(it)`
|
||||
- `py_slice(x,i,j,k)`
|
||||
- `py_with(mgr, body_fn)`
|
||||
- `py_raise`
|
||||
- `py_is`
|
||||
- `py_eq`
|
||||
|
||||
Data model support: descriptor get/set, method binding, MRO lookup, exception hierarchy, StopIteration protocol.
|
||||
|
||||
Perf annotations: mark pure or inline candidates; keep stable ABI.
|
||||
|
||||
### CLI/flags
|
||||
Modes:
|
||||
- `--readable`
|
||||
- `--optimized`
|
||||
- `--debug`
|
||||
- `--emit-sourcemap`
|
||||
- `--dump-corepy`
|
||||
- `--strict-builtins`
|
||||
|
||||
Caching: hash of Python AST + flags to cache Nyash output, source map, and diagnostics.
|
||||
|
||||
Watch/incremental: re-transpile changed modules, preserve source map continuity.
|
||||
|
||||
### Tests
|
||||
- Golden tests: Python snippet → Nyash output diff, with normalization.
|
||||
- Differential: run under CPython vs Nyash runtime for functional parity on a corpus (unit/property tests).
|
||||
- Conformance: edge cases (scoping, descriptors, generators, exceptions) and evaluation order tests.
|
||||
|
||||
## Pitfalls & Remedies
|
||||
|
||||
### Evaluation order
|
||||
Python's left-to-right arg eval, starred/unpacking, and kw conflict checks. Enforce by sequencing temps precisely before `py_call`.
|
||||
|
||||
### Shadowing builtins/globals
|
||||
Only specialize when proven not shadowed in any reachable scope. Provide `--strict-builtins` to disable specialization unless guaranteed.
|
||||
|
||||
### Identity vs equality
|
||||
`is` is reference identity; avoid folding or substituting.
|
||||
|
||||
### Integer semantics
|
||||
Python's bigints; ensure Nyash numeric layer matches or route to bigints in `py_*`.
|
||||
|
||||
## Future Extensibility
|
||||
|
||||
### Plugins
|
||||
Pass manager with hooks (`before_lower`, `after_lower`, `on_node_<Type>`). Allow project-local rewrites and macros, with access to symbol/type info.
|
||||
|
||||
### Custom rules
|
||||
DSL for pattern→rewrite with predicates (types, purity), e.g., rewrite `dataclass` patterns to Nyash records.
|
||||
|
||||
### Multi-language
|
||||
Keeping the Nyash script as a stable contract invites other frontends (e.g., a subset of JS/TypeScript or Lua) to target Nyash; keep `py_*` separate from language-agnostic intrinsics to avoid contamination.
|
||||
|
||||
### Gradual migration
|
||||
As Nyash grows Pythonic libraries, progressively replace `py_*` with native Nyash idioms; keep a compatibility layer for mixed projects.
|
||||
|
||||
## Concrete Translation Sketches
|
||||
|
||||
### Attribute
|
||||
```python
|
||||
a.b
|
||||
```
|
||||
→
|
||||
```nyash
|
||||
py_getattr(a, "b")
|
||||
```
|
||||
|
||||
### Call
|
||||
```python
|
||||
f(x, y=1, *as, **kw)
|
||||
```
|
||||
→
|
||||
```nyash
|
||||
py_call(f, [x], {"y":1}, as, kw)
|
||||
```
|
||||
|
||||
### If
|
||||
```python
|
||||
if a and b:
|
||||
```
|
||||
→
|
||||
```nyash
|
||||
let _t=py_truthy(a); if _t { if py_truthy(b) { ... } }
|
||||
```
|
||||
|
||||
### For/else
|
||||
```python
|
||||
for x in xs:
|
||||
if cond:
|
||||
break
|
||||
else:
|
||||
else_block
|
||||
```
|
||||
→
|
||||
```nyash
|
||||
let _it = py_iter(xs);
|
||||
let _broken=false;
|
||||
loop {
|
||||
let _n = py_next(_it) catch StopIteration { break };
|
||||
x = _n;
|
||||
...
|
||||
if cond { _broken=true; break }
|
||||
}
|
||||
if !_broken { else_block }
|
||||
```
|
||||
|
||||
### With
|
||||
Evaluate mgr, call `__enter__`, bind val; try body; on exception, call `__exit__(type,e,tb)` and suppress if returns true; finally call `__exit__(None,None,None)` when no exception.
|
||||
|
||||
### Decorators
|
||||
```nyash
|
||||
let f = <def>;
|
||||
f = decoN(...(deco1(f)));
|
||||
name = f
|
||||
```
|
||||
|
||||
## Why Nyash Script First
|
||||
|
||||
- **Debuggability**: Human-readable Nyash is easier to inspect, diff, and map errors to; source maps stay small and precise.
|
||||
- **Optimization leverage**: Nyash compiler/MIR can keep improving independently; your Python frontend benefits automatically.
|
||||
- **Ecosystem fit**: Generates idiomatic Nyash that other tools (formatters, linters, analyzers) can understand; fosters a consistent DX.
|
||||
@ -0,0 +1,72 @@
|
||||
# Gemini先生の分析:Python→Nyashトランスパイルの「面白さ」と「可能性」
|
||||
|
||||
2025-08-30 - Geminiによる深い洞察
|
||||
|
||||
## 1. 創造的な活用方法 - 「ハイブリッドプログラミング」の新しい形
|
||||
|
||||
このアプローチの最大の面白さは、**PythonとNyashの境界を曖昧にし、両者の長所を自在に組み合わせられる「ハイブリッドプログラミング」環境**が生まれる点にあります。
|
||||
|
||||
### パフォーマンスの「目利き」チューニング
|
||||
開発者はまず、書き慣れたPythonで迅速にプロトタイプを構築します。パフォーマンスが問題になる箇所だけ、トランスパイルされたNyashコードを覗き見ます。「なるほど、このリスト内包表記はこういうループになるのか。ここをNyashの並列処理機能に書き換えれば速くなりそうだ」といった具合に、**生成されたコードを"最適化のためのヒント"として活用**し、手動で高性能なNyashコードに置き換えることができます。これは、Pythonの手軽さとネイティブの速度を、開発者が主体的にコントロールできる、非常に楽しいプロセスです。
|
||||
|
||||
### Nyashを操るためのDSL(ドメイン固有言語)としてPythonを使う
|
||||
Pythonの強力なメタプログラミング能力(デコレータ、AST操作など)を使い、「Nyashコードジェネレータ」をPythonで記述できます。例えば、特定の計算パターンを最適化するNyashコードを生成するPythonデコレータを作るのはどうでしょう。
|
||||
|
||||
```python
|
||||
# このデコレータがNyashのSIMD命令を使うコードを生成する
|
||||
@nyash.vectorize
|
||||
def python_function(a, b):
|
||||
return a + b
|
||||
```
|
||||
|
||||
このように、Pythonの簡潔な記述から、裏では非常に複雑で高性能なNyashコードが生成される。これはまさに、**Pythonを「Nyashのための高級マクロ言語」として使う**創造的なハックです。
|
||||
|
||||
### 動的なコード生成と実行
|
||||
実行時にPythonコード文字列を生成し、それをNyashにトランスパイルして即座にネイティブ実行する、といった芸当も可能です。これにより、設定ファイルやユーザー入力に基づいて動的に高性能な処理ロジックを組み立てるような、柔軟なアプリケーションが実現できます。
|
||||
|
||||
## 2. 言語進化への影響 - 共進化するエコシステム
|
||||
|
||||
この方式は、一方的な変換ではなく、両言語が互いに影響を与え合う「共進化」の触媒となります。
|
||||
|
||||
### Nyashへのフィードバック
|
||||
Pythonの標準的なイディオム(例: `with`文、ジェネレータ、リスト内包表記)をNyashに変換する際、「どうもしっくりくる表現がNyashにない」「もっとエレガントに書ける構文が欲しい」という課題が必ず見つかります。これは、**Pythonという巨大なユースケースからNyashが学ぶ絶好の機会**です。このフィードバックループが、Nyashをより表現力豊かで実用的な言語へと進化させます。
|
||||
|
||||
### Pythonコミュニティへの影響
|
||||
「この書き方をすれば、Nyashで速くなる」という知見が広まると、Pythonプログラマーの中に**「Nyash-aware」なコーディングスタイル**が生まれる可能性があります。これは、Pythonのサブセットや方言のようなもので、パフォーマンスを意識した新しいPythonの書き方として定着するかもしれません。Pythonのコードが、静的解析や型ヒントだけでなく、「ネイティブ変換効率」という新しい評価軸を持つようになります。
|
||||
|
||||
## 3. 実装の優雅さ - 「AST to AST」という美しい設計
|
||||
|
||||
トランスパイラの内部実装そのものにも、開発者を楽しませるエレガントなパターンが存在します。
|
||||
|
||||
### AST(抽象構文木)レベルでの変換
|
||||
最もクリーンな実装は、Pythonの`ast`モジュールでソースコードをASTに変換し、そのASTの各ノードを再帰的に辿りながら、対応するNyashのASTノードを構築していく方法です。これは、文字列置換のような場当たり的な方法とは異なり、非常に構造的で堅牢です。Pythonの`for`ループのASTノードが、Nyashの`for`ループのASTノードに1対1で対応付けられる様は、パズルを解くような知的な面白さがあります。
|
||||
|
||||
### 変換パターンの分離と合成
|
||||
Pythonの各構文要素(関数定義、if文、クラスなど)に対応する変換ロジックを、それぞれ独立した小さな関数やクラスとして実装します。これにより、トランスパイラ全体の見通しが良くなり、テストも容易になります。新しい構文への対応も、新しい変換パターンを追加するだけで済みます。このモジュール性は、大規模なソフトウェアを設計する上での美しさそのものです。
|
||||
|
||||
## 4. 教育的インパクト - 生きた「コンパイラ入門」
|
||||
|
||||
このツールは、プログラミング学習者にとって最高の教材となり得ます。
|
||||
|
||||
### 概念の可視化
|
||||
「高級言語の裏側では、実際にはもっと低レベルな処理が行われている」というコンピュータサイエンスの基本概念を、これ以上なく明確に示せます。Pythonのたった1行が、Nyashの数行のコードに展開されるのを見ることで、抽象化のコストとメリットを直感的に理解できます。
|
||||
|
||||
### 言語間の「ロゼッタストーン」
|
||||
PythonとNyashという2つの言語の思考様式の違いを学ぶための、動的な「ロゼッタストーン」になります。「Pythonの辞書は、Nyashではハッシュマップとしてこう表現されるのか」「Pythonの動的型付けは、Nyashの型推論によってこう解決されるのか」といった発見は、学習者にとって大きな喜びとなるでしょう。
|
||||
|
||||
### インタラクティブな学習環境
|
||||
Web上で、左にPython、右にリアルタイムで変換されたNyashコードが表示されるような「Nyash Playground」を作れば、非常に人気の出る学習ツールになるはずです。
|
||||
|
||||
## 5. 長期的な展望 - 5年後、10年後の可能性
|
||||
|
||||
このアプローチは、短期的な実装の容易さだけでなく、長期的に大きな可能性を秘めています。
|
||||
|
||||
### 5年後: Pythonエコシステムのシームレスな高速化
|
||||
トランスパイラの完成度が高まり、主要なPythonライブラリ(NumPy, Pandasの一部など)をNyashに変換できるようになっているかもしれません。`pip install`するだけで、内部的にNyashへ変換・コンパイルされ、ユーザーは意識することなくPythonコードのままネイティブの速度を手に入れる、という未来が考えられます。Pythonの型ヒントが、単なる静的解析のためだけでなく、**Nyashへの最適化コンパイルのための重要なヒント**として活用されているでしょう。
|
||||
|
||||
### 10年後: 「ハイブリッド言語」としての地位確立
|
||||
PythonとNyashの関係は、TypeScriptとJavaScriptの関係に似たものになっているかもしれません。開発者は、プロジェクトの大部分をPythonで書き、パフォーマンスクリティカルな部分はNyashで書く、あるいはPythonで書いたものをトランスパイルして微調整する、という開発スタイルが当たり前になっている可能性があります。Nyashは「Pythonをネイティブ速度で動かすための最高のパートナー言語」としての地位を確立し、両言語は互いに補完し合う強力なエコシステムを形成しているでしょう。最終的には、**Pythonの書きやすさと、ネイティブコードの実行性能を両立させた、究極のスクリプト環境**が実現しているかもしれません。
|
||||
|
||||
## まとめ
|
||||
|
||||
B案(トランスパイル方式)は、単に技術的に堅実なだけでなく、開発者の知的好奇心を刺激し、言語コミュニティ全体を巻き込んで成長していく「面白さ」と「可能性」に満ちた選択です。生成されたNyashコードが「ブラックボックス」ではなく「ホワイトボックス」であることが、デバッグ、最適化、学習、そして未来の創造的なハックへと繋がる鍵となります。この選択は、Nyashプロジェクトの成功に大きく貢献する戦略的な一手だと確信します。
|
||||
@ -0,0 +1,274 @@
|
||||
# PythonCompilerBox Property System活用実装
|
||||
|
||||
## 🎯 概要
|
||||
|
||||
Property System革命(stored/computed/once/birth_once)をPythonCompilerBoxで活用し、Python→Nyash transpilationを実現する技術実装設計。
|
||||
|
||||
## 🏗️ アーキテクチャ設計
|
||||
|
||||
### コアコンポーネント
|
||||
```nyash
|
||||
box PythonCompilerBox {
|
||||
// Property System を活用したコンパイラ実装
|
||||
classifier: PropertyClassifierBox
|
||||
generator: NyashCodeGeneratorBox
|
||||
validator: SemanticValidatorBox
|
||||
|
||||
// コンパイル結果のキャッシュ(once使用)
|
||||
once compilation_cache: MapBox { new MapBox() }
|
||||
|
||||
// 動的に計算される統計情報(computed使用)
|
||||
success_rate: FloatBox { me.get_success_statistics() }
|
||||
total_files_processed: IntegerBox { me.compilation_cache.size() }
|
||||
|
||||
birth() {
|
||||
me.classifier = new PropertyClassifierBox()
|
||||
me.generator = new NyashCodeGeneratorBox()
|
||||
me.validator = new SemanticValidatorBox()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧠 PropertyClassifierBox実装
|
||||
|
||||
```nyash
|
||||
box PropertyClassifierBox {
|
||||
// 分類ルールのキャッシュ(once)
|
||||
once classification_rules: RuleSetBox { load_classification_rules() }
|
||||
|
||||
// 統計情報(computed)
|
||||
classified_count: IntegerBox { me.get_classification_stats().count }
|
||||
accuracy_rate: FloatBox { me.get_classification_stats().accuracy }
|
||||
|
||||
classify_python_property(ast_node) {
|
||||
// Python AST → Property type 分類
|
||||
if me.has_decorator(ast_node, "@property") {
|
||||
if me.is_simple_computation(ast_node) {
|
||||
return "computed" // 単純計算 → computed
|
||||
} else {
|
||||
return "once" // 複雑処理 → キャッシュ推奨
|
||||
}
|
||||
}
|
||||
|
||||
if me.has_decorator(ast_node, "@functools.cached_property") {
|
||||
return "once" // 明示的キャッシュ
|
||||
}
|
||||
|
||||
if me.is_init_assignment(ast_node) {
|
||||
return "stored" // 通常フィールド
|
||||
}
|
||||
|
||||
if me.is_birth_once_candidate(ast_node) {
|
||||
return "birth_once" // 初期化時のみ評価
|
||||
}
|
||||
|
||||
return "unsupported" // Phase 2以降
|
||||
}
|
||||
|
||||
// ヒューリスティック判定
|
||||
is_simple_computation(node) {
|
||||
// 副作用なし+計算量小 → computed適合性判定
|
||||
return me.has_no_side_effects(node) and me.is_lightweight(node)
|
||||
}
|
||||
|
||||
is_birth_once_candidate(node) {
|
||||
// 初期化時のみ必要な重い処理を検出
|
||||
return me.called_in_init_only(node) and me.is_expensive(node)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🏭 NyashCodeGeneratorBox実装
|
||||
|
||||
```nyash
|
||||
box NyashCodeGeneratorBox {
|
||||
// テンプレートエンジン(once)
|
||||
once property_templates: TemplateEngineBox {
|
||||
load_property_templates()
|
||||
}
|
||||
|
||||
// 生成コード統計(computed)
|
||||
generated_lines: IntegerBox { me.count_generated_code_lines() }
|
||||
compression_ratio: FloatBox { me.calculate_compression_ratio() }
|
||||
|
||||
generate_property_declaration(property_info) {
|
||||
local template = me.property_templates.get(property_info.type)
|
||||
|
||||
// Property typeごとの生成
|
||||
peek property_info.type {
|
||||
"stored" => me.generate_stored_property(property_info),
|
||||
"computed" => me.generate_computed_property(property_info),
|
||||
"once" => me.generate_once_property(property_info),
|
||||
"birth_once" => me.generate_birth_once_property(property_info),
|
||||
else => throw UnsupportedPropertyError(property_info.type)
|
||||
}
|
||||
}
|
||||
|
||||
generate_computed_property(info) {
|
||||
// computed property テンプレート
|
||||
return info.name + ": " + info.type + " { " + info.expression + " }"
|
||||
}
|
||||
|
||||
generate_once_property(info) {
|
||||
// once property テンプレート(キャッシュ+例外安全)
|
||||
local code = "once " + info.name + ": " + info.type + " { " + info.expression + " }"
|
||||
|
||||
if info.has_exception_risk {
|
||||
code = code + " catch(ex) { poison(me." + info.name + ", ex); throw ex }"
|
||||
}
|
||||
|
||||
return code
|
||||
}
|
||||
|
||||
generate_birth_once_property(info) {
|
||||
// birth_once property テンプレート
|
||||
return "birth_once " + info.name + ": " + info.type + " { " + info.expression + " }"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔍 SemanticValidatorBox実装
|
||||
|
||||
```nyash
|
||||
box SemanticValidatorBox {
|
||||
// 検証ルール(once)
|
||||
once validation_rules: ValidationRuleSetBox {
|
||||
load_semantic_validation_rules()
|
||||
}
|
||||
|
||||
// 検証結果統計(computed)
|
||||
validation_success_rate: FloatBox { me.get_validation_stats().success_rate }
|
||||
error_categories: ArrayBox { me.get_validation_stats().error_types }
|
||||
|
||||
validate_property_semantics(python_ast, nyash_code) {
|
||||
local errors = new ArrayBox()
|
||||
|
||||
// 1. Property type一致性検証
|
||||
me.validate_property_type_consistency(python_ast, nyash_code, errors)
|
||||
|
||||
// 2. 例外安全性検証
|
||||
me.validate_exception_safety(python_ast, nyash_code, errors)
|
||||
|
||||
// 3. 性能特性検証
|
||||
me.validate_performance_characteristics(python_ast, nyash_code, errors)
|
||||
|
||||
return ValidationResult.new(errors)
|
||||
}
|
||||
|
||||
validate_property_type_consistency(python_ast, nyash_code, errors) {
|
||||
// Pythonの@propertyとNyashのcomputedが対応しているかチェック
|
||||
local python_properties = me.extract_python_properties(python_ast)
|
||||
local nyash_properties = me.extract_nyash_properties(nyash_code)
|
||||
|
||||
loop(python_properties.iter()) property {
|
||||
local expected_type = me.infer_nyash_property_type(property)
|
||||
local actual_type = nyash_properties.get(property.name).type
|
||||
|
||||
if expected_type != actual_type {
|
||||
errors.add(PropertyTypeMismatchError.new(property.name, expected_type, actual_type))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 統合ワークフロー
|
||||
|
||||
```nyash
|
||||
box PythonTranspilationWorkflow {
|
||||
compiler: PythonCompilerBox
|
||||
|
||||
birth() {
|
||||
me.compiler = new PythonCompilerBox()
|
||||
}
|
||||
|
||||
transpile_python_file(file_path) {
|
||||
// 1. Pythonファイル解析
|
||||
local python_ast = me.parse_python_file(file_path)
|
||||
|
||||
// 2. Property分類
|
||||
local classified_properties = me.compiler.classifier.classify_all_properties(python_ast)
|
||||
|
||||
// 3. Nyashコード生成
|
||||
local nyash_code = me.compiler.generator.generate_nyash_code(classified_properties)
|
||||
|
||||
// 4. セマンティック検証
|
||||
local validation_result = me.compiler.validator.validate_property_semantics(python_ast, nyash_code)
|
||||
|
||||
if validation_result.has_errors() {
|
||||
throw TranspilationError.new(validation_result.errors)
|
||||
}
|
||||
|
||||
// 5. コンパイル結果キャッシュ(once活用)
|
||||
me.compiler.compilation_cache.set(file_path, nyash_code)
|
||||
|
||||
return nyash_code
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 テスト実装例
|
||||
|
||||
```nyash
|
||||
box PropertySystemTranspilationTest {
|
||||
test_computed_property_generation() {
|
||||
local python_code = '''
|
||||
class TestClass:
|
||||
@property
|
||||
def doubled_value(self):
|
||||
return self.value * 2
|
||||
'''
|
||||
|
||||
local compiler = new PythonCompilerBox()
|
||||
local result = compiler.transpile(python_code)
|
||||
|
||||
assert result.contains("doubled_value: IntegerBox { me.value * 2 }")
|
||||
}
|
||||
|
||||
test_once_property_generation() {
|
||||
local python_code = '''
|
||||
class TestClass:
|
||||
@functools.cached_property
|
||||
def expensive_calc(self):
|
||||
return heavy_computation()
|
||||
'''
|
||||
|
||||
local compiler = new PythonCompilerBox()
|
||||
local result = compiler.transpile(python_code)
|
||||
|
||||
assert result.contains("once expensive_calc: ResultBox { heavy_computation() }")
|
||||
}
|
||||
|
||||
test_poison_on_throw_integration() {
|
||||
local python_code = '''
|
||||
class TestClass:
|
||||
@functools.cached_property
|
||||
def risky_operation(self):
|
||||
if random.random() < 0.1:
|
||||
raise ValueError("Failed")
|
||||
return success_result()
|
||||
'''
|
||||
|
||||
local compiler = new PythonCompilerBox()
|
||||
local result = compiler.transpile(python_code)
|
||||
|
||||
assert result.contains("catch(ex) { poison(me.risky_operation, ex); throw ex }")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 期待される効果
|
||||
|
||||
### 1. 実装効率の向上
|
||||
- Property System活用により、コンパイラ自体の実装がクリーン
|
||||
- once活用でコンパイルキャッシュ、computed活用で統計計算
|
||||
|
||||
### 2. 生成コードの高品質化
|
||||
- Python property → Nyash property の自然な1:1マッピング
|
||||
- poison-on-throw統合による例外安全性
|
||||
|
||||
### 3. 保守性の向上
|
||||
- Box化されたコンポーネント設計
|
||||
- 明確な責任分離(分類・生成・検証)
|
||||
|
||||
この設計により、Property System革命を最大限活用したPython transpilation実装が実現できます!
|
||||
295
docs/archive/roadmap/phases/phase-10.7/examples.md
Normal file
295
docs/archive/roadmap/phases/phase-10.7/examples.md
Normal file
@ -0,0 +1,295 @@
|
||||
# Python Native実装例
|
||||
|
||||
## 🎯 実装イメージ
|
||||
|
||||
### 使用例1: 基本的な関数のネイティブ化
|
||||
|
||||
```nyash
|
||||
// example1_basic.hako
|
||||
// Pythonコードをネイティブコンパイル
|
||||
|
||||
// Step 1: Pythonコードを用意
|
||||
code = """
|
||||
def fibonacci(n):
|
||||
if n <= 1:
|
||||
return n
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
|
||||
def factorial(n):
|
||||
if n == 0:
|
||||
return 1
|
||||
return n * factorial(n-1)
|
||||
"""
|
||||
|
||||
// Step 2: パース
|
||||
parser = new PythonParserBox()
|
||||
ast = parser.parse(code)
|
||||
print("Parsed functions: " + parser.getStats().get("functions"))
|
||||
|
||||
// Step 3: コンパイル
|
||||
compiler = new PythonCompilerBox()
|
||||
mir_module = compiler.compile(ast)
|
||||
|
||||
// Step 4: 実行
|
||||
if mir_module.isOk() {
|
||||
// ネイティブ実行!
|
||||
module = mir_module.get()
|
||||
|
||||
// 関数を取得して実行
|
||||
fib = module.getFunction("fibonacci")
|
||||
result = fib.call(10)
|
||||
print("fibonacci(10) = " + result) // 55
|
||||
|
||||
fact = module.getFunction("factorial")
|
||||
result = fact.call(5)
|
||||
print("factorial(5) = " + result) // 120
|
||||
} else {
|
||||
print("Compilation failed: " + mir_module.getError())
|
||||
}
|
||||
```
|
||||
|
||||
### 使用例2: コンパイル可否の明確な判定
|
||||
|
||||
```nyash
|
||||
// example2_clear_separation.hako
|
||||
// コンパイルできるかどうか事前に判定
|
||||
|
||||
// Phase 1対応のコード
|
||||
code_phase1 = """
|
||||
def compute_sum(n):
|
||||
total = 0
|
||||
for i in range(n):
|
||||
total += i * i
|
||||
return total
|
||||
|
||||
def factorial(n):
|
||||
if n == 0:
|
||||
return 1
|
||||
return n * factorial(n-1)
|
||||
"""
|
||||
|
||||
// Phase 1未対応のコード
|
||||
code_unsupported = """
|
||||
def fibonacci_generator(n):
|
||||
a, b = 0, 1
|
||||
for _ in range(n):
|
||||
yield a
|
||||
a, b = b, a + b
|
||||
"""
|
||||
|
||||
// コンパイラーで判定
|
||||
parser = new PythonParserBox()
|
||||
compiler = new PythonCompilerBox()
|
||||
|
||||
// Phase 1対応コードのチェック
|
||||
ast1 = parser.parse(code_phase1)
|
||||
result1 = compiler.compile(ast1)
|
||||
if result1.isOk() {
|
||||
print("✅ Phase 1 code compiled successfully!")
|
||||
module = result1.get()
|
||||
print("compute_sum(100) = " + module.call("compute_sum", 100))
|
||||
} else {
|
||||
print("❌ Compilation failed: " + result1.getError())
|
||||
}
|
||||
|
||||
// 未対応コードのチェック
|
||||
ast2 = parser.parse(code_unsupported)
|
||||
result2 = compiler.compile(ast2)
|
||||
if result2.isOk() {
|
||||
print("✅ Compiled successfully!")
|
||||
} else {
|
||||
print("❌ Cannot compile: " + result2.getError())
|
||||
print(" Reason: yield expression not supported in Phase 1")
|
||||
print(" Please use PyRuntimeBox instead")
|
||||
}
|
||||
```
|
||||
|
||||
### 使用例3: プログレッシブ最適化
|
||||
|
||||
```nyash
|
||||
// example3_progressive.hako
|
||||
// 実行しながら徐々に最適化
|
||||
|
||||
// 型推論付きコンパイラー
|
||||
compiler = new PythonCompilerBox()
|
||||
compiler.enableTypeInference(true)
|
||||
compiler.enableProfiling(true)
|
||||
|
||||
// 初回実行(型情報収集)
|
||||
code = """
|
||||
def matrix_multiply(A, B):
|
||||
# 最初は型が不明
|
||||
result = []
|
||||
for i in range(len(A)):
|
||||
row = []
|
||||
for j in range(len(B[0])):
|
||||
sum = 0
|
||||
for k in range(len(B)):
|
||||
sum += A[i][k] * B[k][j]
|
||||
row.append(sum)
|
||||
result.append(row)
|
||||
return result
|
||||
"""
|
||||
|
||||
// プロファイル付き実行
|
||||
for i in range(5) {
|
||||
mir = compiler.compile(parser.parse(code))
|
||||
|
||||
// 実行してプロファイル収集
|
||||
module = mir.get()
|
||||
A = [[1, 2], [3, 4]]
|
||||
B = [[5, 6], [7, 8]]
|
||||
result = module.call("matrix_multiply", A, B)
|
||||
|
||||
// 型情報が蓄積される
|
||||
print("Iteration " + i + ": ")
|
||||
print(" Type confidence: " + compiler.getTypeConfidence())
|
||||
print(" Optimization level: " + compiler.getOptimizationLevel())
|
||||
}
|
||||
|
||||
// 5回実行後、完全に最適化されたコードが生成される
|
||||
```
|
||||
|
||||
### 使用例4: 言語間相互運用
|
||||
|
||||
```nyash
|
||||
// example4_interop.hako
|
||||
// PythonコードとNyashコードのシームレスな連携
|
||||
|
||||
// Pythonで数値計算関数を定義
|
||||
python_math = """
|
||||
import math
|
||||
|
||||
def distance(x1, y1, x2, y2):
|
||||
return math.sqrt((x2-x1)**2 + (y2-y1)**2)
|
||||
|
||||
def normalize(vector):
|
||||
magnitude = math.sqrt(sum(x**2 for x in vector))
|
||||
return [x/magnitude for x in vector]
|
||||
"""
|
||||
|
||||
// コンパイルしてNyashから使用
|
||||
module = compile_python(python_math)
|
||||
|
||||
// Nyash側のゲームロジック
|
||||
box GameObject {
|
||||
init { x, y, vx, vy }
|
||||
|
||||
update(dt) {
|
||||
// Python関数をネイティブ速度で呼び出し
|
||||
me.x = me.x + me.vx * dt
|
||||
me.y = me.y + me.vy * dt
|
||||
|
||||
// 正規化(Pythonの関数を使用)
|
||||
local normalized = module.normalize([me.vx, me.vy])
|
||||
me.vx = normalized[0]
|
||||
me.vy = normalized[1]
|
||||
}
|
||||
|
||||
distanceTo(other) {
|
||||
// Pythonの距離計算関数を使用
|
||||
return module.distance(me.x, me.y, other.x, other.y)
|
||||
}
|
||||
}
|
||||
|
||||
// 完全にネイティブコードとして実行される!
|
||||
```
|
||||
|
||||
### 使用例5: デバッグとプロファイリング
|
||||
|
||||
```nyash
|
||||
// example5_debug.hako
|
||||
// 開発時のデバッグ支援
|
||||
|
||||
// デバッグモード有効
|
||||
parser = new PythonParserBox()
|
||||
parser.enableDebug(true)
|
||||
|
||||
compiler = new PythonCompilerBox()
|
||||
compiler.enableDebug(true)
|
||||
compiler.enableSourceMap(true) // 元のPythonコードへのマッピング
|
||||
|
||||
problematic_code = """
|
||||
def buggy_function(items):
|
||||
total = 0
|
||||
for item in items:
|
||||
# バグ: itemが文字列の場合エラー
|
||||
total += item * 2
|
||||
return total / len(items)
|
||||
"""
|
||||
|
||||
// コンパイル試行
|
||||
result = compiler.compile(parser.parse(problematic_code))
|
||||
|
||||
if result.isErr() {
|
||||
// 詳細なエラー情報
|
||||
diag = compiler.getDiagnostics()
|
||||
print("Compilation failed at line " + diag.line)
|
||||
print("Issue: " + diag.message)
|
||||
print("Suggestion: " + diag.suggestion)
|
||||
|
||||
// フォールバックで実行してランタイムエラーを確認
|
||||
runtime = new PythonRuntimeBox()
|
||||
try {
|
||||
runtime.exec(problematic_code)
|
||||
runtime.call("buggy_function", ["a", "b", "c"])
|
||||
} catch (e) {
|
||||
print("Runtime error: " + e.message)
|
||||
print("This would have been caught at compile time!")
|
||||
}
|
||||
}
|
||||
|
||||
// プロファイリング情報
|
||||
profiler = new PythonProfiler()
|
||||
profiler.attach(module)
|
||||
profiler.run()
|
||||
|
||||
print("Hot spots:")
|
||||
print(profiler.getHotSpots())
|
||||
print("Type instability:")
|
||||
print(profiler.getTypeInstability())
|
||||
```
|
||||
|
||||
## 🎯 実装の進化
|
||||
|
||||
### Phase 1(現在)
|
||||
```python
|
||||
# これらがネイティブ化可能
|
||||
def add(x, y): return x + y
|
||||
def factorial(n): ...
|
||||
def fibonacci(n): ...
|
||||
```
|
||||
|
||||
### Phase 2(予定)
|
||||
```python
|
||||
# 特殊メソッド対応
|
||||
class Vector:
|
||||
def __add__(self, other): ...
|
||||
def __len__(self): ...
|
||||
|
||||
# 内包表記
|
||||
squares = [x**2 for x in range(10)]
|
||||
```
|
||||
|
||||
### Phase 3(将来)
|
||||
```python
|
||||
# 完全な言語機能
|
||||
async def fetch_data(): ...
|
||||
@decorator
|
||||
def enhanced_function(): ...
|
||||
yield from generator
|
||||
```
|
||||
|
||||
## 🚀 パフォーマンス期待値
|
||||
|
||||
```
|
||||
Benchmark: Fibonacci(30)
|
||||
CPython: 1.234s
|
||||
PyPy: 0.123s
|
||||
Nyash Native: 0.012s (100x faster!)
|
||||
|
||||
Benchmark: Matrix Multiplication (100x100)
|
||||
CPython: 5.678s
|
||||
NumPy: 0.234s
|
||||
Nyash Native: 0.198s (NumPyに匹敵!)
|
||||
```
|
||||
249
docs/archive/roadmap/phases/phase-10.7/implementation.md
Normal file
249
docs/archive/roadmap/phases/phase-10.7/implementation.md
Normal file
@ -0,0 +1,249 @@
|
||||
# Phase 10.7 実装詳細
|
||||
|
||||
## 🛠️ 技術アーキテクチャ
|
||||
|
||||
### 2段階変換パイプライン
|
||||
|
||||
```
|
||||
Python AST → CorePy IR → Nyash AST → Nyashスクリプト
|
||||
```
|
||||
|
||||
**CorePy IR**の役割:
|
||||
- Pythonの複雑な構文を正規化
|
||||
- セマンティクスを明示的に(with→try/finally等)
|
||||
- 最適化しやすい中間表現
|
||||
|
||||
### 実装構造
|
||||
|
||||
```rust
|
||||
// plugins/nyash-python-parser-plugin/src/lib.rs
|
||||
#[plugin_box]
|
||||
pub struct PythonParserBox {
|
||||
base: BoxBase,
|
||||
}
|
||||
|
||||
#[plugin_methods]
|
||||
impl PythonParserBox {
|
||||
pub fn parse(&self, code: &str) -> Result<Box<dyn NyashBox>> {
|
||||
Python::with_gil(|py| {
|
||||
let ast_mod = py.import("ast")?;
|
||||
let tree = ast_mod.call_method1("parse", (code,))?;
|
||||
Ok(self.convert_ast(tree)?)
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📐 Python固有機能の実装戦略
|
||||
|
||||
### 1. デフォルト引数の罠
|
||||
|
||||
```python
|
||||
# Python: 定義時に一度だけ評価
|
||||
def bad_default(lst=[]):
|
||||
lst.append(1)
|
||||
return lst
|
||||
```
|
||||
|
||||
```nyash
|
||||
// 生成されるNyash
|
||||
box GeneratedModule {
|
||||
init { _default_lst }
|
||||
|
||||
constructor() {
|
||||
me._default_lst = new ArrayBox() // 定義時に一度だけ
|
||||
}
|
||||
|
||||
bad_default(lst) {
|
||||
if lst == null {
|
||||
lst = me._default_lst // 同じインスタンスを再利用!
|
||||
}
|
||||
lst.append(1)
|
||||
return lst
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. LEGB スコーピング
|
||||
|
||||
```python
|
||||
# Local → Enclosing → Global → Builtin
|
||||
global_var = 1
|
||||
def outer():
|
||||
enclosing_var = 2
|
||||
def inner():
|
||||
local_var = 3
|
||||
```
|
||||
|
||||
実装:
|
||||
- シンボルテーブルでスコープ管理
|
||||
- クロージャはBox/Cellで実装
|
||||
- global/nonlocalフラグを追跡
|
||||
|
||||
### 3. for/else, while/else
|
||||
|
||||
```python
|
||||
for i in range(10):
|
||||
if i == 5:
|
||||
break
|
||||
else:
|
||||
print("No break")
|
||||
```
|
||||
|
||||
```nyash
|
||||
// 生成されるNyash
|
||||
local _broken = false
|
||||
local _iter = py_iter(range(10))
|
||||
loop(true) {
|
||||
local _next = py_next(_iter)
|
||||
if _next.isStopIteration() { break }
|
||||
local i = _next.value
|
||||
|
||||
if i == 5 {
|
||||
_broken = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if not _broken {
|
||||
print("No break")
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 パスパイプライン
|
||||
|
||||
```
|
||||
Parse Python AST
|
||||
↓
|
||||
Symbol table analysis
|
||||
↓
|
||||
Normalize to CorePy IR
|
||||
↓
|
||||
Scope/closure analysis
|
||||
↓
|
||||
Type metadata attachment
|
||||
↓
|
||||
Lower to Nyash AST
|
||||
↓
|
||||
Peephole optimization
|
||||
↓
|
||||
Pretty-print + source map
|
||||
```
|
||||
|
||||
## 📊 最適化戦略
|
||||
|
||||
### トランスパイル時の最適化
|
||||
- 定数畳み込み
|
||||
- ループ不変式の巻き上げ
|
||||
- ビルトイン関数の直接呼び出し(シャドウイングなし時)
|
||||
- 冗長な`py_truthy()`の除去
|
||||
|
||||
### Nyashコンパイラに委ねる最適化
|
||||
- インライン展開
|
||||
- レジスタ割り当て
|
||||
- ループアンローリング
|
||||
- ベクトル化
|
||||
|
||||
### 型情報の活用
|
||||
```python
|
||||
def add(x: int, y: int) -> int:
|
||||
return x + y
|
||||
```
|
||||
→ 型ヒントがあれば`py_binop`ではなく直接整数演算
|
||||
|
||||
## 🐛 エラー処理とデバッグ
|
||||
|
||||
### ソースマップ
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["example.py"],
|
||||
"mappings": "AAAA,IAAM,CAAC,GAAG...",
|
||||
"names": ["add", "x", "y"]
|
||||
}
|
||||
```
|
||||
|
||||
### デバッグモード
|
||||
```bash
|
||||
nyash-transpile --debug example.py
|
||||
# 出力:
|
||||
# - CorePy IRダンプ
|
||||
# - Nyashプレビュー(元のPython行ヒント付き)
|
||||
# - 変換トレース
|
||||
```
|
||||
|
||||
### エラーメッセージ
|
||||
```
|
||||
ERROR: Cannot compile function 'async_func' at line 10
|
||||
Reason: async/await not supported in Phase 1
|
||||
AST Node: AsyncFunctionDef
|
||||
Suggestion: Use PyRuntimeBox or wait for Phase 3
|
||||
```
|
||||
|
||||
## ⚡ パフォーマンス最適化
|
||||
|
||||
### ホットパス識別
|
||||
```nyash
|
||||
// プロファイル情報を活用
|
||||
if compiler.isHotPath(func) {
|
||||
// 積極的な最適化
|
||||
result = compiler.optimizeAggressive(func)
|
||||
} else {
|
||||
// 標準的な変換
|
||||
result = compiler.compile(func)
|
||||
}
|
||||
```
|
||||
|
||||
### JIT連携
|
||||
```nyash
|
||||
// 型特化コード生成
|
||||
@jit_specialize(int, int)
|
||||
def add(x, y):
|
||||
return x + y
|
||||
```
|
||||
|
||||
## 🔌 プラグインAPI
|
||||
|
||||
### 変換フック
|
||||
```rust
|
||||
trait TransformHook {
|
||||
fn before_lower(&mut self, node: &CorePyNode);
|
||||
fn after_lower(&mut self, node: &NyashNode);
|
||||
fn on_function(&mut self, func: &FunctionDef);
|
||||
}
|
||||
```
|
||||
|
||||
### カスタムルール
|
||||
```yaml
|
||||
# custom_rules.yaml
|
||||
rules:
|
||||
- pattern: "dataclass"
|
||||
action: "convert_to_nyash_box"
|
||||
- pattern: "numpy.array"
|
||||
action: "use_native_array"
|
||||
```
|
||||
|
||||
## 📋 実装チェックリスト
|
||||
|
||||
### Phase 1(必須)
|
||||
- [ ] 関数定義(def)
|
||||
- [ ] 条件分岐(if/elif/else)
|
||||
- [ ] ループ(for/while with else)
|
||||
- [ ] 基本演算子
|
||||
- [ ] 関数呼び出し
|
||||
- [ ] return/break/continue
|
||||
- [ ] LEGB スコーピング
|
||||
- [ ] デフォルト引数
|
||||
|
||||
### Phase 2(拡張)
|
||||
- [ ] 例外処理(try/except/finally)
|
||||
- [ ] with文
|
||||
- [ ] list/dict/set comprehensions
|
||||
- [ ] lambda式
|
||||
- [ ] *args, **kwargs
|
||||
|
||||
### Phase 3(高度)
|
||||
- [ ] async/await
|
||||
- [ ] yield/yield from
|
||||
- [ ] デコレータ
|
||||
- [ ] クラス定義(基本)
|
||||
- [ ] import文
|
||||
@ -0,0 +1,194 @@
|
||||
# Python Descriptor Protocol → Nyash Property System マッピング
|
||||
|
||||
## 🎯 概要
|
||||
|
||||
2025-09-18のProperty System革命により、Python transpilationが飛躍的に向上。Pythonのdescriptor protocolを完全にNyashのProperty System(stored/computed/once/birth_once)にマッピングする設計。
|
||||
|
||||
## 🧬 Pythonプロパティ分類とNyashマッピング
|
||||
|
||||
### 1. 通常フィールド → stored
|
||||
```python
|
||||
class PyClass:
|
||||
def __init__(self):
|
||||
self.name = "example" # 通常の属性
|
||||
```
|
||||
```nyash
|
||||
box PyClass {
|
||||
name: StringBox // stored: 通常のフィールドストレージ
|
||||
|
||||
birth() {
|
||||
me.name = "example"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. @property → computed
|
||||
```python
|
||||
class PyClass:
|
||||
@property
|
||||
def full_name(self):
|
||||
return f"{self.first} {self.last}"
|
||||
```
|
||||
```nyash
|
||||
box PyClass {
|
||||
first: StringBox
|
||||
last: StringBox
|
||||
full_name: StringBox { me.first + " " + me.last } // computed: 毎回計算
|
||||
}
|
||||
```
|
||||
|
||||
### 3. @functools.cached_property → once
|
||||
```python
|
||||
import functools
|
||||
|
||||
class PyClass:
|
||||
@functools.cached_property
|
||||
def expensive_data(self):
|
||||
return expensive_computation()
|
||||
```
|
||||
```nyash
|
||||
box PyClass {
|
||||
once expensive_data: DataBox { expensive_computation() } // once: 遅延評価+キャッシュ
|
||||
}
|
||||
```
|
||||
|
||||
### 4. カスタムdescriptor → 判定ロジック
|
||||
```python
|
||||
class CustomDescriptor:
|
||||
def __get__(self, obj, objtype=None):
|
||||
# カスタムロジック
|
||||
pass
|
||||
|
||||
def __set__(self, obj, value):
|
||||
# セットロジック
|
||||
pass
|
||||
|
||||
class PyClass:
|
||||
custom_prop = CustomDescriptor()
|
||||
```
|
||||
|
||||
**判定ロジック(PythonCompilerBox内)**:
|
||||
```nyash
|
||||
box DescriptorAnalyzer {
|
||||
analyze_descriptor(descriptor_ast) {
|
||||
if descriptor_ast.has_get_only() {
|
||||
if descriptor_ast.is_pure_computation() {
|
||||
return "computed" // 副作用なし計算
|
||||
} else {
|
||||
return "once" // 副作用あり=キャッシュ推奨
|
||||
}
|
||||
}
|
||||
|
||||
if descriptor_ast.has_get_and_set() {
|
||||
return "stored" // getterとsetterあり=通常フィールド
|
||||
}
|
||||
|
||||
return "unsupported" // 複雑すぎ→Phase 2以降
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 自動判定アルゴリズム
|
||||
|
||||
### Phase 1: 基本パターン認識
|
||||
```python
|
||||
def classify_python_property(ast_node):
|
||||
# 1. デコレータ解析
|
||||
if has_decorator(ast_node, "@property"):
|
||||
if is_simple_computation(ast_node.body):
|
||||
return "computed"
|
||||
else:
|
||||
return "once" # 複雑→キャッシュ推奨
|
||||
|
||||
# 2. cached_property検出
|
||||
if has_decorator(ast_node, "@functools.cached_property"):
|
||||
return "once"
|
||||
|
||||
# 3. 通常の__init__内代入
|
||||
if is_init_assignment(ast_node):
|
||||
return "stored"
|
||||
|
||||
# 4. descriptor検出(Phase 2以降)
|
||||
if has_custom_descriptor(ast_node):
|
||||
return analyze_descriptor_complexity(ast_node)
|
||||
```
|
||||
|
||||
### Phase 2: 高度な判定(将来)
|
||||
- **副作用解析**: I/O、外部状態変更の検出
|
||||
- **コスト解析**: 計算量推定による once vs computed 判定
|
||||
- **依存解析**: 他のプロパティとの依存関係
|
||||
|
||||
## 🌟 poison-on-throw統合
|
||||
|
||||
### Python例外 → Nyash例外処理
|
||||
```python
|
||||
class PyClass:
|
||||
@functools.cached_property
|
||||
def risky_operation(self):
|
||||
if random.random() < 0.1:
|
||||
raise ValueError("Failed!")
|
||||
return expensive_result()
|
||||
```
|
||||
|
||||
```nyash
|
||||
box PyClass {
|
||||
once risky_operation: ResultBox {
|
||||
if random_float() < 0.1 {
|
||||
throw ValueError("Failed!")
|
||||
}
|
||||
return expensive_result()
|
||||
} catch(ex) {
|
||||
poison(me.risky_operation, ex) // poison-on-throw適用
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 実装フェーズ
|
||||
|
||||
### Phase 10.7a: 基本認識(1週間)
|
||||
- @property, @cached_property, 通常フィールドの自動分類
|
||||
- 単純なcomputedプロパティ生成
|
||||
|
||||
### Phase 10.7b: 拡張判定(2週間)
|
||||
- カスタムdescriptor解析
|
||||
- 副作用検出ロジック
|
||||
- poison-on-throw統合
|
||||
|
||||
### Phase 10.7c: 最適化(1週間)
|
||||
- 依存解析による once vs computed 最適選択
|
||||
- LLVM最適化との連携
|
||||
|
||||
## 🧪 テストケース
|
||||
|
||||
### 成功パターン
|
||||
```python
|
||||
# シンプルcomputed
|
||||
@property
|
||||
def area(self): return self.width * self.height # → computed
|
||||
|
||||
# キャッシュ必要
|
||||
@functools.cached_property
|
||||
def heavy_calc(self): return sum(range(1000000)) # → once
|
||||
|
||||
# 通常フィールド
|
||||
def __init__(self): self.name = "test" # → stored
|
||||
```
|
||||
|
||||
### 限界ケース(Phase 2以降)
|
||||
```python
|
||||
# 複雑なdescriptor(未対応)
|
||||
class ComplexDescriptor:
|
||||
def __get__(self, obj, objtype=None):
|
||||
# 複雑な条件分岐、外部API呼び出し等
|
||||
pass
|
||||
```
|
||||
|
||||
## 🚀 期待される効果
|
||||
|
||||
1. **開発体験**: PythonプロパティがNyashで自然に表現
|
||||
2. **性能向上**: LLVMによるproperty最適化(10-50x高速化)
|
||||
3. **型安全性**: NyashのBox型システムによる実行時安全性
|
||||
4. **保守性**: 生成されたNyashコードの可読性・編集可能性
|
||||
|
||||
このマッピング設計により、PythonからNyashへの自然で高性能なtranspilationが実現できます!
|
||||
@ -0,0 +1,152 @@
|
||||
# Phase 10.7 × Property System 革命 - 今すぐ始めるクイックスタート
|
||||
|
||||
## 🎯 Property System革命により実現可能になったPython→Nyash実行
|
||||
|
||||
2025-09-18のProperty System革命により、Python transpilationが飛躍的に実現可能に!
|
||||
|
||||
## 🚀 最短実装ルート(3週間で実用レベル)
|
||||
|
||||
### Week 1: 基本プロパティ認識
|
||||
```bash
|
||||
# プラグイン作成
|
||||
cd plugins/
|
||||
cargo new nyash-python-parser-plugin --lib
|
||||
|
||||
# 最小依存関係
|
||||
echo '[dependencies]
|
||||
pyo3 = { version = "0.22", features = ["auto-initialize"] }
|
||||
nyash-plugin-sdk = { path = "../../crates/plugin-sdk" }' >> Cargo.toml
|
||||
```
|
||||
|
||||
### Week 2-3: Property System活用コンパイラ
|
||||
```rust
|
||||
// src/lib.rs - 最小実装例
|
||||
use pyo3::prelude::*;
|
||||
|
||||
#[pyclass]
|
||||
pub struct PythonCompilerBox {
|
||||
property_classifier: PropertyClassifier,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl PythonCompilerBox {
|
||||
#[new]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
property_classifier: PropertyClassifier::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile_simple(&self, python_code: &str) -> PyResult<String> {
|
||||
let ast = self.parse_python(python_code)?;
|
||||
let classified = self.property_classifier.classify(ast);
|
||||
let nyash_code = self.generate_nyash_with_properties(classified);
|
||||
Ok(nyash_code)
|
||||
}
|
||||
}
|
||||
|
||||
struct PropertyClassifier;
|
||||
|
||||
impl PropertyClassifier {
|
||||
fn new() -> Self { Self }
|
||||
|
||||
fn classify(&self, ast: PythonAst) -> ClassifiedAst {
|
||||
// Phase 1: 基本パターンのみ
|
||||
// @property → computed
|
||||
// @cached_property → once
|
||||
// __init__代入 → stored
|
||||
todo!("実装")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 MVP テストケース
|
||||
|
||||
### 入力Python
|
||||
```python
|
||||
# test_simple.py
|
||||
class Counter:
|
||||
def __init__(self):
|
||||
self.value = 0
|
||||
|
||||
@property
|
||||
def doubled(self):
|
||||
return self.value * 2
|
||||
|
||||
@functools.cached_property
|
||||
def expensive_result(self):
|
||||
return sum(range(1000))
|
||||
```
|
||||
|
||||
### 期待されるNyash出力
|
||||
```nyash
|
||||
box Counter {
|
||||
value: IntegerBox // stored
|
||||
doubled: IntegerBox { me.value * 2 } // computed
|
||||
once expensive_result: IntegerBox { sum_range(1000) } // once
|
||||
|
||||
birth() {
|
||||
me.value = 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 実行テスト
|
||||
```bash
|
||||
# transpilation
|
||||
nyash --pyc test_simple.py -o test_simple.ny
|
||||
|
||||
# ネイティブコンパイル
|
||||
nyash --compile-native test_simple.ny -o test_app
|
||||
|
||||
# 実行(CPython依存なし!)
|
||||
./test_app
|
||||
```
|
||||
|
||||
## 📊 段階的成功指標
|
||||
|
||||
### Phase 1 (1週間後)
|
||||
- ✅ @property, @cached_property認識
|
||||
- ✅ 基本クラス → box変換
|
||||
- ✅ 1つのサンプルPythonファイルが動作
|
||||
|
||||
### Phase 2 (2週間後)
|
||||
- ✅ 継承、メソッド呼び出し対応
|
||||
- ✅ 10個のサンプルファイル成功
|
||||
- ✅ 性能測定(CPythonとの比較)
|
||||
|
||||
### Phase 3 (3週間後)
|
||||
- ✅ エラーハンドリング、例外処理
|
||||
- ✅ 実用的なPythonライブラリ部分対応
|
||||
- ✅ AOT配布可能なサンプルアプリ
|
||||
|
||||
## 🌟 創造的可能性
|
||||
|
||||
### ハイブリッド開発
|
||||
```python
|
||||
# Python側で開発・デバッグ
|
||||
@nyash.optimize # デコレータで高速化指定
|
||||
def heavy_computation(data):
|
||||
return complex_algorithm(data)
|
||||
|
||||
# 本番はNyash AOTで配布
|
||||
```
|
||||
|
||||
### リアルタイムtranspilation IDE
|
||||
- 左: Pythonコード編集
|
||||
- 右: リアルタイムNyash生成表示
|
||||
- 下: 性能比較グラフ
|
||||
|
||||
### 教育効果
|
||||
- Pythonユーザーが自然にNyashを学習
|
||||
- Property Systemの概念理解促進
|
||||
|
||||
## 🎯 今日から始められるアクション
|
||||
|
||||
1. **プラグイン skelton作成** (30分)
|
||||
2. **pyo3でPython AST取得** (2時間)
|
||||
3. **@property検出ロジック** (半日)
|
||||
4. **最初のbox変換** (1日)
|
||||
5. **テスト実行** (30分)
|
||||
|
||||
Property System革命により、この夢が現実になりました!🚀
|
||||
285
docs/archive/roadmap/phases/phase-10.7/testing-plan.md
Normal file
285
docs/archive/roadmap/phases/phase-10.7/testing-plan.md
Normal file
@ -0,0 +1,285 @@
|
||||
# Python Native Testing Plan
|
||||
|
||||
## 🎯 テスト戦略の全体像
|
||||
|
||||
「世界中のPythonコードがNyashのテストケース」という思想のもと、CPythonをオラクルとして使用する包括的なテスト戦略。
|
||||
|
||||
## 🧪 テストレベル
|
||||
|
||||
### 1. プラグインレベルテスト
|
||||
|
||||
#### PythonParserBox Tests
|
||||
```rust
|
||||
// plugins/nyash-python-parser-plugin/tests/parser_tests.rs
|
||||
#[test]
|
||||
fn test_parse_simple_function() {
|
||||
let parser = create_parser_box();
|
||||
let code = "def add(x, y): return x + y";
|
||||
let ast = parser.parse(create_string_box(code));
|
||||
|
||||
assert_eq!(ast.get_type().to_string(), "Module");
|
||||
let functions = ast.get_children();
|
||||
assert_eq!(functions.length(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_with_telemetry() {
|
||||
let parser = create_parser_box();
|
||||
parser.enable_telemetry(true);
|
||||
|
||||
let code = r#"
|
||||
def supported(): return 1
|
||||
async def unsupported(): await foo()
|
||||
"#;
|
||||
|
||||
parser.parse(create_string_box(code));
|
||||
let stats = parser.get_stats();
|
||||
|
||||
assert_eq!(stats.get("total_functions"), 2);
|
||||
assert_eq!(stats.get("supported_functions"), 1);
|
||||
}
|
||||
```
|
||||
|
||||
#### PythonCompilerBox Tests
|
||||
```rust
|
||||
#[test]
|
||||
fn test_compile_arithmetic() {
|
||||
let compiler = create_compiler_box();
|
||||
let ast = /* ... */;
|
||||
|
||||
let mir = compiler.compile(ast);
|
||||
assert!(mir.is_ok());
|
||||
|
||||
// MIR検証
|
||||
let module = mir.unwrap();
|
||||
assert!(module.has_function("add"));
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Differential Testing Framework
|
||||
|
||||
```nyash
|
||||
// tests/differential/framework.hako
|
||||
box DifferentialTester {
|
||||
init { oracle, implementation, results }
|
||||
|
||||
constructor() {
|
||||
me.oracle = new PythonRuntimeBox() // CPython
|
||||
me.implementation = new NativeEngine()
|
||||
me.results = new ArrayBox()
|
||||
}
|
||||
|
||||
test(code) {
|
||||
local oracle_result, impl_result
|
||||
|
||||
// CPythonで実行
|
||||
oracle_result = me.oracle.eval(code)
|
||||
|
||||
// Native実装で実行
|
||||
impl_result = me.implementation.exec(code)
|
||||
|
||||
// 結果比較
|
||||
return me.compare(oracle_result, impl_result)
|
||||
}
|
||||
|
||||
compare(expected, actual) {
|
||||
// 出力、戻り値、例外を比較
|
||||
local match = new MapBox()
|
||||
match.set("output", expected.output == actual.output)
|
||||
match.set("return", expected.return == actual.return)
|
||||
match.set("exception", expected.exception == actual.exception)
|
||||
return match
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. テストケース生成
|
||||
|
||||
#### 基本テストスイート
|
||||
```python
|
||||
# tests/suites/phase1_tests.py
|
||||
|
||||
# 算術演算
|
||||
def test_arithmetic():
|
||||
assert add(2, 3) == 5
|
||||
assert multiply(4, 5) == 20
|
||||
assert divide(10, 2) == 5.0 # true division
|
||||
|
||||
# 制御フロー
|
||||
def test_control_flow():
|
||||
# if/else
|
||||
result = conditional_logic(True, 10, 20)
|
||||
assert result == 10
|
||||
|
||||
# for/else
|
||||
found = search_with_else([1, 2, 3], 5)
|
||||
assert found == "not found" # else節実行
|
||||
|
||||
# デフォルト引数の罠
|
||||
def test_default_args():
|
||||
list1 = append_to_default(1)
|
||||
list2 = append_to_default(2)
|
||||
assert list1 is list2 # 同じリスト!
|
||||
```
|
||||
|
||||
#### Fuzzing with Hypothesis
|
||||
```python
|
||||
# tests/fuzzing/property_tests.py
|
||||
from hypothesis import given, strategies as st
|
||||
|
||||
@given(st.integers(), st.integers())
|
||||
def test_arithmetic_properties(x, y):
|
||||
"""算術演算の性質をテスト"""
|
||||
# Commutativity
|
||||
assert add(x, y) == add(y, x)
|
||||
|
||||
# Identity
|
||||
assert add(x, 0) == x
|
||||
|
||||
# Differential testing
|
||||
native_result = native_add(x, y)
|
||||
cpython_result = x + y
|
||||
assert native_result == cpython_result
|
||||
```
|
||||
|
||||
### 4. ベンチマークスイート
|
||||
|
||||
```nyash
|
||||
// benchmarks/numeric_suite.hako
|
||||
box NumericBenchmark {
|
||||
run() {
|
||||
local suite = new BenchmarkSuite()
|
||||
|
||||
// Fibonacci
|
||||
suite.add("fibonacci", {
|
||||
"cpython": { return me.runCPython("fib.py") },
|
||||
"native": { return me.runNative("fib.py") }
|
||||
})
|
||||
|
||||
// Matrix multiplication
|
||||
suite.add("matrix_mult", {
|
||||
"cpython": { return me.runCPython("matrix.py") },
|
||||
"native": { return me.runNative("matrix.py") }
|
||||
})
|
||||
|
||||
return suite.execute()
|
||||
}
|
||||
}
|
||||
|
||||
// 実行結果例
|
||||
// fibonacci:
|
||||
// CPython: 1.234s
|
||||
// Native: 0.123s (10.0x faster)
|
||||
// matrix_mult:
|
||||
// CPython: 5.678s
|
||||
// Native: 0.456s (12.4x faster)
|
||||
```
|
||||
|
||||
### 5. 回帰テスト
|
||||
|
||||
```yaml
|
||||
# .github/workflows/python-native-tests.yml
|
||||
name: Python Native Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Differential Tests
|
||||
run: |
|
||||
cargo test --package nyash-python-parser-plugin
|
||||
cargo test --package nyash-python-compiler-plugin
|
||||
|
||||
- name: Coverage Report
|
||||
run: |
|
||||
./tools/measure_compilation_coverage.sh
|
||||
# Expected output:
|
||||
# Phase 1 compatible files: 15%
|
||||
# Phase 2 functions: 40% compilable
|
||||
# Phase 3 functions: 10% compilable
|
||||
```
|
||||
|
||||
## 📊 メトリクス収集
|
||||
|
||||
### コンパイル成功率
|
||||
```nyash
|
||||
// 自動計測ツール
|
||||
box CoverageAnalyzer {
|
||||
analyze(directory) {
|
||||
local parser = new PythonParserBox()
|
||||
local compiler = new PythonCompilerBox()
|
||||
local stats = new MapBox()
|
||||
|
||||
for file in directory.glob("*.py") {
|
||||
local ast = parser.parseFile(file)
|
||||
local result = compiler.compile(ast)
|
||||
|
||||
stats.increment("total")
|
||||
if result.isOk() {
|
||||
stats.increment("success")
|
||||
} else {
|
||||
stats.increment("not_compilable")
|
||||
stats.record("unsupported", result.getError())
|
||||
}
|
||||
}
|
||||
|
||||
return stats
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### パフォーマンス追跡
|
||||
```sql
|
||||
-- メトリクスDB
|
||||
CREATE TABLE benchmark_results (
|
||||
id SERIAL PRIMARY KEY,
|
||||
test_name VARCHAR(255),
|
||||
implementation VARCHAR(50), -- 'cpython' or 'native'
|
||||
execution_time FLOAT,
|
||||
memory_usage BIGINT,
|
||||
timestamp TIMESTAMP,
|
||||
git_hash VARCHAR(40)
|
||||
);
|
||||
```
|
||||
|
||||
## 🚨 失敗時の診断
|
||||
|
||||
### デバッグ情報収集
|
||||
```nyash
|
||||
// コンパイル失敗時の詳細情報
|
||||
compiler.enableDebug(true)
|
||||
result = compiler.compile(ast)
|
||||
|
||||
if result.isErr() {
|
||||
local diag = compiler.getDiagnostics()
|
||||
print("Failed at: " + diag.get("location"))
|
||||
print("Reason: " + diag.get("reason"))
|
||||
print("AST node: " + diag.get("node_type"))
|
||||
print("Suggestion: " + diag.get("suggestion"))
|
||||
}
|
||||
```
|
||||
|
||||
### トレース機能
|
||||
```
|
||||
NYASH_PYTHON_TRACE=1 ./target/release/nyash test.py
|
||||
[Parser] Parsing function 'compute' at line 5
|
||||
[Compiler] Compiling BinOp: Add at line 7
|
||||
[Compiler] Unsupported: YieldFrom at line 15
|
||||
[Error] Cannot compile function 'generator_func' - yield not supported
|
||||
```
|
||||
|
||||
## ✅ 受け入れ基準
|
||||
|
||||
### Phase 1完了
|
||||
- [ ] 基本テストスイート100%パス
|
||||
- [ ] Differential testing 100%一致
|
||||
- [ ] Phase 1対応コードの100%コンパイル成功
|
||||
- [ ] 10x性能向上(数値計算ベンチマーク)
|
||||
|
||||
### 各PR必須
|
||||
- [ ] 新機能の単体テスト
|
||||
- [ ] Differential testケース追加
|
||||
- [ ] ベンチマーク結果(該当する場合)
|
||||
- [ ] カバレッジ低下なし
|
||||
@ -0,0 +1,13 @@
|
||||
# DECISIONS (Phase 10.7)
|
||||
|
||||
## 2025-08-30 — 二本立て運用(決定)
|
||||
- 決定: 現行の実行系(PyRuntimeBox, Plugin-First)は維持し、トランスパイル系(Python→Nyash)は All-or-Nothing で併走。
|
||||
- 代替案: トランスパイルの部分フォールバック(実行時にPyRuntimeへ落とす)。
|
||||
- 理由: 実行時の不一致/隠れ分岐を避ける。デプロイ時の挙動を単純に保つ。
|
||||
- 影響: 生成Nyashの品質責任はトランスパイラ側。利用者は明示的に系を選択。
|
||||
|
||||
## 2025-08-30 — Parser/CompilerもプラグインBox(決定)
|
||||
- 決定: PythonParserBox/PythonCompilerBox としてプラグイン化し、CLIから呼び出す。
|
||||
- 代替案: コア組込み。
|
||||
- 理由: Plugin-First原則、配布容易性、差し替え性、隔離テスト。
|
||||
- 影響: plugins/ 以下に新規プラグインを追加。SDKの最小拡張が必要になる場合あり。
|
||||
@ -0,0 +1,39 @@
|
||||
# CorePy IR 最小スキーマ(C2草案)
|
||||
|
||||
目的: Phase 1 の End-to-End を最短で通すための暫定IR。将来は構造化・拡張(with/try/comp/async等)。
|
||||
|
||||
## JSON 形式(暫定)
|
||||
```json
|
||||
{
|
||||
"module": {
|
||||
"functions": [
|
||||
{
|
||||
"name": "main", // 省略可(既定: "main")
|
||||
"return_value": 0, // 省略可(bodyと排他)
|
||||
"body": [ // 省略可(return_valueと排他)
|
||||
{ "Return": { "value": 0 } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
ショートカット(デバッグ/ブリッジ用)
|
||||
```json
|
||||
{ "nyash_source": "static box Generated { main() { return 0 } }" }
|
||||
```
|
||||
|
||||
## 変換規則(最小)
|
||||
- module.functions[0] だけを見る(複数関数は将来対応)
|
||||
- name があれば `static box Generated { <name>() { ... } }`
|
||||
- return_value が数値/文字列なら `return <value>` を生成
|
||||
- body があれば先頭の Return.value を探し、`return <value>` を生成
|
||||
- 上記が無ければ `return 0`
|
||||
|
||||
## 将来(予約)
|
||||
- statements: If/While/For/Assign/Expr などの節を追加
|
||||
- expressions: BinOp/Call/Name/Constant などを構造化
|
||||
- functions配列の複数対応、クロージャは別Box化の方針を検討
|
||||
|
||||
注意: All-or-Nothing 原則のもと、未対応ノードはCompiler側で明示的にエラーにする(現段階では未実装のため、return 0にフォールバックするが、C2終盤でStrict化する)。
|
||||
21
docs/archive/roadmap/phases/phase-10.7/workbench/README.md
Normal file
21
docs/archive/roadmap/phases/phase-10.7/workbench/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Phase 10.7 Workbench
|
||||
|
||||
このフォルダは Python Native(トランスパイル路線, All-or-Nothing)専用の作業台です。仕様・決定・スパイク・タスクをここに集約し、雑多にならないようにします。
|
||||
|
||||
構成
|
||||
- TODO.md: 直近の作業キュー(小粒で管理)
|
||||
- DECISIONS.md: 決定事項(理由/代替案/影響)
|
||||
- SPIKES/: 検証スパイクの成果(小さなPoCやプロト)
|
||||
- notes-YYYYMMDD.md: 打合せ/検討メモ(必要に応じて)
|
||||
|
||||
関連
|
||||
- 計画: ../PLAN.txt
|
||||
- 実装: ../implementation.md
|
||||
- テスト: ../testing-plan.md
|
||||
- 背景: ../README.md
|
||||
|
||||
運用ルール(最小)
|
||||
- 一度に大きくしない(5〜30分単位の成果で刻む)
|
||||
- 決定は DECISIONS.md に残す(誰でも後から辿れる)
|
||||
- スパイクは SPIKES に隔離(本流に混ぜない)
|
||||
|
||||
13
docs/archive/roadmap/phases/phase-10.7/workbench/TODO.md
Normal file
13
docs/archive/roadmap/phases/phase-10.7/workbench/TODO.md
Normal file
@ -0,0 +1,13 @@
|
||||
# TODO (Phase 10.7 Workbench)
|
||||
|
||||
短期(C1〜C3に向けた小粒タスク)
|
||||
- [ ] C1: Parser plugin 雛形スケルトンを作る(pyo3, parse(code)->AstBox/to_json)
|
||||
- [ ] C1: Telemetry最小(node種別カウント, 未対応ノード列挙)
|
||||
- [ ] C2: CorePy IR最小スキーマ(JSON)を commit(with/async系は予約)
|
||||
- [ ] C2: IR→Nyash ASTの最小変換(def/if/for/while/return/算術/比較/呼出し)
|
||||
- [ ] C3: CLI隠しフラグ prototyping(--pyc/--pyc-native)
|
||||
- [ ] Docs: PLANとimplementationの差分同期(週次)
|
||||
|
||||
メモ
|
||||
- All-or-Nothing原則:未対応は即Err(自動フォールバックなし)
|
||||
- 生成Nyashは現行AOT導線で配布可能(Strict)
|
||||
Reference in New Issue
Block a user