diff --git a/lib/bytes/bytes.ww b/lib/bytes/bytes.ww index f7a88198..ab3db696 100644 --- a/lib/bytes/bytes.ww +++ b/lib/bytes/bytes.ww @@ -7,9 +7,6 @@ // 2/3/4-byte needles and falls back to two_way (Crochemore-Perrin) // for longer (ref/hare/bytes/index.ha:61, ref/hare/bytes/two_way.ha). // Correctness equivalent. -// - contains takes a single needle; Hare's contains is variadic -// `(u8 | []u8)...` (ref/hare/bytes/contains.ha:5). No caller needs -// the variadic shape yet; graduate when one does. // equal — true iff `a` and `b` have the same length and contents. // ref/hare/bytes/equal.ha:9. @@ -92,12 +89,26 @@ export fn rindex(s: []u8, needle: (u8 | []u8)) (i32 | void) = { return; }; -// contains — true iff `needle` (byte or sub-slice) appears in `s`. -// ref/hare/bytes/contains.ha:5 (variadic subset; see header note). -export fn contains(s: []u8, needle: (u8 | []u8)) bool = { - match (index(s, needle)) { - case let i: i32 => return true; - case void => return false; +// contains — true iff any of `needles` (byte or sub-slice) appears in `s`. +// ref/hare/bytes/contains.ha:6. +export fn contains(s: []u8, needles: (u8 | []u8)...) bool = { + let i: i32 = 0; + for (i < needles.len) { + match (needles[i]) { + case let b: u8 => { + match (index(s, b)) { + case let bo: i32 => return true; + case void => void; + }; + }; + case let n: []u8 => { + match (index(s, n)) { + case let bo: i32 => return true; + case void => void; + }; + }; + }; + i += 1; }; return false; }; diff --git a/lib/bytes/bytestest.ww b/lib/bytes/bytestest.ww index a25f1a1b..5dcc6350 100644 --- a/lib/bytes/bytestest.ww +++ b/lib/bytes/bytestest.ww @@ -195,6 +195,18 @@ fn fail() void = { os.exit(signalled + 10); }; if (!bytes.contains(a[0:4], n[0:2])) { fail(); }; let m: [2]u8; m[0] = 9u8; m[1] = 9u8; if ( bytes.contains(a[0:4], m[0:2])) { fail(); }; + + // Variadic rows. ref/hare/bytes/contains.ha:6. + signalled = 1700; + if ( bytes.contains(a[0:4])) { fail(); }; + signalled = 1701; + if (!bytes.contains(a[0:4], n[0:2])) { fail(); }; + signalled = 1702; + if (!bytes.contains(a[0:4], 7u8)) { fail(); }; + signalled = 1703; + if (!bytes.contains(a[0:4], m[0:2], n[0:2], 42u8)) { fail(); }; + signalled = 1704; + if ( bytes.contains(a[0:4], m[0:2], 42u8, m[0:2])) { fail(); }; }; // ---- hasprefix -------------------------------------------------------- diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 231cda4a..7ae1d07d 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -867,9 +867,6 @@ export fn freearena(a: *arena) void = { // 2/3/4-byte needles and falls back to two_way (Crochemore-Perrin) // for longer (ref/hare/bytes/index.ha:61, ref/hare/bytes/two_way.ha). // Correctness equivalent. -// - contains takes a single needle; Hare's contains is variadic -// `(u8 | []u8)...` (ref/hare/bytes/contains.ha:5). No caller needs -// the variadic shape yet; graduate when one does. // equal — true iff `a` and `b` have the same length and contents. // ref/hare/bytes/equal.ha:9. @@ -952,12 +949,26 @@ export fn rindex(s: []u8, needle: (u8 | []u8)) (i32 | void) = { return; }; -// contains — true iff `needle` (byte or sub-slice) appears in `s`. -// ref/hare/bytes/contains.ha:5 (variadic subset; see header note). -export fn contains(s: []u8, needle: (u8 | []u8)) bool = { - match (index(s, needle)) { - case let i: i32 => return true; - case void => return false; +// contains — true iff any of `needles` (byte or sub-slice) appears in `s`. +// ref/hare/bytes/contains.ha:6. +export fn contains(s: []u8, needles: (u8 | []u8)...) bool = { + let i: i32 = 0; + for (i < needles.len) { + match (needles[i]) { + case let b: u8 => { + match (index(s, b)) { + case let bo: i32 => return true; + case void => void; + }; + }; + case let n: []u8 => { + match (index(s, n)) { + case let bo: i32 => return true; + case void => void; + }; + }; + }; + i += 1; }; return false; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 043db4a3..91f79bc4 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -867,9 +867,6 @@ export fn freearena(a: *arena) void = { // 2/3/4-byte needles and falls back to two_way (Crochemore-Perrin) // for longer (ref/hare/bytes/index.ha:61, ref/hare/bytes/two_way.ha). // Correctness equivalent. -// - contains takes a single needle; Hare's contains is variadic -// `(u8 | []u8)...` (ref/hare/bytes/contains.ha:5). No caller needs -// the variadic shape yet; graduate when one does. // equal — true iff `a` and `b` have the same length and contents. // ref/hare/bytes/equal.ha:9. @@ -952,12 +949,26 @@ export fn rindex(s: []u8, needle: (u8 | []u8)) (i32 | void) = { return; }; -// contains — true iff `needle` (byte or sub-slice) appears in `s`. -// ref/hare/bytes/contains.ha:5 (variadic subset; see header note). -export fn contains(s: []u8, needle: (u8 | []u8)) bool = { - match (index(s, needle)) { - case let i: i32 => return true; - case void => return false; +// contains — true iff any of `needles` (byte or sub-slice) appears in `s`. +// ref/hare/bytes/contains.ha:6. +export fn contains(s: []u8, needles: (u8 | []u8)...) bool = { + let i: i32 = 0; + for (i < needles.len) { + match (needles[i]) { + case let b: u8 => { + match (index(s, b)) { + case let bo: i32 => return true; + case void => void; + }; + }; + case let n: []u8 => { + match (index(s, n)) { + case let bo: i32 => return true; + case void => void; + }; + }; + }; + i += 1; }; return false; }; diff --git a/selfhost/test/smoke.combined.ww b/selfhost/test/smoke.combined.ww index 536f0fb5..7e26bcb9 100644 --- a/selfhost/test/smoke.combined.ww +++ b/selfhost/test/smoke.combined.ww @@ -758,9 +758,6 @@ export fn exists(path: str) bool = { // 2/3/4-byte needles and falls back to two_way (Crochemore-Perrin) // for longer (ref/hare/bytes/index.ha:61, ref/hare/bytes/two_way.ha). // Correctness equivalent. -// - contains takes a single needle; Hare's contains is variadic -// `(u8 | []u8)...` (ref/hare/bytes/contains.ha:5). No caller needs -// the variadic shape yet; graduate when one does. // equal — true iff `a` and `b` have the same length and contents. // ref/hare/bytes/equal.ha:9. @@ -843,12 +840,26 @@ export fn rindex(s: []u8, needle: (u8 | []u8)) (i32 | void) = { return; }; -// contains — true iff `needle` (byte or sub-slice) appears in `s`. -// ref/hare/bytes/contains.ha:5 (variadic subset; see header note). -export fn contains(s: []u8, needle: (u8 | []u8)) bool = { - match (index(s, needle)) { - case let i: i32 => return true; - case void => return false; +// contains — true iff any of `needles` (byte or sub-slice) appears in `s`. +// ref/hare/bytes/contains.ha:6. +export fn contains(s: []u8, needles: (u8 | []u8)...) bool = { + let i: i32 = 0; + for (i < needles.len) { + match (needles[i]) { + case let b: u8 => { + match (index(s, b)) { + case let bo: i32 => return true; + case void => void; + }; + }; + case let n: []u8 => { + match (index(s, n)) { + case let bo: i32 => return true; + case void => void; + }; + }; + }; + i += 1; }; return false; };