Pattern8 (Boolean Predicate Scan) implementation for is_integer/1:
- New pattern detection for `loop + if not predicate() { return false }`
- JoinIR lowerer with main/loop_step/k_exit structure
- Me receiver passed as param (by-name 禁止)
Key fixes:
1. expr_result = Some(join_exit_value) (Pattern7 style)
2. Tail-call: dst: None (no extra Ret instruction)
3. instruction_rewriter: Add `&& is_loop_header_with_phi` check
- Pattern8 has no carriers → no PHIs → MUST generate Copy bindings
- Without this, ValueId(103/104/105) were undefined
Status: Copy instructions now generated correctly, but exit block
creation issue remains (next step: Step A-C in指示書).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2.3 KiB
2.3 KiB
Status: Active
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 - Design goal:
docs/development/current/main/design/join-explicit-cfg-construction.md
Phase 259: StringUtils.is_integer/1 (nested-if + loop)
Current Status (SSOT)
- Current first FAIL:
json_lint_vm / StringUtils.is_integer/1 - 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 } - post:
return true - caps:
If,Loop,NestedIf,Return
- prelude: nested-if to compute
Goal
StringUtils.is_integer/1を JoinIR で受理し、quick の first FAIL を次へ進める
Proposed Approach (P0)
P0 Design Decision: Pattern8(新規)採用
Why Pattern8?
Pattern6(index_of系)は "見つける" scan(返り値: 整数 i or -1)で、is_integer は "全部検証する" predicate scan(返り値: 真偽値 true/false)。役割が異なるため、Pattern8 として分離した。
Pattern8 vs Pattern6
| Pattern6 (index_of系) | Pattern8 (is_integer系) | |
|---|---|---|
| 役割 | "見つける" scan | "全部検証する" predicate scan |
| Match形 | substring(...) == needle |
not predicate(ch) → early exit |
| 返り値 | Integer (i or -1) | Boolean (true/false) |
| Exit PHI | i(ループ状態変数) |
ret_bool(検証結果) |
| Carriers | [i] (LoopState) | [] (empty, expr_result のみ) |
JoinIR Contract
- jump_args_layout: ExprResultPlusCarriers(carriers=0)
- expr_result: Some(join_exit_value) - ret_bool from k_exit (pipeline handling)
- exit_bindings: Empty(carriers なし)
- SSOT:
join_inputs = entry_func.params.clone() - Me receiver: Passed as param [i, me, s] (by-name 禁止)
受理形(P0固定)
loop(i < s.length()) {
if not this.is_digit(s.substring(i, i + 1)) {
return false
}
i = i + 1
}
return true
- prelude の start 計算は許可(ただし i_init = start で渡す)
- predicate は Me method call(this.is_digit)のみ
- step は 1 固定