diff options
| author | 2026-10-14 09:48:11 +0000 | |
|---|---|---|
| committer | 2026-10-14 09:48:11 +0000 | |
| commit | 98f9e13829204d32c7dea8a58f8f11efc2a38550 (patch) | |
| tree | b96940376e0f2f306ded70736018afa92f6c0c89 /tests/programs/zc0bstr.zc | |
| parent | Merge branch 'worktree-agent-a96a10dc1489688ea' into ccr-0054c02e-dfdvnd (diff) | |
zc0: byte string types, u/m/d as names, enhancements in asm
bstr locals, globals, parameters and returns are byte strings for + , the
comparisons, indexing, slicing, len and put_s; b"..." globals; embed inside
a function. u, m and d are ordinary names: a recast is the letter with the
star touching it (u*x), tags .u .m .d are accepted on types and bare. an
enhancement named inside asm { } emits its opcode. zc0's image of the
genome and language server sources is unchanged.
Diffstat (limited to 'tests/programs/zc0bstr.zc')
| -rw-r--r-- | tests/programs/zc0bstr.zc | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/tests/programs/zc0bstr.zc b/tests/programs/zc0bstr.zc new file mode 100644 index 0000000..bb4ffbc --- /dev/null +++ b/tests/programs/zc0bstr.zc @@ -0,0 +1,96 @@ +namespace; +include rt; + +// packed byte strings in the zc0 subset: the same program runs on the resident +// compiler and, built into a run-only image, on stage 0 (src/tools/zc0.c). it +// covers every b"..." escape, the packed layout, bstr locals, globals, +// parameters and returns, + and the six comparisons, indexing, slicing, len +// and embed. run from the repository root: the embeds read tests/data/embed. + +bstr greeting = b"hello"; +bstr shout; +bstr plain = b"plain"; +embed "tests/data/embed/text.txt" as bstr text; +embed "tests/data/embed/nul.bin" as bstr nul; +embed "tests/data/embed/text.txt" as untyped; + +bstr tag(bstr s) { return b"<" + s + b">"; } +bstr twice(bstr s); +bstr twice(bstr s) { return s + s; } +bstr pick(int n) { + bstr r; + if (n) r = b"yes"; else r = b"no"; + return r; +} +int rank(bstr a, bstr b) { return (a < b) * 8 + (a <= b) * 4 + (a == b) * 2 + (a > b); } +int count(bstr s, int c) { + int n = 0, i = 0; + while (i < len(s)) { if (s[i] == c) n++; i++; } + return n; +} +int num(int n) { rt.put_n(n); rt.put_c(32); return 0; } +int nl() { rt.put_c(10); return 0; } +int bytes(bstr s) { + int i = 0; + num(len(s)); + while (i < len(s)) { num(s[i]); i++; } + nl(); + return 0; +} +int words(bstr s) { + word* w = rt.bstr_storage(s); + int n = 1 + (w[0] >> 3) + 1, i = 0; + while (i < n) { num(w[i]); i++; } + nl(); + return 0; +} + +fn main() { + bstr a = b"abc", b, c; + bstr e = b""; + let u = b"x"; + // every escape the lexer knows: n t r 0 e, and any other character stands for itself + bytes(b"\n\t\r\e\\\"\'\q\x41"); + bytes(b"ab\0cd"); + bytes(b"\0"); + bytes(b"café"); + bytes(b"caf\303\251"); + bytes(b"quote \" inside, 'single', back\\slash"); + // the layout: a length word, bytes packed 8 to a word, a 0 word after a full last word + words(e); + words(b"a"); + words(b"abcdefg"); + words(b"abcdefgh"); + words(b"abcdefghi"); + words(b"0123456789abcdef"); + words(b"0123456789abcdefg"); + words(text); + words(nul); + // declarations, assignment later, a return value, concatenation + b = tag(a); + c = twice(b) + e + u; + rt.put_s(a); rt.put_c(32); rt.put_s(b); rt.put_c(32); rt.put_s(c); nl(); + shout = twice(greeting) + b"!"; + rt.put_s(greeting); rt.put_c(32); rt.put_s(shout); rt.put_c(32); rt.put_s(plain); nl(); + rt.put_s(tag(twice(tag(b"z")))); nl(); + rt.put_s(pick(1) + b"/" + pick(0)); nl(); + // comparisons: below, equal, above, a prefix, the empty string, a 9 byte string + num(rank(b"abc", b"abd")); num(rank(b"abc", b"abc")); num(rank(b"abd", b"abc")); + num(rank(b"ab", b"abc")); num(rank(b"", b"")); num(rank(b"", b"a")); + num(rank(b"abcdefghi", b"abcdefghi")); num(rank(b"abcdefgh", b"abcdefghi")); nl(); + num(a == b"abc"); num(a != b"abc"); num(a == b); num(a != b); + num(tag(a) == b"<abc>"); num(shout > greeting); num(greeting >= shout); num(plain <= plain); nl(); + // indexing, slicing, len + num(a[0]); num(a[2]); num(a[3]); num(len(a)); num(len(e)); num(len(c)); num(len(b"123456789")); nl(); + rt.put_s(c[1:4]); rt.put_c(32); rt.put_s(a[1:2]); rt.put_c(32); rt.put_s(a[0:0]); rt.put_c('|'); + rt.put_s(a[2:99]); rt.put_c('|'); rt.put_s(a[3:1]); rt.put_c('|'); rt.put_s((a + a)[2:4]); nl(); + num(count(c, '<')); num(count(shout, 'l')); num(count(b"mississippi", 's')); num(count(e, 'x')); nl(); + num(b"xyz"[1]); num(len(b"xyz")); num(len(a + a + a)); num(len(tag(e))); nl(); + // embed: a global of the file's bytes, with or without the type, and a local + rt.put_s(text); num(len(text)); num(text[0]); num(text == untyped); num(len(nul)); num(nul[2]); nl(); + embed "tests/data/embed/text.txt" as bstr here; + embed "tests/data/embed/answer.bin" as int answer; + embed "tests/data/embed/text.txt" as char* chars; + rt.put_s(here + b"|" + untyped); num(len(here)); num(here == text); num(answer); num(chars[6]); nl(); + return 0; +} |
