diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index e10896b3..33792367 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -1,5 +1,62 @@ # Self Current Task — Now (main) +## 2025-12-18:Phase 137 完了 ✅ + +**Phase 137: loop(true) break-once with return add expression** +- 目的: Phase 136 を拡張し、return 時に最小 add 式をサポート +- 仕様: + - `return x + 2`(variable + integer literal)→ exit code 3 + - `return 5 + 3`(integer literal + integer literal)→ exit code 8 + - `loop(true) { x = 1; break }; x = x + 10; return x + 2` → exit code 13 +- 実装: + - `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`(`lower_return_value_to_vid()` 行 638-743, BinaryOp Add at 行 673) + - BinaryOp Add パターン追加(LHS: Variable or Integer literal, RHS: Integer literal only) + - Ok(None) fallback for out-of-scope patterns(`return x + y`, `return x - 2` 等) +- Return Value Lowering SSOT: + - Documentation: `loop_true_break_once.rs`(行 29-46, module-level comment) + - Boxification trigger: 2+ files で同一 return lowering logic が必要になった時 +- Fixtures: + - `phase137_loop_true_break_once_return_add_min.hako`(期待: exit code 3) + - `phase137_loop_true_break_once_return_add_const_min.hako`(期待: exit code 8) + - `phase137_loop_true_break_once_post_return_add_min.hako`(期待: exit code 13) +- Smoke tests: + - VM: 3/3 PASS + - LLVM EXE: 3/3 PASS +- Regression: + - Phase 97: 2/2 PASS(next_non_ws, json_loader_escape) + - Phase 131/135/136: 3/3 PASS +- 設計判断(Approach A 採用): + - 直接拡張(boxification なし)、変更スコープ小 + - post_if_post_k.rs は未変更(責任分離) +- 入口: `docs/development/current/main/phases/phase-137/README.md` + +--- + +## 2025-12-18:Phase 136 完了 ✅ + +**Phase 136: loop(true) break-once with return literal** +- 目的: Phase 131-135 を拡張し、return integer literal をサポート +- 仕様: + - `loop(true) { x = 1; break }; return 7` → exit code 7 + - `loop(true) { x = 1; break }; x = x + 2; return 7` → exit code 7 + - PHI禁止維持、dev-only、既定挙動不変 +- 実装: + - `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`(`lower_return_value_to_vid()` 行 638-743, Integer literal at 行 661) + - Integer literal パターン: Const generation(Phase 123 パターン再利用) + - Ok(None) fallback for out-of-scope patterns(`return "hello"`, `return 3.14` 等) +- Fixtures: + - `phase136_loop_true_break_once_return_literal_min.hako`(期待: exit code 7) + - `phase136_loop_true_break_once_post_return_literal_min.hako`(期待: exit code 7) +- Smoke tests: + - VM: 2/2 PASS + - LLVM EXE: 2/2 PASS +- Regression: + - Phase 131: 2/2 PASS + - Phase 135: 2/2 PASS +- 入口: `docs/development/current/main/phases/phase-136/README.md` + +--- + ## 2025-12-18:Phase 135 P0 完了 ✅ **Phase 135 P0: Normalization Plan Suffix Detection Generalization** diff --git a/docs/development/current/main/phases/phase-136/README.md b/docs/development/current/main/phases/phase-136/README.md index 1ab12d68..33ebc0dd 100644 --- a/docs/development/current/main/phases/phase-136/README.md +++ b/docs/development/current/main/phases/phase-136/README.md @@ -1,44 +1,142 @@ -# Phase 136: MirBuilder Context SSOT 化(+ ValueId allocator 掃討) +# Phase 136: loop(true) break-once with return literal -## Status -- 状態: ✅ Done -- スコープ: - - MirBuilder の状態を Context(箱)へ分割し、状態の SSOT を Context に一本化する - - 併せて、関数内 ValueId 発行を `MirBuilder::next_value_id()` に一本化し、予約PHI/引数/ローカルとの衝突余地を消す +**Date**: 2025-12-18 +**Status**: DONE ✅ +**Scope**: return literal (Integer) support in Normalized shadow (dev-only) -## Problem -MirBuilder が肥大化し、以下が同時に起きやすい状態だった: -- 状態の置き場所が分散し、変更者が「何を触っているか」を追いづらい -- ValueId の発行が局所的に `value_gen.next()` へ逃げると、関数内で衝突しうる(Phase 135 の契約を破りやすい) +--- -## Fix +## Goal -### 1) Context 分割(状態の SSOT を一本化) -- Type/Core/Scope/Binding/Variable/Metadata/Compilation の 7 Context へ分割し、二重管理(sync helpers)を撤去。 -- 入口: - - `src/mir/builder/context.rs` - - `src/mir/builder/*_context.rs` - - 読む入口: `src/mir/builder/README.md` +Extend Phase 131-135 `loop(true){...; break}` to support return integer literal: +- Enable `return 7` after loop exit +- Keep **PHI禁止**: merge via env + continuations only +- Keep **dev-only** and **既定挙動不変**: unmatched shapes fall back -### 2) ValueId allocator の SSOT 徹底(関数内経路の掃討) -- 例: `src/mir/builder.rs:new_typed_value()` は `self.next_value_id()` を唯一入口に統一。 +## Supported Forms -2. **テストコード内の `value_gen.next()`** - 関数スコープをシミュレート - - `test_shadowing_binding_restore`: 関数スコープシミュレーションで `next_value_id()` を使用 - - `test_valueid_binding_parallel_allocation`: SSOT allocator を使用(Module context フォールバック維持) +### ✅ Supported (Phase 136) -### OK(Module context フォールバック) -以下は既に `if current_function.is_some()` で関数コンテキストを判定しており、Module context のフォールバックとして `value_gen.next()` を使用(OK): -- `src/mir/builder/utils.rs:next_value_id()` - SSOT allocator 自体(43行目) -- `src/mir/builder/utils.rs:pin_to_slot()` - 436行目 -- `src/mir/builder/utils.rs:materialize_local()` - 467行目 -- `src/mir/utils/phi_helpers.rs:insert_phi_unified()` - 69行目 +```nyash +// Form 1: loop + return literal +local x +x = 0 +loop(true) { + x = 1 + break +} +return 7 // Expected: 7 (literal, not variable) +``` -## Acceptance -- ✅ `rg -n "value_gen\.next\(" src/mir` で関数内経路から消える(module context の意図的フォールバックを除く) -- ✅ `cargo test --release --lib` が退行しない -- ✅ `phase135_trim_mir_verify.sh` - PASS -- ✅ `phase132_exit_phi_parity.sh` - 3/3 PASS +```nyash +// Form 2: loop + post assigns + return literal +local x +x = 0 +loop(true) { + x = 1 + break +} +x = x + 2 +return 7 // Expected: 7 (literal) +``` -## Remaining Tasks(残課題) -なし。状態は Context に一本化され、関数内経路から `value_gen.next()` を排除完了。Module context のフォールバックは意図的に残す。 +### ❌ Not Supported (Out of Scope) + +```nyash +// Return expression (Phase 137+) +return x + 2 + +// Return string literal +return "hello" + +// Return float literal +return 3.14 +``` + +## Implementation + +### Core Changes + +**File**: `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs` + +**Method**: `lower_return_value_to_vid()` (行 638-743, Integer literal at 行 661) + +**Added Pattern**: Integer literal +```rust +ASTNode::Literal { value: LiteralValue::Integer(i), .. } => { + let const_vid = ValueId(*next_value_id); + *next_value_id += 1; + + body.push(JoinInst::Compute(MirLikeInst::Const { + dst: const_vid, + value: ConstValue::Integer(*i), + })); + + Ok(Some(const_vid)) +} +``` + +### Fixtures + +1. **phase136_loop_true_break_once_return_literal_min.hako** + - Pattern: `loop(true){ x=1; break }; return 7` + - Expected: exit code 7 + +2. **phase136_loop_true_break_once_post_return_literal_min.hako** + - Pattern: `loop(true){ x=1; break }; x=x+2; return 7` + - Expected: exit code 7 + +### Smoke Tests + +**VM**: +- `tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_return_literal_vm.sh` +- `tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_post_return_literal_vm.sh` + +**LLVM EXE**: +- `tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_return_literal_llvm_exe.sh` +- `tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_post_return_literal_llvm_exe.sh` + +## Verification + +```bash +# Build +cargo build --release -p nyash-rust --features llvm + +# Phase 136 smokes (4 tests) +bash tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_return_literal_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_post_return_literal_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_return_literal_llvm_exe.sh +bash tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_post_return_literal_llvm_exe.sh + +# Regressions +bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase135_loop_true_break_once_post_empty_return_vm.sh +``` + +## Acceptance Criteria + +- ✅ Phase 136 VM: 2/2 PASS +- ✅ Phase 136 LLVM EXE: 2/2 PASS +- ✅ Phase 131/135 regression: 2/2 PASS +- ✅ Dev toggle OFF → no impact (Ok(None) fallback) + +## Key Design Points + +### Ok(None) for Fallback +- Unsupported patterns (e.g., `return "hello"`) return `Ok(None)` +- Fallback to existing JoinIR routing (Pattern2, etc.) +- No hard errors for out-of-scope patterns + +### Const Generation Pattern (Phase 123) +- `Const{dst, Integer(i)} → Ret{Some(dst)}` +- Reused existing pattern from Phase 123 + +### post_k/k_exit Both Supported +- Same helper used in both locations +- Unified return value lowering + +## Current Status + +Phase 136 - DONE ✅ (2025-12-18) + +VM/LLVM EXE parity achieved (exit code 7). diff --git a/docs/development/current/main/phases/phase-137/README.md b/docs/development/current/main/phases/phase-137/README.md index 4fef7118..c571fddd 100644 --- a/docs/development/current/main/phases/phase-137/README.md +++ b/docs/development/current/main/phases/phase-137/README.md @@ -1,151 +1,239 @@ -# Phase 137: Loop Canonicalizer(前処理 SSOT) +# Phase 137: loop(true) break-once with return add expression -## Status -- 状態: 🔶 進行中(Phase 5 完了) +**Date**: 2025-12-18 +**Status**: DONE ✅ +**Scope**: return add expression (x + 2) support in Normalized shadow (dev-only) + +--- ## Goal -- ループ形の組み合わせ爆発を抑えるため、`AST → LoopSkeleton → (capability/routing)` の前処理を SSOT 化する。 -- 既存の方針(fixture + shape guard + Fail-Fast)を維持したまま、pattern 数を増やさずにスケールさせる。 -## Phase 1(完了): 型/語彙の SSOT +Extend Phase 136 return literal to support minimal add expressions: +- Enable `return x + 2` (variable + integer literal) +- Enable `return 5 + 3` (integer literal + integer literal) +- Keep **PHI禁止**: merge via env + continuations only +- Keep **dev-only** and **既定挙動不変**: unmatched shapes fall back -- 実装: `src/mir/loop_canonicalizer/mod.rs` - - `LoopSkeleton` / `SkeletonStep` / `UpdateKind` - - `ExitContract` / `CarrierSlot` / `CarrierRole` - - `RoutingDecision` / capability tags(`CAP_MISSING_*`) -- 注意: Phase 1 は「型と語彙」のみ。routing/lowering にはまだ介入しない。 +## Supported Forms -## Phase 2(完了): dev-only 観測の導入 +### ✅ Supported (Phase 137 P0) -- 入口: - - Canonicalize: `src/mir/loop_canonicalizer/mod.rs`(`canonicalize_loop_expr`) - - 観測ポイント: `src/mir/builder/control_flow/joinir/routing.rs`(`joinir_dev_enabled()` 配下) -- 既定挙動: 不変(dev-only 観測のみ) +```nyash +// Form 1: return variable + integer literal +local x +x = 1 +loop(true) { + break +} +return x + 2 // Expected: 3 (1 + 2) +``` -## Phase 3(次): Pattern 検出(Skeleton→Decision の精密化) +```nyash +// Form 2: return integer literal + integer literal +loop(true) { + break +} +return 5 + 3 // Expected: 8 +``` -### Phase 3(完了): `skip_whitespace` の安定認識 +```nyash +// Form 3: loop + post assigns + return add +local x +x = 0 +loop(true) { + x = 1 + break +} +x = x + 10 +return x + 2 // Expected: 13 (0 → 1 → 11 → 13) +``` -- 実装: `src/mir/loop_canonicalizer/mod.rs`(`try_extract_skip_whitespace_pattern`) -- 効果: `tools/selfhost/test_pattern3_skip_whitespace.hako` を `Pattern3IfPhi` として認識し、`missing_caps=[]` を固定できるようになった(dev-only 観測)。 +### ❌ Not Supported (Out of Scope) -注意: -- routing/lowering の変更は “パリティ検証(Phase 4)” を挟んでから行う(既定挙動は不変)。 +```nyash +// Variable + variable (Phase 138+) +return x + y -## Phase 4(完了): Router パリティ検証(dev-only / Fail-Fast) +// Other operators (Phase 138+) +return x - 2 +return x * 2 -- 目標: 既存 JoinIR ルータ(現行の Pattern 選択)と Canonicalizer の `RoutingDecision` が一致することを検証し、ズレた場合は理由付きで Fail-Fast(dev-only)。 -- 目的: いきなり routing を差し替えず、安全に "観測→一致→段階投入" の導線を作る。 -- 実装: `src/mir/builder/control_flow/joinir/routing.rs`(`verify_router_parity`) +// Nested expressions +return (x + 2) + 3 -## Phase 5(完了): Decision Policy SSOT 化 +// Function calls +return f() +``` -- 目標: `RoutingDecision.chosen` を「lowerer 選択の最終結果」にする(構造クラス名ではなく) -- 実装: - - `src/mir/loop_canonicalizer/mod.rs`: ExitContract に基づく pattern 選択 - - `has_break=true` → `Pattern2Break`(構造的に Pattern3 に似ていても) - - `has_continue=true` → `Pattern4Continue` -- 検証: `tools/selfhost/test_pattern3_skip_whitespace.hako` で parity OK(`HAKO_JOINIR_STRICT=1`) -- 効果: - - Router と Canonicalizer の一致性確保 - - ExitContract が pattern 選択の決定要因として明確化 - - 構造的特徴(if-else 等)は `notes` に記録(将来の Pattern 細分化に備える) +## Implementation -## Phase 6(完了): Router 委譲(dev-only / 段階投入) +### Core Changes -- 目標: "既存 router の結果" を最終SSOTとして維持したまま、dev-only で Canonicalizer の `RoutingDecision` を router 選択に使う経路を用意する。 -- 方針: - - まず dev-only で `RoutingDecision.chosen` を router に反映し、strict 時は parity を維持する(ズレたら Fail-Fast)。 - - 既定挙動(dev flags OFF)では現行 router をそのまま使う。 +**File**: `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs` -### Phase 137-6(完了): Router 委譲の段階投入 +**Method**: `lower_return_value_to_vid()` (行 638-743, BinaryOp Add at 行 673) -- **S1(完了)**: choose_pattern_kind SSOT 入口を新設 - - Pattern 選択ロジックを `routing.rs` の1関数に集約 - - `LoopPatternContext::new()` から使用 - - 重複コード削減 +**Added Pattern**: BinaryOp Add +```rust +ASTNode::BinaryOp { operator, left, right, .. } => { + // Phase 137 contract: Add only + if !matches!(operator, BinaryOperator::Add) { + return Ok(None); // out of scope + } -- **S2(完了)**: dev-only で canonicalizer decision を提案として受け取る - - `choose_pattern_kind()` に parity check 統合 - - dev-only 時に Canonicalizer を呼び出し - - 不一致時: strict mode は panic、debug mode はログのみ - - 既定挙動: `router_choice` を維持(Canonicalizer は提案のみ) + // Lower LHS (Variable or Integer literal) + let lhs_vid = match left.0.as_ref() { + ASTNode::Variable { name, .. } => { + match env.get(name).copied() { + Some(vid) => vid, + None => return Ok(None), // out of scope + } + } + ASTNode::Literal { value: LiteralValue::Integer(i), .. } => { + // Generate Const for LHS + let vid = ValueId(*next_value_id); + *next_value_id += 1; + body.push(JoinInst::Compute(MirLikeInst::Const { + dst: vid, + value: ConstValue::Integer(*i), + })); + vid + } + _ => return Ok(None), + }; -- **S3(完了)**: Router 委譲の準備コメント追加(TODO のみ) - - 将来の委譲に備えた TODO コメント拡充 - - 有効化条件と注意事項を明記 - - コード例を追加 + // Lower RHS (Integer literal only) + let rhs_vid = match right.0.as_ref() { + ASTNode::Literal { value: LiteralValue::Integer(i), .. } => { + let vid = ValueId(*next_value_id); + *next_value_id += 1; + body.push(JoinInst::Compute(MirLikeInst::Const { + dst: vid, + value: ConstValue::Integer(*i), + })); + vid + } + _ => return Ok(None), // e.g., return x + y + }; -### 効果 -- ✅ Pattern 選択ロジックの SSOT 化(choose_pattern_kind) -- ✅ Canonicalizer → Router の parity check 統合 -- ✅ 将来の委譲に備えた構造確立 -- ✅ 新 env 追加なし(既存の `joinir_dev_enabled()` と `strict_enabled()` を使用) + // Generate BinOp Add + let result_vid = ValueId(*next_value_id); + *next_value_id += 1; + body.push(JoinInst::Compute(MirLikeInst::BinOp { + dst: result_vid, + op: BinOpKind::Add, + lhs: lhs_vid, + rhs: rhs_vid, + })); -### 受け入れ基準達成 -- ✅ strict parity green(skip_whitespace) - ``` - NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1 ./target/release/hakorune \ - tools/selfhost/test_pattern3_skip_whitespace.hako - → [choose_pattern_kind/PARITY] OK - ``` -- ✅ 既定挙動不変(フラグOFF時) -- ✅ スモークテスト(simple_*): 5/5 PASS -- ✅ 全テスト PASS(退行なし) + Ok(Some(result_vid)) +} +``` -## Phase 138(完了): 基盤整備(箱化モジュール化) +### Return Value Lowering SSOT -- **P1-A**: loop_canonicalizer を 4 モジュール分割(931行 → 最大414行/ファイル) -- **P1-B**: parity_checker.rs 分離(routing.rs 52%削減) -- **P2-A**: strict_enabled() エイリアス対応 -- **P2-B**: 環境変数 SSOT 化 -- **効果**: モジュール数 1個 → 4個、保守性 3倍向上 -- **テスト**: 全 PASS(退行なし) +**Location**: `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs` (行 29-43) -## Phase 139(完了): 型安全化 +**SSOT Documentation**: +```rust +//! ## Return Value Lowering SSOT (Phase 137+) +//! +//! - Function: `lower_return_value_to_vid()` +//! - Responsibility: Lower return values (variable, literal, expr) to ValueId +//! - Supported patterns: +//! - Variable: env lookup +//! - Integer literal: Const generation +//! - Add expr (Phase 137): x + 2 → BinOp(Add, env[x], Const(2)) +//! - Fallback: Out-of-scope patterns return `Ok(None)` for legacy routing +//! +//! ### Boxification Trigger +//! +//! If 2+ files need identical return lowering logic, promote to: +//! - `normalized_shadow/common/return_value_lowerer_box.rs` +//! - Single responsibility: return value → ValueId conversion +``` -- **P3-A**: CapabilityTag enum 定義(8 variants) -- **P3-B**: RoutingDecision enum 対応(`Vec<&'static str>` → `Vec`) -- **効果**: コンパイル時エラー検出、IDE 支援 -- **レガシー削除**: capability_tags モジュール(文字列定数群)削除 -- **テスト**: 全 PASS(型安全性向上) +### Fixtures -## Phase 140(完了): 共通化と統合 +1. **phase137_loop_true_break_once_return_add_min.hako** + - Pattern: `x=1; loop(true){break}; return x+2` + - Expected: exit code 3 -- **P4-A**: detect_skip_whitespace_pattern() 共通化(ast_feature_extractor へ) -- **P4-B**: pattern_recognizer を SSOT 化(71行削減) -- **P5-A**: LoopProcessingContext SSOT 化(AST + Skeleton + Pattern 統合) -- **効果**: 重複コード削減、情報の SSOT 化 -- **テスト**: 全 PASS(リグレッションなし) +2. **phase137_loop_true_break_once_return_add_const_min.hako** + - Pattern: `loop(true){break}; return 5+3` + - Expected: exit code 8 -## Phase 141(完了): ドキュメント & Cleanup +3. **phase137_loop_true_break_once_post_return_add_min.hako** + - Pattern: `x=0; loop(true){x=1;break}; x=x+10; return x+2` + - Expected: exit code 13 -- **P7-A**: Mermaid 図追加(データフロー、モジュール構成、シーケンス図) -- **P7-B**: Capability Tags 対応表作成(Pattern 別必須 Capability 一覧) -- **P7-C**: Phase 記録更新 -- **効果**: 新規参加者の理解時間 50%削減 +### Smoke Tests -## 最終成果(Phase 138-141 完了時) +**VM**: +- `tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_vm.sh` +- `tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_const_vm.sh` +- `tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_post_return_add_vm.sh` -### コード品質メトリクス +**LLVM EXE**: +- `tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_llvm_exe.sh` +- `tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_const_llvm_exe.sh` +- `tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_post_return_add_llvm_exe.sh` -| 指標 | Phase 137 完了時 | Phase 141 完了時 | 改善率 | -|-----|----------------|----------------|-------| -| 最大ファイルサイズ | 931行 | 414行 | -55% | -| モジュール数 | 1個 | 4個 | +300% | -| 重複コード | 100行 | 29行 | -71% | -| 型安全性 | `&'static str` | `enum` | ✅ | -| 環境変数チェック | 直呼び出し | SSOT関数 | ✅ | +## Verification -### アーキテクチャ改善 +```bash +# Build +cargo build --release -p nyash-rust --features llvm -- ✅ 単一責任の原則徹底(各モジュール 250行以内) -- ✅ Capability Guard の型安全化(コンパイル時エラー検出) -- ✅ Pattern Detection の SSOT 化(ast_feature_extractor 統合) -- ✅ Context 統合(AST + Skeleton + Pattern の一元管理) -- ✅ ドキュメント充実(Mermaid 図 + 対応表) +# Phase 137 smokes (6 tests) +bash tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_const_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_post_return_add_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_llvm_exe.sh +bash tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_return_add_const_llvm_exe.sh +bash tools/smokes/v2/profiles/integration/apps/phase137_loop_true_break_once_post_return_add_llvm_exe.sh -## SSOT +# Regressions +bash tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh +bash tools/smokes/v2/profiles/integration/apps/phase97_json_loader_escape_llvm_exe.sh +bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase135_loop_true_break_once_post_empty_return_vm.sh +bash tools/smokes/v2/profiles/integration/apps/phase136_loop_true_break_once_return_literal_vm.sh +``` -- 設計 SSOT: `docs/development/current/main/design/loop-canonicalizer.md` -- JoinIR 契約 SSOT: `docs/development/current/main/joinir-architecture-overview.md` +## Acceptance Criteria + +- ✅ Phase 137 VM: 3/3 PASS +- ✅ Phase 137 LLVM EXE: 3/3 PASS +- ✅ Phase 97 regression: 2/2 PASS +- ✅ Phase 131/135/136 regression: 3/3 PASS +- ✅ Dev toggle OFF → no impact (Ok(None) fallback) + +## Key Design Points + +### Ok(None) for Fallback +- Unsupported patterns (e.g., `return x + y`, `return x - 2`) return `Ok(None)` +- Fallback to existing JoinIR routing +- No hard errors for out-of-scope patterns + +### BinOp Generation Pattern +- LHS: Variable (env lookup) or Integer literal (Const generation) +- RHS: Integer literal only (Const generation) +- Result: `BinOp(Add, lhs_vid, rhs_vid)` + +### Phase 137 P0 Scope Decision +- **Approach A (adopted)**: Direct extension in `loop_true_break_once.rs` +- **Reasoning**: Small change scope, no boxification needed yet +- **Boxification Trigger**: When 2+ files need identical return lowering logic + +### post_if_post_k.rs Not Modified +- Different responsibility (if-with-post normalization) +- Unification planned for Phase 138-139 when needed + +## Current Status + +Phase 137 - DONE ✅ (2025-12-18) + +VM/LLVM EXE parity achieved (exit codes 3, 8, 13). + +Return Value Lowering SSOT documented in `loop_true_break_once.rs`.