Commit Graph

35 Commits

Author SHA1 Message Date
a2c5fd90fe feat(joinir): Phase 188.3 - Pattern6 (NestedLoopMinimal) 選択ロジック実装
## Phase 188.3 進捗: Phase 2 完了 (6/13 tasks)

### 実装完了 

**Phase 1: Fixture作成**
- apps/tests/phase1883_nested_minimal.hako 追加
  - Add/Compare のみ(乗算なし)
  - 期待 exit code: 9 (3×3 nested loops)
- 既存 lowering で fallback 動作確認

**Phase 2: 選択ロジック (SSOT)**
- LoopPatternContext に step_tree_max_loop_depth フィールド追加
- choose_pattern_kind() に Pattern6 選択ロジック実装:
  1. Cheap check (has_inner_loop)
  2. StepTree 構築 (max_loop_depth 取得)
  3. AST validation (is_pattern6_lowerable)
- pattern6_nested_minimal.rs モジュール作成 (stub)
- LOOP_PATTERNS に Pattern6 entry 追加
- **検証**: Pattern6 が正しく選択される 

### 設計原則 (確認済み)

1. **Fail-Fast**: Pattern6 選択後は Ok(None) で逃げない
2. **outer 変数 write-back 検出 → validation false** (Phase 188.4+)
3. **最小実装**: inner local だけ、Pattern1 モデル二重化
4. **cfg! 依存なし**: production で動作

### 検証結果

```
[choose_pattern_kind] has_inner_loop=true
[choose_pattern_kind] max_loop_depth=2
[choose_pattern_kind] is_pattern6_lowerable=true
 Pattern6 SELECTED!
```

Stub からの期待エラー:
```
[ERROR]  [Pattern6] Nested loop lowering not yet implemented
```

### 次: Phase 3 (Lowering 実装 - 推定4時間)

残りタスク:
- Phase 3-1: AST 抽出ヘルパー
- Phase 3-2: Validation ヘルパー
- Phase 3-3: Continuation 生成 (outer_step, inner_step, k_inner_exit)
- Phase 3-4: fixture が exit=9 を返すことを検証

### 変更ファイル

**新規**:
- apps/tests/phase1883_nested_minimal.hako
- src/mir/builder/control_flow/joinir/patterns/pattern6_nested_minimal.rs
- docs/development/current/main/phases/phase-188.{1,2,3}/README.md

**変更**:
- src/mir/builder/control_flow/joinir/routing.rs (Pattern6 選択)
- src/mir/builder/control_flow/joinir/patterns/router.rs (Context 拡張)
- src/mir/builder/control_flow/joinir/patterns/mod.rs (module 宣言)

🎯 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 05:45:12 +09:00
7a575e30cc refactor(joinir): Phase 286 P3.2 cleanup + normalizer modularization
## Legacy Pattern5 削除 (488行)
- pattern5_infinite_early_exit.rs 完全削除
- LOOP_PATTERNS テーブルからエントリ削除
- Plan extractor が SSOT

## Normalizer 分割 (3294行 → 12ファイル)
- helpers.rs: 共通ヘルパー関数
- pattern*.rs: 各パターン専用ファイル
- mod.rs: ディスパッチャ

## ドキュメント更新
- Phase 286 README: クリーンアップ完了・Fail-Fast方針記載
- Phase 287 README: 将来計画

quick smoke 154/154 PASS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 10:30:08 +09:00
22945c190c feat(joinir): Phase 286 P3.2 - Pattern5 Plan line (loop(true) + early exit)
- Pattern5InfiniteEarlyExitPlan (Return/Break variants)
- extract_pattern5_plan() for loop(true) literal only
- normalize_pattern5_return(): 5 blocks CFG (header→body→found/step)
- normalize_pattern5_break(): 6 blocks CFG with carrier PHI
- NormalizationPlanBox exclusion for Pattern5-style loops
- Fixtures: phase286_pattern5_{return,break}_min.hako
- quick smoke 154/154 PASS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 09:56:34 +09:00
b235a5b6db feat(joinir): Phase 286 P3.1 - Pattern2 Plan line 完走(after_bb PHI)
Pattern2(Loop with Break)を Plan/Frag SSOT へ移行。

主な変更:
- Pattern2BreakPlan 追加(DomainPlan variant)
- extract_pattern2_plan() 実装(PoC サブセット厳守)
- normalize_pattern2_break() 実装(6-block CFG, 3 PHI)
- after_bb PHI が本質: carrier_out = PHI(header: carrier_current, break_then: carrier_break)
- router に Pattern2 追加(Pattern1 より前、より具体的)

テスト:
- Fixture B (break without update): PASS (出力 11)
- quick smoke: 154/154 PASS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 05:56:30 +09:00
0fca2df5be feat(joinir): Phase 286 P2.6.1 - Pattern3 Plan 完走(normalizer 実装 + Fail-Fast 統一)
## 変更内容

### Router Fail-Fast 統一
- Pattern3 stub fallback 特例を撤去
- extract 成功 → normalize/lower 失敗は即 Err(他パターンと統一)

### normalize_pattern3_if_phi() 実装
- CFG 構造: 8 blocks (preheader, header, body, then, else, merge, step, after)
- PHI 構成: 3本(header×2 + merge×1)
  - Header: loop_var_current, carrier_current
  - Merge: carrier_next (if-else 合流)
- Frag: BranchStub×2 + EdgeStub×4(Pattern1 流儀の直接構築)

### 発見・修正
- lowerer は body_bb の block_effects を無視して loop_plan.body を emit
- body_bb effects は CorePlan::Effect(...) として loop_plan.body に配置

## テスト結果
- Phase 118 smoke: PASS (出力 12)
- quick: 154/154 PASS
- Plan line 完走確認: route=plan ... Pattern3_IfPhi MATCHED

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:39:36 +09:00
4d17e3d812 feat(joinir): Phase 286 P2.6 - Pattern3 Plan 基盤 + Pattern1 退行修正
## Pattern1 退行修正(構造的 Fail-Fast)
- Router に pattern_kind ガード追加(ctx.pattern_kind != Pattern1SimpleWhile → skip)
- has_if_else_statement() ヘルパー追加(再帰版、ScopeBox/Loop 内もチェック)
- Pattern1 extractor に if-else 拒否追加

## Pattern3 Plan 基盤
- DomainPlan: Pattern3IfPhiPlan 構造体追加
- Extractor: extract_pattern3_plan() 追加
- Normalizer: normalize_pattern3_if_phi() スタブ追加(レガシー JoinIR へフォールバック)
- Router: PLAN_EXTRACTORS に Pattern3 追加

## テスト結果
- quick 154 PASS
- Phase 118 smoke PASS(出力 12、退行解消)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:01:11 +09:00
21daf1b7dd refactor(joinir): Phase 286 コード品質改善 - ヘルパー共通化 + static box フィルタ
## 1. lower_*_ast ヘルパー共通化
- `lower_value_ast()` に MethodCall 対応追加
- Pattern8 normalizer も共有ヘルパーを使用
- Pattern1/8/9 で一貫した lowering ロジック

## 2. PLAN_EXTRACTORS ドキュメント追加
- `WithPostLoop` variant: 将来拡張用として残存理由を明記
- 現在は常に `&[]` を渡すが、post-loop segment analysis 用に保持

## 3. Legacy Pattern8 残存 + static box フィルタ
- Plan extractor は pure 関数(builder にアクセス不可)
- router 側で static box フィルタリングを実装
- static box コンテキストは legacy Pattern8 へ fallback
- legacy 残存理由をドキュメント化

## 検証
- Quick: 154 PASS, 0 FAILED
- Pattern8 integration: exit 7

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 03:35:02 +09:00
832d018046 feat(joinir): Phase 286 P2.4.1 - Pattern8 normalizer 実装 + Fail-Fast 化
## 概要
Pattern8 (BoolPredicateScan) を Plan line で完走させる。
stub normalizer を完全実装に置き換え、legacy fallback を禁止。

## Step 0: Fixture 簡約
- `?:` ternary → `if/else` に変更(PoC 安定化)

## Step 1: Router Fail-Fast 化
- 文字列判定 `e.contains("[normalizer/pattern8]")` を削除
- extract が Some → normalize/lower 失敗は即 Err(fallback 禁止)
- extract が None → 次の extractor へ(legacy 含む)

## Step 2: Pattern8 normalizer 実装
- CFG: preheader → header(PHI) → body → found/step → after
- found: return false(早期脱出)
- after: return true(ループ完走)
- compose::cleanup() で 2 つの Return exit をマージ

## 検証結果
- Integration: exit 7 
- Plan 完走: route=plan strategy=extract pattern=Pattern8 MATCHED
- Regression: quick 154 PASS, 0 FAILED

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 03:17:48 +09:00
064cae169e feat(joinir): Phase 286 P2.4 - Pattern8 BoolPredicateScan Plan化 PoC
## 概要
Pattern8 (BoolPredicateScan) を Plan extraction routing に追加。
static box 除外(Phase 269 決定)を尊重し、非 static box fixture で PoC。

## 実装内容
- Pattern8BoolPredicateScanPlan struct + DomainPlan variant
- extract_pattern8_plan(): 条件・predicate check・increment 抽出
- normalize_pattern8_bool_predicate_scan(): PoC stub(CoreExitPlan::Return 未統合)
- PLAN_EXTRACTORS テーブルに Pattern8 追加(3rd priority)
- エラーフォールバック: Plan normalization 失敗時 → legacy Pattern8 へ

## 動作フロー
Plan extraction MATCHED → normalization failed (PoC stub) → legacy Pattern8 MATCHED

## 検証結果
- Integration: phase286_pattern8_plan_poc_vm PASS (exit 7)
- Regression: quick 154 PASS, 0 FAILED

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 03:01:11 +09:00
1d24e9a106 feat(joinir): Phase 286 P2.3 + Phase 287 - Pattern9 Plan化 + Router table-driven
## Phase 286 P2.3: Pattern9 AccumConstLoop Plan化 PoC

- DomainPlan::Pattern9AccumConstLoop 追加
- PlanNormalizer::normalize_pattern9_accum_const_loop() 実装
  - PHI 2本(loop_var, acc_var)
  - const/var 両方 OK(sum = sum + 1 または sum = sum + i)
- Pattern9 は Pattern1 より優先(より具体的なパターン)
- Integration test: phase286_pattern9_frag_poc PASS (return: 3)
- Regression: quick 154 PASS

## Phase 287: Router table-driven Plan extraction

- PLAN_EXTRACTORS static table で Pattern6/7/4/9/1 を統一管理
- PlanExtractorEntry/PlanExtractorVariant 構造体追加
- try_plan_extractors() で ~100行 → 3行に集約
- メンテナンス性向上(新 Pattern 追加はテーブル1行追加のみ)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 02:38:09 +09:00
a824346e30 feat(joinir): Phase 286 P2/P2.1/P2.2 - JoinIR Line Absorption (Pattern1/4 Plan化 PoC + hygiene)
Phase 286 P2: Pattern4 (Loop with Continue) を Plan/Frag SSOT に移行
- DomainPlan::Pattern4Continue 追加
- PlanNormalizer::normalize_pattern4_continue() 実装(phi_bindings による PHI dst 優先参照)
- Router integration(Plan line routing → legacy fallback)
- Integration test PASS (output: 6), quick smoke 154/154 PASS

Phase 286 P2.1: Pattern1 (SimpleWhile) を Plan/Frag SSOT に移行
- DomainPlan::Pattern1SimpleWhile 追加
- PlanNormalizer::normalize_pattern1_simple_while() 実装(4ブロック、1 PHI、phi_bindings 流用)
- Router integration(Plan line routing → legacy fallback)
- Integration test PASS (return: 3), quick smoke 154/154 PASS

Phase 286 P2.2: hygiene(extractor重複排除 + router小整理)
- extractor helper化: extract_loop_increment_plan を common_helpers.rs に統一
  - Pattern1/Pattern4 が呼ぶだけに変更(重複排除 ~25行)
- router helper化: lower_via_plan() を追加し Pattern6/7/4/1 で共用
  - 3行パターン(normalize→verify→lower)を1関数に集約(ボイラープレート削減 ~40行)

成果物:
- DomainPlan 2パターン新規追加(Pattern1SimpleWhile, Pattern4Continue)
- Normalizer 2つの normalize 関数追加
- Router に Plan line ブロック追加 + lower_via_plan() helper
- Extractor に extract_pattern1_plan() 追加
- Integration fixtures 2個 + smoke tests 2個

検証:
- quick smoke: 154/154 PASS
- integration: phase286_pattern1_frag_poc PASS, phase286_pattern4_frag_poc PASS
- Plan line routing: route=plan strategy=extract で Pattern1/4 検出確認

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-26 02:03:22 +09:00
41d92bedb9 refactor(extractors): Phase 282 P9a - CommonExtractionHelpers SSOT統合(スコープ限定版)
# Phase 282 P9a 完了 (Scope-Limited Integration)

## 実装内容
- **common_helpers.rs 作成**: 4グループの共通ヘルパー統合 (316行)
  - Group 1: Control Flow Counting (count_control_flow - 汎用カウンター)
  - Group 2: Control Flow Detection (has_break/continue/return_statement)
  - Group 3: Condition Validation (extract_loop_variable, is_true_literal)
  - Group 4: Pattern5専用ヘルパー (validate_continue_at_end, validate_break_in_simple_if)

- **Pattern統合完了**: Pattern5 → Pattern4 → Pattern2 → Pattern1
  - Pattern5: ~90行削減 (5 tests PASS)
  - Pattern4: ~66行削減 (5 tests PASS)
  - Pattern2: ~67行削減 (4 tests PASS)
  - Pattern1: ~28行削減 (3 tests PASS)
  - Pattern3: 別フェーズに延期(pattern固有ロジック除外)

## 成果
- **コード削減**: ~251行(Pattern3除く、total ~400行見込み)
- **テスト**: 40 unit tests PASS (23 common_helpers + 17 extractors)
- **スモークテスト**: 45 PASS, 1 pre-existing FAIL(退行ゼロ)
- **ビルド警告**: 130 → 120 (-10)

## USER CORRECTIONS適用済み
1.  スコープ限定(共通ロジックのみ、pattern固有除外)
2.  Placeholder禁止(SSOT違反排除)
3.  統合順序変更(Pattern3を最後/別フェーズへ)

## 追加ドキュメント
- Phase 284 計画追加(Return as ExitKind SSOT)
- 10-Now.md, 30-Backlog.md 更新

🎯 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 11:14:28 +09:00
a2be79b875 docs(router): Phase 282 P2 - Comment archaeology + TODO cleanup
Step 2: Router comment updates
- Update Phase references (183, 273, 282 retained)
- Document ExtractionBased status (Pattern8/9 already done)
- Remove obsolete Phase references (187, 193, 195)

Step 3: TODO cleanup
- pattern5: Remove completed TODO (lowering fully implemented)
- pattern_pipeline: Clarify loop_update_summary status (reserved)
- apply_policy: Mark current_static_box_name as low-priority refactor

Step 4: Pattern3 legacy references
- Simplify module docstring (remove legacy mode details)
- Update inline comments (legacy removal Phase 242-EX-A)

Changes: Comment/docstring only (zero behavior change)
Test: cargo build --release (0 errors)
2025-12-23 05:35:42 +09:00
519e58a977 docs(router): Phase 282 P0+P1 - Router shrinkage SSOT + entrypoint logging
P0: Documentation SSOT (~80 lines added)
- Router Responsibilities SSOT (DOES/DOESN'T split)
- Ok(None)/Err boundary rules (Fail-Fast principle)
- Entrypoint table (Plan/JoinIR/None, 収束先明記)
- Pattern番号 = 症状ラベル定義(最小記述)

P1: Minimal Code (~10 lines)
- 4 trace statements modified (router.rs)
- Entrypoint-based logging (route=plan/joinir/none)
- Pattern names preserved (backward compatible)
- No new environment variables (既存trace機構のみ)

Test Results:
- quick profile: 45 PASS / 1 FAIL (既知failure)
- Pattern6 VM: PASS (phase258_p0_index_of_string_vm.sh)
- Pattern6 LLVM: PASS (phase258_p0_index_of_string_llvm_exe.sh)
- Zero regression 

Phase 282 Goal Achieved:
- Router shrinkage complete (SSOT positioning clear)
- Pattern numbers → symptom labels transition documented
- CFG construction converges to emit_frag() SSOT
2025-12-23 05:03:25 +09:00
6f1d0df187 docs(plan): Phase 273 P4 - Plan Line SSOT Documentation Finalization
Phase 273 P4 では、Plan ライン(Extractor → Normalizer → Verifier → Lowerer)を
"current operational SSOT" として文書化し、アーキテクチャの収束を明文化した。

## Changes

### router.rs docstring 更新
- "Phase 273 P3: Plan Line is Current SSOT for Pattern6/7" セクション追加
- ルーティング戦略を明示(Plan entry points → legacy table)
- SSOT Entry Points を列挙(Pattern6/7 Normalizer, Pattern1-5 各 Lowerer)

### phase-273/README.md 更新
- P3 completion section 追加(generalized CoreLoopPlan 移行完了)
- P3+ Legacy Removal section 追加(~174 lines 削除記録)
- P4 Proposal section 追加(Documentation Finalization チェックリスト)
- SSOT Documentation Entry Points リスト追加(5 つの SSOT 入口)

### joinir-architecture-overview.md 更新
- Section 2.1.2 "Plan-Based Patterns (Pattern6-7, Phase 273 P3)" 追加
- Plan Extractor, Normalizer, Verifier, Lowerer の Box 構造を文書化
- Plan line vs JoinIR line 比較表追加(収束性・SSOT 特性の対比)
- SSOT characteristics リスト追加(Normalizer SSOT, emit_frag SSOT 等)

## SSOT Entry Points(Phase 273 P3 完了時点)

1. **ルーティング**: `router.rs::route_loop_pattern()` - Pattern6/7 Plan entry points
2. **型定義**: `plan/mod.rs` - DomainPlan/CorePlan 固定語彙
3. **正規化**: `plan/normalizer.rs` - Pattern 固有知識一元管理
4. **検証**: `plan/verifier.rs` - fail-fast 不変条件(V2-V9)
5. **降格**: `plan/lowerer.rs` - Pattern-agnostic MIR emission

## Test

-  VM regression: phase254_p0_index_of_vm.sh (PASS)
-  LLVM regression: phase258_p0_index_of_string_llvm_exe.sh (PASS)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 00:34:38 +09:00
e4b5a8e832 feat(plan): Phase 273 P2 Step 3-6 - Pattern7 (SplitScan) to Plan line
Migrate Pattern7 from legacy lowering to Plan architecture:

DomainPlan (mod.rs):
- Added SplitScan(SplitScanPlan) variant
- SplitScanPlan: s_var, sep_var, result_var, i_var, start_var

Extractor (pattern7_split_scan.rs):
- extract_split_scan_plan() returning DomainPlan
- Reuses existing extract_split_scan_parts()

Router (router.rs):
- Pattern7 now uses Plan line (Normalize→Verify→Lower)
- Removed from LOOP_PATTERNS table

Normalizer (normalizer.rs):
- normalize_split_scan() - 400+ lines migrated from impl
- 6 blocks: preheader/header/body/then/else/step/after
- 4 PHIs: header(2) + step(2) for i/start carriers
- Side effect: push with EffectMask::MUT

Bug fixes:
- Pattern6 extractor returns Ok(None) for non-match (allows fallback)
- Reverse scan filtered early in extractor (P1 scope)

Tests:
- phase256_p0_split_vm: PASS (exit=3)
- phase258_p0_index_of_string_vm: PASS (exit=6)

Lowerer no longer contains "split" - pattern-agnostic achieved!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 23:35:43 +09:00
960241795d feat(mir/llvm): Phase 273 P0-P1 DomainPlan→CorePlan + LLVM arg fix
Phase 273 P0-P1: Two-layer plan architecture
- DomainPlan: Pattern-specific knowledge (ScanWithInit)
- CorePlan: Fixed vocabulary (Seq, Loop, If, Effect, Exit)
- ValueId references only (String expressions forbidden)
- Pipeline: Extractor→Normalizer→Verifier→Lowerer

New plan/ module:
- mod.rs: Type definitions, SSOT spec
- normalizer.rs: DomainPlan→CorePlan + ID allocation
- verifier.rs: V1-V6 invariant checks (fail-fast)
- lowerer.rs: CorePlan→MIR (pattern-agnostic)

LLVM fix (ChatGPT):
- function_lower.py: Fix argument reference bug
- Phase 258 index_of_string now PASS on LLVM backend

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 22:42:56 +09:00
757193891f feat(llvm/phi): Phase 277 P1 - fail-fast validation for PHI strict mode
## Summary
Implemented fail-fast validation for PHI ordering and value resolution in strict mode.

## Changes

### P1-1: Strict mode for "PHI after terminator"
- File: `src/llvm_py/phi_wiring/wiring.py::ensure_phi`
- Behavior: `NYASH_LLVM_PHI_STRICT=1` → RuntimeError if PHI created after terminator
- Default: Warning only (no regression)

### P1-2: Strict mode for "fallback 0"
- File: `src/llvm_py/phi_wiring/wiring.py::wire_incomings`
- Behavior: Strict mode forbids silent fallback to 0 (2 locations)
  - Location 1: Unresolvable incoming value
  - Location 2: Type coercion failure
- Error messages point to next debug file: `llvm_builder.py::_value_at_end_i64`

### P1-3: Connect verify_phi_ordering() to execution path
- File: `src/llvm_py/builders/function_lower.py`
- Behavior: Verify PHI ordering after all instructions emitted
- Debug mode: Shows " All N blocks have correct PHI ordering"
- Strict mode: Raises RuntimeError with block list if violations found

## Testing
 Test 1: strict=OFF - passes without errors
 Test 2: strict=ON - passes without errors (no violations in test fixtures)
 Test 3: debug mode - verify_phi_ordering() connected and running

## Scope
- LLVM harness (Python) changes only
- No new environment variables (uses existing 3 from Phase 277 P2)
- No JoinIR/Rust changes (root fix is Phase 279)
- Default behavior unchanged (strict mode opt-in)

## Next Steps
- Phase 278: Remove deprecated env var support
- Phase 279: Root fix - unify "2本のコンパイラ" pipelines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 14:48:37 +09:00
df715e909e feat(edgecfg): Phase 268-270 savepoint (if_form adoption + Pattern9 minimal loop SSOT) 2025-12-21 23:12:52 +09:00
a767f0f3a9 feat(joinir): Phase 259 P0 - Pattern8 BoolPredicateScan + Copy binding fix
Pattern8 (Boolean Predicate Scan) implementation for is_integer/1:
- New pattern detection for `loop + if not predicate() { return false }`
- JoinIR lowerer with main/loop_step/k_exit structure
- Me receiver passed as param (by-name 禁止)

Key fixes:
1. expr_result = Some(join_exit_value) (Pattern7 style)
2. Tail-call: dst: None (no extra Ret instruction)
3. instruction_rewriter: Add `&& is_loop_header_with_phi` check
   - Pattern8 has no carriers → no PHIs → MUST generate Copy bindings
   - Without this, ValueId(103/104/105) were undefined

Status: Copy instructions now generated correctly, but exit block
creation issue remains (next step: Step A-C in指示書).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 02:40:07 +09:00
64f679354a fix(joinir): Phase 256 P1 - Carrier PHI wiring and parameter mapping (in progress)
**Status**: Core carrier PHI issue partially resolved, debugging loop body

**Progress**:
 Task 1: split_scan_minimal.rs Carriers-First ordering (6 locations)
 Task 2: pattern7_split_scan.rs boundary configuration (host/join inputs, exit_bindings, expr_result)
 Result now flows from k_exit to post-loop code (RC issue resolved)
⚠️  Loop body instruction execution needs review

**Key Fixes**:
1. Fixed host_inputs/join_inputs to match main() params Carriers-First order
2. Added result to exit_bindings (CarrierRole::LoopState)
3. Added result back to loop_invariants for variable initialization
4. Added expr_result=join_exit_value_result for loop expression return
5. Fixed jump args to k_exit to include all 4 params [i, start, result, s]

**Current Issue**:
- Loop body type errors resolved (String vs Integer fixed)
- New issue: Loop body computations (sep_len) undefined in certain blocks
- Likely cause: JoinIR→MIR conversion of local variables needs review

**Next Steps**:
- Review JoinValueSpace allocation and ValueId mapping in conversion
- Verify loop_step instruction ordering and block structure
- May need to refactor bound computation or revisit split algorithm

🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-20 01:24:04 +09:00
2d9c6ea3c6 feat(joinir): Phase 254-255 - Pattern 6 (ScanWithInit) + exit PHI DCE fix
## Phase 254: Pattern 6 (ScanWithInit) Detection & JoinIR Lowering

Pattern 6 detects index_of/find/contains-style loops:
- Loop condition: i < x.length()
- Loop body: if with method call condition + early return
- Step: i = i + 1
- Post-loop: return not-found value (-1)

Key features:
- Minimal lowering: main/loop_step/k_exit functions
- substring hoisted to init-time BoxCall
- Two k_exit jumps (found: i, not found: -1)
- Tests: phase254_p0_index_of_min.hako

## Phase 255 P0: Multi-param Loop CarrierInfo

Implemented CarrierInfo architecture for Pattern 6's 3-variable loop (s, ch, i):
- i: LoopState (header PHI + exit PHI)
- s, ch: ConditionOnly (header PHI only)
- Alphabetical ordering for determinism
- All 3 PHI nodes created correctly
- Eliminates "undefined ValueId" errors

## Phase 255 P1: Exit PHI DCE Fix

Prevents exit PHI from being deleted by DCE:
- PostLoopEarlyReturnStepBox emits post-loop guard
- if (i != -1) { return i } forces exit PHI usage
- Proven pattern from Pattern 2 (balanced_depth_scan)
- VM/LLVM backends working

## Test Results

 pattern254_p0_index_of_vm.sh: PASS (exit code 1)
 pattern254_p0_index_of_llvm_exe.sh: PASS (mock)
 Quick profile: json_lint_vm PASS (progresses past index_of)
 Pattern 1-5: No regressions

## Files Added

- src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs
- src/mir/join_ir/lowering/scan_with_init_minimal.rs
- apps/tests/phase254_p0_index_of_min.hako
- docs/development/current/main/phases/phase-254/README.md
- docs/development/current/main/phases/phase-255/README.md

🧠 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:32:25 +09:00
51017a0f9a feat(joinir): Phase 92 P0-2 - Skeleton to LoopPatternContext (Option A)
SSOT principle: Pass canonicalizer-derived ConditionalStep info to Pattern2 lowerer
without re-detecting from AST.

Changes:
- router.rs: Add skeleton: Option<&'a LoopSkeleton> to LoopPatternContext
- parity_checker.rs: Return (Result, Option<LoopSkeleton>) to reuse skeleton
- routing.rs: Pass skeleton to context when joinir_dev_enabled()
- pattern2_with_break.rs: Detect ConditionalStep in can_lower()

Next: P0-3 implements actual JoinIR generation for ConditionalStep.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 15:22:29 +09:00
fc4c343d88 refactor(mir): Phase 137-6-S1 - choose_pattern_kind SSOT入口を新設
## 目的
Pattern 選択ロジックを SSOT 化し、将来の Canonicalizer 委譲に備える

## 変更内容

### 新規関数: `choose_pattern_kind()`
- 場所: `src/mir/builder/control_flow/joinir/routing.rs`
- 責務: Pattern 選択の SSOT 入口
- 実装: 既存の LoopFeatures ベース選択ロジックを集約

### LoopPatternContext の更新
- `new()` で `choose_pattern_kind()` を使用
- 既存の分散した選択ロジックを SSOT に統一

## 効果
-  Pattern 選択ロジックの SSOT 化(1箇所に集約)
-  将来の Canonicalizer 委譲に備えた構造確立
-  既定挙動完全不変(既存テスト全て PASS)

## テスト結果
-  `cargo build --release`: 成功
-  スモークテスト(simple_*): 5/5 PASS
-  退行なし

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 07:37:23 +09:00
18d56d5b88 refactor(joinir): Box-First cleanup - trace unification + SSOT + Fail-Fast
## Changes

### 1. eprintln! to trace.rs unification
**File**: src/mir/builder/control_flow/joinir/routing.rs
- Replaced direct eprintln! with trace::trace().routing()
- Box-First principle: Log responsibility centralized in trace.rs
- Enables filtering via HAKO_JOINIR_DEBUG=1

### 2. Priority field removal (SSOT)
**File**: src/mir/builder/control_flow/joinir/patterns/router.rs
- Removed #[allow(dead_code)] priority field
- Array order is SSOT (Single Source of Truth) for pattern priority
- Pattern try order: Pattern5 → Pattern4 → Pattern3 → Pattern1 → Pattern2
- Eliminated dead code warning

### 3. catch_unwind removal (Fail-Fast)
**File**: src/mir/builder/control_flow/joinir/routing_legacy_binding.rs
- Removed catch_unwind + Ok(None) silent error swallowing
- Fail-Fast principle: Panics propagate explicitly
- Enables early detection of panic sources

## Verification

 Build: cargo build --release (0 errors)
 Tests: 71 JoinIR tests all PASS
 VM: /tmp/p1_return_i.hako → Result: 3
 LLVM: /tmp/p1_return_i.hako → Mock exit code: 0

## Design Principles Applied

- **Box-First**: Log responsibility → trace.rs
- **SSOT**: Array order defines priority (no redundant field)
- **Fail-Fast**: Explicit failures, no silent error swallowing

## Statistics

- 3 files changed
- 53 deletions, 28 insertions
- Net: -25 lines (code reduction)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 03:27:47 +09:00
233a49d902 feat(joinir): Phase 131-11 A-C - InfiniteEarlyExit パターン追加(検出部分)
## Step A: Feature Detection
- LoopPatternKind::InfiniteEarlyExit (Pattern 5) 追加
- LoopFeatures::is_infinite_loop フィールド追加
- detect_infinite_loop() で loop(true) 検出

## Step B: Classification Logic
- classify() を更新: Pattern 5 を Pattern 4 より優先
- Pattern 4 を狭化: has_continue && !has_break のみ
- 誤ルーティング完全除去

## Step C: Pattern Module
- pattern5_infinite_early_exit.rs 新規作成
- Fail-Fast 設計: 超狭い shape guard
- lowering はスケルトン(Phase 131-11-D で実装)

## 動作確認
- Pattern 5 正常検出 
- Shape guards 動作(1 break, 1 continue, 1 carrier)
- Pattern 4 誤ルーティング回避 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 09:59:34 +09:00
59a985b7fa joinir: clean pattern visibility and refactor pattern2 pipeline 2025-12-11 19:11:26 +09:00
d7805e5974 feat(joinir): Phase 213-2 Step 2-2 & 2-3 Data structure extensions
Extended PatternPipelineContext and CarrierUpdateInfo for Pattern 3 AST-based generalization.

Changes:
1. PatternPipelineContext:
   - Added loop_condition: Option<ASTNode>
   - Added loop_body: Option<Vec<ASTNode>>
   - Added loop_update_summary: Option<LoopUpdateSummary>
   - Updated build_pattern_context() for Pattern 3

2. CarrierUpdateInfo:
   - Added then_expr: Option<ASTNode>
   - Added else_expr: Option<ASTNode>
   - Updated analyze_loop_updates() with None defaults

Status: Phase 213-2 Steps 2-2 & 2-3 complete
Next: Create Pattern3IfAnalyzer to extract if statement and populate update summary
2025-12-10 00:01:53 +09:00
32a91e31ac feat(joinir): Phase 200-B/C/D capture analysis + Phase 201-A reserved_value_ids infra
Phase 200-B: FunctionScopeCaptureAnalyzer implementation
- analyze_captured_vars_v2() with structural loop matching
- CapturedEnv for immutable function-scope variables
- ParamRole::Condition for condition-only variables

Phase 200-C: ConditionEnvBuilder extension
- build_with_captures() integrates CapturedEnv into ConditionEnv
- fn_body propagation through LoopPatternContext to Pattern 2

Phase 200-D: E2E verification
- capture detection working for base, limit, n etc.
- Test files: phase200d_capture_minimal.hako, phase200d_capture_in_condition.hako

Phase 201-A: MirBuilder reserved_value_ids infrastructure
- reserved_value_ids: HashSet<ValueId> field in MirBuilder
- next_value_id() skips reserved IDs
- merge/mod.rs sets/clears reserved IDs around JoinIR merge

Phase 201: JoinValueSpace design document
- Param/Local/PHI disjoint regions design
- API: alloc_param(), alloc_local(), reserve_phi()
- Migration plan for Pattern 1-4 lowerers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:32:03 +09:00
3ece6896c4 refactor(joinir): Phase 183-1 Unify pattern detection in loop_pattern_detection
Consolidates duplicate pattern detection logic across two routing layers.

## Changes

1. **Unified Detection Documentation**:
   - Added Phase 183 comments to `loop_pattern_detection::classify()`
   - Documented that this is the single source of truth for pattern classification
   - Both routers now reference this centralized function

2. **Router Documentation Updates**:
   - `patterns/router.rs`: Added Phase 183 comments explaining structure-based routing
   - `loop_pattern_router.rs`: Added unified detection section
   - Both routers now explicitly reference shared detection logic

3. **Improved Debug Output**:
   - Added `pattern_kind` to debug message in `route_loop_pattern()`
   - Helps diagnose pattern matching failures

## Benefits

- **Single source of truth**: Pattern classification logic in one place
- **Consistency**: Both routers use same detection algorithm
- **Maintainability**: Changes to classification rules only needed once
- **Documentation**: Clear references between routers and detection module

## Testing

 All loop_pattern_detection tests pass
 Pattern 2 tests pass
 No behavioral changes, pure documentation/organization refactoring

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 22:17:06 +09:00
95f3aa429e refactor(joinir): Extract legacy binding path to routing_legacy_binding.rs
Phase 179-A Step 2: Separate LoopFrontendBinding JSON construction logic
into dedicated module for better organization.

Changes:
- New file: routing_legacy_binding.rs (223 lines)
- routing.rs: cf_loop_joinir_impl() simplified to 15 lines (delegates to legacy path)
- Routing now clearly separates pattern-based vs. legacy binding paths

Benefits:
- Clear separation of concerns (pattern router vs. legacy whitelist)
- routing.rs reduced from 364 to 146 lines (60% reduction)
- Legacy path isolated for future deprecation
2025-12-08 18:36:13 +09:00
d28ba4cd9d refactor(joinir): Phase 193-1 - AST Feature Extractor Box modularization
**Phase 193-1**: Create independent AST Feature Extractor Box module

## Summary
Extracted feature detection logic from router.rs into a new, reusable
ast_feature_extractor.rs module. This improves:
- **Modularity**: Feature extraction is now a pure, side-effect-free module
- **Reusability**: Can be used for Pattern 5-6 detection and analysis tools
- **Testability**: Pure functions can be unit tested independently
- **Maintainability**: Clear separation of concerns (router does dispatch, extractor does analysis)

## Changes

### New Files
- **src/mir/builder/control_flow/joinir/patterns/ast_feature_extractor.rs** (+180 lines)
  - `detect_continue_in_body()`: Detect continue statements
  - `detect_break_in_body()`: Detect break statements
  - `extract_features()`: Full feature extraction pipeline
  - `detect_if_else_phi_in_body()`: Pattern detection for if-else PHI
  - `count_carriers_in_body()`: Heuristic carrier counting
  - Unit tests for basic functionality

### Modified Files
- **src/mir/builder/control_flow/joinir/patterns/router.rs**
  - Removed 75 lines of feature detection code
  - Now delegates to `ast_features::` module
  - Phase 193 documentation in comments
  - Cleaner separation of concerns

- **src/mir/builder/control_flow/joinir/patterns/mod.rs**
  - Added module declaration for ast_feature_extractor
  - Updated documentation with Phase 193 info

## Architecture
```
router.rs (10 lines)
  └─→ ast_feature_extractor.rs (180 lines)
      - Pure functions for AST analysis
      - No side effects
      - High reusability
      - Testable in isolation
```

## Testing
 Build succeeds: `cargo build --release` compiles cleanly
 Binary compatibility: Existing .hako files execute correctly
 No logic changes: Feature detection identical to previous implementation

## Metrics
- Lines moved from router to new module: 75
- New module total: 180 lines (including tests and documentation)
- Router.rs reduced by ~40% in feature detection code
- New module rated  for reusability and independence

## Next Steps
- Phase 193-2: CarrierInfo Builder Enhancement
- Phase 193-3: Pattern Classification Improvement
- Phase 194: Further pattern detection optimizations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 03:30:03 +09:00
a21501286e feat(joinir): Structural pattern detection + Pattern 4 scaffold
- Add LoopFeatures struct for structure-based detection (no name deps)
- Add LoopPatternKind enum and classify() function
- Pattern 3: has_if_else_phi && !has_break && !has_continue
- Pattern 4: has_continue == true (detection only, lowering TODO)
- Unify router to use extract_features()/classify() instead of legacy
- Remove AST dependency, use LoopForm/LoopScope only
- Add Pattern 4 test file (loop_continue_pattern4.hako)
- Pattern 3 test passes (sum=9)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 00:10:27 +09:00
abfe0b198b feat(joinir): Phase 195 - Unified JoinLoopTrace for all JoinIR debug output
Created centralized tracing module for JoinIR loop lowering operations,
consolidating scattered eprintln! calls into a single SSOT interface.

# Implementation

1. **Created trace.rs module** (~233 lines)
   - JoinLoopTrace struct with env var controls
   - Unified API: pattern(), varmap(), joinir_stats(), phi(), merge(), etc.
   - Global singleton via trace() function
   - Supports 5 env vars: NYASH_TRACE_VARMAP, NYASH_JOINIR_DEBUG,
     NYASH_OPTION_C_DEBUG, NYASH_JOINIR_MAINLINE_DEBUG, NYASH_LOOPFORM_DEBUG

2. **Updated debug.rs** - Delegates trace_varmap() to JoinLoopTrace

3. **Updated routing.rs** - All eprintln! replaced with trace calls (10 instances)

4. **Updated pattern routers** - All 3 patterns now use unified trace
   - pattern1_minimal.rs: 6 replacements
   - pattern2_with_break.rs: 6 replacements
   - pattern3_with_if_phi.rs: 6 replacements
   - router.rs: 2 replacements

5. **Updated merge/block_allocator.rs** - 6 eprintln! → trace calls

# Benefits

- **Single Source of Truth**: All trace control through environment variables
- **Consistent Format**: Unified [trace:*] prefix for easy filtering
- **Zero Overhead**: No output when env vars unset
- **Easy Extension**: Add new trace points via existing API
- **Better Debug Experience**: Structured output with clear categories

# Testing

 cargo build --release - Success
 NYASH_TRACE_VARMAP=1 - Shows varmap traces only
 NYASH_JOINIR_DEBUG=1 - Shows joinir + blocks + routing traces
 No env vars - No debug output
 apps/tests/loop_min_while.hako - All tests pass

# Related

- Phase 191-194 groundwork (modular merge structure)
- NYASH_TRACE_VARMAP added today for variable_map debugging
- Consolidates ~80 scattered eprintln! calls across JoinIR

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:23:51 +09:00
67e2bfada4 feat(joinir): Phase 194 - Table-driven loop pattern router
Replace if/else chain with table-driven pattern dispatch for easier
pattern addition and maintenance.

# Changes

## New Files
- router.rs (137 lines): Pattern router table and dispatch logic
  - LoopPatternContext: Context passed to detect/lower functions
  - LoopPatternEntry: Pattern registration structure
  - LOOP_PATTERNS: Static table with 3 registered patterns
  - route_loop_pattern(): Single dispatch function

## Modified Files
- patterns/mod.rs (+8 lines): Export router module
- pattern1_minimal.rs (+19 lines): Added can_lower() + lower() wrapper
- pattern2_with_break.rs (+17 lines): Added can_lower() + lower() wrapper
- pattern3_with_if_phi.rs (+22 lines): Added can_lower() + lower() wrapper
- routing.rs (-21 lines): Replaced if/else chain with router call

# Architecture Improvement

## Before (if/else chain)
```rust
if func_name == "main" && has_sum {
    return pattern3(...);
} else if func_name == "main" {
    return pattern1(...);
} else if func_name == "JoinIrMin.main/0" {
    return pattern2(...);
}
```

## After (table-driven)
```rust
let ctx = LoopPatternContext::new(...);
route_loop_pattern(self, &ctx)?
```

# Adding New Patterns (Now Trivial!)

1. Create pattern4_your_name.rs
2. Implement can_lower() + lower()
3. Add entry to LOOP_PATTERNS table

That's it! No routing logic changes needed.

# Testing

 Pattern 1 (loop_min_while.hako): PASSED
 Pattern 2 (joinir_min_loop.hako): PASSED
 Pattern 3 (loop_if_phi.hako): Routes correctly (VM error is pre-existing)

Router logging verified:
```
NYASH_TRACE_VARMAP=1 ./target/release/hakorune apps/tests/*.hako
[route] Pattern 'Pattern1_Minimal' matched for function 'main'
[route] Pattern 'Pattern2_WithBreak' matched for function 'JoinIrMin.main/0'
[route] Pattern 'Pattern3_WithIfPhi' matched for function 'main'
```

# Line Counts

- router.rs: 137 lines (new)
- Total pattern files: 491 lines (3 patterns)
- routing.rs: Reduced by 21 lines (-6%)
- Net addition: +137 lines (infrastructure investment)

# Documentation

See router.rs header for:
- Architecture overview
- How to add new patterns
- Priority ordering (Pattern3=30, Pattern1=10, Pattern2=20)

Phase 194 complete - pattern addition is now a trivial task!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 22:11:39 +09:00