fix(joinir): Phase 196 Select double-remap bug in instruction_rewriter
Root cause: PHI inputs were being remapped twice in instruction_rewriter.rs - Line 304: remap_instruction() already remapped JoinIR → Host ValueIds - Line 328: remap_value() attempted to remap again → undefined ValueIds Fix: Only remap block IDs, use already-remapped ValueIds as-is Test results: - phase195_sum_count.hako → 93 ✅ (multi-carrier P3) - loop_if_phi.hako → sum=9 ✅ (single-carrier P3) - loop_min_while.hako → 0,1,2 ✅ (Pattern 1) - joinir_min_loop.hako → RC:0 ✅ (Pattern 2) - No [joinir/freeze], no regressions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -385,3 +385,190 @@ Section 7.2 "残タスク" に追記:
|
||||
### 判断基準
|
||||
- Phase 194 の実戦投入で「どこが詰まったか」を見て優先順位決定
|
||||
- 無理に全部対応しない(Fail-Fast で課題を明確化)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Status
|
||||
|
||||
**完了日**: 2025-12-09
|
||||
|
||||
### 実装サマリ
|
||||
|
||||
**JoinIR 対応ループ** (4/10):
|
||||
- ✅ _skip_whitespace (Pattern 2) - Already whitelisted
|
||||
- ✅ _trim (leading) (Pattern 5) - Already whitelisted
|
||||
- ✅ _trim (trailing) (Pattern 5) - Already whitelisted
|
||||
- ✅ _match_literal (Pattern 2) - Already whitelisted
|
||||
|
||||
**保留ループ** (6/10):
|
||||
- ❌ _parse_number - ConditionEnv constraint (`digits.indexOf()`)
|
||||
- ❌ _atoi - ConditionEnv constraint (`digits.indexOf()`)
|
||||
- ❌ _parse_string - Complex carriers (escaped flag + continue)
|
||||
- ❌ _unescape_string - Complex carriers (multiple flags)
|
||||
- ❌ _parse_array - Multiple MethodCalls
|
||||
- ❌ _parse_object - Multiple MethodCalls
|
||||
|
||||
### E2E テスト結果
|
||||
|
||||
**テスト環境**:
|
||||
```bash
|
||||
cargo build --release
|
||||
NYASH_DISABLE_PLUGINS=1 NYASH_JOINIR_CORE=1 ./target/release/hakorune tools/hako_shared/json_parser.hako
|
||||
```
|
||||
|
||||
**結果**: ❌ Compilation Error (Expected - Fail-Fast Strategy)
|
||||
|
||||
**エラー内容**:
|
||||
```
|
||||
[ERROR] ❌ MIR compilation error: [cf_loop/pattern2] Lowering failed: [joinir/pattern2] Unsupported condition: uses loop-body-local variables: ["digit_pos"]. Pattern 2 supports only loop parameters and outer-scope variables. Consider using Pattern 5+ for complex loop conditions.
|
||||
```
|
||||
|
||||
**分析**:
|
||||
- `_parse_number` の `digits.indexOf(ch)` が Phase 193 ConditionEnv 制約に引っかかった
|
||||
- `digits` は外部ローカル変数(function-scoped)だが、ConditionEnv には含まれない
|
||||
- **Fail-Fast 戦略通り**: 無理に直さず、Phase 200+ に保留
|
||||
|
||||
### 退行テスト結果 (✅ All Pass)
|
||||
|
||||
```bash
|
||||
# Phase 190: NumberAccumulation
|
||||
./target/release/hakorune apps/tests/phase190_atoi_impl.hako
|
||||
# Expected: 12
|
||||
# Result: ✅ 12 (RC: 0)
|
||||
|
||||
# Phase 191: Body-local init
|
||||
./target/release/hakorune apps/tests/phase191_body_local_atoi.hako
|
||||
# Expected: 123
|
||||
# Result: ✅ 123 (RC: 0)
|
||||
|
||||
# Phase 193: MethodCall in init
|
||||
./target/release/hakorune apps/tests/phase193_init_method_call.hako
|
||||
# Expected: Compilation success
|
||||
# Result: ✅ RC: 0
|
||||
```
|
||||
|
||||
**結論**: 既存インフラに退行なし ✅
|
||||
|
||||
### 技術的発見
|
||||
|
||||
#### 1. **ConditionEnv 制約の明確化** (Phase 200+ 課題)
|
||||
|
||||
**現状** (Phase 193):
|
||||
- ConditionEnv に含まれる変数:
|
||||
- ✅ Loop parameters (loop variable)
|
||||
- ✅ Condition-only bindings (外部変数のループ前評価)
|
||||
- ✅ Body-local variables (ループ内で定義)
|
||||
- ✅ Carrier variables (ループで更新される変数)
|
||||
|
||||
**含まれない変数**:
|
||||
- ❌ Function-scoped local variables (例: `digits`)
|
||||
|
||||
**影響を受けたループ**:
|
||||
- `_parse_number`: `local digits = "0123456789"` → `digit_pos = digits.indexOf(ch)`
|
||||
- `_atoi`: 同様に `digits.indexOf(ch)` 依存
|
||||
|
||||
**解決策案** (Phase 200+):
|
||||
1. **ConditionEnv 拡張**: Function-scoped variables も ConditionEnv に含める
|
||||
2. **.hako リライト**: `digits.indexOf(ch)` を `(ch >= "0" && ch <= "9")` に置換
|
||||
3. **専用パターン**: `indexOf` 専用の Pattern 実装
|
||||
|
||||
#### 2. **P5 Trim Pattern の実用性確認** (✅ 動作確認済み)
|
||||
|
||||
**発見**: Trim pattern が `_trim` で正常動作
|
||||
- ✅ Leading whitespace trim (Pattern 5)
|
||||
- ✅ Trailing whitespace trim (Pattern 5)
|
||||
- ✅ TrimLoopLowerer が `ch` を `is_ch_match` carrier に昇格
|
||||
- ✅ Whitespace check (`[" ", "\t", "\n", "\r"]`) を JoinIR で生成
|
||||
|
||||
**技術詳細** (trace log):
|
||||
```
|
||||
[TrimLoopLowerer] Trim pattern detected! var='ch', literals=["\r", "\n", "\t", " "]
|
||||
[TrimLoopLowerer] LoopBodyLocal 'ch' promoted to carrier 'is_ch_match'
|
||||
[TrimLoopLowerer] Added carrier 'is_ch_match' to ConditionEnv
|
||||
```
|
||||
|
||||
#### 3. **Structure-Only Routing の有効性** (Phase 196 default)
|
||||
|
||||
**現状** (routing.rs Line 45-51):
|
||||
```rust
|
||||
let structure_only = match std::env::var("NYASH_JOINIR_STRUCTURE_ONLY") {
|
||||
Some("0") | Some("off") => false,
|
||||
_ => true, // ← Default: ON
|
||||
};
|
||||
```
|
||||
|
||||
**利点**:
|
||||
- ✅ Whitelist 不要 (関数名ベースの制約なし)
|
||||
- ✅ Pattern-based routing のみで判定
|
||||
- ✅ 段階的拡張が容易
|
||||
|
||||
**懸念**:
|
||||
- ⚠️ サポート外ループで compilation error (Fail-Fast)
|
||||
- ⚠️ ユーザーには `NYASH_JOINIR_STRUCTURE_ONLY=0` で回避可能
|
||||
|
||||
**結論**: 現状の Structure-only routing で Phase 194 の目的は達成可能
|
||||
|
||||
### 次のステップ
|
||||
|
||||
#### 優先度 High: Phase 200+ ConditionEnv 拡張
|
||||
|
||||
**目標**: `digits.indexOf()` 対応
|
||||
|
||||
**設計課題**:
|
||||
1. Function-scoped variables をどこまで ConditionEnv に含めるか
|
||||
2. スコープ解析の複雑化リスク
|
||||
3. `.hako` リライトで回避可能か検証
|
||||
|
||||
**影響ループ**: 2/10 (20%) - `_parse_number`, `_atoi`
|
||||
|
||||
#### 優先度 Medium: Phase 195 Pattern 3 拡張
|
||||
|
||||
**目標**: Complex carriers (多段フラグ) 対応
|
||||
|
||||
**設計課題**:
|
||||
1. `is_escape`, `has_next`, `process_escape` のような多段フラグ
|
||||
2. If-in-loop + continue の組み合わせ
|
||||
|
||||
**影響ループ**: 2/10 (20%) - `_parse_string`, `_unescape_string`
|
||||
|
||||
#### 優先度 Low: Phase 195+ MethodCall 拡張
|
||||
|
||||
**目標**: Multiple MethodCalls in loop body
|
||||
|
||||
**設計課題**:
|
||||
1. Phase 193 は init のみ対応、body は未対応
|
||||
2. ネストした MethodCall の扱い
|
||||
|
||||
**影響ループ**: 2/10 (20%) - `_parse_array`, `_parse_object`
|
||||
|
||||
### 推奨ロードマップ
|
||||
|
||||
**Phase 194 完了判定**: ✅ 検証完了(Fail-Fast 戦略成功)
|
||||
|
||||
**Phase 195**: Pattern 3 extension (if-in-loop + multi-flag carriers)
|
||||
- Target: `_parse_string` (代表例)
|
||||
- Defer: `_unescape_string` (複雑すぎるため Pattern 3 安定後)
|
||||
|
||||
**Phase 200+**: ConditionEnv expansion (function-scoped locals)
|
||||
- Target: `_parse_number`, `_atoi`
|
||||
- Design: Function-scoped variable capture strategy
|
||||
|
||||
**Phase 201+**: MethodCall extension (multiple calls in body)
|
||||
- Target: `_parse_array`, `_parse_object`
|
||||
- Design: MethodCall orchestration in loop body
|
||||
|
||||
### まとめ
|
||||
|
||||
**Phase 194 の成果**:
|
||||
1. ✅ Loop inventory 完成 (4 target, 6 deferred)
|
||||
2. ✅ Routing infrastructure 確認 (structure-only mode 動作)
|
||||
3. ✅ 退行テスト全て pass (Phase 190-193)
|
||||
4. ✅ Fail-Fast 戦略実証 (`digits.indexOf` 制約明確化)
|
||||
5. ✅ P5 Trim pattern 実戦検証 (_trim で動作確認)
|
||||
|
||||
**Phase 194 の課題**:
|
||||
1. ConditionEnv 制約 (function-scoped variables 未対応)
|
||||
2. Complex carriers 未対応 (多段フラグ)
|
||||
3. Multiple MethodCalls 未対応
|
||||
|
||||
**全体評価**: Phase 194 は「検証フェーズ」として大成功。次の Phase への明確な道筋を示した。
|
||||
|
||||
Reference in New Issue
Block a user