feat(joinir): Phase 259 P0 - Pattern8 BoolPredicateScan + Copy binding fix
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>
This commit is contained in:
@ -22,8 +22,42 @@ Related:
|
||||
|
||||
## Proposed Approach (P0)
|
||||
|
||||
方針: prelude(nested-if)は既存 lowering のまま、loop 部分だけを scan パターンへ寄せる(構造で解決)。
|
||||
**P0 Design Decision: Pattern8(新規)採用**
|
||||
|
||||
P0 の狙い:
|
||||
- loop の core は “scan until mismatch” で、Pattern6(scan)と近い
|
||||
- ただし return 値が `i/-1` ではなく `true/false` なので、scan パターンの “return payload” を一般化する必要がある可能性がある
|
||||
### 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固定)
|
||||
|
||||
```nyash
|
||||
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 固定
|
||||
|
||||
Reference in New Issue
Block a user