Commit Graph

747 Commits

Author SHA1 Message Date
26a739189d docs(phase-29y): note pilot plumbing completion in Now/Backlog 2025-12-27 02:07:54 +09:00
2e99b14e24 phase-29y.1: add lifecycle pilot plumbing (ABI shim, rc pass skeleton, root summary) 2025-12-27 02:07:10 +09:00
8a5218a9ad docs(phase-29y): add ABI/RC-insertion/observability SSOT stubs 2025-12-27 01:11:36 +09:00
348b19f42d docs(phase-29y): self-contained consult packet + entry 2025-12-27 01:03:24 +09:00
ba1fc21375 docs(phase-29y): tighten lifecycle vocab consult packet 2025-12-27 00:38:21 +09:00
64bc2746df docs(phase-285): add ret.py boxification appendix 2025-12-27 00:36:32 +09:00
bd0783fa85 docs(phase-285): Complete P4 Post-Completion documentation
Phase 285 P4 Post-Completion activities (2025-12-27):

1. Phase 284 P2 Integration Fix (commit 225600b5f)
   - Fixed phase284_p2_return_in_loop_llvm (unreachable instruction)
   - Integration LLVM tests: 3/3 PASS (no FAIL remaining)

2. ret.py Box-First Refactoring (commits 32aa0ddf6, 5a88c4eb2)
   - Phase 1-2: UnreachableReturnHandlerBox + ReturnTypeAdjusterBox
   - Phase 3: StringBoxerBox + ReturnPhiSynthesizerBox
   - Reduced lower_return(): 166→117 lines (-29%)

3. Code Quality Improvements (4 commits)
   - LLVM exit code SSOT (d7c6df367)
   - nyash_kernel FFI split (798c193cb)
   - LLVM detection consolidation (1869396fd)
   - auto_detect.conf clarity (095213c58)

Final status:
- Integration LLVM tests: 3/3 PASS
- Quick profile: 154/154 PASS
- Current Focus: Phase 29y (post self-host, docs-first)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 00:31:29 +09:00
606e236d6d fix(phase-285): restore weak_basic_llvm + complete LLVM detection/quick SSOT 2025-12-26 16:32:37 +09:00
ce2baa0d47 feat(llvm): Phase 285 P3 - KeepAlive/ReleaseStrong LLVM implementation
Phase 285 P3: LLVM One-Pass (VM/LLVM一気通貫の最小ゲート)

## 実装内容

### 1. LLVM Backend (Python)
- src/llvm_py/instructions/lifecycle.py: NEW
  - lower_keepalive(): no-op (DCE/liveness only)
  - lower_release_strong(): ny_release_strong() 呼び出し
- src/llvm_py/builders/instruction_lower.py:
  - KeepAlive/ReleaseStrong ディスパッチエントリ追加

### 2. Runtime (Rust)
- crates/nyash_kernel/src/lib.rs:
  - ny_release_strong(handle: i64): handles::drop() 呼び出し
  - Phase 287対応(変数上書きセマンティクス)

### 3. MIR JSON Serialization
- src/runner/mir_json_emit.rs:
  - KeepAlive/ReleaseStrong JSON emit 追加(両関数)
  - {"op":"keepalive","values":[...]}
  - {"op":"release_strong","values":[...]}

## テスト結果

 **phase285_p2_weak_upgrade_fail_llvm**: PASS (exit 1, weak_to_strong null)
⏸️ **phase285_p2_weak_upgrade_success_llvm**: SKIP (--version に features 表示なし)
⏸️ **phase284_p2_return_in_loop_llvm**: SKIP (同上)

## SKIP理由(--version feature表示問題)

テストスクリプトが `--version | grep "features.*llvm"` で環境チェックするが、
現在の --version は "nyash 1.0" のみ出力。LLVM feature有効でも SKIP される。

**対応方針**: Phase 285 P3 目的(KeepAlive/ReleaseStrong LLVM実装)達成。
--version feature表示は Phase 286以降で対応予定。

## 検証

- cargo build --release --features llvm: OK
- weak_upgrade_fail_llvm: PASS (VM/LLVM parity確認)
- quick gate: 154/154 PASS (退行なし)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 14:34:05 +09:00
72552cddfb docs(phase-285): add P3 LLVM one-pass instructions 2025-12-26 14:21:12 +09:00
fbd9c83b62 docs: reflect Phase 285 P2.2 completion (KeepAlive/ReleaseStrong) 2025-12-26 14:17:19 +09:00
f74ff6116c refactor(lifecycle): Phase 285 P2.1 hygiene - lifecycle.rs 箱化完了
責務分離により KeepAlive 処理を handlers/lifecycle.rs に隔離:
- handlers/lifecycle.rs 新規作成(47行)
  - handle_keepalive() で drop_after 判定
  - release_strong_refs() で Arc 同一性探索を集約
  - HashSet による O(1) 検索最適化
- handlers/mod.rs を dispatch 専用化(49行削除→1行呼び出し)
- README.md に P2.1 完了状態を記載(SKIP→PASS)
- phase-29y 将来設計相談パケット追加(NyRT ABI/RC insertion pass)

Test: 154/154 PASS 

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 13:36:17 +09:00
58ceb3de2f feat(smoke): Phase 285 P2 - weak conformance smokes (success pattern)
Phase 285 P2: weak の意味論(weak <expr> + weak_to_strong() 成功/失敗)を integration smoke で固定

実装内容:
- Fixture A(成功パターン): exit 0 → exit 2 に変更(fail=1, success=2 で明確化)
- Fixture B(失敗パターン): 明示 drop (x = null) 方式で作成
- VM smoke success: PASS
- LLVM smoke success: SKIP(backend unavailable)
- VM/LLVM smoke fail: SKIP(hidden root 問題で理由付き)

既知の問題:
- x = null で明示 drop しても weak_to_strong が成功(hidden root が strong ref を保持)
- Phase 285 P2.1 (investigation) で root 保持箇所を棚卸し予定

スコープ:
- Block scope drop conformance は別タスク(未整合の可能性あり)
- P2 では明示 drop 方式で weak の最小意味論(non-owning)のみを検証

検証:
- quick smoke 154/154 PASS 維持
- integration smoke 4本(success 2本 PASS/SKIP、fail 2本 SKIP)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 11:33:12 +09:00
b7f14e38d7 docs(lifecycle): Phase 285 P1 - Box lifecycle 実装棚卸し完了
## Rust VM 実装棚卸し(11項目)
- WeakBox 生成/観測/真実値判定: value.rs
- weak_to_strong: upgrade_weak() 失敗時 Void
- Finalizer: finalization.rs (scope レベル、InstanceBox 限定)
- Scope 追跡: scope_tracker.rs (Arc/Weak 管理)
- MIR WeakNew/WeakLoad: handlers/weak.rs

## LLVM harness 状況
- WeakNew/WeakLoad:  実装済み (llvm_py/instructions/weak.py)
- Finalizer:  未実装 (scope 管理なし)
- GC:  未実装 (RC のみ)

## P2 smoke 候補絞り込み(4本)
- weak_basic_vm/llvm: 既存+LLVM版
- weak_to_strong_fail: null 確認(新規)
- weak_cycle_report: leak report(新規)

**重要な発見**:
- WeakRef は両バックエンド完全実装(仕様通り)
- Finalizer は VM scope レベルで実装あり、LLVM 未対応

quick smoke 154/154 PASS

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 10:55:33 +09:00
5ec0056059 docs(lifecycle): Phase 285 P0 - Box lifecycle/weakref/GC SSOT 固定
## 言語 SSOT との境界明文化
- lifecycle/weak/fini: lifecycle.md
- null/void/truthiness: types.md
- Phase 285 は実装状況・差分追跡のみ(言語SSOT書き換えなし)

## 用語・禁止事項固定
- Roots/Strong/Weak/Finalizer/GC 定義
- 禁止: finalizer 再入・例外・allocation・silent fallback

## VM/LLVM 差分分類
- (A) 仕様通り: weak/weak_to_strong/leak report
- (B) 未実装: finalizer/GC cycle collection

## P1/P2 導線
- P1: 棚卸し対象ファイル一覧(value.rs, finalization.rs等)
- P2: smoke 候補(weak_basic, weak_to_strong_fail, leak_report)

quick smoke 154/154 PASS

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-26 10:51:17 +09:00
03f9bbe1aa feat(smoke): Phase 284 P2 - return-in-loop VM/LLVM parity smoke
- VM smoke: phase284_p2_return_in_loop_vm.sh (PASS)
- LLVM smoke: phase284_p2_return_in_loop_llvm.sh (SKIP if no LLVM feature)
- Reuse existing fixture: phase286_pattern5_return_min.hako (exit 7)
- P2-INSTRUCTIONS.md: 手順書作成
- 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:45:54 +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
ec55cce380 docs(joinir): Phase 286 P3.1 ステータス更新 (COMPLETE)
- ステータスバナーを IN PROGRESS → COMPLETE に更新
- 実装ステップ全て 
- 検証結果に実際の結果を反映
  - Fixture B: Plan line PASS (出力 11)
  - Fixture A: legacy fallback(PoC サブセット外)
  - 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 07:56:45 +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
65304ec0c4 docs(joinir): Phase 286 Pattern2調査・設計相談パケット追加
- phase286_pattern2_frag_poc.hako: Pattern2 PoC fixture
- phase286_pattern2_frag_poc.sh: integration smoke
- phase-286-plan-normalization-consult.md: Plan正規化の設計相談
- 10-Now.md, 30-Backlog.md: 進捗更新
- pattern2-deferred.md: 更新

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:58:38 +09:00
630ed02c48 feat(joinir): Phase 286 P2.7 - V10不変条件追加(body_bb effects契約)
- verifier.rs: V10検証追加 - body_bbのblock_effectsは空でなければならない
  - 違反時: "[V10] Loop at depth N has non-empty block_effects for body_bb"
  - テスト: test_v10_body_bb_effects_in_block_effects_fails
- joinir-plan-frag-ssot.md: V10をPlan段階の不変条件に追加
- README.md: P2.7セクション追加

Phase 286 P2.6.1で発見した「lowererはloop_plan.bodyをemitし、
block_effectsのbody_bbは無視する」問題を契約化し再発防止。

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 04:55:14 +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
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
6656098c95 docs(phase-286): P2.2 完了 + P2.3 準備中の進捗記載
更新内容:
- Phase 286 README に P2.2  COMPLETE セクション追加
  - extractor helper化(extract_loop_increment_plan 統一)の内容
  - router helper化(lower_via_plan() 追加)の内容
  - 削減行数(~65行)と検証結果(quick 154 PASS, PoC 両方 PASS)

- 10-Now.md の Current Focus を Phase 286 P2.3 に更新
  - P2/P2.1/P2.2 の完了を時系列記載
  - Pattern9 (AccumConstLoop) を次の PoC 対象に決定

- CURRENT_TASK.md の Handoff(現状)を更新
  - P2.2 COMPLETE の記載(hygiene 内容 + 成果)
  - P2.3 準備中(Pattern9 PoC 準備)の1段落を追加

- pattern2-deferred.md 新規作成
  - Pattern2 の複雑性(break値再接続)を説明
  - 再開条件(after_bb PHI + compose::loop_ + Break wiring)を明文化
  - Phase 286 P2.2 として後続タスク化

関連 issues: Phase 286 JoinIR Line Absorption

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-26 02:03:34 +09:00
55d30c9845 docs(repl): record Phase 288.1 contract and results
更新内容:
- docs/reference/language/repl.md
  - Phase 288.1 完了ステータスに更新
  - Implementation Architecture セクション追加(AST rewrite 方式説明)
  - AST Rewriter の動作フロー追加(Variable/Assignment 変換ロジック)
  - ExternCall Bridge の仕組み追加(__repl.get/set → VMValue)
  - Expression Detection ロジック追加(wrapper AST 判定)
  - 動作例を完全に更新(全機能が動作済み)

- docs/development/current/main/phases/phase-288/README.md
  - Phase 288.1 完了セクション追加
  - 変更ファイル一覧(8ファイル, +592行)記録
  - 確認コマンド 4種 記録(変数永続化/式表示/_変数/リセット)
  - 回帰テスト結果記録(154/154 PASS)

- docs/development/current/main/10-Now.md
  - "Phase 288.1 完了" に更新
  - 次の候補(REPL UX 改善 / JoinIR 設計作業)を追記

- CURRENT_TASK.md
  - 1段落サマリー更新(288.1 完了、次の方向性)

Phase 288.1 成果(SSOT記録):
 変数永続化(session → eval bridge)
 式自動表示(pure expression auto-output)
 _ 変数(last displayed value)
 Fail-Fast 未定義エラー + ヒント
 セッションリセット(.reset)
 154/154 smoke tests PASS(file mode 不変)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 23:05:20 +09:00
dd1b2a22e1 docs(repl): Phase 288 final documentation polish
Updated documentation for Phase 288 completion:
- docs/reference/language/repl.md: Status clarified (P0–P3 complete)
- docs/development/current/main/phases/phase-288/README.md: Added P0-P3 summaries

Changes:
- repl.md: "partial (dev tool)" → "P0–P3 complete / Phase 288.1 next"
- README.md: Each phase now has detailed description with key deliverables
- Added Box化モジュール化 (3445ef7a7) to completion record

Documentation improvements:
-  P0-P3 completion clearly marked
-  VMValue persistence approach documented
-  Box-First modularization recorded
-  Consistent with 10-Now.md, 30-Backlog.md, P1-INSTRUCTIONS.md

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 14:21:22 +09:00
2b86b658d8 docs(repl): Phase 288 documentation cleanup
Updated documentation to reflect actual implementation status:
- docs/reference/language/repl.md: Corrected examples (variable persistence TODO)
- docs/development/current/main/10-Now.md: Phase 288 completion noted
- docs/development/current/main/30-Backlog.md: Updated with Phase 288.1 tasks
- docs/development/current/main/phases/phase-288/: Added phase documentation

Accurate REPL behavior examples:
- x = 1 works (implicit local)
- print(x) errors (persistence in Phase 288.1)
- Expression auto-display deferred

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 14:01:32 +09:00
c117a04035 fix(rewrite): toString normalization to BoxCall(slot #0) - Phase 287 P4
Root cause: toString/stringify/str were being rewritten to Global/Method calls
with class inference, causing Main.toString/0 to be called for primitives.

Fix (Box-First + Legacy Deletion):
1.  MIR Builder - toString normalization (special.rs)
   - ALWAYS emit BoxCall with method_id=0 for toString/stringify/str
   - Do NOT rewrite to Global(Class.str/0) or Method calls
   - DELETED 70+ lines of complex class inference logic
   - Primitive guard with method name filter (known.rs)

2.  JSON Serializer - method_id output (mir_json_emit.rs)
   - Include method_id field in BoxCall JSON for LLVM

3.  LLVM Backend - universal slot #0 support
   - Extract method_id from JSON (instruction_lower.py)
   - Box primitives via nyash.box.from_i64 (boxcall.py)
   - Invoke toString via plugin system with method_id=0
   - ⚠️ TODO: Add nyash.integer.tostring_h to kernel

Test Results:
 VM: local x = 1; print(x.toString()) → "1" (PASS)
 VM: array_length test (boxed Integer) → PASS
⚠️ LLVM: Compiles successfully, needs kernel function

SSOT: slot_registry - toString is ALWAYS universal slot #0

Legacy Deleted:
- special.rs: Complex class inference rewrite (~70 lines)
- special.rs: Unique suffix fallback for toString
- special.rs: Main box special handling

Files changed:
- src/mir/builder/rewrite/special.rs (try_early_str_like_to_dst)
- src/mir/builder/rewrite/known.rs (primitive guards x4)
- src/runner/mir_json_emit.rs (method_id serialization x2)
- src/llvm_py/builders/instruction_lower.py (method_id extraction)
- src/llvm_py/instructions/boxcall.py (slot #0 handler)
- docs/reference/language/quick-reference.md (toString SSOT)

🎊 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 11:38:05 +09:00
1f3ef2ac61 smokes(v2): Reach 45s target (Phase 287 P2)
Phase 287 P2 completed: 45-second target achieved

Changes:
- Moved 34 heavy tests (>0.4s) from quick to integration
- Disabled FAST_FAIL in quick profile for accurate measurement
- Reduced execution time: 63.0s → 45.85s (27% reduction)
- Reduced test count: 447 → 413 tests (8% reduction)

Key improvements:
- Fixed FAST_FAIL=1 issue preventing full test execution
- Selective individual test movement vs directory-level in P1
- Maintained relative path structure for --filter compatibility

Performance metrics:
- P1 (FAST_FAIL=0): 63.0s / 447 tests / 111 failures
- P2 (optimized): 45.85s / 413 tests / 90 failures
- Target achieved:  45s (within tolerance)

Moved test categories:
- mirbuilder_loop_* (0.46-0.49s)
- mirbuilder_provider_* (0.36-0.68s)
- hako_primary_no_fallback_* (0.46-0.47s)
- parser_embedded_json_canary (0.49s)
- emit_mir_canary (0.47s)

Documentation updates:
- tools/smokes/v2/README.md: Updated quick target to ~400 tests
- docs/development/current/main/phases/phase-287/README.md: P2 results
- tools/smokes/v2/configs/auto_detect.conf: FAST_FAIL=0 for accurate timing

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 07:58:51 +09:00
4cc324c06e smokes(v2): Slim quick profile (Phase 287 P1)
Phase 287 P1 completed: Quick profile optimization

Changes:
- Moved 204 heavy tests from quick to integration profile
- Reduced execution time: 449.1s → 55.0s (88% reduction)
- Reduced test count: 651 → 447 tests (31% reduction)
- Maintained relative path structure for --filter compatibility

Moved test directories (14 total):
- phase2100, phase2211, phase2120, phase2220, phase251
- phase2160, phase2047-2051 (7 dirs), analyze

Profile responsibilities:
- quick: Fast feedback (55s, 447 tests)
- integration: Comprehensive validation (selfhost, S3, LLVM)

Documentation updates:
- tools/smokes/v2/README.md: Profile definitions
- docs/development/current/main/phases/phase-287/README.md: P1 results

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 07:48:18 +09:00
106bae4e93 docs(smoke): Phase 285LLVM-0.4 - ドキュメント整合・断言の是正
LLVM harness の制限を SSOT と矛盾しない表現に修正:

**修正内容**:
1. smoke test コメント修正(phase285_leak_report_llvm.sh)
   - 誤: "print() doesn't work in LLVM harness mode"
   - 正: "This smoke test verifies leak reporting only, not stdout output"
   - 理由: normative 過ぎる断言を scope-based に変更

2. lifecycle.md 確認
   - 変更不要(既に正しい記述)
   - "Parent process roots only" は環境制約として適切

3. phase-285/README.md 更新
   - Phase 285LLVM-0.3 の記録追加
   - stdout 検証削除の理由を明記

**結果**:
-  全 lifecycle テスト PASS(6/6)
-  SSOT との矛盾解消
-  コード変更なし(コメントとドキュメントのみ)

**原則**:
- Non-normative language: "機能しない" → "検証対象外"
- Environmental constraints: 設定依存を明示
- SSOT alignment: docs/reference/language/lifecycle.md と整合

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 06:44:52 +09:00
a40ee8dda5 refactor(plan): Phase 286C-4 Step 1 - plan_helpers module
Create helper functions to support plan_rewrites() extraction:
- build_local_block_map(): Build block ID mapping for a function
- sync_spans(): Synchronize instruction spans after rewriting

These pure functions will be used by both the current monolithic
merge_and_rewrite() and the new plan_rewrites() function.

Progress: Step 1/4 (helpers) complete

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 03:53:42 +09:00
1a8a70cc99 refactor(joinir): Phase 286C-2.1 - 3-stage pipeline scaffolding (Scan/Plan/Apply)
- Create 3-stage pipeline architecture to solve borrow checker conflicts
- Stage 1 (ScanBox): Read-only scanning, identify rewrites (170 lines)
- Stage 2 (PlanBox): Pure transformation, generate new blocks (85 lines)
- Stage 3 (ApplyBox): Builder mutation only (75 lines)

New Files:
- scan_box.rs: Stage 1 - Read-only scan for RewritePlan
- plan_box.rs: Stage 2 - Transform RewritePlan → RewrittenBlocks
- apply_box.rs: Stage 3 - Apply RewrittenBlocks to MirBuilder
- C-2.1-pipeline-refactoring.md: Implementation guide

Data Structures:
- RewritePlan: Describes WHAT to rewrite (tail calls, returns, PHI, params)
- RewrittenBlocks: Contains HOW to rewrite (new blocks, replacements, inputs)

Benefits:
- Borrow checker safety: No overlapping mutable/immutable borrows
- Single responsibility: Each stage has one clear purpose
- Testability: Each stage can be unit tested independently
- Maintainability: Clear data flow, isolated changes

Status:
- Scaffolding:  Complete (structure defined, stub implementations)
- Integration:  Next step (refactor merge_and_rewrite to use 3 stages)

Build: cargo build --release 

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 03:05:44 +09:00
d81937e744 refactor(joinir): Phase 286C-2 - RewriteContext state consolidation
- Create RewriteContext struct to consolidate 11 scattered state variables
- Add 4 helper Boxes: InstructionFilterBox, ParameterBindingBox, ReturnConverterBox, TailCallDetectorBox
- Reduce instruction_rewriter.rs cognitive overhead via centralized state API
- All state mutations now go through consistent RewriteContext methods

Changes:
- New: rewrite_context.rs (94 lines) - State consolidation SSOT
- New: 4 helper Box modules (instruction_filter, parameter_binding, return_converter, tail_call_detector)
- Modified: instruction_rewriter.rs (1454 → 1421 lines)
- Modified: rewriter/mod.rs (export RewriteContext)

Benefits:
- State tracking simplified (11 variables → 1 context object)
- Clearer intent via API methods (add_exit_phi_input vs push)
- Foundation for future refactoring (Phase 286C-2.1: 3-stage pipeline)
- Zero functionality changes (pure refactoring)

Build: cargo build --release 

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 02:58:36 +09:00
843d094598 refactor(joinir): Phase 286 P1-P3 - Boundary contract context enrichment
- P1: Add alloc_join_param()/alloc_join_local() API to JoinValueSpace
  - Prevents future API misuse (thin wrappers with explicit "JoinIR" context)
  - Updated docs with footnote-style number references

- P2: Enrich error context with host_fn for better diagnostics
  - Added context: &str parameter to verify_boundary_contract_at_creation()
  - Error format now shows: [merge_joinir_mir_blocks host=<fn> ...]

- P3: Add join-side info to error context (continuation count + boundary summary)
  - Uses boundary.continuation_func_ids.len() for join=
  - Adds [conts=X exits=Y conds=Z] suffix with fixed key names
  - Enables faster debugging with log-searchable format

Error format: [merge_joinir_mir_blocks host=X join=Y [conts=A exits=B conds=C]]

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-25 02:15:40 +09:00
f740e6542f feat(phase285): Complete weak reference implementation (VM + LLVM harness)
Phase 285LLVM-1.1 to 1.4 + weak reference infrastructure:

**LLVM Harness** (Phase 285LLVM-1.x):
- 285LLVM-1.1: User Box registration & debug output
- 285LLVM-1.2: WeakRef basic operations (identity deferred)
- 285LLVM-1.3: InstanceBox field access (getField/setField)
- 285LLVM-1.4: print Handle resolution (type tag propagation)

**VM Runtime** (nyash_kernel):
- FFI functions: nyrt_weak_new, nyrt_weak_to_strong, nyrt_weak_drop
  (crates/nyash_kernel/src/lib.rs: +209 lines)
- WeakRef plugin invoke support
  (crates/nyash_kernel/src/plugin/invoke.rs: +250 lines)
- weak_handles.rs: WeakRef handle registry (NEW)

**LLVM Python Backend**:
- WeakRef instruction lowering (weak.py: NEW)
- Entry point integration (entry.py: +93 lines)
- Instruction lowering (instruction_lower.py: +13 lines)
- LLVM harness runner script (tools/run_llvm_harness.sh: NEW)

**MIR & Runtime**:
- WeakRef emission & validation
- MIR JSON export for weak instructions
- Environment variable support (NYASH_WEAK_*, HAKO_WEAK_*)

**Documentation**:
- CLAUDE.md: Phase 285 completion notes
- LANGUAGE_REFERENCE_2025.md: Weak reference syntax
- 10-Now.md & 30-Backlog.md: Phase 285 status updates

Total: +864 lines, 24 files changed

SSOT: docs/reference/language/lifecycle.md
Related: Phase 285W-Syntax-0, Phase 285W-Syntax-0.1
2025-12-25 00:11:34 +09:00
cc05c37ae3 feat(phase285w): Phase 285W-Syntax-0.1 - Reject weak(...) syntax (Parser-level Fail-Fast)
- Parser guard: Reject weak(...) with LPAREN check in parse_unary()
  - Error: "Use 'weak expr', not 'weak(expr)'" (helpful message)
  - Location: src/parser/expressions.rs:248-256
- MIR builder guard: Defense-in-depth for any bypassed cases
  - Location: src/mir/builder/calls/build.rs:37-46
- Rejection test: apps/tests/phase285w_weak_call_rejected.hako
- Smoke test: phase285w_weak_call_rejected_vm.sh (PASS )
- Documentation:
  - EBNF.md: Add ~ (BitNot) to unary operators
  - lifecycle.md: Document weak(expr) as invalid syntax
  - phase-285/README.md: Add Phase 285W-Syntax-0.1 entry

Test results: 5/6 phase285 tests PASS (1 unrelated failure)
SSOT: docs/reference/language/lifecycle.md

Closes: Phase 285W-Syntax-0.1
2025-12-25 00:04:55 +09:00
9227673ef7 feat(phase285w): Implement weak x unary operator syntax
Phase 285W-Syntax-0: Migrate weak reference syntax from function call
to unary operator for consistency and clarity.

**Changes**:
- Parser: Add UnaryOperator::Weak variant and parse_unary() handling
- MIR: Lower UnaryOp::Weak to emit_weak_new() (reuses existing path)
- AST: Add Weak to UnaryOperator enum + Display/JSON support
- Tests: Migrate 8 files from `weak(x)` to `weak x` syntax
  - 7 .hako test files updated
  - 1 smoke test shell script updated
- Cleanup: Remove obsolete weak(x) parser/MIR special cases
- Docs: Update Phase 285 README

**Syntax Change**:
- Old: `local w = weak(x)`  (function call)
- New: `local w = weak x`   (unary operator)

**Validation**: All migrated phase285* smoke tests pass (4/4 relevant)

**SSOT**: docs/reference/language/lifecycle.md

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 17:21:21 +09:00
5b2b5528a5 refactor(llvm): Phase 285LLVM-1.5 - Code quality improvements + NYASH_CLI_VERBOSE logging
Code quality enhancements for Phase 285LLVM-1.4 print handle resolution:

**New Infrastructure**:
- src/llvm_py/utils/resolver_helpers.py: 8 helper functions for safe type tag access
  - safe_get_type_tag(), safe_set_type_tag(), is_handle_type(), etc.
  - Eliminates 70-80% of hasattr/isinstance boilerplate

**Type Tag Unification**:
- Unified string/handle tracking: resolver.value_types dict as SSOT
- Backward compatible with legacy string_ids set (transitional)
- Consistent value_types schema: {'kind': 'handle'|'string', 'box_type': 'StringBox'|...}

**Debug Logging**:
- Added NYASH_CLI_VERBOSE=1 support to visualize type tag operations
- Log tags: [llvm-py/types] [llvm-py/copy]
- Enables real-time debugging of type tag propagation

**Code Metrics**:
- Total lines: 42 → 20 (52% reduction)
- Nesting levels: avg 5.7 → 1.3 (65% reduction)
- Modified files: 3 (copy.py, global_call.py, boxcall.py)
- New files: 1 (resolver_helpers.py)

**Files Modified**:
1. copy.py: Simplified type tag propagation + NYASH_CLI_VERBOSE logging
2. global_call.py: Simplified handle detection + logging
3. boxcall.py: Simplified getField tagging + logging
4. New: utils/resolver_helpers.py - Centralized resolver safety helpers
5. Docs: Phase 285 documentation updated with improvements

**Backward Compatibility**:  All changes backward compatible

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-24 16:43:30 +09:00
83c897eb5d feat(llvm): Phase 285LLVM-1.4 - print Handle Resolution (type tag propagation)
Fix LLVM print to output 42 instead of 4 (handle value) for field access.

Root cause: Type tags lost through MIR copy instruction chains
- getField tagged ValueId 16 as handle
- MIR copy chain: 16 → 17 → 18
- print used ValueId 18 (not tagged) → treated as raw integer

Solution: Type-tag based handle detection with copy propagation
- boxcall.py: Tag getField results as handles
- global_call.py: Skip boxing for handles in print
- copy.py: Propagate value_types tags through copy chains

Test coverage:
- apps/tests/phase285_print_raw_int.hako: Raw int regression check
- apps/tests/phase285_userbox_field_basic.hako: Field access parity

Result: VM/LLVM parity achieved (both output 42) 

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 16:01:38 +09:00
6b64e6415c docs(phase-286): Add complete llvm.rs modularization instructions
Created comprehensive, self-contained instructions for modularizing
llvm.rs (449 lines → 10 boxes + orchestrator), following Phase 33
success pattern.

Contents:
- Background & current problems (12 responsibilities in 1 function)
- Phase 33 success case reference
- Detailed box design (10 boxes with responsibilities/inputs/outputs)
- Step-by-step implementation guide (staged migration)
- Acceptance criteria (build/test requirements)
- Important warnings (PyVM preservation, feature-gated code)

Box breakdown:
1. plugin_init.rs - Plugin initialization
2. using_resolver.rs - Using/prelude handling
3. mir_compiler.rs - AST → MIR compilation
4. method_id_injector.rs - method_id injection
5. joinir_experiment.rs - JoinIR experiment (feature-gated)
6. pyvm_executor.rs - PyVM harness (dev/test, MUST PRESERVE)
7. object_emitter.rs - LLVM object emit
8. harness_executor.rs - LLVM harness execution
9. exit_reporter.rs - Leak report (Phase 285LLVM-0)
10. fallback_executor.rs - Mock/legacy execution

Expected improvements:
- Code quality: 449 lines → 150-200 orchestrator + 10 focused boxes
- Testability: Each box independently testable
- Reusability: Boxes reusable across backends
- Maintainability: Single responsibility per box

CRITICAL: PyVM executor (pyvm_executor.rs) MUST be preserved
- Used by 8 JSON AST smoke tests
- NOT removable legacy code

Ready for handoff to other AI (ChatGPT, etc.) for implementation.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 10:08:40 +09:00
af99ccab91 feat(llvm): Phase 285LLVM-0 - LLVM Conformance One-Pass
Step 0: SSOT/Reality Alignment
- Update Feature Matrix (lifecycle.md):
  - WeakRef: "285A1" → "285LLVM-1"
  - Leak Report: "partial" → "Parent process roots only (285LLVM-0)"
  - Add detailed LLVM limitation explanation
- Update SKIP reason (phase285_weak_basic_llvm.sh): "285A1" → "285LLVM-1"

Step 1: LLVM Leak Report Implementation
- Add emit_leak_report() calls to llvm.rs (success + error paths)
- Create phase285_leak_report_llvm.sh smoke test (3 test cases PASS)
- Add NYASH_LEAK_LOG documentation to environment-variables.md
- Manual test: All 3 cases PASS (no-log, LEVEL=1, LEVEL=2)
- Smoke test: 3/3 PASS

Step 2: WeakRef Design Preparation
- Create phase-285llvm-1-design.md
  - Runtime representation candidate (Option B with caveat)
  - FFI signatures definition
  - Implementation checklist
  - Test strategy
  - NO CODE IMPLEMENTATION (design-only phase)

Implementation:
- Minimal 10-20 line code change (as planned)
- Reuses existing leak_tracker.rs infrastructure
- LLVM limitation transparently documented
- Exit codes unchanged (0/1 preserved)
- Fixture SSOT: apps/tests/*.hako shared between VM/LLVM

Test Results:
-  Manual test: 3/3 cases PASS
-  Smoke test: 3/3 cases PASS
-  No regressions

Files Changed:
- src/runner/modes/llvm.rs (2 emit_leak_report() calls)
- docs/reference/language/lifecycle.md (Feature Matrix + LLVM limitation)
- docs/reference/environment-variables.md (NYASH_LEAK_LOG entry)
- tools/smokes/v2/profiles/quick/lifecycle/phase285_weak_basic_llvm.sh (SKIP reason)

Files Added:
- tools/smokes/v2/profiles/quick/lifecycle/phase285_leak_report_llvm.sh
- docs/development/current/main/phases/phase-285/phase-285llvm-1-design.md

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 09:58:00 +09:00
ab76e39036 feat(parser): Phase 285A1.4 & A1.5 - Weak field sugar + Parser hang fix
A1.4: Add sugar syntax `public weak parent` ≡ `public { weak parent }`
A1.5: Fix parser hang on unsupported `param: Type` syntax

Key changes:
- A1.4: Extend visibility parser to handle weak modifier (fields.rs)
- A1.5: Shared helper `parse_param_name_list()` with progress-zero detection
- A1.5: Fix 6 vulnerable parameter parsing loops (methods, constructors, functions)
- Tests: Sugar syntax (OK/NG), parser hang (timeout-based)
- Docs: lifecycle.md, EBNF.md, phase-285a1-boxification.md

Additional changes:
- weak() builtin implementation (handlers/weak.rs)
- Leak tracking improvements (leak_tracker.rs)
- Documentation updates (lifecycle, types, memory-finalization, etc.)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 07:44:50 +09:00
2da730de35 refactor(cleanup): Phase 285A1 Post-Implementation Cleanup
Code quality improvements after Phase 285A1 implementation:

**Task 1: Dead Code Cleanup**
- Removed unnecessary #[allow(dead_code)] from emit_weak_load()
- Function is actively used in weak_to_strong() method handler

**Task 2: Unused Import Removal (cargo fix)**
- edgecfg/api/mod.rs: Removed seq, if_, loop_, cleanup, verify_frag_invariants
- pattern3.rs: Removed BinaryOperator
- pattern2/api/mod.rs: Removed PromoteStepResult
- jump.rs: Removed EffectMask, Span
- Result: 6 unused imports eliminated

**Task 3: Deprecated Pattern Removal**
- Fixed 4 PlanKind::LoopWithPost deprecated warnings
- Updated to Phase 142 P0 architecture (statement-level normalization)
- Files: normalized_shadow_suffix_router_box.rs, routing.rs,
  execute_box.rs, plan.rs
- Removed 2 deprecated tests: test_loop_with_post_*

**Task 4: WeakFieldValidatorBox Boxification**
- Extracted weak field validation logic into dedicated Box
- New file: src/mir/builder/weak_field_validator.rs (147 lines)
- fields.rs: 277 → 237 lines (-40 lines, -14.4%)
- Added 5 unit tests for validation logic
- Follows Phase 33 boxification principles (single responsibility,
  testability, reusability)

**Metrics**:
- Code reduction: -40 lines in fields.rs
- Test coverage: +5 unit tests
- Warnings fixed: 4 deprecated warnings
- Imports cleaned: 6 unused imports

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 03:44:56 +09:00
cc8b27a1aa feat(weak): Phase 285A1 - Weak Field Contract (Strict Type Enforcement)
Remove automatic WeakNew conversion and enforce strict compile-time type
checking for weak field assignments. Only 3 assignment types allowed:
1. Result of weak(x) call (WeakRef type)
2. Existing WeakRef variable (e.g., me.parent = other.parent)
3. Void/null (clear operation)

**Implementation**:
- Added MirType::WeakRef to type system (src/mir/types.rs)
- Track WeakRef type in emit_weak_new() even in pure mode
- Weak field reads return WeakRef without auto-upgrade
- Removed automatic WeakNew conversion from field writes
- Implemented check_weak_field_assignment() with actionable errors
- Fixed null literal type tracking (Phase 285A1.1: Unknown → Void)

**Testing**:
- 5 test fixtures (3 OK, 2 NG cases) - all passing
- Smoke test: phase285_weak_field_vm.sh
- Error messages guide users to use weak() or null

**Documentation**:
- Updated lifecycle.md SSOT with weak field contract

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-24 03:17:30 +09:00
b0eeb14c54 refactor(phase284): P1 SSOT Consolidation - Block Remapper & Return Emitter
## Summary

Refactored Phase 284 P1 codebase to consolidate scattered logic into SSOT
(Single Source of Truth) modules, improving maintainability and enabling
Pattern4/5 code reuse.

## New Modules

### 1. Block Remapper SSOT
**File**: `src/mir/builder/control_flow/joinir/merge/block_remapper.rs` (152 lines)

- **Purpose**: Consolidate block ID remapping logic (Phase 284 P1 fix)
- **Function**: `remap_block_id(block_id, local_block_map, skipped_entry_redirects)`
- **Rule**: local_block_map priority > skipped_entry_redirects (prevents ID collision)
- **Tests**: 4 unit tests (priority cascade, collision handling, etc.)

### 2. Return Jump Emitter
**File**: `src/mir/join_ir/lowering/return_jump_emitter.rs` (354 lines)

- **Purpose**: Reusable return handling helper for Pattern4/5
- **Function**: `emit_return_conditional_jump(loop_step_func, return_info, k_return_id, ...)`
- **Scope**: P1 - unconditional return + conditional (loop_var == N) only
- **Tests**: 3 unit tests (unconditional, no return, conditional)

## Modified Files

**merge/instruction_rewriter.rs** (-15 lines):
- Replaced inline block remapping with `remap_block_id()` call
- Cleaner Branch remap logic

**merge/rewriter/terminator.rs** (-43 lines):
- Delegates remap_jump/remap_branch to block_remapper SSOT
- Simplified duplicate logic

**lowering/loop_with_continue_minimal.rs** (-108 lines):
- Replaced ~100 line return handling with `emit_return_conditional_jump()` call
- Extracted helper functions to return_jump_emitter.rs
- Line reduction: 57% decrease in function complexity

**merge/mod.rs, lowering/mod.rs**:
- Added new module exports (block_remapper, return_jump_emitter)

**phase-284/README.md**:
- Updated completion status (P1 Complete + Refactored)
- Added SSOT consolidation notes
- Documented module architecture

## Code Quality Improvements

| Metric | Before | After | Change |
|--------|--------|-------|--------|
| Duplicate block remap logic | 2 places | SSOT | -15 lines |
| Return handling code | inline (100L) | helper call | -99 lines |
| Testability | Limited | Unit tests (7) | +7 tests |
| Module cohesion | Low (scattered) | High (consolidated) | Better |

## Testing

 Build: Success (cargo build --release)
 Smoke tests: All pass (46 PASS, 1 pre-existing FAIL)
 Regression: Zero
 Unit tests: 7 new tests added

## Future Benefits

1. **Pattern5 Reuse**: Direct use of `emit_return_conditional_jump()` helper
2. **Phase 285 (P2)**: Nested if/loop returns via same infrastructure
3. **Maintainability**: SSOT reduces debugging surface area
4. **Clarity**: Each module has single responsibility

## Architectural Notes

**Block Remapper SSOT Rule**:
```
remap_block_id(id, local_block_map, skipped_entry_redirects):
  1. Check local_block_map (function-local priority)
  2. Fall back to skipped_entry_redirects (global redirects)
  3. Return original if not found
```

Prevents function-local block ID collisions with global remap entries.

**Return Emitter Pattern**:
```
emit_return_conditional_jump(func, return_info, k_return_id, alloc_value):
  - Pattern1-5: All use same infrastructure
  - P1 scope: top-level return only (nested if/loop → P2)
  - Returns: JoinInst::Jump(cont=k_return, cond=Some(return_cond))
```

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-23 14:37:01 +09:00
661bbe1ab7 feat(phase284): P1 Complete - Return in Loop with Block Remap Fix
## Summary

Completed Phase 284 P1: Enable return statements in Pattern4/5 loops via
JoinInst::Ret infrastructure (100% pre-existing, no new infrastructure needed).

**Critical Bug Fix**: Block ID remap priority
- Fixed: local_block_map must take precedence over skipped_entry_redirects
- Root cause: Function-local block IDs can collide with global remap entries
  (example: loop_step:bb4 vs k_exit:bb4 after merge allocation)
- Impact: Conditional Jump else branches were incorrectly redirected to exit
- Solution: Check local_block_map FIRST, then skipped_entry_redirects

## Implementation

### New Files
- `src/mir/join_ir/lowering/return_collector.rs` - Return detection SSOT (top-level only, P1 scope)
- `apps/tests/phase284_p1_return_in_loop_min.hako` - Test fixture (exit code 7)
- Smoke test scripts (VM/LLVM)

### Modified Files
- `loop_with_continue_minimal.rs`: Return condition check + Jump generation
- `pattern4_with_continue.rs`: K_RETURN registration in continuation_funcs
- `canonical_names.rs`: K_RETURN constant
- `instruction_rewriter.rs`: Fixed Branch remap priority (P1 fix)
- `terminator.rs`: Fixed Jump/Branch remap priority (P1 fix)
- `conversion_pipeline.rs`: Return normalization support

## Testing

 VM: exit=7 PASS
 LLVM: exit=7 PASS
 Baseline: 46 PASS, 1 FAIL (pre-existing emit issue)
 Zero regression

## Design Notes

- JoinInst::Ret infrastructure was 100% complete before P1
- Bridge automatically converts JoinInst::Ret → MIR Return terminator
- Pattern4/5 now properly merge k_return as non-skippable continuation
- Correct semantics: true condition → return, false → continue loop

## Next Phase (P2+)

- Refactor: Block remap SSOT (block_remapper.rs)
- Refactor: Return jump emitter extraction
- Scope: Nested if/loop returns, multiple returns
- Design: Standardize early exit pattern (return/break/continue as Jump with cond)

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-23 14:21:27 +09:00