Commit Graph

831 Commits

Author SHA1 Message Date
7eec4ec0c8 feat(control_tree): Phase 123 if-only compare+return lowering (Normalized, dev-only)
Implements Phase 123 P3: If(cond_ast) minimal lowering with graceful degradation.

**What's Implemented**:
- If node lowering with minimal binary comparison (Variable op Integer)
- Supported operators: ==, !=, <, <=, >, >=
- Generates: Compare + Const + Ret structure
- Graceful degradation: returns Ok(None) for unsupported patterns

**Key Design Decisions**:
1. **Graceful Degradation**: Phase 123 limitations return `Ok(None)` instead of failing
   - Allows dev-only mode to coexist with legacy code
   - Error messages prefixed with `[phase123/...]` are caught
2. **Fail-Fast with Structured Errors**: All limitations use structured error codes
   - Format: `[phase123/category/specific]`
3. **Box-First Principles**:
   - `parse_minimal_compare`: Single responsibility parser
   - `verify_branch_is_return_literal`: Branch validation box
   - `lower_if_node`: If lowering box

**Implementation**:
- Added `lower_if_node`: If lowering with minimal compare
- Added `parse_minimal_compare`: Binary comparison parser
- Added `verify_branch_is_return_literal`: Branch validator
- Updated `lower_if_only_to_normalized` return type: `Result<Option<...>, ...>`
- Updated `test_return_variable_out_of_scope`: Verifies graceful degradation
- Added `test_if_minimal_compare`: Verifies If lowering structure

**Tests**: 8 passed (including graceful degradation test)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 05:50:09 +09:00
f72064f35a feat(control_tree): Phase 123 P1 return integer literal in Normalized if-only
- Add value_ast to StepStmtKind::Return for payload tracking
- Implement lower_return_value for Integer literal → Compute(Const) + Ret
- Add 3 unit tests: integer literal, void, variable fail-fast
- All tests passing (7 passed)
2025-12-18 05:37:13 +09:00
cc1a0946b0 feat(joinir/dev): build Normalized if-only module with structure verification (no behavior change)
Phase 122 P2-P3: Dev-only wiring + structure verification
- Wire Phase 122 emission into existing Phase 121 dev path
- Add verify_normalized_structure() for module validation
- Check: phase, function count, entry point, env args count
- Strict mode: fail-fast on structure mismatch
- No behavior change to existing execution path
2025-12-18 04:52:09 +09:00
7603ef8a6a feat(control_tree): emit Normalized JoinModule for if-only (dev-only)
Phase 122 P1: StepTree→Normalized JoinModule generation
- Generate env layout from writes (SSOT, deterministic)
- Minimal implementation: main function + Ret only
- Full If/Assign/Return lowering in future P2-P4
- Dev-only: no behavior change to existing path
2025-12-18 04:50:32 +09:00
89b868703f feat(joinir/dev): wire Phase 121 StepTree shadow lowering (strict fail-fast) 2025-12-18 04:34:43 +09:00
1e5432f61a feat(control_tree): add StepTree→Normalized shadow lowerer (if-only, dev-only) 2025-12-18 04:31:41 +09:00
dd125cb700 test(control_tree): cover facts→contract determinism 2025-12-18 04:19:14 +09:00
43d3e7c935 refactor(control_tree): split StepTree facts vs contract boxes 2025-12-18 04:18:37 +09:00
98061260a0 refactor(control_tree): store AST cond handles in StepTree (dev-only)
Phase 119: StepTree cond SSOT (AST handle)

- Add AstNodeHandle to StepNode::If and StepNode::Loop
- cond_ast holds Box<ASTNode> clone (dev-only, acceptable overhead)
- cond_sig (AstSummary) remains signature/log material
- signature_basis_string() unchanged (Span-free, deterministic)
- Tests: cond_ast population + signature stability confirmed
2025-12-18 04:09:00 +09:00
052040e59c refactor(joinir): extract ExitArgsCollectorBox for jump_args SSOT
Phase 118 refactoring: Box modularization for exit value collection.

# Changes
- Created `exit_args_collector.rs` with ExitArgsCollectorBox
- Extracted jump_args processing logic from instruction_rewriter.rs
- Implemented SSOT for offset calculation (0 vs 1 legacy layout)
- Added comprehensive unit tests (6 tests, all passing)

# Design
- **Responsibility**: Collects exit PHI inputs + carrier inputs from jump_args
- **SSOT**: Centralized offset calculation logic
- **Fail-Fast**: Validates jump_args length against exit_bindings
- **Phase 118 P2 Contract**: Uses boundary.exit_bindings as SSOT

# Key Features
- Filters ConditionOnly carriers (no exit PHI needed)
- Handles both direct mapping (offset=0) and legacy layout (offset=1)
- Strict mode: Fail-Fast on validation errors
- Non-strict mode: Warns and continues with best effort

# Test Results
- Unit tests: 6/6 PASS
- Phase 118 smoke tests: PASS (VM + LLVM)
- Phase 117 regression: PASS

# Reduced Code Complexity
- instruction_rewriter.rs: ~90 lines → ~25 lines (box call)
- Offset logic: Centralized in ExitArgsCollectorBox

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 03:56:21 +09:00
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
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
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
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
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
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