feat(joinir): Phase 259 P0 complete - Pattern8 final fixes + docs (pre-block-params migration)
Phase 259 P0: Pattern8 (BoolPredicateScan) 完全完了 is_integer/1 を Pattern8 で受理し、VM/LLVM EXE 両方で動作確認完了。 次の大工事(block-parameterized CFG への移行)前のマイルストーンとして記録。 ## Key Fixes Applied 1. **skipped_entry_redirects** (instruction_rewriter.rs) - k_exit のスキップ時、entry block 参照を exit_block_id へリダイレクト - BasicBlockId not found エラーを根治 2. **loop_var_name** (pattern8_scan_bool_predicate.rs) - merge_entry_block 選択に使用(`Some(parts.loop_var.clone())`) - 未設定時の誤った entry block 選択を修正 3. **loop_invariants** (pattern8_scan_bool_predicate.rs) - PHI-free 不変量パラメータ(`[(me, me_host), (s, s_host)]`) - loop_var_name 設定時、BoundaryInjector が join_inputs Copy を全スキップするため必要 - Pattern6 と同じ設計(header PHI で不変量を保持) 4. **expr_result** (pattern8_scan_bool_predicate.rs) - k_exit からの返り値を明示設定(`Some(join_exit_value)`) - Pattern7 style(推測ではなく明示) 5. **Smoke test scripts** - set +e パターンで exit code 7 をキャプチャ - LLVM EXE スクリプトにコメント追加(tools/build_llvm.sh 経由の明記) ## Contract Documentation - join-explicit-cfg-construction.md に Pattern8 契約の具体例を追加 - "pattern増でも推測増にしない" の実例として記録 - loop_var_name / loop_invariants / expr_result / jump_args_layout の契約を明示 - 20-Decisions.md に正規化(Semantic/Plumbing)の分離方針を追記 - DOCS_LAYOUT.md に重要ドキュメントへの参照を追加 ## Test Results - ✅ VM smoke test: `[PASS] phase259_p0_is_integer_vm` (exit 7) - ✅ LLVM EXE: tools/build_llvm.sh 経由で exit 7 確認 - ✅ --verify: PASS ## Next FAIL (Phase 260+) - Function: `Main.main/0` in `apps/examples/json_lint/main.hako` - Error: `[cf_loop/pattern2] Failed to extract break condition from loop body` - Pattern: Nested loop(外側 loop + 内側 loop with break) 🚀 次の大工事: block-parameterized CFG への移行を開始します。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
Status: Active
|
||||
Scope: `StringUtils.is_integer/1`(nested-if + loop)を JoinIR で受理して `--profile quick` を進める。
|
||||
Status: ✅ P0 Complete
|
||||
Scope: `StringUtils.is_integer/1`(nested-if + loop)を JoinIR で受理して `--profile quick` を進める。
|
||||
Related:
|
||||
- Now: `docs/development/current/main/10-Now.md`
|
||||
- Phase 258: `docs/development/current/main/phases/phase-258/README.md`
|
||||
@ -7,9 +7,51 @@ Related:
|
||||
|
||||
# Phase 259: `StringUtils.is_integer/1` (nested-if + loop)
|
||||
|
||||
## P0 Result (2025-12-21)
|
||||
|
||||
- **is_integer/1**: Pattern8 で認識・実行成功 ✅
|
||||
- **VM smoke test**: `[PASS] phase259_p0_is_integer_vm` ✅
|
||||
- **Exit code**: 7(is_integer("123") == true)
|
||||
- **json_lint_vm**: まだ FAIL(別問題: nested-loop with break / Pattern2)
|
||||
|
||||
### Key Fixes Applied
|
||||
|
||||
1. `expr_result = Some(join_exit_value)` - Pattern7 style で明示設定
|
||||
2. `loop_var_name = Some(parts.loop_var.clone())` - merge_entry_block 選択用
|
||||
3. `loop_invariants = [(me, me_host), (s, s_host)]` - PHI-free 不変量パラメータ
|
||||
4. `skipped_entry_redirects` - k_exit のスキップ時ブロック参照リダイレクト
|
||||
|
||||
## Current Status (SSOT)
|
||||
|
||||
- Current first FAIL: `json_lint_vm / StringUtils.is_integer/1`
|
||||
- ✅ is_integer/1 は Pattern8 で解決
|
||||
- ❌ json_lint_vm は別の nested-loop with break パターンで失敗中(Phase 260+)
|
||||
|
||||
### Next FAIL (Phase 260+)
|
||||
|
||||
- **Function**: `Main.main/0` in `apps/examples/json_lint/main.hako`
|
||||
- **Error**: `[cf_loop/pattern2] Failed to extract break condition from loop body`
|
||||
- **Pattern**: Nested loop(外側 `loop(i < cases.length())` 内で内側 `loop(j < valid.length())` + break)
|
||||
- **AST Structure**:
|
||||
```
|
||||
loop(i < cases.length()) {
|
||||
local s = ...
|
||||
local ok = 0
|
||||
local j = 0
|
||||
loop(j < valid.length()) { // ← 内側ループ
|
||||
if (s == valid.get(j)) {
|
||||
ok = 1
|
||||
break // ← Pattern2 が抽出失敗
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
if (ok == 1) { print("OK") } else { print("ERROR") }
|
||||
i = i + 1
|
||||
}
|
||||
```
|
||||
- **Reproduce**:
|
||||
```bash
|
||||
./target/release/hakorune --backend vm apps/examples/json_lint/main.hako
|
||||
```
|
||||
- Shape summary(ログ由来):
|
||||
- prelude: nested-if to compute `start` (handles leading `"-"`)
|
||||
- loop: `loop(i < s.length()) { if not this.is_digit(s.substring(i, i+1)) { return false } i = i + 1 }`
|
||||
|
||||
Reference in New Issue
Block a user