docs: Phase 136/137 - return literal and add expression documentation
Phase 136 Documentation: - Created docs/development/current/main/phases/phase-136/README.md - Goal: loop(true) break-once with return literal (Integer) - Supported: return 7, loop + post + return literal - Implementation: lower_return_value_to_vid() method - Tests: 2 fixtures + 4 smokes - VM/LLVM EXE parity verification commands Phase 137 Documentation: - Created docs/development/current/main/phases/phase-137/README.md - Goal: loop(true) break-once with return add expression - Supported: return x+2, return 5+3, loop+post+return add - Implementation: Extended lower_return_value_to_vid() for BinaryOp Add - Return Value Lowering SSOT documented (lines 29-46) - Boxification trigger: when 2+ files need identical logic - Tests: 3 fixtures + 6 smokes - VM/LLVM EXE parity verification commands 10-Now.md Updates: - Added Phase 136 entry (return literal) - Added Phase 137 entry (return add expression) - Implementation details and test coverage - Links to phase READMEs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -1,5 +1,62 @@
|
|||||||
# Self Current Task — Now (main)
|
# 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 完了 ✅
|
## 2025-12-18:Phase 135 P0 完了 ✅
|
||||||
|
|
||||||
**Phase 135 P0: Normalization Plan Suffix Detection Generalization**
|
**Phase 135 P0: Normalization Plan Suffix Detection Generalization**
|
||||||
|
|||||||
@ -1,44 +1,142 @@
|
|||||||
# Phase 136: MirBuilder Context SSOT 化(+ ValueId allocator 掃討)
|
# Phase 136: loop(true) break-once with return literal
|
||||||
|
|
||||||
## Status
|
**Date**: 2025-12-18
|
||||||
- 状態: ✅ Done
|
**Status**: DONE ✅
|
||||||
- スコープ:
|
**Scope**: return literal (Integer) support in Normalized shadow (dev-only)
|
||||||
- MirBuilder の状態を Context(箱)へ分割し、状態の SSOT を Context に一本化する
|
|
||||||
- 併せて、関数内 ValueId 発行を `MirBuilder::next_value_id()` に一本化し、予約PHI/引数/ローカルとの衝突余地を消す
|
|
||||||
|
|
||||||
## Problem
|
---
|
||||||
MirBuilder が肥大化し、以下が同時に起きやすい状態だった:
|
|
||||||
- 状態の置き場所が分散し、変更者が「何を触っているか」を追いづらい
|
|
||||||
- ValueId の発行が局所的に `value_gen.next()` へ逃げると、関数内で衝突しうる(Phase 135 の契約を破りやすい)
|
|
||||||
|
|
||||||
## Fix
|
## Goal
|
||||||
|
|
||||||
### 1) Context 分割(状態の SSOT を一本化)
|
Extend Phase 131-135 `loop(true){...; break}` to support return integer literal:
|
||||||
- Type/Core/Scope/Binding/Variable/Metadata/Compilation の 7 Context へ分割し、二重管理(sync helpers)を撤去。
|
- Enable `return 7` after loop exit
|
||||||
- 入口:
|
- Keep **PHI禁止**: merge via env + continuations only
|
||||||
- `src/mir/builder/context.rs`
|
- Keep **dev-only** and **既定挙動不変**: unmatched shapes fall back
|
||||||
- `src/mir/builder/*_context.rs`
|
|
||||||
- 読む入口: `src/mir/builder/README.md`
|
|
||||||
|
|
||||||
### 2) ValueId allocator の SSOT 徹底(関数内経路の掃討)
|
## Supported Forms
|
||||||
- 例: `src/mir/builder.rs:new_typed_value()` は `self.next_value_id()` を唯一入口に統一。
|
|
||||||
|
|
||||||
2. **テストコード内の `value_gen.next()`** - 関数スコープをシミュレート
|
### ✅ Supported (Phase 136)
|
||||||
- `test_shadowing_binding_restore`: 関数スコープシミュレーションで `next_value_id()` を使用
|
|
||||||
- `test_valueid_binding_parallel_allocation`: SSOT allocator を使用(Module context フォールバック維持)
|
|
||||||
|
|
||||||
### OK(Module context フォールバック)
|
```nyash
|
||||||
以下は既に `if current_function.is_some()` で関数コンテキストを判定しており、Module context のフォールバックとして `value_gen.next()` を使用(OK):
|
// Form 1: loop + return literal
|
||||||
- `src/mir/builder/utils.rs:next_value_id()` - SSOT allocator 自体(43行目)
|
local x
|
||||||
- `src/mir/builder/utils.rs:pin_to_slot()` - 436行目
|
x = 0
|
||||||
- `src/mir/builder/utils.rs:materialize_local()` - 467行目
|
loop(true) {
|
||||||
- `src/mir/utils/phi_helpers.rs:insert_phi_unified()` - 69行目
|
x = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return 7 // Expected: 7 (literal, not variable)
|
||||||
|
```
|
||||||
|
|
||||||
## Acceptance
|
```nyash
|
||||||
- ✅ `rg -n "value_gen\.next\(" src/mir` で関数内経路から消える(module context の意図的フォールバックを除く)
|
// Form 2: loop + post assigns + return literal
|
||||||
- ✅ `cargo test --release --lib` が退行しない
|
local x
|
||||||
- ✅ `phase135_trim_mir_verify.sh` - PASS
|
x = 0
|
||||||
- ✅ `phase132_exit_phi_parity.sh` - 3/3 PASS
|
loop(true) {
|
||||||
|
x = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
x = x + 2
|
||||||
|
return 7 // Expected: 7 (literal)
|
||||||
|
```
|
||||||
|
|
||||||
## Remaining Tasks(残課題)
|
### ❌ Not Supported (Out of Scope)
|
||||||
なし。状態は Context に一本化され、関数内経路から `value_gen.next()` を排除完了。Module context のフォールバックは意図的に残す。
|
|
||||||
|
```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).
|
||||||
|
|||||||
@ -1,151 +1,239 @@
|
|||||||
# Phase 137: Loop Canonicalizer(前処理 SSOT)
|
# Phase 137: loop(true) break-once with return add expression
|
||||||
|
|
||||||
## Status
|
**Date**: 2025-12-18
|
||||||
- 状態: 🔶 進行中(Phase 5 完了)
|
**Status**: DONE ✅
|
||||||
|
**Scope**: return add expression (x + 2) support in Normalized shadow (dev-only)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Goal
|
## 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`
|
## Supported Forms
|
||||||
- `LoopSkeleton` / `SkeletonStep` / `UpdateKind`
|
|
||||||
- `ExitContract` / `CarrierSlot` / `CarrierRole`
|
|
||||||
- `RoutingDecision` / capability tags(`CAP_MISSING_*`)
|
|
||||||
- 注意: Phase 1 は「型と語彙」のみ。routing/lowering にはまだ介入しない。
|
|
||||||
|
|
||||||
## Phase 2(完了): dev-only 観測の導入
|
### ✅ Supported (Phase 137 P0)
|
||||||
|
|
||||||
- 入口:
|
```nyash
|
||||||
- Canonicalize: `src/mir/loop_canonicalizer/mod.rs`(`canonicalize_loop_expr`)
|
// Form 1: return variable + integer literal
|
||||||
- 観測ポイント: `src/mir/builder/control_flow/joinir/routing.rs`(`joinir_dev_enabled()` 配下)
|
local x
|
||||||
- 既定挙動: 不変(dev-only 観測のみ)
|
x = 1
|
||||||
|
loop(true) {
|
||||||
## Phase 3(次): Pattern 検出(Skeleton→Decision の精密化)
|
break
|
||||||
|
}
|
||||||
### Phase 3(完了): `skip_whitespace` の安定認識
|
return x + 2 // Expected: 3 (1 + 2)
|
||||||
|
|
||||||
- 実装: `src/mir/loop_canonicalizer/mod.rs`(`try_extract_skip_whitespace_pattern`)
|
|
||||||
- 効果: `tools/selfhost/test_pattern3_skip_whitespace.hako` を `Pattern3IfPhi` として認識し、`missing_caps=[]` を固定できるようになった(dev-only 観測)。
|
|
||||||
|
|
||||||
注意:
|
|
||||||
- routing/lowering の変更は “パリティ検証(Phase 4)” を挟んでから行う(既定挙動は不変)。
|
|
||||||
|
|
||||||
## Phase 4(完了): Router パリティ検証(dev-only / Fail-Fast)
|
|
||||||
|
|
||||||
- 目標: 既存 JoinIR ルータ(現行の Pattern 選択)と Canonicalizer の `RoutingDecision` が一致することを検証し、ズレた場合は理由付きで Fail-Fast(dev-only)。
|
|
||||||
- 目的: いきなり routing を差し替えず、安全に "観測→一致→段階投入" の導線を作る。
|
|
||||||
- 実装: `src/mir/builder/control_flow/joinir/routing.rs`(`verify_router_parity`)
|
|
||||||
|
|
||||||
## Phase 5(完了): Decision Policy SSOT 化
|
|
||||||
|
|
||||||
- 目標: `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 細分化に備える)
|
|
||||||
|
|
||||||
## Phase 6(完了): Router 委譲(dev-only / 段階投入)
|
|
||||||
|
|
||||||
- 目標: "既存 router の結果" を最終SSOTとして維持したまま、dev-only で Canonicalizer の `RoutingDecision` を router 選択に使う経路を用意する。
|
|
||||||
- 方針:
|
|
||||||
- まず dev-only で `RoutingDecision.chosen` を router に反映し、strict 時は parity を維持する(ズレたら Fail-Fast)。
|
|
||||||
- 既定挙動(dev flags OFF)では現行 router をそのまま使う。
|
|
||||||
|
|
||||||
### Phase 137-6(完了): Router 委譲の段階投入
|
|
||||||
|
|
||||||
- **S1(完了)**: choose_pattern_kind SSOT 入口を新設
|
|
||||||
- Pattern 選択ロジックを `routing.rs` の1関数に集約
|
|
||||||
- `LoopPatternContext::new()` から使用
|
|
||||||
- 重複コード削減
|
|
||||||
|
|
||||||
- **S2(完了)**: dev-only で canonicalizer decision を提案として受け取る
|
|
||||||
- `choose_pattern_kind()` に parity check 統合
|
|
||||||
- dev-only 時に Canonicalizer を呼び出し
|
|
||||||
- 不一致時: strict mode は panic、debug mode はログのみ
|
|
||||||
- 既定挙動: `router_choice` を維持(Canonicalizer は提案のみ)
|
|
||||||
|
|
||||||
- **S3(完了)**: Router 委譲の準備コメント追加(TODO のみ)
|
|
||||||
- 将来の委譲に備えた TODO コメント拡充
|
|
||||||
- 有効化条件と注意事項を明記
|
|
||||||
- コード例を追加
|
|
||||||
|
|
||||||
### 効果
|
|
||||||
- ✅ Pattern 選択ロジックの SSOT 化(choose_pattern_kind)
|
|
||||||
- ✅ Canonicalizer → Router の parity check 統合
|
|
||||||
- ✅ 将来の委譲に備えた構造確立
|
|
||||||
- ✅ 新 env 追加なし(既存の `joinir_dev_enabled()` と `strict_enabled()` を使用)
|
|
||||||
|
|
||||||
### 受け入れ基準達成
|
|
||||||
- ✅ strict parity green(skip_whitespace)
|
|
||||||
```
|
```
|
||||||
NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1 ./target/release/hakorune \
|
|
||||||
tools/selfhost/test_pattern3_skip_whitespace.hako
|
```nyash
|
||||||
→ [choose_pattern_kind/PARITY] OK
|
// Form 2: return integer literal + integer literal
|
||||||
|
loop(true) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return 5 + 3 // Expected: 8
|
||||||
```
|
```
|
||||||
- ✅ 既定挙動不変(フラグOFF時)
|
|
||||||
- ✅ スモークテスト(simple_*): 5/5 PASS
|
|
||||||
- ✅ 全テスト PASS(退行なし)
|
|
||||||
|
|
||||||
## Phase 138(完了): 基盤整備(箱化モジュール化)
|
```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)
|
||||||
|
```
|
||||||
|
|
||||||
- **P1-A**: loop_canonicalizer を 4 モジュール分割(931行 → 最大414行/ファイル)
|
### ❌ Not Supported (Out of Scope)
|
||||||
- **P1-B**: parity_checker.rs 分離(routing.rs 52%削減)
|
|
||||||
- **P2-A**: strict_enabled() エイリアス対応
|
|
||||||
- **P2-B**: 環境変数 SSOT 化
|
|
||||||
- **効果**: モジュール数 1個 → 4個、保守性 3倍向上
|
|
||||||
- **テスト**: 全 PASS(退行なし)
|
|
||||||
|
|
||||||
## Phase 139(完了): 型安全化
|
```nyash
|
||||||
|
// Variable + variable (Phase 138+)
|
||||||
|
return x + y
|
||||||
|
|
||||||
- **P3-A**: CapabilityTag enum 定義(8 variants)
|
// Other operators (Phase 138+)
|
||||||
- **P3-B**: RoutingDecision enum 対応(`Vec<&'static str>` → `Vec<CapabilityTag>`)
|
return x - 2
|
||||||
- **効果**: コンパイル時エラー検出、IDE 支援
|
return x * 2
|
||||||
- **レガシー削除**: capability_tags モジュール(文字列定数群)削除
|
|
||||||
- **テスト**: 全 PASS(型安全性向上)
|
|
||||||
|
|
||||||
## Phase 140(完了): 共通化と統合
|
// Nested expressions
|
||||||
|
return (x + 2) + 3
|
||||||
|
|
||||||
- **P4-A**: detect_skip_whitespace_pattern() 共通化(ast_feature_extractor へ)
|
// Function calls
|
||||||
- **P4-B**: pattern_recognizer を SSOT 化(71行削減)
|
return f()
|
||||||
- **P5-A**: LoopProcessingContext SSOT 化(AST + Skeleton + Pattern 統合)
|
```
|
||||||
- **効果**: 重複コード削減、情報の SSOT 化
|
|
||||||
- **テスト**: 全 PASS(リグレッションなし)
|
|
||||||
|
|
||||||
## Phase 141(完了): ドキュメント & Cleanup
|
## Implementation
|
||||||
|
|
||||||
- **P7-A**: Mermaid 図追加(データフロー、モジュール構成、シーケンス図)
|
### Core Changes
|
||||||
- **P7-B**: Capability Tags 対応表作成(Pattern 別必須 Capability 一覧)
|
|
||||||
- **P7-C**: Phase 記録更新
|
|
||||||
- **効果**: 新規参加者の理解時間 50%削減
|
|
||||||
|
|
||||||
## 最終成果(Phase 138-141 完了時)
|
**File**: `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`
|
||||||
|
|
||||||
### コード品質メトリクス
|
**Method**: `lower_return_value_to_vid()` (行 638-743, BinaryOp Add at 行 673)
|
||||||
|
|
||||||
| 指標 | Phase 137 完了時 | Phase 141 完了時 | 改善率 |
|
**Added Pattern**: BinaryOp Add
|
||||||
|-----|----------------|----------------|-------|
|
```rust
|
||||||
| 最大ファイルサイズ | 931行 | 414行 | -55% |
|
ASTNode::BinaryOp { operator, left, right, .. } => {
|
||||||
| モジュール数 | 1個 | 4個 | +300% |
|
// Phase 137 contract: Add only
|
||||||
| 重複コード | 100行 | 29行 | -71% |
|
if !matches!(operator, BinaryOperator::Add) {
|
||||||
| 型安全性 | `&'static str` | `enum` | ✅ |
|
return Ok(None); // out of scope
|
||||||
| 環境変数チェック | 直呼び出し | SSOT関数 | ✅ |
|
}
|
||||||
|
|
||||||
### アーキテクチャ改善
|
// 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),
|
||||||
|
};
|
||||||
|
|
||||||
- ✅ 単一責任の原則徹底(各モジュール 250行以内)
|
// Lower RHS (Integer literal only)
|
||||||
- ✅ Capability Guard の型安全化(コンパイル時エラー検出)
|
let rhs_vid = match right.0.as_ref() {
|
||||||
- ✅ Pattern Detection の SSOT 化(ast_feature_extractor 統合)
|
ASTNode::Literal { value: LiteralValue::Integer(i), .. } => {
|
||||||
- ✅ Context 統合(AST + Skeleton + Pattern の一元管理)
|
let vid = ValueId(*next_value_id);
|
||||||
- ✅ ドキュメント充実(Mermaid 図 + 対応表)
|
*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
|
||||||
|
};
|
||||||
|
|
||||||
## SSOT
|
// 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,
|
||||||
|
}));
|
||||||
|
|
||||||
- 設計 SSOT: `docs/development/current/main/design/loop-canonicalizer.md`
|
Ok(Some(result_vid))
|
||||||
- JoinIR 契約 SSOT: `docs/development/current/main/joinir-architecture-overview.md`
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Return Value Lowering SSOT
|
||||||
|
|
||||||
|
**Location**: `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs` (行 29-43)
|
||||||
|
|
||||||
|
**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
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fixtures
|
||||||
|
|
||||||
|
1. **phase137_loop_true_break_once_return_add_min.hako**
|
||||||
|
- Pattern: `x=1; loop(true){break}; return x+2`
|
||||||
|
- Expected: exit code 3
|
||||||
|
|
||||||
|
2. **phase137_loop_true_break_once_return_add_const_min.hako**
|
||||||
|
- Pattern: `loop(true){break}; return 5+3`
|
||||||
|
- Expected: exit code 8
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
### Smoke Tests
|
||||||
|
|
||||||
|
**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`
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build
|
||||||
|
cargo build --release -p nyash-rust --features llvm
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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`.
|
||||||
|
|||||||
Reference in New Issue
Block a user