// inttest — exercises lib/strconv integer parse: parseint / stoi64 / // stou64 / the iN/uN width wrappers. Run with // `out/bin/ww run lib/strconv/test/inttest.ww`. Same // signalled-then-fail()-with-+10 pattern as decimaltest / bytestest: // a non-zero exit code (signalled+10) pinpoints the failing case. // // Verbatim port of ref/hare/strconv/stoi.ha:56-86 (stoi/stoi_bases) and // stou.ha:116-138 (stou/stou_bases). Hare's strconv integer tests are // flat assert SEQUENCES, not row-array tables — mirrored here as inline // per-case checks (feedback_test_match_hare_source: inline @test-fn for // verbatim ports). Each case sets `signalled` first so a failure's exit // code identifies the exact assertion. // // Lives in lib/strconv/test/ (not lib/strconv/) so `import strconv` // resolves to the lib/strconv DIRECTORY (pulls the full package), not // the strconv.ww FILE — same rationale as 922_decimal_run. // // Hex/oct/bin expected values are written in decimal (ww has no 0x/0o/0b // literal form for the expectation side); the original Hare radix form // is noted inline. package strconv; import strconv; import os; let signalled: i32 = 0; fn fail() void = { os.exit(signalled + 10); }; fn cki(id: i32, s: str, b: base, want: i64) void = { signalled = id; match (stoi64(s, b)) { case let v: i64 => if (v != want) { fail(); }; case let e: invalid => fail(); case let e: overflow => fail(); }; }; fn cki_inv(id: i32, s: str, b: base, idx: i32) void = { signalled = id; match (stoi64(s, b)) { case let v: i64 => fail(); case let e: invalid => if (e: i32 != idx) { fail(); }; case let e: overflow => fail(); }; }; fn cki_ovf(id: i32, s: str, b: base) void = { signalled = id; match (stoi64(s, b)) { case let v: i64 => fail(); case let e: invalid => fail(); case let e: overflow => { }; }; }; fn cku(id: i32, s: str, b: base, want: u64) void = { signalled = id; match (stou64(s, b)) { case let v: u64 => if (v != want) { fail(); }; case let e: invalid => fail(); case let e: overflow => fail(); }; }; fn cku_inv(id: i32, s: str, b: base, idx: i32) void = { signalled = id; match (stou64(s, b)) { case let v: u64 => fail(); case let e: invalid => if (e: i32 != idx) { fail(); }; case let e: overflow => fail(); }; }; fn cku_ovf(id: i32, s: str, b: base) void = { signalled = id; match (stou64(s, b)) { case let v: u64 => fail(); case let e: invalid => fail(); case let e: overflow => { }; }; }; fn cki32_ovf(id: i32, s: str, b: base) void = { signalled = id; match (stoi32(s, b)) { case let v: i32 => fail(); case let e: invalid => fail(); case let e: overflow => { }; }; }; fn cki32(id: i32, s: str, b: base, want: i32) void = { signalled = id; match (stoi32(s, b)) { case let v: i32 => if (v != want) { fail(); }; case let e: invalid => fail(); case let e: overflow => fail(); }; }; // ref/hare/strconv/stoi.ha:56-79. @test fn test_stoi64() void = { cki_inv(1, "", base.DEC, 0); cki_inv(2, "abc", base.DEC, 0); cki_inv(3, "1a", base.DEC, 1); cki_inv(4, "+", base.DEC, 1); cki_inv(5, "-+", base.DEC, 1); cki_inv(6, "-z", base.DEC, 1); cki_ovf(7, "9223372036854775808", base.DEC); cki_ovf(8, "-9223372036854775809", base.DEC); cki(9, "0", base.DEC, 0); cki(10, "1", base.DEC, 1); cki(11, "+1", base.DEC, 1); cki(12, "-1", base.DEC, -1); cki(13, "9223372036854775807", base.DEC, 9223372036854775807i64); // I64_MIN. Spelled -I64_MAX-1 (Hare's own two's-complement identity, // stoi64 comment in stoi.ha:11) because the wwstage mis-lexes the // direct literal -9223372036854775808 (and types.I64_MIN) to 0 — // proj #245. The INPUT string is unaffected; stoi64 parses it to the // correct value on both stages. This isolates the parse test from #245. cki(14, "-9223372036854775808", base.DEC, -9223372036854775807i64 - 1i64); // width wrapper boundaries (ref/hare/strconv/stoi.ha:74-78). cki32_ovf(15, "2147483648", base.DEC); cki32_ovf(16, "-2147483649", base.DEC); cki32(17, "2147483647", base.DEC, 2147483647i32); cki32(18, "-2147483648", base.DEC, -2147483648i32); }; // ref/hare/strconv/stoi.ha:81-86. @test fn test_stoi64_bases() void = { cki(20, "-7f", base.HEX, -127i64); // -0x7f cki(21, "7F", base.HEX, 127i64); // 0x7f cki(22, "37", base.OCT, 31i64); // 0o37 cki(23, "-110101", base.BIN, -53i64); // -0b110101 }; // ref/hare/strconv/stou.ha:116-130. @test fn test_stou64() void = { cku_inv(30, "", base.DEC, 0); cku_inv(31, "+", base.DEC, 1); cku_inv(32, "+a", base.DEC, 1); cku_inv(33, "abc", base.DEC, 0); cku_inv(34, "1a", base.DEC, 1); cku_ovf(35, "18446744073709551616", base.DEC); cku_ovf(36, "184467440737095516150", base.DEC); cku_ovf(37, "-1", base.DEC); cku(38, "0", base.DEC, 0u64); cku(39, "1", base.DEC, 1u64); cku(40, "18446744073709551615", base.DEC, 18446744073709551615u64); }; // ref/hare/strconv/stou.ha:132-138. @test fn test_stou64_bases() void = { cku(41, "f", base.HEX_LOWER, 15u64); // 0xf cku(42, "7f", base.HEX, 127u64); // 0x7f cku(43, "7F", base.HEX, 127u64); // 0x7f cku(44, "37", base.OCT, 31u64); // 0o37 cku(45, "110101", base.BIN, 53u64); // 0b110101 }; export fn main() i32 = { test_stoi64(); test_stoi64_bases(); test_stou64(); test_stou64_bases(); return 0; };