refactor(joinir): Extract legacy binding path to routing_legacy_binding.rs
Phase 179-A Step 2: Separate LoopFrontendBinding JSON construction logic into dedicated module for better organization. Changes: - New file: routing_legacy_binding.rs (223 lines) - routing.rs: cf_loop_joinir_impl() simplified to 15 lines (delegates to legacy path) - Routing now clearly separates pattern-based vs. legacy binding paths Benefits: - Clear separation of concerns (pattern router vs. legacy whitelist) - routing.rs reduced from 364 to 146 lines (60% reduction) - Legacy path isolated for future deprecation
This commit is contained in:
@ -40,6 +40,19 @@ JoinIR ラインで守るべきルールを先に書いておくよ:
|
||||
- JoinIR が対応していないループパターン / if パターンは、必ず `[joinir/freeze]` 等で明示的にエラーにする。
|
||||
- LoopBuilder 等へのサイレントフォールバックは禁止。
|
||||
|
||||
7. **Param の役割(ParamRole)を分ける**
|
||||
- JoinIR 側で扱うパラメータは概念的に 3 種類に分かれる:
|
||||
- 条件専用(Condition param): 継続条件や break 条件だけに使う値
|
||||
- キャリア(Carrier param): ループ状態(pos/result など)として更新される値
|
||||
- 式結果(Expr param): ループが式として返す値
|
||||
- ExitLine / Header PHI / InstructionRewriter は **Carrier param だけ** を対象にし、Condition/Expr param は上書きしない。
|
||||
- 現状は ConditionBinding/ExitMeta/JoinFragmentMeta で役割を区別しており、将来 ParamRole enum として明示する予定。
|
||||
|
||||
8. **LoopHeader PHI dst は予約領域(上書き禁止)**
|
||||
- LoopHeaderPhiBuilder が生成したヘッダ PHI の dst ValueId は「現在のループ値」の SSOT として扱い、
|
||||
BoundaryInjector や InstructionRewriter が `Copy` などで二度書きすることを禁止する。
|
||||
- merge ラインでは「ヘッダ PHI dst に対する新しい定義が出てきたら debug モードで panic する」ことで契約違反を早期検出する。
|
||||
|
||||
---
|
||||
|
||||
## 2. 主な箱と責務
|
||||
|
||||
@ -33,9 +33,9 @@
|
||||
| P2: Break | `joinir_min_loop.hako` | 単純 | 条件付きbreak | なし | なし | Outer | 単一 |
|
||||
| P3: If‑PHI | `loop_if_phi.hako` | 単純 | なし | なし | if‑PHI | Outer | 条件付き |
|
||||
| P4: Continue | `loop_continue_pattern4` | 単純 | なし | 条件付きcont | なし | Outer | 単一 |
|
||||
| P5: Trim‑like* | `TrimTest.trim`(設計中) | 単純 | 条件付きbreak | なし | なし | BodyLocal | 単一 |
|
||||
| P5: Trim‑like* | `TrimTest.trim`(設計中) | 単純 | 条件付きbreak | なし | なし | BodyLocal | 複数 |
|
||||
|
||||
\*P5 は Phase 171 時点では「検出+安全性判定」まで。実際の JoinIR lower は Phase 172 以降の仕事。
|
||||
\*P5 は Phase 171 時点では「検出+安全性判定」までだったが、Phase 172–176 で Trim / `_skip_whitespace` / `_parse_string` 最小版について JoinIR→MIR lower と複数キャリア更新まで実装済み。
|
||||
|
||||
ここまでで:
|
||||
|
||||
@ -209,4 +209,3 @@ loop (i < n) {
|
||||
JsonParserBox / Trim 系ループのインベントリと、どの Pattern に入るかの観測ログ。
|
||||
- `phase171-pattern5-loop-inventory.md`
|
||||
Trim/JsonParser 向け Pattern5(LoopBodyLocal 条件)設計の進捗。
|
||||
|
||||
|
||||
71
docs/development/current/main/phase178-string-detection.md
Normal file
71
docs/development/current/main/phase178-string-detection.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Phase 178: LoopUpdateAnalyzer String Detection
|
||||
|
||||
## Summary
|
||||
|
||||
Phase 178 extends `LoopUpdateAnalyzer` to detect string/complex carrier updates,
|
||||
enabling Fail-Fast behavior for unsupported patterns.
|
||||
|
||||
## Changes
|
||||
|
||||
### 1. UpdateRhs Enum Extension (`loop_update_analyzer.rs`)
|
||||
|
||||
Added two new variants:
|
||||
- `StringLiteral(String)` - for `result = result + "x"` patterns
|
||||
- `Other` - for method calls and complex expressions
|
||||
|
||||
### 2. analyze_rhs Extension
|
||||
|
||||
Extended to detect:
|
||||
- String literals: `ASTNode::Literal { value: LiteralValue::String(_) }`
|
||||
- Method calls: `ASTNode::MethodCall { .. }`
|
||||
- Other complex expressions: `ASTNode::Call`, `ASTNode::BinaryOp`, etc.
|
||||
|
||||
### 3. Pattern 2/4 can_lower Updates
|
||||
|
||||
Both `pattern2_with_break.rs` and `pattern4_with_continue.rs` now check for
|
||||
string/complex updates in `can_lower()` and return `false` if detected.
|
||||
|
||||
This triggers a clear error message instead of silent incorrect behavior.
|
||||
|
||||
### 4. Legacy Fallback Comment Fixes
|
||||
|
||||
Updated misleading comments about "legacy fallback" - LoopBuilder was removed
|
||||
in Phase 187-2 and all loops must use JoinIR.
|
||||
|
||||
## Behavior
|
||||
|
||||
When a loop contains string concatenation like:
|
||||
```nyash
|
||||
loop(i < limit) {
|
||||
result = result + "x" // String update
|
||||
i = i + 1
|
||||
}
|
||||
```
|
||||
|
||||
Phase 178 now produces a clear error:
|
||||
```
|
||||
[pattern2/can_lower] Phase 178: String/complex update detected, rejecting Pattern 2 (unsupported)
|
||||
[ERROR] MIR compilation error: [joinir/freeze] Loop lowering failed:
|
||||
JoinIR does not support this pattern, and LoopBuilder has been removed.
|
||||
```
|
||||
|
||||
## Test Results
|
||||
|
||||
- P1 (simple while): OK
|
||||
- P2 (break + int carriers): OK
|
||||
- P4 (continue + multi-carrier): OK
|
||||
- String loops: Fail-Fast with clear error
|
||||
|
||||
## Known Issues
|
||||
|
||||
- **79 global test failures**: Pre-existing issue, NOT caused by Phase 178
|
||||
- Confirmed by `git stash` test - failures exist in HEAD~1
|
||||
- Tracked separately from Phase 178
|
||||
|
||||
## Future Work
|
||||
|
||||
To support string loops, either:
|
||||
1. Add JoinIR instructions for string concatenation (Option A)
|
||||
2. Process loop body statements in MIR alongside JoinIR control flow (Option B)
|
||||
|
||||
Phase 178 provides the detection foundation for future string support.
|
||||
Reference in New Issue
Block a user