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:
nyash-codex
2025-12-09 03:18:05 +09:00
parent 1af92d8aea
commit 57cf67002e
3 changed files with 261 additions and 12 deletions

View File

@ -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
--- ---

View File

@ -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 loweringPhase 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 で処理

View 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`(退行確認)