432fc96082
refactor(joinir): extract IfSumExitMetaBuilderBox for Fail-Fast carrier binding
...
Phase 118 refactoring: Box modularization for ExitMeta generation.
# Changes
- Created `exit_meta_builder.rs` with IfSumExitMetaBuilderBox
- Extracted ExitMeta generation logic from loop_with_if_phi_if_sum.rs
- Implemented Fail-Fast contract (carrier name validation)
- Added comprehensive unit tests (5 tests, all passing)
# Design
- **Responsibility**: Builds ExitMeta from carrier name + ValueId
- **Fail-Fast**: Validates carrier names immediately
- **Reusability**: Can be used by other patterns (Pattern 4, etc.)
# Test Results
- Unit tests: 5/5 PASS
- Phase 118 smoke tests: PASS (VM + LLVM)
- Phase 117 regression: PASS
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 03:56:10 +09:00
1080dee58f
fix(joinir): Phase 118 Pattern3 exit carrier PHI SSOT
2025-12-18 03:43:00 +09:00
2ab460f0a8
feat(joinir): error_tags freeze_with_hint
...
- Add freeze_with_hint(tag, msg, hint) API
- Format: "[joinir/<tag>] <msg> Hint: <hint>"
- Panic on empty hint (must provide actionable suggestion)
- Keep existing freeze() for backward compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-17 23:45:40 +09:00
aa29dc8085
feat(joinir): emit balanced depth-scan derived vars
2025-12-17 22:32:50 +09:00
f1a570fd45
feat(joinir): Phase 107 balanced depth-scan policy (analysis-only)
2025-12-17 22:25:34 +09:00
ae2a1d4339
refactor(joinir): boxify Pattern2 routing and schedule facts
2025-12-17 21:24:46 +09:00
27fd9720d0
feat(joinir): string accumulator emitter (JoinIR)
...
- Add StringAccumulatorEmitter in join_ir/lowering/common/
- Emit string concat as BinOp(Add) for polymorphic VM/LLVM handling
- Ensure VM/LLVM same semantics
- Fail-Fast: RHS must be Variable (not Literal/MethodCall)
- Pattern2 wiring: string carrier昇格 + type refinement + validation
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-17 16:33:18 +09:00
468977e9b3
feat(joinir): allow accumulator as LoopState carrier (Pattern2 + ScopeManager delegation)
...
- Integrate MutableAccumulatorAnalyzer into pattern2_with_break.rs
- Delegate read-only check to ScopeManager (SSOT search order)
- Promote valid accumulators to mutable LoopState carriers
- Accumulator updates handled by existing carrier mechanism
- Fail-Fast: mutable RHS (not supported yet)
- Allow LoopBodyLocal RHS (validated later in lowering)
- loop_body_local_init.rs: Align receiver search order with SSOT (ConditionEnv first)
- Error prefix: [joinir/mutable-acc]
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-17 06:10:50 +09:00
0661e92225
feat(joinir): phase 100 P1 - pinned local analyzer and wiring into CapturedEnv
...
- Implement PinnedLocalAnalyzer box to identify pinned loop-outer locals
* Pure AST analysis (no MIR dependencies)
* Detects locals: defined before loop, referenced in loop, NOT assigned in loop
* 5 unit tests covering all edge cases (no assignment, assigned, empty body, etc.)
- Integrate PinnedLocalAnalyzer into pattern2_with_break.rs
* Call analyzer with loop body AST and candidate locals from variable_map
* Wire pinned locals into CapturedEnv with CapturedKind::Pinned
* Fail-Fast on host_id lookup failure or analyzer errors
- Update loop_body_local_init.rs resolver to search CapturedEnv
* New search order: LoopBodyLocalEnv → ConditionEnv → CapturedEnv
* Access via cond_env.captured (already integrated in ConditionEnv)
* Updated error message to show full search order
- All existing tests pass (1101 passed, 1 unrelated failure)
- Smoke tests verified: phase96_json_loader_next_non_ws_vm, phase94_p5b_escape_e2e
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-17 05:32:35 +09:00
0c7ea21cac
refactor(joinir): phase 100 P1 - add CapturedKind (Explicit/Pinned) to CapturedVar
...
- Add CapturedKind enum to types.rs (Explicit for traditional, Pinned for Phase 100)
- Update CapturedVar struct to include kind field
- Add insert() and insert_pinned() helper methods to CapturedEnv
- Update analyzers.rs to specify kind field in all CapturedVar instantiations
- Export CapturedKind from function_scope_capture module
- Update scope_manager.rs test to include kind field
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-17 05:32:17 +09:00
7ab459503b
feat(joinir): Phase 94 - P5b escape full E2E (derived ch + +1/+2)
2025-12-17 00:59:33 +09:00
c213ecc3c0
refactor(mir): Phase 93 リファクタリング - 箱化モジュール化
...
## 概要
Phase 93 P0実装後のコード整理。スケジュール決定ロジックとbreak semanticsを
明確化し、デバッグログを統一。
## 変更内容
### 1. スケジュール決定ロジックの関数化 (step_schedule.rs)
- `ScheduleDecision`構造体追加(判定結果+理由+デバッグコンテキスト)
- `decide_pattern2_schedule()` - スケジュール決定のSSOT
- `build_pattern2_schedule_from_decision()` - 新しい決定ベースAPI
- 判定理由が4種類で明確化(ConditionOnly → body-local → loop-local → default)
- 後方互換性維持(`Pattern2ScheduleContext`はwrapperに)
### 2. ConditionOnlyRecipe強化 (condition_only_emitter.rs)
- `BreakSemantics` enum追加(WhenMatch vs WhenNotMatch)
- `generate_break_condition()` - semanticsに基づくAST生成
- `from_trim_helper_condition_only()` - factory method追加
- break semanticsがrecipeに明示的に含まれる
### 3. trim_loop_lowering.rs簡素化
- `generate_condition_only_break_condition()`削除(DRY原則)
- `recipe.generate_break_condition()`で統一
- break条件生成ロジックが1箇所に集約
### 4. デバッグログ統一
- `[phase93/schedule]` - スケジュール決定
- `[phase93/condition-only]` - ConditionOnlyレシピ作成
- `[phase93/break-cond]` - break条件生成
- 既存の`joinir_dev_enabled()`使用(新規env var不要)
## テスト結果
- step_schedule: 10 tests PASS
- condition_only_emitter: 4 tests PASS
- 後方互換性維持
## 統計
- 3ファイル変更
- +249行 / -57行 = +192 net
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-16 23:43:03 +09:00
04fdac42f2
feat(mir): Phase 93 P0 - ConditionOnly Derived Slot実装
...
## 概要
body-local変数を参照するbreak条件が毎イテレーション正しく再計算される
ConditionOnlyパターンを実装。
## 問題
- `is_ch_match`がConditionBindingで運ばれると初回計算値が固定
- loop header PHIで更新されず、毎周回同じ値がコピーされる
- 結果: `if ch == "b" { break }` が正しく動作しない
## 解決策 (B: ConditionOnly)
1. ConditionOnlyRecipe作成 - Derived slot再計算レシピ
2. setup_condition_env_bindings()でConditionBinding登録停止
3. Pattern2スケジュールでbody-init → break順序保証
4. break条件: ConditionOnlyでは非反転版を使用
## 変更ファイル
- condition_only_emitter.rs (NEW): Derived slot再計算ロジック
- step_schedule.rs: from_env()にhas_condition_only_recipe追加
- loop_with_break_minimal.rs: スケジュール決定でrecipe考慮
- trim_loop_lowering.rs: ConditionOnly用break条件生成追加
## テスト
- step_schedule: 6 tests PASS (新規1: condition_only_recipe_triggers_body_first)
- condition_only_emitter: 3 tests PASS
- Phase 92 baseline: 2 cases PASS
- E2E: /tmp/test_body_local_simple.hako → 出力 "1" ✓
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-16 23:24:11 +09:00
d2972c1437
feat(joinir): Phase 92完了 - ConditionalStep + body-local変数サポート
...
## Phase 92全体の成果
**Phase 92 P0-P2**: ConditionalStep JoinIR生成とbody-local変数サポート
- ConditionalStep(条件付きキャリア更新)のJoinIR生成実装
- Body-local変数(ch等)の条件式での参照サポート
- 変数解決優先度: ConditionEnv → LoopBodyLocalEnv
**Phase 92 P3**: BodyLocalPolicyBox + 安全ガード
- BodyLocalPolicyDecision実装(Accept/Reject判定)
- BodyLocalSlot + DualValueRewriter(JoinIR/MIR二重書き込み)
- Fail-Fast契約(Cannot promote LoopBodyLocal検出)
**Phase 92 P4**: E2E固定+回帰最小化 (本コミット)
- Unit test 3本追加(body-local変数解決検証)
- Integration smoke追加(phase92_pattern2_baseline.sh、2ケースPASS)
- P4-E2E-PLAN.md、P4-COMPLETION.md作成
## 主要な実装
### ConditionalStep(条件付きキャリア更新)
- `conditional_step_emitter.rs`: JoinIR Select命令生成
- `loop_with_break_minimal.rs`: ConditionalStep検出と統合
- `loop_with_continue_minimal.rs`: Pattern4対応
### Body-local変数サポート
- `condition_lowerer.rs`: body-local変数解決機能
- `lower_condition_to_joinir`: body_local_env パラメータ追加
- 変数解決優先度実装(ConditionEnv優先)
- Unit test 3本追加: 変数解決/優先度/エラー
- `header_break_lowering.rs`: break条件でbody-local変数参照
- 7ファイルで後方互換ラッパー(lower_condition_to_joinir_no_body_locals)
### Body-local Policy & Safety
- `body_local_policy.rs`: BodyLocalPolicyDecision(Accept/Reject)
- `body_local_slot.rs`: JoinIR/MIR二重書き込み
- `dual_value_rewriter.rs`: ValueId書き換えヘルパー
## テスト体制
### Unit Tests (+3)
- `test_body_local_variable_resolution`: body-local変数解決
- `test_variable_resolution_priority`: 変数解決優先度(ConditionEnv優先)
- `test_undefined_variable_error`: 未定義変数エラー
- 全7テストPASS(cargo test --release condition_lowerer::tests)
### Integration Smoke (+1)
- `phase92_pattern2_baseline.sh`:
- Case A: loop_min_while.hako (Pattern2 baseline)
- Case B: phase92_conditional_step_minimal.hako (条件付きインクリメント)
- 両ケースPASS、integration profileで発見可能
### 退行確認
- ✅ 既存Pattern2Breakテスト正常(退行なし)
- ✅ Phase 135 smoke正常(MIR検証PASS)
## アーキテクチャ設計
### 変数解決メカニズム
```rust
// Priority 1: ConditionEnv (loop params, captured)
if let Some(value_id) = env.get(name) { return Ok(value_id); }
// Priority 2: LoopBodyLocalEnv (body-local like `ch`)
if let Some(body_env) = body_local_env {
if let Some(value_id) = body_env.get(name) { return Ok(value_id); }
}
```
### Fail-Fast契約
- Delta equality check (conditional_step_emitter.rs)
- Variable resolution error messages (ConditionEnv)
- Body-local promotion rejection (BodyLocalPolicyDecision::Reject)
## ドキュメント
- `P4-E2E-PLAN.md`: 3レベルテスト戦略(Level 1-2完了、Level 3延期)
- `P4-COMPLETION.md`: Phase 92完了報告
- `README.md`: Phase 92全体のまとめ
## 将来の拡張(Phase 92スコープ外)
- Body-local promotionシステム拡張
- P5bパターン認識の汎化(flagベース条件サポート)
- 完全なP5b E2Eテスト(body-local promotion実装後)
🎯 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-16 21:37:07 +09:00
568619df89
feat(mir): Phase 92 P2-2 - Body-local variable support for ConditionalStep
...
Phase 92 P2-2完了:ConditionalStepのcondition(ch == '\\'など)でbody-local変数をサポート
## 主要変更
### 1. condition_lowerer.rs拡張
- `lower_condition_to_joinir`に`body_local_env`パラメータ追加
- 変数解決優先度:ConditionEnv → LoopBodyLocalEnv
- すべての再帰ヘルパー(comparison, logical_and, logical_or, not, value_expression)対応
### 2. conditional_step_emitter.rs修正
- `emit_conditional_step_update`に`body_local_env`パラメータ追加
- condition loweringにbody-local環境を渡す
### 3. loop_with_break_minimal.rs修正
- break condition loweringをbody-local init の**後**に移動(line 411)
- header_break_lowering::lower_break_conditionにbody_local_env渡す
- emit_conditional_step_updateにbody_local_env渡す(line 620)
### 4. header_break_lowering.rs修正
- `lower_break_condition`に`body_local_env`パラメータ追加
- scope_managerにbody-local環境を渡す
### 5. 全呼び出し箇所修正
- expr_lowerer.rs (2箇所)
- method_call_lowerer.rs (2箇所)
- loop_with_if_phi_if_sum.rs (3箇所)
- loop_with_continue_minimal.rs (1箇所)
- carrier_update_emitter.rs (1箇所・legacy)
## アーキテクチャ改善
### Break Condition Lowering順序修正
旧: Header → **Break Cond** → Body-local Init
新: Header → **Body-local Init** → Break Cond
理由:break conditionが`ch == '\"'`のようにbody-local変数を参照する場合、body-local initが先に必要
### 変数解決優先度(Phase 92 P2-2)
1. ConditionEnv(ループパラメータ、captured変数)
2. LoopBodyLocalEnv(body-local変数like `ch`)
## テスト
### ビルド
✅ cargo build --release成功(30 warnings、0 errors)
### E2E
⚠️ body-local promotion問題でブロック(Phase 92範囲外)
- Pattern2はbody-local変数をcarrier promotionする必要あり
- 既存パターン(A-3 Trim, A-4 DigitPos)に`ch = get_char(i)`が該当しない
- **Phase 92 P2-2目標(condition loweringでbody-local変数サポート)は達成**
## 次タスク(Phase 92 P3以降)
- body-local variable promotion拡張(Pattern2で`ch`のような変数を扱う)
- P5b E2Eテスト完全動作確認
## Phase 92 P2-2完了
✅ Body-local変数のcondition lowering対応完了
✅ ConditionalStepでbody-local変数参照可能
✅ Break condition lowering順序修正
2025-12-16 17:08:15 +09:00
3093ac2ca4
refactor(joinir): Phase 92 P1 - 箱化モジュール化・レガシー削除
...
P1-1: ConditionalStep lowering を1箱に隔離
- 新規作成: src/mir/join_ir/lowering/common/conditional_step_emitter.rs
- emit_conditional_step_update() を carrier_update_emitter.rs から移動
- Fail-Fast 不変条件チェック追加(then_delta != else_delta)
- 副作用を減らしたクリーンなインターフェース
- 包括的なテストスイート(3テスト)
P1-0: 境界SSOTの固定
- routing.rs: skeleton 設定をrouting層から削除
- pattern2_with_break.rs: skeleton 取得をlower()内部に閉じ込め
- parity_checker から skeleton を直接取得
- skeleton の使用を Pattern2 のみに限定
P1-2: escape recognizer をSSOTに戻す
- escape_pattern_recognizer.rs: 未使用フィールド削除
- quote_char, escape_char 削除(使われていない)
- 責務を cond/delta 抽出のみに限定
- pattern_recognizer.rs: デフォルト値を使用
P1-3: E2Eテスト作成(実行は後回し)
- apps/tests/test_pattern5b_escape_minimal.hako 作成
- body-local 変数対応後に検証予定
テスト結果:
- conditional_step_emitter tests: 3 passed
- Pattern2 tests: 18 passed
- Regression: 0 failures
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-16 15:53:40 +09:00
a718af3213
feat(joinir): Phase 92 P0-3 - ConditionalStep → JoinIR Select generation
...
Complete implementation of P5b escape sequence handling pattern lowering:
Core changes:
- skeleton_types.rs: Add `cond` field to ConditionalStep for escape condition
- escape_pattern_recognizer.rs: Extract and return escape_cond AST
- pattern_recognizer.rs: Pass escape_cond to ConditionalStep
- canonicalizer.rs: Store escape_cond in ConditionalStep variant
JoinIR lowering:
- carrier_update_emitter.rs: Add emit_conditional_step_update() function
- Lower condition AST via lower_condition_to_joinir
- Compute both then/else branches (carrier + delta)
- Emit JoinInst::Select for conditional carrier update
- loop_with_break_minimal.rs: Add skeleton parameter, detect ConditionalStep
- pattern2_with_break.rs: Pass skeleton to lowering function
Backward compatibility:
- skeleton=None preserves existing Pattern1-4 behavior
- fixtures.rs, tests.rs updated for new signature
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-16 15:36:36 +09:00
d0d3512be4
refactor(mir): Phase 140-P4-B - pattern_recognizer を SSOT 化(71 行削減)
...
- try_extract_skip_whitespace_pattern を ast_feature_extractor 呼び出しに変更
- 重複コード 100+ 行削減(250 → 179 行)
- crate-wide re-export chain 確立(ast_feature_extractor → patterns → joinir → control_flow → builder → mir)
- 全テスト PASS(14 tests)
- フォーマット適用
Phase 140-P4-A/P4-B 完了:SSOT 化成功
2025-12-16 07:09:22 +09:00
e404746612
refactor(mir): Phase 139-P3-B - RoutingDecision を enum 対応 + レガシー削除
...
- RoutingDecision の missing_caps を Vec<CapabilityTag> に変更(型安全化)
- error_tags は to_tag() メソッドで自動生成
- 全 callsite を enum variant に修正
- capability_tags モジュール(文字列定数群)を完全削除
- 全テスト PASS(型安全性向上を確認)
- フォーマット適用
2025-12-16 07:02:14 +09:00
b92f85f993
refactor(mir): Remove TypeContext legacy fields (Phase 2-3/7)
...
完全移行→削除の安全順序(Option C)に従い、TypeContext の
deprecated フィールドと sync helpers を完全削除。
⚠️ 危険ゾーン: TypeFactsBox 等の同名フィールドと混同しないよう、
ファイル単位で手作業移行を実施。
## Changes
- Migrated all MirBuilder access sites to type_ctx.* (manual, 40+ files)
- Removed 3 deprecated fields (value_types, value_kinds, value_origin_newbox)
- Removed 2 sync helpers (sync_type_ctx_to_legacy, sync_legacy_to_type_ctx)
- Verified TypeFactsBox, CalleeGuardBox unchanged (no false positives)
## Tests
- cargo test --release --lib: 1029/1033 PASS
- TypeFactsBox integration: PASS (borrowed references unchanged)
- Deprecation warnings: 456 → 255 (-201, -44%)
## Safety Verification
✅ TypeFactsBox unchanged (still uses &'a BTreeMap borrowed references)
✅ CalleeGuardBox unchanged
✅ CalleeResolverBox unchanged
✅ BoxCompilationContext unchanged
Phase 2 Progress: 3/7 contexts complete (43%)
- ✅ MetadataContext
- ✅ CoreContext
- ✅ TypeContext (this commit)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-15 23:27:24 +09:00
d82c332a40
feat(joinir): Phase 135 P0 - ConditionLoweringBox allocator SSOT (ValueId collision fix)
...
## Summary
Root cause: ConditionLoweringBox was bypassing ConditionContext.alloc_value (SSOT allocator),
causing ValueId collisions between JoinIR condition params and lowered instructions.
## Changes
1. **ConditionLoweringBox (expr_lowerer.rs)**: Must use ConditionContext.alloc_value
- Pass &mut ConditionContext to lower_condition (SSOT allocator)
- Eliminates internal counter usage
2. **Allocator unification (condition_lowerer.rs, method_call_lowerer.rs)**:
- Accept &mut dyn FnMut() -> ValueId as allocator parameter
- Ensures all lowering paths use same SSOT allocator
3. **Boundary Copy deduplication (joinir_inline_boundary_injector.rs)**:
- Deduplicate condition_bindings by dst
- Fail-Fast if different sources target same dst (MIR SSA violation)
4. **Trim pattern fixes (trim_loop_lowering.rs, trim_pattern_validator.rs, stmts.rs)**:
- Use builder.next_value_id() instead of value_gen.next() in function context
- Ensures function-level ValueId allocation respects reserved PHI dsts
## Acceptance
✅ ./target/release/hakorune --verify apps/tests/phase133_json_skip_whitespace_min.hako
✅ Smoke: phase135_trim_mir_verify.sh - MIR SSA validation PASS
✅ Regression: phase132_exit_phi_parity.sh - 3/3 PASS
✅ Regression: phase133_json_skip_whitespace_llvm_exe.sh - compile-only PASS
🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-15 18:49:08 +09:00
3f58f34592
feat(llvm): Phase 132-P0 - block_end_values tuple-key fix for cross-function isolation
...
## Problem
`block_end_values` used block ID only as key, causing collisions when
multiple functions share the same block IDs (e.g., bb0 in both
condition_fn and main).
## Root Cause
- condition_fn's bb0 → block_end_values[0]
- main's bb0 → block_end_values[0] (OVERWRITES!)
- PHI resolution gets wrong snapshot → dominance error
## Solution (Box-First principle)
Change key from `int` to `Tuple[str, int]` (func_name, block_id):
```python
# Before
block_end_values: Dict[int, Dict[int, ir.Value]]
# After
block_end_values: Dict[Tuple[str, int], Dict[int, ir.Value]]
```
## Files Modified (Python - 6 files)
1. `llvm_builder.py` - Type annotation update
2. `function_lower.py` - Pass func_name to lower_blocks
3. `block_lower.py` - Use tuple keys for snapshot save/load
4. `resolver.py` - Add func_name parameter to resolve_incoming
5. `wiring.py` - Thread func_name through PHI wiring
6. `phi_manager.py` - Debug traces
## Files Modified (Rust - cleanup)
- Removed deprecated `loop_to_join.rs` (297 lines deleted)
- Updated pattern lowerers for cleaner exit handling
- Added lifecycle management improvements
## Verification
- ✅ Pattern 1: VM RC: 3, LLVM Result: 3 (no regression)
- ⚠️ Case C: Still has dominance error (separate root cause)
- Needs additional scope fixes (phi_manager, resolver caches)
## Design Principles
- **Box-First**: Each function is an isolated Box with scoped state
- **SSOT**: (func_name, block_id) uniquely identifies block snapshots
- **Fail-Fast**: No cross-function state contamination
## Known Issues (Phase 132-P1)
Other function-local state needs same treatment:
- phi_manager.predeclared
- resolver caches (i64_cache, ptr_cache, etc.)
- builder._jump_only_blocks
## Documentation
- docs/development/current/main/investigations/phase132-p0-case-c-root-cause.md
- docs/development/current/main/investigations/phase132-p0-tuple-key-implementation.md
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-15 05:36:50 +09:00
447d4ea246
feat(llvm): Phase 132 - Pattern 1 exit value parity fix + Box-First refactoring
...
## Phase 132: Exit PHI Value Parity Fix
### Problem
Pattern 1 (Simple While) returned 0 instead of final loop variable value (3)
- VM: RC: 3 ✅ (correct)
- LLVM: Result: 0 ❌ (wrong)
### Root Cause (Two Layers)
1. **JoinIR/Boundary**: Missing exit_bindings → ExitLineReconnector not firing
2. **LLVM Python**: block_end_values snapshot dropping PHI values
### Fix
**JoinIR** (simple_while_minimal.rs):
- Jump(k_exit, [i_param]) passes exit value
**Boundary** (pattern1_minimal.rs):
- Added LoopExitBinding with carrier_name="i", role=LoopState
- Enables ExitLineReconnector to update variable_map
**LLVM** (block_lower.py):
- Use predeclared_ret_phis for reliable PHI filtering
- Protect builder.vmap PHIs from overwrites (SSOT principle)
### Result
- ✅ VM: RC: 3
- ✅ LLVM: Result: 3
- ✅ VM/LLVM parity achieved
## Phase 132-Post: Box-First Refactoring
### Rust Side
**JoinModule::require_function()** (mod.rs):
- Encapsulate function search logic
- 10 lines → 1 line (90% reduction)
- Reusable for Pattern 2-5
### Python Side
**PhiManager Box** (phi_manager.py - new):
- Centralized PHI lifecycle management
- 47 lines → 8 lines (83% reduction)
- SSOT: builder.vmap owns PHIs
- Fail-Fast: No silent overwrites
**Integration**:
- LLVMBuilder: Added phi_manager
- block_lower.py: Delegated to PhiManager
- tagging.py: Register PHIs with manager
### Documentation
**New Files**:
- docs/development/architecture/exit-phi-design.md
- docs/development/current/main/investigations/phase132-llvm-exit-phi-wrong-result.md
- docs/development/current/main/phases/phase-132/
**Updated**:
- docs/development/current/main/10-Now.md
- docs/development/current/main/phase131-3-llvm-lowering-inventory.md
### Design Principles
- Box-First: Logic encapsulated in classes/methods
- SSOT: Single Source of Truth (builder.vmap for PHIs)
- Fail-Fast: Early explicit failures, no fallbacks
- Separation of Concerns: 3-layer architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-15 03:17:31 +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
2a18a66154
feat(joinir): Phase Next - parse_array/object 同型 fixture
...
## 実ループ制御構造の抽出
- parse_array_min.program.json (n=10 → acc=6)
- parse_object_min.program.json (n=10 → acc=7)
## 既存パターン再利用
- ContinueReturn lowering 活用(新規 lowering 不要)
- 優れたモジュール再利用の実証
## Tests
- +4 tests (ParseArray 2本 + ParseObject 2本)
- +1 test fixed (Phase 88 error message 更新)
- normalized_dev: 64→69 passed (+5)
## 箱化評価
- 単一責任: ✅
- 境界明確: ✅ (SSOT)
- 再利用性: ✅ (既存パターン活用)
- テスト容易性: ✅
- SSOT: ✅ (dev_fixtures.rs)
## レガシー探索
- デッドコード: なし
- 重複コード: なし
- クリーンな状態維持
Impact:
- 実ループ寄せの基盤確立
- モジュール設計の成功実証
- 技術的負債ゼロ
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 04:09:46 +09:00
df57d3d320
refactor(joinir): Refactor-A+B - Null literal + ContinueReturn 一般化
...
## Refactor-A: Null literal 対応
- expr.rs に "Null" case 追加
- ConstValue::Null → JoinValue::Unit マッピング
## Refactor-B: ContinueReturn 一般化
- 複数 return-if 許可(同値のみ)
- json_values_equal() ヘルパー追加
- Fail-Fast: 異なる値は即エラー
## Fixtures & Tests
- null_literal_min.program.json (return null)
- continue_return_multi_min.program.json (複数 return null)
- +1 test (vm_bridge 検証)
Impact:
- normalized_dev: 63→64 passed (+1)
- lib: 993 passed (回帰なし)
- 箱化スコア: 5/5 (全項目満点)
- 実ループ(_parse_array/_parse_object) 準備完了
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 04:01:05 +09:00
45add0f5d3
feat(joinir): Phase 90 P0 - ParseStringComposite pattern
...
## Composite Pattern
- Continue(escape i+=2) + EarlyReturn(close quote)
- parse_string_composite_pattern.rs (50行、continue_return 再利用)
- 89% コード削減(450行→50行)
## Shape Detection
- BinOp Add const 2 検出(escape 特徴)
- LoopStepInspector 活用(Phase 89 リファクタ成果)
## SSOT Integration
- dev_fixtures.rs に登録
- StepCalculator 再利用(Phase 89-2 成果)
## Tests
- +2 tests (vm_bridge + 期待値 n=10→acc=5)
- normalized_dev: 61→63 passed
- lib: 993 passed (回帰なし)
Impact:
- Reuse over Duplication 実践
- Phase 89 リファクタ成果の完全活用
- 箱化原則 5/5 遵守
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 03:36:45 +09:00
70ceec1e3e
refactor(joinir): Phase 89 リファクタリング - 1) LoopStepInspector共通化
...
変更内容:
- 新規ファイル: loop_step_inspector.rs (純関数ヘルパー集合)
- has_select_instruction(): Select 命令検出
- has_compare_instruction(): Compare 命令検出
- count_conditional_jumps(): 条件付き Jump のカウント
- has_tail_call(): tail call 検出
- has_reasonable_param_count(): パラメータ数妥当性チェック
- shape_guard.rs を Inspector 使用に変更
- is_pattern4_continue_minimal(): 重複ロジック削減
- is_pattern_continue_return_minimal(): 重複ロジック削減
メリット:
- 散在していた検出ロジックを1箇所で管理
- detector 間で重複コード削減
- 単一責任の原則に準拠
- テスト容易性向上(単体テスト付き)
テスト結果:
- lib tests: 993 passed (回帰なし)
- normalized_dev tests: 61 passed / 1 failed (ベースライン維持)
- loop_step_inspector 単体テスト: +5 (新規)
Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 03:16:32 +09:00
90c45e544b
refactor(joinir): Phase 89 リファクタリング - 3) Frontend再帰探索
...
変更内容:
- Break/Continue/Return 検出を再帰的探索に変更
- has_break_in_loop_body(): top-level If のみ → 再帰的探索
- has_continue_in_loop_body(): top-level If のみ → 再帰的探索
- has_return_in_loop_body(): top-level If のみ → 再帰的探索
- ネストした If/Block 内のステートメントも検出可能に
- ヘルパー関数追加:
- has_break_recursive()
- has_continue_recursive()
- has_return_recursive()
理由:
- Phase 90+ で合成形パターン(ネストした If/Block)に対応する準備
- 現状では top-level のみチェックしているため、深い階層で誤判定の可能性
影響範囲:
- loop_frontend_binding.rs のルーティングロジック
- Phase 90 の合成形パターンで正確な検出が可能に
テスト結果:
- lib tests: 993 passed (回帰なし)
- normalized_dev tests: 61 passed / 1 failed (ベースライン維持)
Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 03:13:05 +09:00
98a0b8396f
refactor(joinir): Phase 89 リファクタリング - 2) ShapeCapability分類修正
...
変更内容:
- 新規 capability 追加: P4ContinueEarlyReturn
- Continue + Early Return 専用の capability
- P4ContinueSkipWs と明確に分離
- PatternContinueReturnMinimal のマッピング修正
- P4ContinueSkipWs → P4ContinueEarlyReturn に変更
- is_p2_core_capability に P4ContinueEarlyReturn を追加
理由:
- P4ContinueSkipWs は「Continue のみ」のパターン
- PatternContinueReturnMinimal は「Continue + Early Return」の合成形
- 将来の拡張時に混乱を避けるため、今のうちに分離
テスト結果:
- lib tests: 993 passed (回帰なし)
- normalized_dev tests: 61 passed / 1 failed (ベースライン維持)
Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 03:09:16 +09:00
6bcc70e07e
refactor(joinir): Phase 89 リファクタリング - 5) fixture名SSOT化
...
変更内容:
- 新規ファイル: src/mir/join_ir/normalized/dev_fixtures.rs (SSOT)
- NormalizedDevFixture enum で fixture 名・パス・ルーティング統一管理
- ALL_DEV_FIXTURES 配列で一覧化
- fixture_content() / load_and_lower() ヘルパー実装
- FunctionRoute を route.rs に分離
- ast_lowerer/route.rs 新規作成
- resolve_function_route() を route.rs に移動
- dev fixtures を SSOT から自動登録
- fixtures.rs を簡潔化
- 4つの builder 関数を SSOT 呼び出しに変更
- 散在していた include_str! パスを削除
メリット:
- typo・不一致によるルーティングミスを防止
- 新しい fixture 追加時は1箇所のみ変更
- 責務の明確化(route.rs / dev_fixtures.rs)
テスト結果:
- lib tests: 993 passed (回帰なし)
- normalized_dev tests: 61 passed / 1 failed (ベースライン維持)
Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 03:07:53 +09:00
730a80f33f
feat(joinir): Phase 89 P1 - ContinueReturn lowering implementation
...
## ContinueReturn 独立箱
- continue_return_pattern.rs (457行)
- Continue + Early Return の JoinIR lowering
- StepCalculator 再利用(3箇所)
- Fail-Fast 原則徹底(5箇所検証)
## Dispatcher 配線
- mod.rs: LoopPattern::ContinueReturn 対応
- allowlist: pattern_continue_return_minimal 追加
## Fixture & Tests
- fixtures.rs: build_pattern_continue_return_min
- shapes.rs: +2 tests (vm_bridge + 期待値 n=10→acc=4)
Impact:
- normalized_dev: 61 passed (+2)
- lib tests: 993 passed (回帰なし)
- 箱化原則:単一責任・境界明確・再利用性高
Next: Phase 90 - _parse_string 合成 fixture
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 02:02:47 +09:00
39affbf00d
refactor(joinir): Phase 89-2 - StepCalculator Box extraction
...
Extract step increment logic from Continue pattern into reusable Box:
New Module:
- step_calculator.rs (161 lines)
- extract_linear_increment(): Detect i + const patterns
- calculate_step_difference(): Compute step delta
- 6 comprehensive unit tests (100% coverage)
Changes:
- continue_pattern.rs: Use StepCalculator instead of local function
- Removed extract_add_i_const() (20 lines)
- Cleaner separation of concerns
- mod.rs: Register step_calculator module
Benefits:
- Reusability: Available for ContinueReturn and future patterns
- Testability: Independent pure functions with unit tests
- Extensibility: Easy to add i *= 2 support later
- SSOT: Single source of truth for step increment logic
Code Metrics:
- continue_pattern.rs: 321 → 305 lines (5% reduction)
- New tests: +6 (993 total passed)
- Complexity: Reduced (pure function extraction)
Tests: 993 passed (no regression)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 01:49:45 +09:00
6d61e8f578
refactor(joinir): Phase 89-1 - Continue pattern error message enhancement
...
Improve error messages in Continue pattern lowering for better debugging:
Changes:
- Missing 'i' increment: Add Expected/Found/Hint format
- Invalid step increment form: Include JSON debug output
- Invalid 'then' branch step: Include JSON debug output
- Missing accumulator update: Add Expected/Found/Hint format
Benefits:
- 50% reduction in debug turnaround time (estimated)
- Clear actionable hints for users
- Explicit Expected vs Found comparison
Tests: 987 passed (no regression)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 01:46:51 +09:00
4e3fc4ad49
feat(joinir): Phase 89 P0 - Continue + Early Return pattern detector
...
## Pattern4 Detector 締め
- is_pattern4_continue_minimal() を厳しく
- Select 必須 + conditional Jump exactly 1
- loop 内 return を P4 と誤認しない
## 新パターン箱
- LoopPattern::ContinueReturn enum 追加
- has_return_in_loop_body() helper 追加
- Fail-Fast: UnimplementedPattern error
## Normalized-dev 統合
- NormalizedDevShape::PatternContinueReturnMinimal
- detector: Select + conditional Jumps >= 2
- canonical には入れない(dev-only)
## Documentation
- 10-Now.md, CURRENT_TASK.md 更新
Impact:
- 987 lib tests PASS
- 60 normalized_dev tests PASS
- Pattern4 誤爆防止
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 00:59:58 +09:00
b71a18495d
feat(joinir): Phase 88 - Pattern4 continue + variable step increment
...
Continue Pattern 拡張:
- then側の i=i+const 差分加算 + acc更新を許可
- continue_pattern.rs:193 で可変ステップ検出
Dev Router 許可:
- ast_lowerer/mod.rs:92 で normalized_dev feature時に新パターンを有効化
Fixtures & Tests:
- jsonparser_unescape_string_step2_min fixture追加(submodule)
- normalized_joinir_min.rs に shape テスト追加
- shapes.rs に expected shape 定義
Documentation:
- joinir-architecture-overview.md に Phase 88 到達点を追記
Impact:
- Pattern4 continue + 可変インクリメント(i+=1 or i+=2)対応
- _unescape_string 制御構造の土台確立
- normalized_dev tests PASS
Next: _unescape_string 残り複合ループ対応
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-14 00:29:56 +09:00
33f03d9775
refactor(joinir): Phase 86 - Carrier init builder, debug migration, error tags
...
P1: Carrier Initialization Builder (HIGH) ✅
- New module: carrier_init_builder.rs (197 lines, 8 tests)
- Refactored loop_header_phi_builder.rs (-34 lines)
- Centralized CarrierInit value generation (SSOT)
- Eliminates scattered match patterns across header PHI, exit line
- Consistent debug output: [carrier_init_builder] format
- Net: -34 lines of duplicated logic
P2: Remaining DebugOutputBox Migration (QUICK) ✅
- Migrated carrier_info.rs::record_promoted_binding()
- Uses DebugOutputBox for JOINIR_DEBUG checks
- Maintains JOINIR_TEST_DEBUG override for test diagnostics
- Consistent log formatting: [context/category] message
- Net: +3 lines (SSOT migration)
P3: Error Message Centralization (LOW) ✅
- New module: error_tags.rs (136 lines, 5 tests)
- Migrated 3 error sites:
* ownership/relay:runtime_unsupported (plan_validator.rs)
* joinir/freeze (control_flow/mod.rs)
* (ExitLine errors were debug messages, not returns)
- Centralized error tag generation (freeze, exit_line_contract, ownership_relay_unsupported, etc.)
- Net: +133 lines (SSOT module + tests)
Total changes:
- New files: carrier_init_builder.rs (197), error_tags.rs (136)
- Modified: 6 files
- Production code: +162 lines (SSOT investment)
- Tests: 987/987 PASS (982→987, +5 new tests)
- Phase 81 ExitLine: 2/2 PASS
- Zero compilation errors/warnings
Benefits:
✅ Single Responsibility: Each helper has one concern
✅ Testability: 13 new unit tests (8 carrier init, 5 error tags)
✅ Consistency: Uniform debug/error formatting
✅ SSOT: Centralized CarrierInit and error tag generation
✅ Discoverability: Easy to find all error types
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-13 21:48:02 +09:00
8c2bc45be6
refactor(joinir): Phase 85 - Quick wins: loop_patterns removal, DebugOutputBox, dead_code audit
...
Quick Win 1: Remove loop_patterns_old.rs (COMPLETED)
- Deleted obsolete legacy loop pattern dispatcher (914 lines)
- All patterns (Break/Continue/Simple) now in modular loop_patterns/ system
- Moved helper functions (has_break_in_loop_body, has_continue_in_loop_body) to analysis.rs
- Updated loop_frontend_binding.rs to remove fallback
- Verified zero regressions: 974/974 lib tests PASS
Quick Win 2: DebugOutputBox consolidation (COMPLETED)
- New module: src/mir/join_ir/lowering/debug_output_box.rs (170 lines)
- Centralized debug output management with automatic HAKO_JOINIR_DEBUG checking
- Refactored 4 files to use DebugOutputBox:
- condition_env.rs: 3 scattered checks → 3 Box calls
- carrier_binding_assigner.rs: 1 check → 1 Box call
- scope_manager.rs: 3 checks → 3 Box calls
- analysis.rs: Updated lower_loop_with_if_meta to use new pattern system
- Benefits: Consistent formatting, centralized control, zero runtime cost when disabled
- Added 4 unit tests for DebugOutputBox
Quick Win 3: Dead code directive audit (COMPLETED)
- Audited all 40 #[allow(dead_code)] directives in lowering/
- Findings: All legitimate (Phase utilities, future placeholders, API completeness)
- No unsafe removals needed
- Categories:
- Phase 192 utilities (whitespace_check, entry_builder): Public API with tests
- Phase 231 placeholders (expr_lowerer): Explicitly marked future use
- Const helpers (value_id_ranges): API completeness
- Loop metadata (loop_update_summary): Future phase fields
Result: Net -858 lines, improved code clarity, zero regressions
Tests: 974/974 PASS (gained 4 from DebugOutputBox tests)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-13 19:25:11 +09:00
9e32807a96
refactor(joinir): Phase 82-83 - Debug flag SSOT + Fallback verification
...
Phase 82: Centralized JoinIR debug flag reading
- Added is_joinir_debug() SSOT function in joinir_flags.rs
- Replaced 16 direct env::var() calls across 8 files
- Updated docs to recommend HAKO_JOINIR_DEBUG (NYASH_ deprecated)
- Backward compat: Both env vars work
Phase 83: Verified promoted carrier fallback behavior
- Confirmed NO fallback to name-based lookup for DigitPos/Trim
- Documented fallback expectations in Phase 80/81 docs
- Added verification commands and expected output
Changes:
- src/config/env/joinir_flags.rs: +187 lines (new SSOT module)
- 8 files: env var reads → is_joinir_debug() calls
- 3 docs: HAKO_JOINIR_DEBUG examples + fallback sections
- 1 summary doc: phase82-83-debug-flag-ssot-summary.md
Tests: 970/970 lib PASS, 58/58 normalized_dev PASS
Impact: Dev-only (zero production changes)
2025-12-13 19:01:14 +09:00
84129a7ed4
feat(joinir): Phase 80-B/C/D - Pattern3/4 BindingId wiring + E2E tests (dev-only)
...
Task 80-B (P1): Pattern3 (if-sum) BindingId registration
- pattern3_with_if_phi.rs: Added BindingId→ValueId registration
- Loop var + condition bindings registration (lines 131-159)
- Debug logs: [phase80/p3] tags
- Follows Pattern2 template structure
Task 80-C (P2): Pattern4 (continue) BindingId registration
- pattern4_with_continue.rs: Pass binding_map to lowerer (lines 341-352)
- loop_with_continue_minimal.rs: Added BindingId→ValueId registration (lines 206-230)
- Loop var + condition bindings registration
- Debug logs: [phase80/p4] tags
- Follows Pattern2 template structure
Task 80-D (P3): E2E tests for BindingId lookup
- tests/normalized_joinir_min.rs: Added 2 new tests (lines 2182-2222)
- test_phase80_p3_bindingid_lookup_works(): Pattern3 verification
- test_phase80_p4_bindingid_lookup_works(): Pattern4 verification
- Manual fallback detection via NYASH_JOINIR_DEBUG=1
Task P4: Cleanup
- Fixed unused variable warnings (loop_var_join_id → _loop_var_join_id)
- Fixed unnecessary mut warning (cargo fix auto-applied)
- pattern2_with_break.rs: Clean up pre-existing unused warning
Result: BindingId operational across Pattern2/3/4
Tests: 970/970 PASS (baseline, E2E tests in normalized_dev feature)
Design: dev-only, dual-path maintained, zero production impact
Phase 74-80 complete: BindingId migration fully operational across all patterns
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-13 18:05:14 +09:00
b7f7882558
feat(joinir): Phase 79 Activation - BindingId wiring operational (dev-only)
...
Phase 79 の最終段階:BindingId を ExprLowerer に配線し、end-to-end で動作確認。
Key changes:
- ExprLowerer wiring:
- scope_resolution.rs: build_condition_env_from_scope_with_binding() (BindingId-aware)
- expr_lowerer.rs: lower_condition() uses BindingId priority lookup
- ConditionEnv extension:
- register_loop_var_binding(): Loop var BindingId→ValueId registration
- register_condition_binding(): Condition-only carrier BindingId→ValueId registration
- Pattern2 integration:
- pattern2_with_break.rs: Loop var registration (Line 116-128)
- pattern2_with_break.rs: Carrier role-based registration (Line 381-425)
- Debug logging: [phase79] tags for registration, [binding_pilot/hit] for lookup success
- E2E tests (normalized_joinir_min.rs, debug-only):
- test_phase79_digitpos_bindingid_lookup_works(): DigitPos pattern verification
- test_phase79_trim_bindingid_lookup_works(): Trim pattern verification
Result: BindingId lookup actually works end-to-end
- Promoted carriers resolve via BindingId, not string hacks
- Debug: NYASH_JOINIR_DEBUG=1 shows [phase79] Registered loop var BindingId, [binding_pilot/hit] BindingId(1) -> ValueId(100)
Tests: 1025/1025 lib PASS
Design: dev-only feature-gated, dual-path maintained (BindingId priority + name fallback)
Phase 74-79 complete: BindingId migration fully operational
- Infrastructure (74-76): BindingId type, binding_map, 3-tier lookup, promoted_bindings map
- Implementation (77): DigitPos/Trim populate, legacy deprecate
- Refactoring (78-79 Refactoring): PromotedBindingRecorder, Detector/Recorder split
- Activation (80 Foundation + 79 Activation): CarrierBindingAssigner + ExprLowerer wiring
2025-12-13 16:48:41 +09:00
8b48bec962
feat(joinir): Phase 78 - BindingId infrastructure for promoted carriers (dev-only)
...
Phase 78 adds infrastructure to assign BindingIds to synthetic promoted
carriers (e.g., is_digit_pos, is_ch_match), enabling type-safe promoted
variable lookup without string-based naming conventions.
Key Changes:
1. CarrierVar.binding_id field (dev-only):
- Added Option<BindingId> to track BindingId for each carrier
- Updated all constructors and struct instantiations
2. CarrierBindingAssigner Box (new file, 273 lines):
- Allocates BindingIds for promoted carriers via builder.allocate_binding_id()
- Records original → promoted mapping in promoted_bindings
- Sets binding_id field on promoted CarrierVar
- Includes 3 comprehensive unit tests
3. ConditionEnv.register_carrier_binding() (new method):
- Registers carrier BindingId → ValueId mappings
- Enables type-safe lookup via binding_id_map
4. Logging cleanup:
- Gated 6 eprintln! statements with NYASH_JOINIR_DEBUG
- Unified logging tags to [binding_pilot/*]
Design Decisions:
- Promoters create CarrierInfo, lowering code assigns BindingIds
- CarrierBindingAssigner called from Pattern2/4 lowering (has builder access)
- Clear documentation prevents misuse (promoters lack builder access)
Files modified (18):
- carrier_info.rs: binding_id field added to CarrierVar
- carrier_binding_assigner.rs: New Box for BindingId allocation
- condition_env.rs: register_carrier_binding() method
- mod.rs: Module exports
- pattern2_with_break.rs, pattern4_with_continue.rs: Updated for binding_id
- loop_body_*_promoter.rs: Logging cleanup + binding_id in structs
- phase78-bindingid-promoted-carriers.md: Architecture documentation
Tests: 970/970 PASS (zero regressions)
Status: Infrastructure complete, integration deferred to Phase 79
Next Phase: Wire CarrierBindingAssigner in Pattern2/4 lowering + E2E tests
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-13 16:20:33 +09:00
0aad016be2
chore(joinir): quiet legacy promoted lookup warning
2025-12-13 06:12:21 +09:00
72173c1ac8
feat(joinir): Phase 77 - BindingId expansion implementation (dev-only)
...
Phase 77 implements promoted_bindings population in DigitPos/Trim promoters
and deprecates legacy name-based resolution paths.
Changes:
- DigitPosPromoter: Added binding_map field and record_promoted_binding() calls
- TrimLoopHelper: Added binding_map field for ch → is_ch_match tracking
- Pattern2/4: Wired binding_map from builder.binding_map to promoters
- Legacy deprecation: Added #[deprecated] to resolve_promoted_join_id()
- Dual-path design: BindingId priority + name fallback maintained
Files modified (8):
- pattern2_with_break.rs, pattern4_with_continue.rs: binding_map wiring
- trim_loop_lowering.rs: Trim promoter integration
- carrier_info.rs: Deprecation warnings
- scope_manager.rs: Deprecated fallback paths
- loop_body_carrier_promoter.rs: Trim binding_map support
- loop_body_cond_promoter.rs: Orchestrator updates
- loop_body_digitpos_promoter.rs: DigitPos binding_map support
Tests: 958/958 PASS (zero regressions)
Design: Type-safe BindingId mapping replaces string-based promoted variable resolution
Phase 78+ will delete deprecated code (~50 lines) and make binding_map required.
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-13 05:58:57 +09:00
342bcb8f50
fix(joinir): Phase 76 - Fix test struct initialization for promoted_bindings
2025-12-13 05:36:35 +09:00
11e68203c8
feat(joinir): Phase 76 - promoted_bindings map (dev-only)
...
Phase 76 introduces type-safe promotion tracking via promoted_bindings
(BindingId→BindingId map). Replaces fragile string matching hacks with
compiler-checked identity mapping.
Changes:
- carrier_info.rs: Added promoted_bindings field and resolution methods
- pattern4_carrier_analyzer.rs: Updated for BindingId integration
- pattern_pipeline.rs: Carrier resolution via promoted_bindings
- loop_with_break_minimal/tests.rs: Added promoted_bindings tests
- normalized/fixtures.rs: Extended with Phase 76 fixtures
Tests: 5/5 new unit tests PASS (record/resolve/merge/default/overwrite)
Tests: lib 958/958 PASS, normalized_dev 54/54 PASS (no regressions)
Design: Dual-path (BindingId OR name) enables gradual Phase 77+ transition.
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-13 05:35:14 +09:00
c18dde238a
feat(joinir): Phase 75 - BindingId pilot lookup (dev-only)
...
Phase 75 pilots BindingId-based variable lookup in the ScopeManager and
ConditionEnv components. Demonstrates "BindingId priority → name fallback"
strategy with comprehensive testing and zero production impact.
Changes:
- scope_manager.rs: Added lookup_with_binding() trait method
- condition_env.rs: Implemented resolve_var_with_binding() with 3-tier fallback
- expr_lowerer.rs: Integrated pilot lookup paths
- condition_lowering_box.rs: Updated with BindingId support
Tests: 3/3 new pilot tests PASS (priority/fallback/legacy)
Tests: lib 958/958 PASS, normalized_dev 54/54 PASS (no regressions)
Design: Feature-gated with normalized_dev, enables Phase 76 expansion.
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com >
2025-12-13 05:35:04 +09:00
851bf4f8a5
design(joinir): Phase 73 - ScopeManager BindingId Migration Design + PoC
...
Phase 73 plans migration from name-based to BindingId-based scope management
in JoinIR lowering, aligning with MIR's lexical scope model.
Design decision: Option A (Parallel BindingId Layer) with gradual migration.
Migration roadmap: Phases 74-77, ~8-12 hours total, zero production impact.
Changes:
- phase73-scope-manager-design.md: SSOT design (~700 lines)
- phase73-completion-summary.md: Deliverables summary
- phase73-index.md: Navigation index
- scope_manager_bindingid_poc/: Working PoC (437 lines, dev-only)
Tests: 6/6 PoC tests PASS, lib 950/950 PASS
Implementation: Parallel layer (no changes to existing code paths)
🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-13 03:41:40 +09:00
c2df1cacf6
feat(joinir): Phase 70-B - Multihop Relay Passthrough Support (dev-only)
...
Phase 70-B relaxes runtime guard from "always error" to "unsupported only".
Adds structural detection (is_supported_multihop_pattern) to distinguish:
- Simple passthrough (no self-updates): ACCEPT
- Complex patterns (self-conflict, etc): REJECT with [ownership/relay:runtime_unsupported]
Changes:
- plan_validator.rs: +is_supported_multihop_pattern() method + unit tests
- normalized_joinir_min.rs: +2 integration tests for passthrough/rejection
- phase70-relay-runtime-guard.md: Phase 70 series status table added
Tests: normalized_dev 52/52 PASS, lib 950/950 PASS
Design: Structural detection only (no by-name branching)
🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com >
2025-12-13 03:41:20 +09:00
db9c9055fa
obs(joinir): Phase 72 - PHI Reserved Region Observation Complete
...
## Summary
Observed PHI dst ValueId distribution to determine if verifier can enforce
reserved region (0-99). **Conclusion: Verifier strengthening NOT recommended.**
## Key Finding
PHI dst allocation does NOT architecturally respect reserved region:
- PHI dst comes from `builder.next_value_id()` (host MirBuilder)
- Reserved region (0-99) is a JoinValueSpace contract for JoinIR lowering
- These are separate allocation pools with no enforcement mechanism
- Current stability is accidental (ValueId allocation ordering)
## Evidence
Manual verification (`apps/tests/loop_min_while.hako`):
- PHI dst = %3 (ValueId(3)) ✅ in reserved region
- Works because PHI allocated early in function (0-20 typical)
- JoinValueSpace allocates high (100+, 1000+)
- Accidental separation, not enforced
## Implementation
Added observation infrastructure (debug-only):
- `src/mir/join_ir/verify_phi_reserved.rs` (266 lines)
- PHI dst observer with distribution analyzer
- Region classifier (Reserved/Param/Local)
- Human-readable report generator
- Instrumentation at PHI allocation points:
- loop_header_phi_builder.rs:94, 151
- Debug-only `observe_phi_dst()` calls
## Test Results
- Unit tests: ✅ 4/4 PASS (verify_phi_reserved module)
- Lib tests: ✅ 950/950 PASS, 56 ignored
- Normalized tests: ✅ 54/54 PASS
- Manual verification: ✅ PHI dst in 0-99 observed
## Decision: Document, Don't Enforce
**Rationale**:
1. No architectural mechanism to enforce PHI dst ∈ [0, 99]
2. Adding verifier creates false assumptions about allocation order
3. Current system stable through separate pools (950/950 tests)
4. Future architectural fix possible (Phase 73+) but not urgent
## Documentation
- PHASE_72_SUMMARY.md: Executive summary and implementation record
- phase72-phi-reserved-observation.md: Detailed findings and analysis
- CURRENT_TASK.md: Phase 72 completion entry
## Next Steps
- Phase 73: Update architecture overview with Phase 72 findings
- Optional: Explicit PHI reserved pool (future enhancement)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-13 03:23:02 +09:00