lib/encoding+math tests: hand-main plumbing -> assert (@test conversion B2)

This commit is contained in:
2026-06-10 18:52:53 +09:00
parent 6ef2bbcb95
commit 56450e68ce
6 changed files with 451 additions and 462 deletions

View File

@@ -26,8 +26,8 @@ fn encvec(input: str, expect: str) void = {
let outbuf: [128]u8;
let n: i32 = putstr(input, inbuf[0:128], 0);
let m: i32 = base32.encode(outbuf[0:128], inbuf[0:n]);
if (m != expect.len) { let _: i32 = 1/0; };
if (!streq(outbuf[0:m], expect)) { let _: i32 = 1/0; };
assert(!(m != expect.len));
assert(!(!streq(outbuf[0:m], expect)));
};
@test fn rfc4648_std() void = {
@@ -48,10 +48,10 @@ fn decvec(input: str, expect: str) void = {
let r: (i32 | base32.invalid) = base32.decode(outbuf[0:128], inbuf[0:n]);
match (r) {
case let m: i32 => {
if (m != expect.len) { let _: i32 = 1/0; };
if (!streq(outbuf[0:m], expect)) { let _: i32 = 1/0; };
assert(!(m != expect.len));
assert(!(!streq(outbuf[0:m], expect)));
};
case let e: base32.invalid => { let _: i32 = 1/0; };
case let e: base32.invalid => { abort(); };
};
};
@@ -70,8 +70,8 @@ fn enchexvec(input: str, expect: str) void = {
let outbuf: [128]u8;
let n: i32 = putstr(input, inbuf[0:128], 0);
let m: i32 = base32.encodehex(outbuf[0:128], inbuf[0:n]);
if (m != expect.len) { let _: i32 = 1/0; };
if (!streq(outbuf[0:m], expect)) { let _: i32 = 1/0; };
assert(!(m != expect.len));
assert(!(!streq(outbuf[0:m], expect)));
};
@test fn rfc4648_hex() void = {
@@ -96,18 +96,18 @@ fn enchexvec(input: str, expect: str) void = {
let enc: [16]u8;
let dec: [5]u8;
let m: i32 = base32.encode(enc[0:16], raw[0:5]);
if (m != 8) { let _: i32 = 1/0; };
assert(!(m != 8));
let r: (i32 | base32.invalid) = base32.decode(dec[0:5], enc[0:m]);
match (r) {
case let n: i32 => {
if (n != 5) { let _: i32 = 1/0; };
assert(!(n != 5));
let i: i32 = 0;
for (i < 5) {
if (dec[i] != raw[i]) { let _: i32 = 1/0; };
assert(!(dec[i] != raw[i]));
i += 1;
};
};
case let e: base32.invalid => { let _: i32 = 1/0; };
case let e: base32.invalid => { abort(); };
};
};
@@ -118,32 +118,32 @@ fn enchexvec(input: str, expect: str) void = {
let n: i32 = putstr("ABCD", inbuf[0:16], 0);
let r1: (i32 | base32.invalid) = base32.decode(outbuf[0:16], inbuf[0:n]);
match (r1) {
case let m: i32 => { let _: i32 = 1/0; };
case let m: i32 => { abort(); };
case let e: base32.invalid => void;
};
// Bad pad count (5 '=' is illegal — must be 0,1,3,4,6).
let n2: i32 = putstr("MZX=====", inbuf[0:16], 0);
let r2: (i32 | base32.invalid) = base32.decode(outbuf[0:16], inbuf[0:n2]);
match (r2) {
case let m: i32 => { let _: i32 = 1/0; };
case let m: i32 => { abort(); };
case let e: base32.invalid => void;
};
// Bad char ('1' is not in the std alphabet).
let n3: i32 = putstr("MZ1W6YTB", inbuf[0:16], 0);
let r3: (i32 | base32.invalid) = base32.decode(outbuf[0:16], inbuf[0:n3]);
match (r3) {
case let m: i32 => { let _: i32 = 1/0; };
case let m: i32 => { abort(); };
case let e: base32.invalid => void;
};
};
@test fn sizes() void = {
if (base32.encodedsize(0) != 0) { let _: i32 = 1/0; };
if (base32.encodedsize(1) != 8) { let _: i32 = 1/0; };
if (base32.encodedsize(5) != 8) { let _: i32 = 1/0; };
if (base32.encodedsize(6) != 16) { let _: i32 = 1/0; };
if (base32.decodedsize(8) != 5) { let _: i32 = 1/0; };
if (base32.decodedsize(16) != 10) { let _: i32 = 1/0; };
assert(!(base32.encodedsize(0) != 0));
assert(!(base32.encodedsize(1) != 8));
assert(!(base32.encodedsize(5) != 8));
assert(!(base32.encodedsize(6) != 16));
assert(!(base32.decodedsize(8) != 5));
assert(!(base32.decodedsize(16) != 10));
};
export fn main() i32 = {

View File

@@ -2,9 +2,8 @@
// Run with `out/bin/ww run lib/encoding/base64/base64_test.ww`. Mirrors
// Hare's base64 @test fns (ref/hare/encoding/base64/base64.ha:315,514,
// 601) over the RFC 4648 §10 vectors, table-driven (parallel arrays;
// tuple-row arrays are blocked by #111). Same signalled-then-fail()-
// with-+10 pattern as the rest of the 9xx stdlib tests; non-zero exit
// pinpoints the failing scenario.
// tuple-row arrays are blocked by #111). A failing row aborts via the
// assert/abort builtin (task #5 @test conversion).
//
// The streaming decoder (newdecoder) is deferred (#247-sibling), so the
// decode side is exercised through decodestr only.
@@ -16,11 +15,8 @@ import bytes;
import errors;
import io;
import memio;
import os;
import strings;
let signalled: i32 = 0;
fn fail() void = { os.exit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
@@ -38,19 +34,19 @@ fn streq(a: str, b: str) bool = {
fn enc_check(enc: *base64.encoding, raw: []u8, expect: str) void = {
let out: memio.stream = memio.dynamic();
match (base64.encode(&out.vt, enc, raw)) {
case let n: size => { if (n: i32 != raw.len) { fail(); }; };
case let e: io.error => fail();
case let n: size => { assert(!(n: i32 != raw.len)); };
case let e: io.error => abort();
};
if (!streq(memio.string(&out), expect)) { fail(); };
if (!streq(base64.encodestr(enc, raw), expect)) { fail(); };
assert(!(!streq(memio.string(&out), expect)));
assert(!(!streq(base64.encodestr(enc, raw), expect)));
};
// dec_check — decodestr(`encoded`) must round-trip back to `raw`.
// ref/hare/encoding/base64/base64.ha:514.
fn dec_check(enc: *base64.encoding, encoded: str, raw: []u8) void = {
match (base64.decodestr(enc, encoded)) {
case let b: []u8 => { if (!bytes.equal(b, raw)) { fail(); }; };
case let e: errors.invalid => fail();
case let b: []u8 => { assert(!(!bytes.equal(b, raw))); };
case let e: errors.invalid => abort();
};
};
@@ -58,7 +54,7 @@ fn dec_check(enc: *base64.encoding, encoded: str, raw: []u8) void = {
// ref/hare/encoding/base64/base64.ha:525.
fn inval_check(enc: *base64.encoding, encoded: str) void = {
match (base64.decodestr(enc, encoded)) {
case let b: []u8 => fail();
case let b: []u8 => abort();
case let e: errors.invalid => void;
};
};
@@ -105,7 +101,7 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = {
let raw: [3]u8 = [0xFBu8, 0xFFu8, 0xBFu8];
let s_std: str = base64.encodestr(&base64.std_encoding, raw[0:3]);
let s_url: str = base64.encodestr(&base64.url_encoding, raw[0:3]);
if (streq(s_std, s_url)) { fail(); };
assert(!(streq(s_std, s_url)));
dec_check(&base64.std_encoding, s_std, raw[0:3]);
dec_check(&base64.url_encoding, s_url, raw[0:3]);
@@ -148,22 +144,22 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = {
// ---- size calc ---- ref/hare/encoding/base64/base64.ha:601
@test fn sizes() void = {
if (base64.encodedsize(0) != 0) { fail(); };
if (base64.encodedsize(1) != 4) { fail(); };
if (base64.encodedsize(2) != 4) { fail(); };
if (base64.encodedsize(3) != 4) { fail(); };
if (base64.encodedsize(4) != 8) { fail(); };
if (base64.encodedsize(10) != 16) { fail(); };
if (base64.encodedsize(119) != 160) { fail(); };
if (base64.encodedsize(120) != 160) { fail(); };
if (base64.encodedsize(121) != 164) { fail(); };
if (base64.encodedsize(122) != 164) { fail(); };
if (base64.encodedsize(123) != 164) { fail(); };
if (base64.decodedsize(0) != 0) { fail(); };
if (base64.decodedsize(4) != 3) { fail(); };
if (base64.decodedsize(8) != 6) { fail(); };
if (base64.decodedsize(160) != 120) { fail(); };
if (base64.decodedsize(164) != 123) { fail(); };
assert(!(base64.encodedsize(0) != 0));
assert(!(base64.encodedsize(1) != 4));
assert(!(base64.encodedsize(2) != 4));
assert(!(base64.encodedsize(3) != 4));
assert(!(base64.encodedsize(4) != 8));
assert(!(base64.encodedsize(10) != 16));
assert(!(base64.encodedsize(119) != 160));
assert(!(base64.encodedsize(120) != 160));
assert(!(base64.encodedsize(121) != 164));
assert(!(base64.encodedsize(122) != 164));
assert(!(base64.encodedsize(123) != 164));
assert(!(base64.decodedsize(0) != 0));
assert(!(base64.decodedsize(4) != 3));
assert(!(base64.decodedsize(8) != 6));
assert(!(base64.decodedsize(160) != 120));
assert(!(base64.decodedsize(164) != 123));
};
// ---- round-trip every byte value 0..255 (std + url) ----
@@ -178,27 +174,27 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = {
let s: str = base64.encodestr(&base64.std_encoding, src[0:256]);
match (base64.decodestr(&base64.std_encoding, s)) {
case let b: []u8 => {
if (b.len != 256) { fail(); };
if (!bytes.equal(b, src[0:256])) { fail(); };
assert(!(b.len != 256));
assert(!(!bytes.equal(b, src[0:256])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
let u: str = base64.encodestr(&base64.url_encoding, src[0:256]);
match (base64.decodestr(&base64.url_encoding, u)) {
case let b: []u8 => {
if (b.len != 256) { fail(); };
if (!bytes.equal(b, src[0:256])) { fail(); };
assert(!(b.len != 256));
assert(!(!bytes.equal(b, src[0:256])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
};
export fn main() i32 = {
signalled = 1; rfc4648_std();
signalled = 2; rfc4648_url();
signalled = 3; urlsafe_distinct();
signalled = 4; decode_invalid();
signalled = 5; sizes();
signalled = 6; roundtrip_all_bytes();
rfc4648_std();
rfc4648_url();
urlsafe_distinct();
decode_invalid();
sizes();
roundtrip_all_bytes();
return 0;
};

View File

@@ -1,8 +1,8 @@
// hextest — exercises lib/encoding/hex's io-streaming surface. Run with
// `out/bin/ww run lib/encoding/hex/hextest.ww`. Mirrors Hare's hex
// @test fns (ref/hare/encoding/hex/hex.ha:82,96,194) plus a full-byte
// round-trip. Same signalled-then-fail()-with-+10 pattern as the rest of
// the 9xx stdlib tests; non-zero exit pinpoints the failing scenario.
// round-trip. A failing row aborts via the assert/abort builtin (task #5
// @test conversion).
//
// The streaming decoder (newdecoder) is deferred (#247), so the decode
// side is exercised through decodestr only.
@@ -14,10 +14,7 @@ import errors;
import hex;
import io;
import memio;
import os;
let signalled: i32 = 0;
fn fail() void = { os.exit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
@@ -40,24 +37,24 @@ fn cafebabe() [8]u8 = {
@test fn encodestr_basic() void = {
let in: [8]u8 = cafebabe();
if (!streq(hex.encodestr(in[0:8]), "cafebabedeadf00d")) { fail(); };
assert(!(!streq(hex.encodestr(in[0:8]), "cafebabedeadf00d")));
};
// 0x00 → "00" guards a sign-extend / signed-shift on the high nibble.
@test fn encodestr_zero() void = {
let in: [1]u8; in[0] = 0u8;
if (!streq(hex.encodestr(in[0:1]), "00")) { fail(); };
assert(!(!streq(hex.encodestr(in[0:1]), "00")));
};
// 0xFF → "ff" guards an off-by-one in the digit lookup.
@test fn encodestr_ff() void = {
let in: [1]u8; in[0] = 0xFFu8;
if (!streq(hex.encodestr(in[0:1]), "ff")) { fail(); };
assert(!(!streq(hex.encodestr(in[0:1]), "ff")));
};
@test fn encodestr_empty() void = {
let in: [1]u8;
if (hex.encodestr(in[0:0]).len != 0) { fail(); };
assert(!(hex.encodestr(in[0:0]).len != 0));
};
// ---- encode (io.handle sink) ---- ref/hare/encoding/hex/hex.ha:96
@@ -66,10 +63,10 @@ fn cafebabe() [8]u8 = {
let in: [8]u8 = cafebabe();
let out: memio.stream = memio.dynamic();
match (hex.encode(&out.vt, in[0:8])) {
case let n: size => { if (n: i32 != 16) { fail(); }; };
case let e: io.error => fail();
case let n: size => { assert(!(n: i32 != 16)); };
case let e: io.error => abort();
};
if (!streq(memio.string(&out), "cafebabedeadf00d")) { fail(); };
assert(!(!streq(memio.string(&out), "cafebabedeadf00d")));
};
// ---- decodestr round-trip ---- ref/hare/encoding/hex/hex.ha:194
@@ -78,9 +75,9 @@ fn cafebabe() [8]u8 = {
match (hex.decodestr("cafebabedeadf00d")) {
case let b: []u8 => {
let want: [8]u8 = cafebabe();
if (!bytes.equal(b, want[0:8])) { fail(); };
assert(!(!bytes.equal(b, want[0:8])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
};
@@ -90,9 +87,9 @@ fn cafebabe() [8]u8 = {
match (hex.decodestr("CAFEBABEDEADF00D")) {
case let b: []u8 => {
let want: [8]u8 = cafebabe();
if (!bytes.equal(b, want[0:8])) { fail(); };
assert(!(!bytes.equal(b, want[0:8])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
};
@@ -100,16 +97,16 @@ fn cafebabe() [8]u8 = {
match (hex.decodestr("CaFeBaBeDeAdF00d")) {
case let b: []u8 => {
let want: [8]u8 = cafebabe();
if (!bytes.equal(b, want[0:8])) { fail(); };
assert(!(!bytes.equal(b, want[0:8])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
};
@test fn decodestr_empty() void = {
match (hex.decodestr("")) {
case let b: []u8 => { if (b.len != 0) { fail(); }; };
case let e: errors.invalid => fail();
case let b: []u8 => { assert(!(b.len != 0)); };
case let e: errors.invalid => abort();
};
};
@@ -119,21 +116,21 @@ fn cafebabe() [8]u8 = {
@test fn decodestr_odd() void = {
match (hex.decodestr("abc")) {
case let b: []u8 => fail();
case let b: []u8 => abort();
case let e: errors.invalid => void;
};
};
@test fn decodestr_bad() void = {
match (hex.decodestr("zz00")) { // 'z' isn't hex
case let b: []u8 => fail();
case let b: []u8 => abort();
case let e: errors.invalid => void;
};
};
@test fn decodestr_bad_mid() void = {
match (hex.decodestr("aabbgg")) { // 'g' isn't hex
case let b: []u8 => fail();
case let b: []u8 => abort();
case let e: errors.invalid => void;
};
};
@@ -148,29 +145,29 @@ fn cafebabe() [8]u8 = {
i += 1;
};
let s: str = hex.encodestr(src[0:256]);
if (s.len != 512) { fail(); };
assert(!(s.len != 512));
match (hex.decodestr(s)) {
case let b: []u8 => {
if (b.len != 256) { fail(); };
if (!bytes.equal(b, src[0:256])) { fail(); };
assert(!(b.len != 256));
assert(!(!bytes.equal(b, src[0:256])));
};
case let e: errors.invalid => fail();
case let e: errors.invalid => abort();
};
};
export fn main() i32 = {
signalled = 1; encodestr_basic();
signalled = 2; encodestr_zero();
signalled = 3; encodestr_ff();
signalled = 4; encodestr_empty();
signalled = 5; encode_stream();
signalled = 6; decodestr_lower();
signalled = 7; decodestr_upper();
signalled = 8; decodestr_mixed();
signalled = 9; decodestr_empty();
signalled = 10; decodestr_odd();
signalled = 11; decodestr_bad();
signalled = 12; decodestr_bad_mid();
signalled = 13; roundtrip_all_bytes();
encodestr_basic();
encodestr_zero();
encodestr_ff();
encodestr_empty();
encode_stream();
decodestr_lower();
decodestr_upper();
decodestr_mixed();
decodestr_empty();
decodestr_odd();
decodestr_bad();
decodestr_bad_mid();
roundtrip_all_bytes();
return 0;
};

View File

@@ -1,16 +1,12 @@
// utf8test — exercises lib/encoding/utf8. Run with
// `out/bin/ww run lib/encoding/utf8/utf8test.ww`. Same signalled-
// then-fail()-with-+10 pattern as hex / base32 / time tests:
// non-zero exit pinpoints the failing scenario.
// `out/bin/ww run lib/encoding/utf8/utf8test.ww`. A failing row aborts
// via the assert/abort builtin (task #5 @test conversion).
package utf8_test;
import bytes;
import encoding.utf8;
import os;
let signalled: i32 = 0;
fn fail() void = { os.exit(signalled + 10); };
fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
@@ -27,14 +23,14 @@ fn streq(a: str, b: str) bool = {
// 0x7FF → 2, 0x800 → 3, 0xFFFF → 3, 0x10000 → 4, 0x10FFFF → 4.
@test fn runesz_ranges() void = {
if (utf8.runesz(0u32: rune) != 1) { fail(); };
if (utf8.runesz(0x7Fu32: rune) != 1) { fail(); };
if (utf8.runesz(0x80u32: rune) != 2) { fail(); };
if (utf8.runesz(0x7FFu32: rune) != 2) { fail(); };
if (utf8.runesz(0x800u32: rune) != 3) { fail(); };
if (utf8.runesz(0xFFFFu32: rune) != 3) { fail(); };
if (utf8.runesz(0x10000u32: rune) != 4) { fail(); };
if (utf8.runesz(0x10FFFFu32: rune) != 4) { fail(); };
assert(!(utf8.runesz(0u32: rune) != 1));
assert(!(utf8.runesz(0x7Fu32: rune) != 1));
assert(!(utf8.runesz(0x80u32: rune) != 2));
assert(!(utf8.runesz(0x7FFu32: rune) != 2));
assert(!(utf8.runesz(0x800u32: rune) != 3));
assert(!(utf8.runesz(0xFFFFu32: rune) != 3));
assert(!(utf8.runesz(0x10000u32: rune) != 4));
assert(!(utf8.runesz(0x10FFFFu32: rune) != 4));
};
// ---- utf8sz: start-byte classification --------------------------------
@@ -43,39 +39,39 @@ fn streq(a: str, b: str) bool = {
@test fn utf8sz_classify() void = {
match (utf8.utf8sz(0u8)) {
case let n: i32 => { if (n != 1) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 1)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0x7Fu8)) {
case let n: i32 => { if (n != 1) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 1)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0x80u8)) { // continuation
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
match (utf8.utf8sz(0xC1u8)) { // overlong 2-byte lead
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
match (utf8.utf8sz(0xC2u8)) {
case let n: i32 => { if (n != 2) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 2)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0xE0u8)) {
case let n: i32 => { if (n != 3) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 3)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0xF0u8)) {
case let n: i32 => { if (n != 4) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case let n: i32 => { assert(!(n != 4)); };
case let e: utf8.invalid => { abort(); };
};
match (utf8.utf8sz(0xF8u8)) { // 5-byte lead — illegal in modern UTF-8
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
match (utf8.utf8sz(0xFFu8)) {
case let n: i32 => { fail(); };
case let n: i32 => { abort(); };
case let e: utf8.invalid => void;
};
};
@@ -87,35 +83,35 @@ fn streq(a: str, b: str) bool = {
@test fn encode_ascii() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0x41u32: rune); // 'A'
if (n != 1) { fail(); };
if (out[0] != 0x41u8) { fail(); };
assert(!(n != 1));
assert(!(out[0] != 0x41u8));
};
@test fn encode_two_byte() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0xE9u32: rune); // 'é' U+00E9
if (n != 2) { fail(); };
if (out[0] != 0xC3u8) { fail(); };
if (out[1] != 0xA9u8) { fail(); };
assert(!(n != 2));
assert(!(out[0] != 0xC3u8));
assert(!(out[1] != 0xA9u8));
};
@test fn encode_three_byte() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0x20ACu32: rune); // '€' U+20AC
if (n != 3) { fail(); };
if (out[0] != 0xE2u8) { fail(); };
if (out[1] != 0x82u8) { fail(); };
if (out[2] != 0xACu8) { fail(); };
assert(!(n != 3));
assert(!(out[0] != 0xE2u8));
assert(!(out[1] != 0x82u8));
assert(!(out[2] != 0xACu8));
};
@test fn encode_four_byte() void = {
let out: [4]u8;
let n: i32 = utf8.encoderune(out[0:4], 0x1F980u32: rune); // '🦀' U+1F980
if (n != 4) { fail(); };
if (out[0] != 0xF0u8) { fail(); };
if (out[1] != 0x9Fu8) { fail(); };
if (out[2] != 0xA6u8) { fail(); };
if (out[3] != 0x80u8) { fail(); };
assert(!(n != 4));
assert(!(out[0] != 0xF0u8));
assert(!(out[1] != 0x9Fu8));
assert(!(out[2] != 0xA6u8));
assert(!(out[3] != 0x80u8));
};
// ---- decoder.next: valid 1/2/3/4-byte ---------------------------------
@@ -127,10 +123,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0x41u8;
let d: utf8.decoder = utf8.decode(src[0:1]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0x41u32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0x41u32: rune)); };
};
};
@@ -139,10 +135,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xC3u8; src[1] = 0xA9u8;
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0xE9u32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0xE9u32: rune)); };
};
};
@@ -151,10 +147,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xE2u8; src[1] = 0x82u8; src[2] = 0xACu8;
let d: utf8.decoder = utf8.decode(src[0:3]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0x20ACu32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0x20ACu32: rune)); };
};
};
@@ -163,10 +159,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xF0u8; src[1] = 0x9Fu8; src[2] = 0xA6u8; src[3] = 0x80u8;
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { if (r != 0x1F980u32: rune) { fail(); }; };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
case let r: rune => { assert(!(r != 0x1F980u32: rune)); };
};
};
@@ -180,9 +176,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:3]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -192,9 +188,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -204,9 +200,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -220,9 +216,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case let r: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -234,10 +230,10 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xF4u8; src[1] = 0x8Fu8; src[2] = 0xBFu8; src[3] = 0xBFu8;
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: rune => { if (r != 0x10FFFFu32: rune) { fail(); }; };
case let r: utf8.invalid => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { assert(!(r != 0x10FFFFu32: rune)); };
case let r: utf8.invalid => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -249,9 +245,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case utf8.more => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case let r: utf8.invalid => { abort(); };
};
};
@@ -262,9 +258,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:0]);
match (utf8.next(&d)) {
case utf8.done => void;
case let r: rune => { fail(); };
case utf8.more => { fail(); };
case let r: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.more => { abort(); };
case let r: utf8.invalid => { abort(); };
};
};
@@ -281,7 +277,7 @@ fn streq(a: str, b: str) bool = {
src[12] = 0xE3u8; src[13] = 0x81u8; src[14] = 0xAFu8; // は
src[15] = 0u8;
match (utf8.validate(src[0:16])) {
case let e: utf8.invalid => { fail(); };
case let e: utf8.invalid => { abort(); };
case void => void;
};
};
@@ -291,14 +287,14 @@ fn streq(a: str, b: str) bool = {
src[0] = 0xEDu8; src[1] = 0xA0u8; src[2] = 0x80u8; // surrogate
match (utf8.validate(src[0:3])) {
case let e: utf8.invalid => void;
case void => { fail(); };
case void => { abort(); };
};
};
@test fn validate_empty_ok() void = {
let src: [1]u8;
match (utf8.validate(src[0:0])) {
case let e: utf8.invalid => { fail(); };
case let e: utf8.invalid => { abort(); };
case void => void;
};
};
@@ -313,9 +309,9 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:1]);
match (utf8.prev(&d)) {
case utf8.done => void;
case let r: rune => { fail(); };
case utf8.more => { fail(); };
case let e: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.more => { abort(); };
case let e: utf8.invalid => { abort(); };
};
};
@@ -329,11 +325,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:1]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x41u32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0x41u32: rune)); };
case => { abort(); };
};
};
@@ -343,11 +339,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:2]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0xE9u32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0xE9u32: rune)); };
case => { abort(); };
};
};
@@ -357,11 +353,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:3]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x20ACu32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0x20ACu32: rune)); };
case => { abort(); };
};
};
@@ -371,11 +367,11 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
match (utf8.next(&d)) {
case let r: rune => void;
case => { fail(); };
case => { abort(); };
};
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x1F980u32: rune) { fail(); }; };
case => { fail(); };
case let r: rune => { assert(!(r != 0x1F980u32: rune)); };
case => { abort(); };
};
};
@@ -398,24 +394,24 @@ fn streq(a: str, b: str) bool = {
for (i < 6) {
match (utf8.next(&d)) {
case let r: rune => { fwd[i] = r: u32; };
case => { fail(); };
case => { abort(); };
};
i += 1;
};
if (utf8.position(&d) != 16) { fail(); };
assert(!(utf8.position(&d) != 16));
i = 0;
for (i < 6) {
match (utf8.prev(&d)) {
case let r: rune => {
if ((r: u32) != fwd[5 - i]) { fail(); };
assert(!((r: u32) != fwd[5 - i]));
};
case => { fail(); };
case => { abort(); };
};
i += 1;
};
match (utf8.prev(&d)) {
case utf8.done => void;
case => { fail(); };
case => { abort(); };
};
};
@@ -435,9 +431,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 2;
match (utf8.prev(&d)) {
case utf8.more => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case let e: utf8.invalid => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case let e: utf8.invalid => { abort(); };
};
};
@@ -448,9 +444,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 2;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -461,9 +457,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 3;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -474,9 +470,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 4;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -490,9 +486,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 3;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -506,10 +502,10 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(src[0:4]);
d.offs = 4;
match (utf8.prev(&d)) {
case let r: rune => { if (r != 0x10FFFFu32: rune) { fail(); }; };
case let e: utf8.invalid => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { assert(!(r != 0x10FFFFu32: rune)); };
case let e: utf8.invalid => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -526,9 +522,9 @@ fn streq(a: str, b: str) bool = {
d.offs = 4;
match (utf8.prev(&d)) {
case let e: utf8.invalid => void;
case let r: rune => { fail(); };
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let r: rune => { abort(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
};
};
@@ -551,38 +547,38 @@ fn streq(a: str, b: str) bool = {
let d1: utf8.decoder = utf8.decode(src[0:16]);
let d2: utf8.decoder = utf8.decode(src[0:16]);
if (!bytes.equal(utf8.remaining(&d1), src[0:16])) { fail(); };
if (utf8.slice(&d1, &d2).len != 0) { fail(); };
if (utf8.slice(&d2, &d1).len != 0) { fail(); };
if (utf8.position(&d1) != 0) { fail(); };
assert(!(!bytes.equal(utf8.remaining(&d1), src[0:16])));
assert(!(utf8.slice(&d1, &d2).len != 0));
assert(!(utf8.slice(&d2, &d1).len != 0));
assert(!(utf8.position(&d1) != 0));
let i: i32 = 0;
for (i < 2) {
match (utf8.next(&d1)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d2)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d1)) { case let r: rune => void; case => { abort(); }; };
match (utf8.next(&d2)) { case let r: rune => void; case => { abort(); }; };
i += 1;
};
if (utf8.position(&d1) != 6) { fail(); };
if (!bytes.equal(utf8.remaining(&d1), src[6:16])) { fail(); };
if (utf8.slice(&d1, &d2).len != 0) { fail(); };
assert(!(utf8.position(&d1) != 6));
assert(!(!bytes.equal(utf8.remaining(&d1), src[6:16])));
assert(!(utf8.slice(&d1, &d2).len != 0));
i = 0;
for (i < 3) {
match (utf8.next(&d2)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d2)) { case let r: rune => void; case => { abort(); }; };
i += 1;
};
if (utf8.position(&d2) != 15) { fail(); };
if (!bytes.equal(utf8.remaining(&d2), src[15:16])) { fail(); };
if (!bytes.equal(utf8.slice(&d1, &d2), src[6:15])) { fail(); };
assert(!(utf8.position(&d2) != 15));
assert(!(!bytes.equal(utf8.remaining(&d2), src[15:16])));
assert(!(!bytes.equal(utf8.slice(&d1, &d2), src[6:15])));
i = 0;
for (i < 3) {
match (utf8.next(&d1)) { case let r: rune => void; case => { fail(); }; };
match (utf8.next(&d1)) { case let r: rune => void; case => { abort(); }; };
i += 1;
};
if (utf8.slice(&d1, &d2).len != 0) { fail(); };
match (utf8.next(&d1)) { case let r: rune => void; case => { fail(); }; };
if (utf8.remaining(&d1).len != 0) { fail(); };
assert(!(utf8.slice(&d1, &d2).len != 0));
match (utf8.next(&d1)) { case let r: rune => void; case => { abort(); }; };
assert(!(utf8.remaining(&d1).len != 0));
};
// ---- strerror: constant rendering -------------------------------------
@@ -591,7 +587,7 @@ fn streq(a: str, b: str) bool = {
@test fn strerror_cases() void = {
let e: utf8.invalid;
if (!streq(utf8.strerror(e), "Invalid UTF-8")) { fail(); };
assert(!(!streq(utf8.strerror(e), "Invalid UTF-8")));
};
// ---- round-trip: encode → decode → equal rune --------------------------
@@ -609,52 +605,52 @@ fn streq(a: str, b: str) bool = {
let d: utf8.decoder = utf8.decode(buf[0:n]);
match (utf8.next(&d)) {
case let r: rune => {
if ((r: u32) != runes[i]) { fail(); };
assert(!((r: u32) != runes[i]));
};
case utf8.done => { fail(); };
case utf8.more => { fail(); };
case let e: utf8.invalid => { fail(); };
case utf8.done => { abort(); };
case utf8.more => { abort(); };
case let e: utf8.invalid => { abort(); };
};
i += 1;
};
};
export fn main() i32 = {
signalled = 1; runesz_ranges();
signalled = 2; utf8sz_classify();
signalled = 3; encode_ascii();
signalled = 4; encode_two_byte();
signalled = 5; encode_three_byte();
signalled = 6; encode_four_byte();
signalled = 7; decode_one_byte();
signalled = 8; decode_two_byte();
signalled = 9; decode_three_byte();
signalled = 10; decode_four_byte();
signalled = 11; decode_surrogate();
signalled = 12; decode_overlong();
signalled = 13; decode_out_of_range();
signalled = 14; decode_bad_continuation();
signalled = 15; decode_max_in_range();
signalled = 16; decode_truncated();
signalled = 17; decode_done();
signalled = 18; validate_mixed_ok();
signalled = 19; validate_malformed();
signalled = 20; validate_empty_ok();
signalled = 21; roundtrip();
signalled = 22; prev_done_at_start();
signalled = 23; prev_one_byte();
signalled = 24; prev_two_byte();
signalled = 25; prev_three_byte();
signalled = 26; prev_four_byte();
signalled = 27; prev_mixed_roundtrip();
signalled = 28; prev_continuation_only_more();
signalled = 29; prev_incomplete_invalid();
signalled = 30; prev_surrogate_invalid();
signalled = 31; prev_overlong_invalid();
signalled = 32; prev_extracont_invalid();
signalled = 33; prev_max_in_range();
signalled = 34; prev_min_out_of_range();
signalled = 35; remaining_slice_position();
signalled = 36; strerror_cases();
runesz_ranges();
utf8sz_classify();
encode_ascii();
encode_two_byte();
encode_three_byte();
encode_four_byte();
decode_one_byte();
decode_two_byte();
decode_three_byte();
decode_four_byte();
decode_surrogate();
decode_overlong();
decode_out_of_range();
decode_bad_continuation();
decode_max_in_range();
decode_truncated();
decode_done();
validate_mixed_ok();
validate_malformed();
validate_empty_ok();
roundtrip();
prev_done_at_start();
prev_one_byte();
prev_two_byte();
prev_three_byte();
prev_four_byte();
prev_mixed_roundtrip();
prev_continuation_only_more();
prev_incomplete_invalid();
prev_surrogate_invalid();
prev_overlong_invalid();
prev_extracont_invalid();
prev_max_in_range();
prev_min_out_of_range();
remaining_slice_position();
strerror_cases();
return 0;
};

View File

@@ -14,122 +14,122 @@ import types;
@test fn test_addi8() void = {
let (res, overflow) = checked.addi8(100, 20);
if (res != 120) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 120));
assert(!(overflow));
let (res2, overflow2) = checked.addi8(100, 50);
if (res2 != -106) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -106));
assert(!(!overflow2));
};
@test fn test_addi16() void = {
let (res, overflow) = checked.addi16(32700, 60);
if (res != 32760) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 32760));
assert(!(overflow));
let (res2, overflow2) = checked.addi16(32700, 100);
if (res2 != -32736) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -32736));
assert(!(!overflow2));
};
@test fn test_addi32() void = {
let (res, overflow) = checked.addi32(2147483600, 40);
if (res != 2147483640) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 2147483640));
assert(!(overflow));
let (res2, overflow2) = checked.addi32(2147483600, 100);
if (res2 != -2147483596) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -2147483596));
assert(!(!overflow2));
};
@test fn test_addi64() void = {
let (res, overflow) = checked.addi64(9223372036854775800, 5);
if (res != 9223372036854775805) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 9223372036854775805));
assert(!(overflow));
let (res2, overflow2) = checked.addi64(9223372036854775800, 10);
if (res2 != -9223372036854775806) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -9223372036854775806));
assert(!(!overflow2));
};
@test fn test_addu8() void = {
let (res, overflow) = checked.addu8(200u8, 50u8);
if (res != 250u8) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 250u8));
assert(!(overflow));
let (res2, overflow2) = checked.addu8(200u8, 100u8);
if (res2 != 44u8) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 44u8));
assert(!(!overflow2));
};
@test fn test_addu16() void = {
let (res, overflow) = checked.addu16(65500u16, 30u16);
if (res != 65530u16) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 65530u16));
assert(!(overflow));
let (res2, overflow2) = checked.addu16(65500u16, 50u16);
if (res2 != 14u16) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 14u16));
assert(!(!overflow2));
};
@test fn test_addu32() void = {
let (res, overflow) = checked.addu32(4294967200u32, 90u32);
if (res != 4294967290u32) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 4294967290u32));
assert(!(overflow));
let (res2, overflow2) = checked.addu32(4294967200u32, 100u32);
if (res2 != 4u32) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 4u32));
assert(!(!overflow2));
};
@test fn test_addu64() void = {
let (res, overflow) = checked.addu64(18446744073709551600u64, 10u64);
if (res != 18446744073709551610u64) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 18446744073709551610u64));
assert(!(overflow));
let (res2, overflow2) = checked.addu64(18446744073709551610u64, 50u64);
if (res2 != 44u64) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 44u64));
assert(!(!overflow2));
};
@test fn test_subi8() void = {
let (res, overflow) = checked.subi8(-100, 20);
if (res != -120) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != -120));
assert(!(overflow));
let (res2, overflow2) = checked.subi8(-100, 50);
if (res2 != 106) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 106));
assert(!(!overflow2));
// I8_MAX, I8_MIN boundary
let (res3, overflow3) = checked.subi8(127, -128);
if (res3 != -1) { let _: i32 = 1/0; };
if (!overflow3) { let _: i32 = 1/0; };
assert(!(res3 != -1));
assert(!(!overflow3));
};
@test fn test_subi16() void = {
let (res, overflow) = checked.subi16(-32700, 60);
if (res != -32760) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != -32760));
assert(!(overflow));
let (res2, overflow2) = checked.subi16(-32700, 100);
if (res2 != 32736) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 32736));
assert(!(!overflow2));
// I16_MAX, I16_MIN boundary
let (res3, overflow3) = checked.subi16(32767, -32768);
if (res3 != -1) { let _: i32 = 1/0; };
if (!overflow3) { let _: i32 = 1/0; };
assert(!(res3 != -1));
assert(!(!overflow3));
};
@test fn test_subi32() void = {
let (res, overflow) = checked.subi32(-2147483600, 40);
if (res != -2147483640) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != -2147483640));
assert(!(overflow));
let (res2, overflow2) = checked.subi32(-2147483600, 100);
if (res2 != 2147483596) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 2147483596));
assert(!(!overflow2));
// I32_MAX, I32_MIN boundary
let (res3, overflow3) = checked.subi32(2147483647, -2147483648);
if (res3 != -1) { let _: i32 = 1/0; };
if (!overflow3) { let _: i32 = 1/0; };
assert(!(res3 != -1));
assert(!(!overflow3));
};
@test fn test_subi64() void = {
let (res, overflow) = checked.subi64(-9223372036854775800, 5);
if (res != -9223372036854775805) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != -9223372036854775805));
assert(!(overflow));
let (res2, overflow2) = checked.subi64(-9223372036854775800, 10);
if (res2 != 9223372036854775806) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 9223372036854775806));
assert(!(!overflow2));
// I64_MAX, I64_MIN boundary — Hare's subi64 @test 3rd case
// subi64(I64_MAX, I64_MIN). Omitted while #89 is open: the I64_MIN
// literal -9223372036854775808 makes wwstage emit `MOVQ $-, AX`
@@ -141,92 +141,92 @@ import types;
@test fn test_subu8() void = {
let (res, overflow) = checked.subu8(250u8, 50u8);
if (res != 200u8) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 200u8));
assert(!(overflow));
let (res2, overflow2) = checked.subu8(44u8, 100u8);
if (res2 != 200u8) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 200u8));
assert(!(!overflow2));
};
@test fn test_subu16() void = {
let (res, overflow) = checked.subu16(65530u16, 30u16);
if (res != 65500u16) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 65500u16));
assert(!(overflow));
let (res2, overflow2) = checked.subu16(14u16, 50u16);
if (res2 != 65500u16) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 65500u16));
assert(!(!overflow2));
};
@test fn test_subu32() void = {
let (res, overflow) = checked.subu32(4294967290u32, 90u32);
if (res != 4294967200u32) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 4294967200u32));
assert(!(overflow));
let (res2, overflow2) = checked.subu32(4u32, 100u32);
if (res2 != 4294967200u32) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 4294967200u32));
assert(!(!overflow2));
};
@test fn test_subu64() void = {
let (res, overflow) = checked.subu64(18446744073709551610u64, 10u64);
if (res != 18446744073709551600u64) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 18446744073709551600u64));
assert(!(overflow));
let (res2, overflow2) = checked.subu64(44u64, 50u64);
if (res2 != 18446744073709551610u64) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 18446744073709551610u64));
assert(!(!overflow2));
};
@test fn test_muli8() void = {
let (res, overflow) = checked.muli8(11, 11);
if (res != 121) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 121));
assert(!(overflow));
let (res2, overflow2) = checked.muli8(12, 12);
if (res2 != -112) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -112));
assert(!(!overflow2));
};
@test fn test_muli16() void = {
let (res, overflow) = checked.muli16(181, 181);
if (res != 32761) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 32761));
assert(!(overflow));
let (res2, overflow2) = checked.muli16(182, 182);
if (res2 != -32412) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -32412));
assert(!(!overflow2));
};
@test fn test_muli32() void = {
let (res, overflow) = checked.muli32(46340, 46340);
if (res != 2147395600) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 2147395600));
assert(!(overflow));
let (res2, overflow2) = checked.muli32(46341, 46341);
if (res2 != -2147479015) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != -2147479015));
assert(!(!overflow2));
};
@test fn test_mulu8() void = {
let (res, overflow) = checked.mulu8(15u8, 15u8);
if (res != 225u8) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 225u8));
assert(!(overflow));
let (res2, overflow2) = checked.mulu8(16u8, 16u8);
if (res2 != 0u8) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 0u8));
assert(!(!overflow2));
};
@test fn test_mulu16() void = {
let (res, overflow) = checked.mulu16(255u16, 255u16);
if (res != 65025u16) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 65025u16));
assert(!(overflow));
let (res2, overflow2) = checked.mulu16(256u16, 256u16);
if (res2 != 0u16) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 0u16));
assert(!(!overflow2));
};
@test fn test_mulu32() void = {
let (res, overflow) = checked.mulu32(65535u32, 65535u32);
if (res != 4294836225u32) { let _: i32 = 1/0; };
if (overflow) { let _: i32 = 1/0; };
assert(!(res != 4294836225u32));
assert(!(overflow));
let (res2, overflow2) = checked.mulu32(65536u32, 65536u32);
if (res2 != 0u32) { let _: i32 = 1/0; };
if (!overflow2) { let _: i32 = 1/0; };
assert(!(res2 != 0u32));
assert(!(!overflow2));
};
// Saturating vectors from ref/hare/math/checked/saturating.ha @test
@@ -235,141 +235,141 @@ import types;
// -9223372036854775808 (which the wwstage formatter miscompiles, #89).
@test fn test_sat_addi8() void = {
if (checked.sat_addi8(100, 20) != 120) { let _: i32 = 1/0; };
if (checked.sat_addi8(100, 50) != types.I8_MAX) { let _: i32 = 1/0; };
if (checked.sat_addi8(-100, -50) != types.I8_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_addi8(100, 20) != 120));
assert(!(checked.sat_addi8(100, 50) != types.I8_MAX));
assert(!(checked.sat_addi8(-100, -50) != types.I8_MIN));
};
@test fn test_sat_addi16() void = {
if (checked.sat_addi16(32700, 60) != 32760) { let _: i32 = 1/0; };
if (checked.sat_addi16(32700, 100) != types.I16_MAX) { let _: i32 = 1/0; };
if (checked.sat_addi16(-32700, -100) != types.I16_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_addi16(32700, 60) != 32760));
assert(!(checked.sat_addi16(32700, 100) != types.I16_MAX));
assert(!(checked.sat_addi16(-32700, -100) != types.I16_MIN));
};
@test fn test_sat_addi32() void = {
if (checked.sat_addi32(2147483600, 40) != 2147483640) { let _: i32 = 1/0; };
if (checked.sat_addi32(2147483600, 100) != types.I32_MAX) { let _: i32 = 1/0; };
if (checked.sat_addi32(-2147483600, -100) != types.I32_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_addi32(2147483600, 40) != 2147483640));
assert(!(checked.sat_addi32(2147483600, 100) != types.I32_MAX));
assert(!(checked.sat_addi32(-2147483600, -100) != types.I32_MIN));
};
@test fn test_sat_addi64() void = {
if (checked.sat_addi64(9223372036854775800, 5) != 9223372036854775805) { let _: i32 = 1/0; };
if (checked.sat_addi64(9223372036854775800, 10) != types.I64_MAX) { let _: i32 = 1/0; };
if (checked.sat_addi64(-9223372036854775800, -10) != types.I64_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_addi64(9223372036854775800, 5) != 9223372036854775805));
assert(!(checked.sat_addi64(9223372036854775800, 10) != types.I64_MAX));
assert(!(checked.sat_addi64(-9223372036854775800, -10) != types.I64_MIN));
};
@test fn test_sat_addu8() void = {
if (checked.sat_addu8(200u8, 50u8) != 250u8) { let _: i32 = 1/0; };
if (checked.sat_addu8(200u8, 100u8) != types.U8_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_addu8(200u8, 50u8) != 250u8));
assert(!(checked.sat_addu8(200u8, 100u8) != types.U8_MAX));
};
@test fn test_sat_addu16() void = {
if (checked.sat_addu16(65500u16, 30u16) != 65530u16) { let _: i32 = 1/0; };
if (checked.sat_addu16(65500u16, 50u16) != types.U16_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_addu16(65500u16, 30u16) != 65530u16));
assert(!(checked.sat_addu16(65500u16, 50u16) != types.U16_MAX));
};
@test fn test_sat_addu32() void = {
if (checked.sat_addu32(4294967200u32, 90u32) != 4294967290u32) { let _: i32 = 1/0; };
if (checked.sat_addu32(4294967200u32, 100u32) != types.U32_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_addu32(4294967200u32, 90u32) != 4294967290u32));
assert(!(checked.sat_addu32(4294967200u32, 100u32) != types.U32_MAX));
};
@test fn test_sat_addu64() void = {
if (checked.sat_addu64(18446744073709551600u64, 10u64) != 18446744073709551610u64) { let _: i32 = 1/0; };
if (checked.sat_addu64(18446744073709551600u64, 50u64) != types.U64_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_addu64(18446744073709551600u64, 10u64) != 18446744073709551610u64));
assert(!(checked.sat_addu64(18446744073709551600u64, 50u64) != types.U64_MAX));
};
@test fn test_sat_subi8() void = {
if (checked.sat_subi8(-100, 20) != -120) { let _: i32 = 1/0; };
if (checked.sat_subi8(-100, 50) != types.I8_MIN) { let _: i32 = 1/0; };
if (checked.sat_subi8(100, -50) != types.I8_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_subi8(-100, 20) != -120));
assert(!(checked.sat_subi8(-100, 50) != types.I8_MIN));
assert(!(checked.sat_subi8(100, -50) != types.I8_MAX));
};
@test fn test_sat_subi16() void = {
if (checked.sat_subi16(-32700, 60) != -32760) { let _: i32 = 1/0; };
if (checked.sat_subi16(-32700, 100) != types.I16_MIN) { let _: i32 = 1/0; };
if (checked.sat_subi16(32700, -100) != types.I16_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_subi16(-32700, 60) != -32760));
assert(!(checked.sat_subi16(-32700, 100) != types.I16_MIN));
assert(!(checked.sat_subi16(32700, -100) != types.I16_MAX));
};
@test fn test_sat_subi32() void = {
if (checked.sat_subi32(-2147483600, 40) != -2147483640) { let _: i32 = 1/0; };
if (checked.sat_subi32(-2147483600, 100) != types.I32_MIN) { let _: i32 = 1/0; };
if (checked.sat_subi32(2147483600, -100) != types.I32_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_subi32(-2147483600, 40) != -2147483640));
assert(!(checked.sat_subi32(-2147483600, 100) != types.I32_MIN));
assert(!(checked.sat_subi32(2147483600, -100) != types.I32_MAX));
};
@test fn test_sat_subi64() void = {
if (checked.sat_subi64(-9223372036854775800, 5) != -9223372036854775805) { let _: i32 = 1/0; };
if (checked.sat_subi64(-9223372036854775800, 10) != types.I64_MIN) { let _: i32 = 1/0; };
if (checked.sat_subi64(9223372036854775800, -10) != types.I64_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_subi64(-9223372036854775800, 5) != -9223372036854775805));
assert(!(checked.sat_subi64(-9223372036854775800, 10) != types.I64_MIN));
assert(!(checked.sat_subi64(9223372036854775800, -10) != types.I64_MAX));
};
// The third/fourth rows of each sat_subu* test go beyond Hare's two
// vectors: a==b (exact-zero, non-saturating edge) and 0U*_MAX (extreme
// operand forcing the deepest underflow). #28 reviewer hardening.
@test fn test_sat_subu8() void = {
if (checked.sat_subu8(250u8, 50u8) != 200u8) { let _: i32 = 1/0; };
if (checked.sat_subu8(44u8, 100u8) != types.U8_MIN) { let _: i32 = 1/0; };
if (checked.sat_subu8(100u8, 100u8) != 0u8) { let _: i32 = 1/0; };
if (checked.sat_subu8(0u8, 255u8) != types.U8_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_subu8(250u8, 50u8) != 200u8));
assert(!(checked.sat_subu8(44u8, 100u8) != types.U8_MIN));
assert(!(checked.sat_subu8(100u8, 100u8) != 0u8));
assert(!(checked.sat_subu8(0u8, 255u8) != types.U8_MIN));
};
@test fn test_sat_subu16() void = {
if (checked.sat_subu16(65530u16, 30u16) != 65500u16) { let _: i32 = 1/0; };
if (checked.sat_subu16(14u16, 50u16) != types.U16_MIN) { let _: i32 = 1/0; };
if (checked.sat_subu16(1000u16, 1000u16) != 0u16) { let _: i32 = 1/0; };
if (checked.sat_subu16(0u16, 65535u16) != types.U16_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_subu16(65530u16, 30u16) != 65500u16));
assert(!(checked.sat_subu16(14u16, 50u16) != types.U16_MIN));
assert(!(checked.sat_subu16(1000u16, 1000u16) != 0u16));
assert(!(checked.sat_subu16(0u16, 65535u16) != types.U16_MIN));
};
@test fn test_sat_subu32() void = {
if (checked.sat_subu32(4294967290u32, 90u32) != 4294967200u32) { let _: i32 = 1/0; };
if (checked.sat_subu32(4u32, 100u32) != types.U32_MIN) { let _: i32 = 1/0; };
if (checked.sat_subu32(1000000u32, 1000000u32) != 0u32) { let _: i32 = 1/0; };
if (checked.sat_subu32(0u32, 4294967295u32) != types.U32_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_subu32(4294967290u32, 90u32) != 4294967200u32));
assert(!(checked.sat_subu32(4u32, 100u32) != types.U32_MIN));
assert(!(checked.sat_subu32(1000000u32, 1000000u32) != 0u32));
assert(!(checked.sat_subu32(0u32, 4294967295u32) != types.U32_MIN));
};
@test fn test_sat_subu64() void = {
if (checked.sat_subu64(18446744073709551610u64, 10u64) != 18446744073709551600u64) { let _: i32 = 1/0; };
if (checked.sat_subu64(44u64, 50u64) != types.U64_MIN) { let _: i32 = 1/0; };
if (checked.sat_subu64(1000000u64, 1000000u64) != 0u64) { let _: i32 = 1/0; };
if (checked.sat_subu64(0u64, 18446744073709551615u64) != types.U64_MIN) { let _: i32 = 1/0; };
assert(!(checked.sat_subu64(18446744073709551610u64, 10u64) != 18446744073709551600u64));
assert(!(checked.sat_subu64(44u64, 50u64) != types.U64_MIN));
assert(!(checked.sat_subu64(1000000u64, 1000000u64) != 0u64));
assert(!(checked.sat_subu64(0u64, 18446744073709551615u64) != types.U64_MIN));
};
@test fn test_sat_muli8() void = {
if (checked.sat_muli8(11, 11) != 121) { let _: i32 = 1/0; };
if (checked.sat_muli8(12, 12) != types.I8_MAX) { let _: i32 = 1/0; };
if (checked.sat_muli8(12, -12) != types.I8_MIN) { let _: i32 = 1/0; };
if (checked.sat_muli8(-12, 12) != types.I8_MIN) { let _: i32 = 1/0; };
if (checked.sat_muli8(-12, -12) != types.I8_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_muli8(11, 11) != 121));
assert(!(checked.sat_muli8(12, 12) != types.I8_MAX));
assert(!(checked.sat_muli8(12, -12) != types.I8_MIN));
assert(!(checked.sat_muli8(-12, 12) != types.I8_MIN));
assert(!(checked.sat_muli8(-12, -12) != types.I8_MAX));
};
@test fn test_sat_muli16() void = {
if (checked.sat_muli16(181, 181) != 32761) { let _: i32 = 1/0; };
if (checked.sat_muli16(182, 182) != types.I16_MAX) { let _: i32 = 1/0; };
if (checked.sat_muli16(182, -182) != types.I16_MIN) { let _: i32 = 1/0; };
if (checked.sat_muli16(-182, 182) != types.I16_MIN) { let _: i32 = 1/0; };
if (checked.sat_muli16(-182, -182) != types.I16_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_muli16(181, 181) != 32761));
assert(!(checked.sat_muli16(182, 182) != types.I16_MAX));
assert(!(checked.sat_muli16(182, -182) != types.I16_MIN));
assert(!(checked.sat_muli16(-182, 182) != types.I16_MIN));
assert(!(checked.sat_muli16(-182, -182) != types.I16_MAX));
};
@test fn test_sat_muli32() void = {
if (checked.sat_muli32(46340, 46340) != 2147395600) { let _: i32 = 1/0; };
if (checked.sat_muli32(46341, 46341) != types.I32_MAX) { let _: i32 = 1/0; };
if (checked.sat_muli32(46341, -46341) != types.I32_MIN) { let _: i32 = 1/0; };
if (checked.sat_muli32(-46341, 46341) != types.I32_MIN) { let _: i32 = 1/0; };
if (checked.sat_muli32(-46341, -46341) != types.I32_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_muli32(46340, 46340) != 2147395600));
assert(!(checked.sat_muli32(46341, 46341) != types.I32_MAX));
assert(!(checked.sat_muli32(46341, -46341) != types.I32_MIN));
assert(!(checked.sat_muli32(-46341, 46341) != types.I32_MIN));
assert(!(checked.sat_muli32(-46341, -46341) != types.I32_MAX));
};
@test fn test_sat_mulu8() void = {
if (checked.sat_mulu8(15u8, 15u8) != 225u8) { let _: i32 = 1/0; };
if (checked.sat_mulu8(16u8, 16u8) != types.U8_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_mulu8(15u8, 15u8) != 225u8));
assert(!(checked.sat_mulu8(16u8, 16u8) != types.U8_MAX));
};
@test fn test_sat_mulu16() void = {
if (checked.sat_mulu16(255u16, 255u16) != 65025u16) { let _: i32 = 1/0; };
if (checked.sat_mulu16(256u16, 256u16) != types.U16_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_mulu16(255u16, 255u16) != 65025u16));
assert(!(checked.sat_mulu16(256u16, 256u16) != types.U16_MAX));
};
@test fn test_sat_mulu32() void = {
if (checked.sat_mulu32(65535u32, 65535u32) != 4294836225u32) { let _: i32 = 1/0; };
if (checked.sat_mulu32(65536u32, 65536u32) != types.U32_MAX) { let _: i32 = 1/0; };
assert(!(checked.sat_mulu32(65535u32, 65535u32) != 4294836225u32));
assert(!(checked.sat_mulu32(65536u32, 65536u32) != types.U32_MAX));
};
// Direct read of types::U*_MIN (all 0, ref/hare/types/limits.ha:30,36,
@@ -377,11 +377,11 @@ import types;
// exercise the U*_MIN, but assert the bare values here so a regression in
// lib/types surfaces standalone.
@test fn test_types_min() void = {
if (types.U8_MIN != 0u8) { let _: i32 = 1/0; };
if (types.U16_MIN != 0u16) { let _: i32 = 1/0; };
if (types.U32_MIN != 0u32) { let _: i32 = 1/0; };
if (types.U64_MIN != 0u64) { let _: i32 = 1/0; };
if (types.RUNE_MIN != '\0') { let _: i32 = 1/0; };
assert(!(types.U8_MIN != 0u8));
assert(!(types.U16_MIN != 0u16));
assert(!(types.U32_MIN != 0u32));
assert(!(types.U64_MIN != 0u64));
assert(!(types.RUNE_MIN != '\0'));
};
export fn main() i32 = {

View File

@@ -4,11 +4,11 @@ import random;
@test fn seq() void = {
let r: random.random = random.init(1234567u64);
if (random.next(&r) != 6457827717110365317u64) { let _: i32 = 1/0; };
if (random.next(&r) != 3203168211198807973u64) { let _: i32 = 1/0; };
if (random.next(&r) != 9817491932198370423u64) { let _: i32 = 1/0; };
if (random.next(&r) != 4593380528125082431u64) { let _: i32 = 1/0; };
if (random.next(&r) != 16408922859458223821u64) { let _: i32 = 1/0; };
assert(!(random.next(&r) != 6457827717110365317u64));
assert(!(random.next(&r) != 3203168211198807973u64));
assert(!(random.next(&r) != 9817491932198370423u64));
assert(!(random.next(&r) != 4593380528125082431u64));
assert(!(random.next(&r) != 16408922859458223821u64));
};
@test fn deterministic() void = {
@@ -16,7 +16,7 @@ import random;
let b: random.random = random.init(42u64);
let i: i32 = 0;
for (i < 32) {
if (random.next(&a) != random.next(&b)) { let _: i32 = 1/0; };
assert(!(random.next(&a) != random.next(&b)));
i += 1;
};
};
@@ -28,7 +28,7 @@ import random;
let v: u32 = random.u32n(&r, 17u32);
// v stored as u64 with possible high bits — mask before compare.
let vv: u64 = (v: u64) & 0xFFFFFFFFu64;
if (vv >= 17u64) { let _: i32 = 1/0; };
assert(!(vv >= 17u64));
i += 1;
};
};
@@ -38,7 +38,7 @@ import random;
let i: i32 = 0;
for (i < 200) {
let v: u64 = random.u64n(&r, 16u64);
if (v >= 16u64) { let _: i32 = 1/0; };
assert(!(v >= 16u64));
i += 1;
};
};
@@ -48,7 +48,7 @@ import random;
let i: i32 = 0;
for (i < 200) {
let v: u64 = random.u64n(&r, 100u64);
if (v >= 100u64) { let _: i32 = 1/0; };
assert(!(v >= 100u64));
i += 1;
};
};