feat(joinir): Phase 45-46 read_quoted_from IfMerge implementation

Phase 45: read_quoted_from JoinIR Frontend/Bridge
- Implement lower_read_quoted_pattern() for Guard if + Loop with break + accumulator pattern
- Add T1-T4 Route B E2E tests (all PASS)
- Create phase45_read_quoted_fixture.hako for Route A testing

Phase 46: IfMerge extension for loop-internal if-body reassignment
- Add escape handling: if ch == "\\" { i = i+1; ch = s.substring(...) }
- Use IfMerge to merge i and ch after if-body (speculative execution)
- T5 PASS: "a\"b" → 'a"b' (escape handling works!)

Dev flags:
- HAKO_JOINIR_READ_QUOTED=1: Enable Phase 45 JoinIR route
- HAKO_JOINIR_READ_QUOTED_IFMERGE=1: Enable Phase 46 IfMerge escape handling

Test results (Route B):
- T1: "abc" → 'abc' 
- T2: "" → '' 
- T3: abc → '' 
- T4: xx"def" → 'def' 
- T5: "a\"b" → 'a"b' 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-28 17:13:52 +09:00
parent 66098fb9c8
commit d3eff1fceb
10 changed files with 1393 additions and 92 deletions

View File

@ -0,0 +1,45 @@
// Phase 45: read_quoted_from JoinIR fixture tests
// This file tests the original MiniJsonCur.read_quoted_from behavior
// and will be used for A/B testing (Route A vs Route B)
using lang.src.vm.boxes.json_cur
static box Main {
main(args) {
// Test 1: Simple quoted string "abc" -> abc
local s1 = "\"abc\""
local r1 = MiniJsonCur.read_quoted_from(s1, 0)
print("T1:" + r1)
if r1 != "abc" { print("FAIL:T1") return 1 }
// Test 2: Empty quoted string "" -> (empty)
local s2 = "\"\""
local r2 = MiniJsonCur.read_quoted_from(s2, 0)
print("T2:" + r2)
if r2 != "" { print("FAIL:T2") return 1 }
// Test 3: Not starting with quote -> (empty, guard if)
local s3 = "abc"
local r3 = MiniJsonCur.read_quoted_from(s3, 0)
print("T3:" + r3)
if r3 != "" { print("FAIL:T3") return 1 }
// Test 4: Offset position xx"def" at pos 2 -> def
local s4 = "xx\"def\""
local r4 = MiniJsonCur.read_quoted_from(s4, 2)
print("T4:" + r4)
if r4 != "def" { print("FAIL:T4") return 1 }
// Test 5: Escape sequence "a\"b" -> a"b
// KNOWN ISSUE: Variable reassignment inside if-block doesn't generate PHI
// See Phase 45 README for details. JoinIR IfMerge should fix this.
// Skipping this test for now.
// local s5 = "\"a\\\"b\""
// local r5 = MiniJsonCur.read_quoted_from(s5, 0)
// print("T5:" + r5)
// if r5 != "a\"b" { print("FAIL:T5") return 1 }
print("ALL_PASS")
return 0
}
}