docs: JoinIR Chapter 1 foundation complete summary + Phase 191 spec
- Added Section 7 to joinir-architecture-overview.md with completion status - Updated CURRENT_TASK.md with Phase 191-193 roadmap - Created phase191-body-local-integration.md instruction document 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -244,20 +244,20 @@
|
|||||||
- **修正**: `body_local_start_offset = env.len() + carrier_info.carriers.len()`
|
- **修正**: `body_local_start_offset = env.len() + carrier_info.carriers.len()`
|
||||||
- **E2E 結果**: `phase190_atoi_impl.hako` → 12 ✅、`phase190_parse_number_impl.hako` → 123 ✅
|
- **E2E 結果**: `phase190_atoi_impl.hako` → 12 ✅、`phase190_parse_number_impl.hako` → 123 ✅
|
||||||
- ExitLine contract Verifier 追加(`#[cfg(debug_assertions)]`)
|
- ExitLine contract Verifier 追加(`#[cfg(debug_assertions)]`)
|
||||||
- **残課題**: body-local 変数 assignment は JoinIR 未対応(Phase 186 line に残タスク)
|
- **残課題**: body-local 変数 assignment は JoinIR 未対応(Phase 191 で対応)
|
||||||
- [ ] Phase 191: 複雑 NumberAccumulation 対応
|
- [ ] **Phase 191: Body-Local Init & Update Lowering Integration**
|
||||||
- Complex addend 対応 (`v = v * 10 + f(x)`)
|
- **目的**: LoopBodyLocalEnv / UpdateEnv / LoopBodyLocalInitLowerer を Pattern2/4 に本番統合
|
||||||
- Phase 189 キャリア検出ブロッカー解決
|
- 191-1: 対象ケース選定(body-local が原因で JoinIR OFF な代表ループ 1 本)
|
||||||
- _atoi, _parse_number の完全実装
|
- 191-2: LoopBodyLocalInitLowerer の Pattern2 統合(init emission 位置は body 先頭)
|
||||||
- [ ] Phase 185+: Body-local Pattern2/4 統合 + String ops 有効化
|
- 191-3: UpdateEnv 統合確認(ConditionEnv + LoopBodyLocalEnv 両方から解決)
|
||||||
- Pattern2/4 lowerer に LoopBodyLocalEnv 統合
|
- 191-4: E2E テスト(body-local 版 _atoi で期待値確認)
|
||||||
- body-local 変数(`local temp` in loop body)の完全 MIR 生成対応
|
- 191-5: ドキュメント更新(phase184/186.md + CURRENT_TASK)
|
||||||
- String concat フィルタの段階的緩和
|
- [ ] Phase 192: Complex addend 対応
|
||||||
- _parse_number, _atoi 完全実装
|
- `v = v * 10 + f(x)` のような method call を含むパターン
|
||||||
- [ ] Phase 183+: JsonParser 中級パターン実装
|
- addend を事前計算して temp に格納
|
||||||
|
- [ ] Phase 193: JsonParser 残りループ展開
|
||||||
- _parse_array, _parse_object (P4 Continue, MethodCall 複数対応)
|
- _parse_array, _parse_object (P4 Continue, MethodCall 複数対応)
|
||||||
- _parse_string 完全版 (P2/P4, string concat + escape)
|
- _parse_string 完全版 (P2/P4, string concat + escape)
|
||||||
- [ ] Phase 184+: JsonParser 高級パターン実装
|
|
||||||
- _unescape_string (P4 Continue, 複雑キャリア + flatten)
|
- _unescape_string (P4 Continue, 複雑キャリア + flatten)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -456,3 +456,51 @@ JoinIR は Rust 側だけでなく、将来的に .hako selfhost コンパイラ
|
|||||||
「sum」「ch」など名前ベースの判定は LoopUpdateSummary / TrimLoopHelper の内部に閉じ込める。
|
「sum」「ch」など名前ベースの判定は LoopUpdateSummary / TrimLoopHelper の内部に閉じ込める。
|
||||||
|
|
||||||
この Roadmap は、JoinIR 層の変更や selfhost 深度を進めるたびに更新していくよ。
|
この Roadmap は、JoinIR 層の変更や selfhost 深度を進めるたびに更新していくよ。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. JoinIR 第1章:基盤完成サマリ(2025-12-09 時点)
|
||||||
|
|
||||||
|
### 7.1 現在の対応状況
|
||||||
|
|
||||||
|
**Pattern サポート**:
|
||||||
|
| Pattern | 説明 | 状態 |
|
||||||
|
|---------|------|------|
|
||||||
|
| P1 Simple | `loop(cond) { body }` | ✅ 完成 |
|
||||||
|
| P2 Break | `loop(cond) { if(...) break }` | ✅ 完成 |
|
||||||
|
| P3 If-PHI | `loop { if(...) a else b; use(φ) }` | ✅ 完成 |
|
||||||
|
| P4 Continue | `loop { if(...) continue }` | ✅ 完成 |
|
||||||
|
| P5 Trim | LoopBodyLocal → bool carrier 昇格 | ✅ 基本完成 |
|
||||||
|
|
||||||
|
**UpdateKind サポート**:
|
||||||
|
| UpdateKind | 例 | 状態 |
|
||||||
|
|------------|-----|------|
|
||||||
|
| CounterLike | `i = i + 1` | ✅ |
|
||||||
|
| AccumulationLike | `sum = sum + x` | ✅ |
|
||||||
|
| StringAppendChar | `s = s + ch` | ✅ |
|
||||||
|
| StringAppendLiteral | `s = s + "lit"` | ✅ |
|
||||||
|
| NumberAccumulation | `v = v * 10 + digit` | ✅ (Phase 190) |
|
||||||
|
| Complex | method call 含む | ❌ Fail-Fast |
|
||||||
|
|
||||||
|
**アーキテクチャ SSOT ライン**:
|
||||||
|
- ✅ LoopHeaderPhiBuilder: ループ変数・キャリアの PHI を SSOT で生成
|
||||||
|
- ✅ ExitLineReconnector: PHI dst → variable_map 接続
|
||||||
|
- ✅ JoinInlineBoundaryBuilder: 全パターンで Builder パターン統一
|
||||||
|
- ✅ JoinIRVerifier: デバッグビルドで契約検証
|
||||||
|
- ✅ ExitLine Contract Verifier: PHI 配線検証(Phase 190-impl-D)
|
||||||
|
|
||||||
|
### 7.2 残タスク(Phase 191+ で対応予定)
|
||||||
|
|
||||||
|
1. **body-local 変数の init + update lowering(Phase 186/191 ライン)**
|
||||||
|
- `local digit = s[i] - '0'` のような body-local 変数の JoinIR/MIR 生成
|
||||||
|
- LoopBodyLocalEnv / UpdateEnv インフラは Phase 184 で実装済み
|
||||||
|
- Pattern2/4 への統合が残タスク
|
||||||
|
|
||||||
|
2. **Complex addend 対応(Phase 191+)**
|
||||||
|
- `v = v * 10 + digits.indexOf(ch)` のような method call を含む NumberAccumulation
|
||||||
|
- 現状は Fail-Fast で拒否、将来的に addend を事前計算して temp に格納
|
||||||
|
|
||||||
|
3. **JsonParser 残り複雑ループ・selfhost ループへの適用**
|
||||||
|
- `_parse_array` / `_parse_object`(P4 Continue + 複数 MethodCall)
|
||||||
|
- `_unescape_string`(複雑なキャリア + flatten)
|
||||||
|
- selfhost `.hako` コンパイラの全ループを JoinIR で処理
|
||||||
|
|||||||
201
docs/development/current/main/phase191-body-local-integration.md
Normal file
201
docs/development/current/main/phase191-body-local-integration.md
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
# Phase 191: Body-Local Init & Update Lowering Integration
|
||||||
|
|
||||||
|
**Status**: Ready for Implementation
|
||||||
|
**Date**: 2025-12-09
|
||||||
|
**Prerequisite**: Phase 190-impl complete (NumberAccumulation + PHI wiring fixed)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 目的
|
||||||
|
|
||||||
|
Phase 184/186 で作った `LoopBodyLocalEnv`, `UpdateEnv`, `LoopBodyLocalInitLowerer` を
|
||||||
|
Pattern2/4 の中に本番統合して、`local digit = ...` などの body-local を JoinIR/MIR にきちんと落とす。
|
||||||
|
|
||||||
|
P2/P4 の既存ループ(`_atoi` など)を、body-local を含んだ形でも JoinIR で動かせるようにする。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 191-1: 対象ケースの再確認(1本に絞る)
|
||||||
|
|
||||||
|
### 目標
|
||||||
|
「いま body-local が原因で JoinIR を OFF にしている代表ループ」を 1 本だけ選ぶ。
|
||||||
|
|
||||||
|
### 候補
|
||||||
|
```nyash
|
||||||
|
// _atoi 簡略版
|
||||||
|
local digit = s[i] - '0'
|
||||||
|
result = result * 10 + digit
|
||||||
|
```
|
||||||
|
|
||||||
|
または body-local を使う最小テスト:
|
||||||
|
```nyash
|
||||||
|
// phase191_body_local_atoi.hako
|
||||||
|
static box Main {
|
||||||
|
main() {
|
||||||
|
local result = 0
|
||||||
|
local i = 0
|
||||||
|
loop(i < 3) {
|
||||||
|
local digit = i + 1 // body-local
|
||||||
|
result = result * 10 + digit
|
||||||
|
i = i + 1
|
||||||
|
}
|
||||||
|
print(result) // Expected: 123
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 成果物
|
||||||
|
- 選定した代表ループのファイルパス
|
||||||
|
- なぜ現在 JoinIR で通らないかの説明(body-local init が emit されていない)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 191-2: LoopBodyLocalInitLowerer の統合
|
||||||
|
|
||||||
|
### 対象ファイル
|
||||||
|
- `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`
|
||||||
|
- 必要なら `pattern4_with_continue.rs` も
|
||||||
|
|
||||||
|
### 実装内容
|
||||||
|
|
||||||
|
ループ lowering の流れの中で:
|
||||||
|
|
||||||
|
1. ループ本体 AST を `LoopBodyLocalInitLowerer` に渡して、
|
||||||
|
body-local の `local` 定義 (`digit = ...`) を JoinIR に emit しつつ、
|
||||||
|
`LoopBodyLocalEnv` に `name -> join_id` を登録させる。
|
||||||
|
|
||||||
|
2. ここで emit するのは「init 分」だけ(Update 分は既に `CarrierUpdateEmitter` + `UpdateEnv` に任せる)。
|
||||||
|
|
||||||
|
### init emission の位置
|
||||||
|
|
||||||
|
- ループ body の **先頭**(carrier update より前)に出るようにする。
|
||||||
|
- JoinIR 側の ValueId 空間は、Phase 190-impl-D での衝突回避ルール (`body_local_start_offset`) に従う。
|
||||||
|
|
||||||
|
### コード変更例
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// pattern2_with_break.rs 内
|
||||||
|
|
||||||
|
// Phase 191: Emit body-local initializations
|
||||||
|
let body_local_env = LoopBodyLocalInitLowerer::lower_init(
|
||||||
|
&body_ast,
|
||||||
|
&mut join_builder,
|
||||||
|
&mut alloc_body_local_value,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Phase 191: Create UpdateEnv with both condition and body-local
|
||||||
|
let update_env = UpdateEnv::new(condition_env.clone(), body_local_env.clone());
|
||||||
|
|
||||||
|
// Emit carrier updates using UpdateEnv
|
||||||
|
for (carrier_name, update_expr) in &carrier_info.updates {
|
||||||
|
CarrierUpdateEmitter::emit_carrier_update_with_env(
|
||||||
|
&mut join_builder,
|
||||||
|
carrier_name,
|
||||||
|
update_expr,
|
||||||
|
&update_env,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 191-3: UpdateEnv 統合の確認
|
||||||
|
|
||||||
|
### 対象ファイル
|
||||||
|
- `src/mir/join_ir/lowering/carrier_update_emitter.rs`(すでに UpdateEnv 対応済み)
|
||||||
|
|
||||||
|
### 確認内容
|
||||||
|
|
||||||
|
選んだ代表ループで:
|
||||||
|
- `UpdateEnv` が:
|
||||||
|
- `ConditionEnv`(LoopParam / OuterLocal)
|
||||||
|
- `LoopBodyLocalEnv`(今回 lower した init の join_id)
|
||||||
|
両方を見て `digit` や `temp` を正しく解決できているか確認。
|
||||||
|
|
||||||
|
### ユニットテスト追加
|
||||||
|
|
||||||
|
body-local `digit` を含む NumberAccumulation 更新を与えて、
|
||||||
|
JoinIR 側で Mul/Add 生成がエラーなく通ること:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[test]
|
||||||
|
fn test_number_accumulation_with_body_local() {
|
||||||
|
// UpdateEnv with body-local "digit" → ValueId(10)
|
||||||
|
let mut body_local_env = LoopBodyLocalEnv::new();
|
||||||
|
body_local_env.register("digit", ValueId(10));
|
||||||
|
|
||||||
|
let condition_env = ConditionEnv::new();
|
||||||
|
let update_env = UpdateEnv::new(condition_env, body_local_env);
|
||||||
|
|
||||||
|
// Resolve "digit" should return ValueId(10)
|
||||||
|
assert_eq!(update_env.resolve("digit"), Some(ValueId(10)));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 191-4: E2E テスト
|
||||||
|
|
||||||
|
### テストケース
|
||||||
|
|
||||||
|
191-1 で選んだ Minimal `_atoi` ループを:
|
||||||
|
- body-local 版(`local digit = ...`)に戻して、
|
||||||
|
- `NYASH_JOINIR_CORE=1` で実行 → 期待値が返ることを確認。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# E2E テスト実行
|
||||||
|
./target/release/hakorune apps/tests/phase191_body_local_atoi.hako
|
||||||
|
# Expected output: 123
|
||||||
|
```
|
||||||
|
|
||||||
|
### 退行チェック
|
||||||
|
|
||||||
|
- 既存の int-only ループ(body-local なし)が引き続き動くこと
|
||||||
|
- `phase190_atoi_impl.hako` → 12
|
||||||
|
- `phase190_parse_number_impl.hako` → 123
|
||||||
|
- Trim/JsonParser の P5/P2 ラインに影響がないこと
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 191-5: ドキュメント更新
|
||||||
|
|
||||||
|
### 更新対象
|
||||||
|
|
||||||
|
1. **phase184-body-local-mir-lowering.md** / **phase186-body-local-init-lowering.md**:
|
||||||
|
- 「Phase 191 で Pattern2/4 に統合完了」と追記
|
||||||
|
- 代表ループ名と、init → UpdateEnv → PHI → ExitLine までの流れを 1 ケースだけ図解
|
||||||
|
|
||||||
|
2. **CURRENT_TASK.md**:
|
||||||
|
- Phase 191: 完了マーク
|
||||||
|
- 残タスク(もし他のループは後回しにするなら)を更新
|
||||||
|
|
||||||
|
3. **joinir-architecture-overview.md**:
|
||||||
|
- Section 7.2 の残タスク「body-local 変数の init + update lowering」を完了マークに更新
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 成功基準
|
||||||
|
|
||||||
|
- [ ] 代表ループ(body-local 版 `_atoi`)が JoinIR only で期待値を返す
|
||||||
|
- [ ] 既存テスト(phase190_*.hako)が退行しない
|
||||||
|
- [ ] UpdateEnv が body-local 変数を正しく解決できる
|
||||||
|
- [ ] ドキュメントが更新されている
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 関連ファイル
|
||||||
|
|
||||||
|
### インフラ(Phase 184 で実装済み)
|
||||||
|
- `src/mir/join_ir/lowering/loop_body_local_env.rs`
|
||||||
|
- `src/mir/join_ir/lowering/update_env.rs`
|
||||||
|
- `src/mir/join_ir/lowering/carrier_update_emitter.rs`
|
||||||
|
|
||||||
|
### 統合対象
|
||||||
|
- `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`
|
||||||
|
- `src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs`
|
||||||
|
|
||||||
|
### テストファイル
|
||||||
|
- `apps/tests/phase191_body_local_atoi.hako`(新規作成)
|
||||||
|
- `apps/tests/phase190_atoi_impl.hako`(退行確認)
|
||||||
|
- `apps/tests/phase190_parse_number_impl.hako`(退行確認)
|
||||||
Reference in New Issue
Block a user