fn expect_int(label: String, got: Int, want: Int) -> Void { if got == want { println("ok " + label) } else { println("FAIL " + label + " got=" + int_to_str(got) + " want=" + int_to_str(want)) } } fn expect_str(label: String, got: String, want: String) -> Void { if str_eq(got, want) { println("ok " + label) } else { println("FAIL " + label + " got='" + got + "' want='" + want + "'") } } // 1. basic char access across a string let s: String = "hello" expect_int("char[0]=h", str_char_code(s, 0), 104) expect_int("char[4]=o", str_char_code(s, 4), 111) expect_int("char[5] OOB -> 0", str_char_code(s, 5), 0) expect_int("char[-1] OOB -> 0", str_char_code(s, -1), 0) expect_int("empty string OOB", str_char_code("", 0), 0) // 2. slices expect_str("slice(0,5)", str_slice(s, 0, 5), "hello") expect_str("slice(1,3)", str_slice(s, 1, 3), "el") expect_str("slice past end clamps", str_slice(s, 3, 99), "lo") expect_str("slice inverted -> empty", str_slice(s, 4, 2), "") // 3. DIFFERENT strings must not share a cached length (the real hazard) let a: String = "abc" let b: String = "abcdefghij" expect_int("a[2]=c", str_char_code(a, 2), 99) expect_int("a[3] OOB", str_char_code(a, 3), 0) expect_int("b[9]=j", str_char_code(b, 9), 106) expect_int("b[3]=d after a", str_char_code(b, 3), 100) expect_int("a[3] still OOB after b", str_char_code(a, 3), 0) // 4. many distinct strings interleaved — forces cache slot collisions fn interleave(n: Int) -> Int { let i: Int = 0 let bad: Int = 0 while i < n { let t: String = int_to_str(i) let l: Int = str_len(t) let last: Int = str_char_code(t, l - 1) let oob: Int = str_char_code(t, l) if oob != 0 { let bad2: Int = bad + 1 let bad: Int = bad2 } if last == 0 { let bad3: Int = bad + 1 let bad: Int = bad3 } let i2: Int = i + 1 let i: Int = i2 } return bad } expect_int("1000 interleaved strings, no bad reads", interleave(1000), 0) // 5. concatenation changes length — cache must not report the old one let g: String = "12345" let g2: String = g + "6789" expect_int("grown string len via char", str_char_code(g2, 8), 57) expect_int("original still bounded", str_char_code(g, 5), 0) println("done")