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

5.9 KiB
Raw Blame History

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 本だけ選ぶ。

候補

// _atoi 簡略版
local digit = s[i] - '0'
result = result * 10 + digit

または body-local を使う最小テスト:

// 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 しつつ、 LoopBodyLocalEnvname -> join_id を登録させる。

  2. ここで emit するのは「init 分」だけUpdate 分は既に CarrierUpdateEmitter + UpdateEnv に任せる)。

init emission の位置

  • ループ body の 先頭carrier update より前)に出るようにする。
  • JoinIR 側の ValueId 空間は、Phase 190-impl-D での衝突回避ルール (body_local_start_offset) に従う。

コード変更例

// 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 が:
    • ConditionEnvLoopParam / OuterLocal
    • LoopBodyLocalEnv(今回 lower した init の join_id 両方を見て digittemp を正しく解決できているか確認。

ユニットテスト追加

body-local digit を含む NumberAccumulation 更新を与えて、 JoinIR 側で Mul/Add 生成がエラーなく通ること:

#[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 で実行 → 期待値が返ることを確認。
# 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(退行確認)