Files
hakorune/docs/development/current/main/phase191-body-local-integration.md
nyash-codex 57cf67002e 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>
2025-12-09 03:18:05 +09:00

202 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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