Commit Graph

1409 Commits

Author SHA1 Message Date
1080dee58f fix(joinir): Phase 118 Pattern3 exit carrier PHI SSOT 2025-12-18 03:43:00 +09:00
ce7e2c1b91 refactor(env): centralize NYASH_JOINIR_STRUCTURE_ONLY flag
Moved NYASH_JOINIR_STRUCTURE_ONLY environment variable handling
from inline std::env::var() in routing.rs to a centralized helper
function in src/config/env/joinir_flags.rs.

Changes:
- Added joinir_structure_only_enabled() helper function
- Replaced direct env::var() call in routing.rs with helper
- Maintains existing behavior: default ON, NYASH_JOINIR_STRUCTURE_ONLY=0/off to disable
- Follows env module centralization pattern (Box Theory: separation of concerns)

Testing:
- cargo test --lib: 1126 passed 
- Regression: Phase 107 VM smoke 
- Phase 113/114 maintained 

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:19:14 +09:00
09ce24e132 feat(joinir): Phase 112 strict guard for StepTree required_caps
- Add control_tree_capability_guard.rs with check(tree, func_name, strict, dev)
- Allowlist: If, NestedIf, Loop, Return, Break, Continue
- Deny (strict): NestedLoop, TryCatch, Throw, Lambda, While, ForRange, Match, Arrow
- Wire into lower_function_body() (strict-only check)
- Error format: [joinir/control_tree/cap_missing/<Cap>] with 1-line Hint
- Unit tests: nested_loop_rejects, if_only_passes, strict_false_passes
- Default behavior unchanged (strict=false always Ok)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 01:38:25 +09:00
14730c227f feat(control_tree): add StepTreeContract and signature (dev-only) 2025-12-18 00:57:58 +09:00
9bcda215f8 refactor(joinir): split Pattern2 orchestrator into smaller steps 2025-12-18 00:44:31 +09:00
e4735f4054 refactor(control_tree): use ASTNode::span SSOT 2025-12-18 00:32:23 +09:00
3987aa5b06 refactor(joinir): drop unused break helper wrappers 2025-12-18 00:30:01 +09:00
e65bb791b9 refactor(builder): route debug logs via trace 2025-12-18 00:29:57 +09:00
2b5c141e22 feat(control_tree): add StepTree builder (dev-only) 2025-12-18 00:22:21 +09:00
a9f92f8f1a refactor(joinir): add hints for Phase107/104/100 policy rejects
- balanced_depth_scan: missing_tail_inc, missing_return_i hints
- read_digits: missing_eos_guard, digit_set_mismatch hints
- pinned: missing_host_id hint
- Gradual migration (representative cases only)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 23:45:49 +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
27e8e0f16a refactor(joinir): Phase 108 unify Pattern2 policy routing 2025-12-17 23:30:08 +09:00
3c1d8a824d feat(joinir): extend balanced depth-scan policy to object family 2025-12-17 23:09:19 +09:00
09dd10349f refactor(joinir): make Pattern2 body-local handling policy-driven 2025-12-17 23:00:26 +09:00
10a2f3b48b refactor(joinir): centralize balanced depth-scan policy decision 2025-12-17 22:59:27 +09:00
6036627920 fix(joinir): avoid false rejects in balanced depth-scan policy 2025-12-17 22:52:29 +09:00
d8ce9fdb99 fix(joinir): wire balanced depth-scan policy through Pattern2 2025-12-17 22:47:36 +09:00
9ec2e28b6a feat(joinir): add Pattern2 post-loop early return step 2025-12-17 22:32:55 +09:00
aa29dc8085 feat(joinir): emit balanced depth-scan derived vars 2025-12-17 22:32:50 +09:00
bf80789757 feat(joinir): route balanced depth-scan via Pattern2 policy 2025-12-17 22:32:43 +09:00
f1a570fd45 feat(joinir): Phase 107 balanced depth-scan policy (analysis-only) 2025-12-17 22:25:34 +09:00
5f4d8ba112 refactor(joinir): Phase 106 Pattern2 step boxes 2025-12-17 22:01:19 +09:00
368b363694 refactor(joinir): split Pattern2 facts from lowering orchestration 2025-12-17 21:34:11 +09:00
ae2a1d4339 refactor(joinir): boxify Pattern2 routing and schedule facts 2025-12-17 21:24:46 +09:00
950560a3d9 test(joinir): Phase 104 read_digits loop(true) parity 2025-12-17 18:29:27 +09:00
d859e46163 fix(llvm_py): tag stringish across copy/phi for concat 2025-12-17 16:57:06 +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
ad072e5e09 feat(joinir): string accumulator analyzer/spec
- Add AccumulatorKind::{Int, String} to MutableAccumulatorSpec
- Detect string accumulator pattern: out = out + ch (ch is Variable)
- Delegate string-ish type check to existing box facts
- Unit tests for Int vs String accumulator detection

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 16:33:11 +09:00
1b83a92aed test(llvm_py): cover duplicate incoming per pred 2025-12-17 16:12:22 +09:00
0ea2b7d2cb fix(llvm_py): stabilize PHI incoming selection (no overwrite by failed candidate) 2025-12-17 16:12:16 +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
8a40b5700a feat(joinir): detect mutable accumulator pattern (AST-only, spec minimal)
- Implement MutableAccumulatorAnalyzer in loop_pattern_detection/
- Detect shape: target = target + x (Add only, x ∈ {Var, Literal})
- Does NOT check read-only (delegated to ScopeManager)
- Multiple assignments → return None (not our pattern, let other code handle it)
- 6 unit tests covering OK/NG cases
- Error prefix: [joinir/mutable-acc-spec]

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 06:10:38 +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
6d73fc3404 feat(llvm): Phase 97 Box/Policy refactoring complete
Box化完了:
- CallRoutePolicyBox: Call routing SSoT
- PrintArgMarshallerBox: Print marshalling SSoT
- TypeFactsBox: Type propagation SSoT
- PhiSnapshotPolicyBox: PHI contract SSoT
- PluginErrorContext: Structured error reporting

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 04:14:26 +09:00
65763c1ed6 feat(llvm): Phase 97 - Call/PHI/Plugin強化 + リファクタリング準備
## 概要
LLVM backend のCall処理、PHI wiring、Plugin loader を強化。
次のリファクタリング(箱化モジュール化)のための準備も含む。

## 変更内容

### LLVM Call処理強化
- `mir_call/__init__.py`: Call ルーティングロジック改善
- `mir_call/global_call.py`: print処理の marshal強化
- `mir_call/method_call.py`: メソッド呼び出し処理改善
- `boxcall.py`: BoxCall処理改善

### PHI処理強化
- `phi_manager.py`: PHI管理改善
- `phi_wiring/wiring.py`: PHI配線ロジック強化(+17行)
- `phi_wiring/tagging.py`: Type tagging改善
- `resolver.py`: Value解決ロジック強化(+34行)

### Copy伝播
- `copy.py`: Copy命令のType tag伝播追加(+10行)

### Plugin loader強化
- `library.rs`: エラー出力改善、[plugin/missing]ログ追加(+34行)
- fail-fast強化

### テスト
- `phase97_json_loader_escape_llvm_exe.sh`: Phase 97 E2Eテスト追加
- `phase97_next_non_ws_llvm_exe.sh`: Phase 97 E2Eテスト追加

### その他
- `nyash_kernel/lib.rs`: Kernel側の改善(+23行)

## 統計
- 14ファイル変更
- +256行 / -53行 = +203 net

## 次のリファクタリング準備
以下の箇所がリファクタリング対象として識別済み:
1. Call ルーティング箱の明文化
2. print の marshal 箱
3. TypeFacts/Tagging 箱の一本化
4. PHI Snapshot 契約のSSOT
5. Plugin loader のエラー出力統合

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 03:51:03 +09:00
af8c00dedb test(joinir): add break condition extraction SSOT tests 2025-12-17 02:12:34 +09:00
bc1a09f2c3 fix(joinir): Phase 96 next_non_ws break condition SSOT 2025-12-17 01:59:21 +09:00
ad67d50798 refactor(joinir): unify policy decisions and trim routing 2025-12-17 01:20:35 +09:00
8e17534829 refactor(joinir): move P5b escape policy under patterns/policies 2025-12-17 01:14:07 +09:00
e2cf15b141 test: isolate box factory policy env in tests 2025-12-17 01:06:46 +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
51017a0f9a feat(joinir): Phase 92 P0-2 - Skeleton to LoopPatternContext (Option A)
SSOT principle: Pass canonicalizer-derived ConditionalStep info to Pattern2 lowerer
without re-detecting from AST.

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

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

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 15:22:29 +09:00
6169ae03d6 docs(phase-92): Phase 92 P0-1 - ConditionalStep contract (SSOT) documentation
### Changes

#### 1. skeleton_types.rs - ConditionalStep Contract Documentation
Added comprehensive SSOT contract documentation for `UpdateKind::ConditionalStep`:

**Invariants** (Fail-Fast):
1. Single Update: Updates same carrier exactly once per iteration
2. Constant Deltas: Both then_delta and else_delta are compile-time constants
3. Pure Condition: Escape condition has no side effects
4. No Reassignment: Carrier not reassigned elsewhere in loop body
5. Deterministic: Update path determined solely by escape condition

**Supported Use Cases**:
- Escape sequence handling (e.g., `if ch == '\\' { i += 2 } else { i += 1 }`)
- Conditional skip patterns (e.g., `if skip { pos += len } else { pos += 1 }`)

**Fail-Fast Conditions**:
- Multiple updates → Error
- Non-constant deltas → Error
- Side-effect conditions → Error
- Carrier reassignment → Error

**Lowering Strategy** (Phase 92 P0):
Pattern2Break handles ConditionalStep by generating if-else in JoinIR with PHI merge.

### Context

Phase 92 P0-1 complete: Contract (SSOT) established for ConditionalStep.

Next step: P0-2 - Add ConditionalStep support to Pattern2 lowerer.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 15:07:40 +09:00