diff options
| -rw-r--r-- | TODO.md | 2 | ||||
| -rw-r--r-- | docs/history/43-stdlib/notes.md | 4 | ||||
| -rw-r--r-- | src/tools/zc0.c | 68 | ||||
| -rw-r--r-- | tests/conformance/1-source/lit_string_over_4095_bytes.zc | 10 | ||||
| -rw-r--r-- | tests/conformance/3-expressions/cast_as_pointer_type.zc | 15 | ||||
| -rw-r--r-- | tests/conformance/5-declarations/fn_param_tag_u_rejected.zc | 6 | ||||
| -rw-r--r-- | tests/conformance/known.txt | 11 | ||||
| -rw-r--r-- | tests/programs/embed_local_array.zc | 11 |
8 files changed, 98 insertions, 29 deletions
@@ -505,7 +505,7 @@ sorted by how hard each is to implement; the final full suite stays last. items with an architecture note carry the design worked out so far, enough to brief someone without re-reading the code. -- [ ] remaining zc0 gaps: string literals over 4095 bytes, `embed` of an array type inside a function, `x as T` with more than a single name (`x as int*`), zc0 silently accepting `.u` on a parameter, and integer literals (`010` is 8 in zc0, 10 in the compiler; zc0 saturates on overflow). `docs/history/43-stdlib/notes.md` still says zc0 reserves u/m/d: add a pointer forward rather than rewriting history. +- [x] remaining zc0 gaps, one commit each on work/xref: string literals have no length limit (the token text grows; `1-source/lit_string_over_4095_bytes.zc`); `.u` on a typed parameter is rejected with the compiler's message, "a parameter tag is .m or .d" (`5-declarations/fn_param_tag_u_rejected.zc`); `x as T` reads a whole type, so `x as int*` and `x as char**` work (`3-expressions/cast_as_pointer_type.zc`); `embed` of an array type inside a function puts the elements in the code and the local holds their address (`tests/programs/embed_local_array.zc`, a parity program); integer literals as the compiler reads them, so `010` is 10, `0x` is 0 and values wrap modulo 2^64 (the eleven class b literal entries left `known.txt`). `docs/history/43-stdlib/notes.md` has a forward note that zc0 no longer reserves u/m/d. the genome is byte-identical to main's. - [x] verify both compilers against `docs/SPEC.md`: `tests/conformance/<section>/` (sections 1 to 8 plus `9-appendix-b`, 657 programs), runner `tests/conformance/run.sh` (`--zc0`, `--zym`, `--zy`, `-w`), understood failures in `tests/conformance/known.txt` (class a self-hosted bug, b zc0, c spec issue), wired into the interp section of `tests/test.sh`. zy 626 ok, 31 known; zc0 221 ok, 38 known, 398 skipped (outside appendix a). appendix b.2 items 1 to 16 confirmed except b.2.8, which is documented behavior (5.3.2, 3.14.2; the spec wins). top-level `o3 { }` is rejected (4.10.2, class c, left alone). the seven class a bugs are fixed, one commit each: a bad literal in a function's first statement (capture_scan left panic set), `u*d` with visible `u`/`d`, the bstr flag surviving a cast, the 24-parameter limit, `return e;` in a void function (now dropped, yields 0), `memdebug scrub;`, and `case member():` on a member with fields. the conformance run is in `tests/test.sh` but not in `-q`. open: `rt.memreport()` reports buddy capacity (`rt.new(2)` is 3 words), whether that is the spec's W; whether top-level `unchecked;` is in the zc0 subset. - [ ] fix the implementation bugs listed in `docs/SPEC.md` appendix b, once confirmed: enum members can't reference earlier members; a plain function redefinition silently shadows the first; a prototype after the definition hides it; `?:` with one int and one float branch gives garbage; `bool` not normalised; float global initializers rejected; `include std;` inside a function body; syntax-error recovery hiding later errors; unterminated `/*` and string literals; `x as int * y`; prototypes needing parameter names; `len(char*)` with typecheck off; duplicate `case` labels; local `const` in constant expressions; constant expressions without precedence (`1+2*3` is 9). (`memdebug scrub;` is fixed; a global initializer naming another global giving its address is documented behavior, 5.3.2.) fix the prose items the appendix lists too. - [ ] (partly done, see "agent work at the end of the session") a cross-reference report: for every global of the compiler, the functions that write it and the ones that only read it. build it from the language server's references (`textDocument/references` on `build/bin/zclsp`, so scoping is exact) and classify each reference as a write when an assignment operator, `++` or `--` follows it. output under `build/xref/`; a committed baseline and a `--check` mode that fails when a new writer of a global appears, so it can run in ci. diff --git a/docs/history/43-stdlib/notes.md b/docs/history/43-stdlib/notes.md index 65fbebc..6a603d8 100644 --- a/docs/history/43-stdlib/notes.md +++ b/docs/history/43-stdlib/notes.md @@ -45,3 +45,7 @@ milliseconds per tree of depth 12. gcc on this run was 0.091 for malloc and 0.01 | zc arm64 jit, qemu-user, o3 arena | 0.702 | 0.724 | `bench/run.sh` timed the llvm plain tree at 47 repetitions, median 6.89 ms (1.66 to 7.67), and the o3 tree at 115 repetitions, median 7.14 ms (6.82 to 7.61). a slope from 400 repetitions to 1600 on the same binary is 7.50 ms for the plain tree (7.46 to 7.63) and 6.99 ms for the o3 tree (6.94 to 7.06). those two are the after column. on the interpreter the o3 tree is 64.62 ms and the plain tree is 73.02 ms. + +## later + +zc0 no longer reserves `u`, `m` and `d`: they are ordinary names there too, as in the resident compiler, and a recast is the letter with the star touching it (`u*x`). see the header of `src/tools/zc0.c`. diff --git a/src/tools/zc0.c b/src/tools/zc0.c index af85ff8..664ea79 100644 --- a/src/tools/zc0.c +++ b/src/tools/zc0.c @@ -34,7 +34,19 @@ static char module_name[64]; static char *src; static int pos, line = 1, tstart, hdr_start; /* the signature of the function being defined: its header's source text, for the language server (ZC0DOCS) */ static char sgtext[400], sgname[80]; -static int tk, glue; static int64_t tv; static char ts[4096]; /* current token */ +static int tk, glue; static int64_t tv; /* current token */ +/* the token's text. it grows as a long string literal or name needs; there is no fixed limit */ +static char ts0[4096]; static char *ts = ts0; static size_t tscap = sizeof ts0; +static void tsroom(size_t n) +{ + size_t c = tscap; char *nb; + if (n < tscap) return; + while (c <= n) c *= 2; + nb = ts == ts0 ? malloc(c) : realloc(ts, c); + if (!nb) { fprintf(stderr, "zc0: out of memory for a token\n"); exit(1); } + if (ts == ts0) memcpy(nb, ts0, sizeof ts0); + ts = nb; tscap = c; +} static int xf, xs, lvi; /* float, byte string; the plain local it came from, or -1 */ static int64_t *img; static int imgcap, here = GORG; @@ -133,6 +145,24 @@ static void docblock(void) while (dn && (dbuf[dn - 1] == ' ' || dbuf[dn - 1] == '\t' || dbuf[dn - 1] == '\r' || dbuf[dn - 1] == '\n')) dn--; dbuf[dn++] = '\n'; dlast = line; docpending = 1; } +/* an integer literal at pos, as the compiler reads it: decimal digits (a leading 0 is + not octal: 010 is 10), or 0x and hex digits (0x alone is 0). the value wraps modulo + 2^64 instead of saturating. the token text is the literal's source. */ +static void intlit(int base) +{ + int p = pos, d; uint64_t u = 0; + if (base == 16) pos += 2; + for (;;) { + int c = (unsigned char)src[pos]; + if (c >= '0' && c <= '9') d = c - '0'; + else if (base == 16 && c >= 'a' && c <= 'f') d = c - 'a' + 10; + else if (base == 16 && c >= 'A' && c <= 'F') d = c - 'A' + 10; + else break; + u = u * (uint64_t)base + (uint64_t)d; pos++; + } + tsroom((size_t)(pos - p) + 1); memcpy(ts, src + p, (size_t)(pos - p)); ts[pos - p] = 0; + tv = (int64_t)u; tk = T_NUM; +} static void next(void) { int ws = 0, i; @@ -153,7 +183,7 @@ static void next(void) if (isdigit((unsigned char)src[pos]) || (src[pos] == '.' && isdigit((unsigned char)src[pos + 1]))) { int p = pos, fl = 0; if (src[pos] == '0' && (src[pos + 1] == 'x' || src[pos + 1] == 'X')) { - char *e; tv = (int64_t)strtoll(src + pos, &e, 0); memcpy(ts, src + pos, e - src - pos); ts[e - src - pos] = 0; pos = e - src; tk = T_NUM; return; + intlit(16); return; } if (src[p] == '.') { int nch = (unsigned char)src[p + 1]; @@ -186,22 +216,21 @@ static void next(void) } b[n] = 0; memcpy(ts, b, (size_t)n + 1); tv = (int64_t)fop_parse(b); tk = T_FLT; return; } - { char *e; tv = (int64_t)strtoll(src + pos, &e, 0); memcpy(ts, src + pos, e - src - pos); ts[e - src - pos] = 0; pos = e - src; tk = T_NUM; return; } + intlit(10); return; } if (isalpha((unsigned char)src[pos]) || src[pos] == '_') { - i = 0; while (isalnum((unsigned char)src[pos]) || src[pos] == '_') ts[i++] = src[pos++]; + i = 0; while (isalnum((unsigned char)src[pos]) || src[pos] == '_') { tsroom((size_t)i + 2); ts[i++] = src[pos++]; } ts[i] = 0; if (i == 1 && ts[0] == 'b' && src[pos] == '"') { pos++; i = 0; while (src[pos] && src[pos] != '"') { - if (i >= 4095) { die("a byte string literal is at most 4095 bytes; embed larger data"); break; } - ts[i++] = (char)esc(); + tsroom((size_t)i + 2); ts[i++] = (char)esc(); } ts[i] = 0; if (src[pos] == '"') pos++; tk = T_BSTR; return; } if (src[pos] == '.' && (!strcmp(ts,"rt") || !strcmp(ts,"run") || !strcmp(ts,"core") || !strcmp(ts,"lsp") || !strcmp(ts,"std") || !strcmp(ts,"icon"))) { - ts[i++] = src[pos++]; - while (isalnum((unsigned char)src[pos]) || src[pos] == '_') ts[i++] = src[pos++]; + tsroom((size_t)i + 2); ts[i++] = src[pos++]; + while (isalnum((unsigned char)src[pos]) || src[pos] == '_') { tsroom((size_t)i + 2); ts[i++] = src[pos++]; } ts[i] = 0; } tk = T_ID; return; @@ -210,8 +239,7 @@ static void next(void) if (src[pos] == '"') { pos++; i = 0; while (src[pos] && src[pos] != '"') { - if (i >= 4095) { die("a string literal is at most 4095 bytes"); break; } - ts[i++] = (char)esc(); + tsroom((size_t)i + 2); ts[i++] = (char)esc(); } ts[i] = 0; pos++; tk = T_STR; return; } @@ -220,9 +248,10 @@ static void next(void) for (i = 0; ops2[i]; i++) if (!strncmp(src + pos, ops2[i], 2)) { strcpy(ts, ops2[i]); pos += 2; return; } ts[0] = src[pos++]; ts[1] = 0; } -typedef struct { char *src; int pos, line, tk, glue; int64_t tv; char ts[4096]; int xf, xs; } Lex; -static void lexsave(Lex *L) { L->src = src; L->pos = pos; L->line = line; L->tk = tk; L->glue = glue; L->tv = tv; memcpy(L->ts, ts, sizeof ts); L->xf = xf; L->xs = xs; } -static void lexrest(Lex *L) { src = L->src; pos = L->pos; line = L->line; tk = L->tk; glue = L->glue; tv = L->tv; memcpy(ts, L->ts, sizeof ts); xf = L->xf; xs = L->xs; } +/* a saved lexer position. ts is a copy of the token text (malloc), released by lexrest */ +typedef struct { char *src; int pos, line, tk, glue; int64_t tv; char *ts; size_t tn; int xf, xs; } Lex; +static void lexsave(Lex *L) { L->src = src; L->pos = pos; L->line = line; L->tk = tk; L->glue = glue; L->tv = tv; L->tn = strlen(ts) + 1; L->ts = malloc(L->tn); if (!L->ts) { fprintf(stderr, "zc0: out of memory\n"); exit(1); } memcpy(L->ts, ts, L->tn); L->xf = xf; L->xs = xs; } +static void lexrest(Lex *L) { src = L->src; pos = L->pos; line = L->line; tk = L->tk; glue = L->glue; tv = L->tv; tsroom(L->tn); memcpy(ts, L->ts, L->tn); free(L->ts); L->ts = 0; xf = L->xf; xs = L->xs; } static int is(const char *s) { return (tk == T_OP || tk == T_ID) && !strcmp(ts, s); } static int accept(const char *s) { if (is(s)) { next(); return 1; } return 0; } static void expect(const char *s) { if (!accept(s)) { char b[64]; sprintf(b, "expected '%s'", s); die(b); } } @@ -626,7 +655,7 @@ static void postfix(void) else if (is("(")) { rval(); n = args(); lit(n); op(O_PICK); op(O_CALL); op(O_SWAP); op(O_DROP); xf = 0; xs = 0; lvi = -1; } else if (accept("++")) incdec(1, 1); else if (accept("--")) incdec(1, -1); - else if (accept("as")) ident(); + else if (accept("as")) ptype0(); /* the whole type, as the compiler reads it: x as int*, x as char** */ else return; } } @@ -820,7 +849,10 @@ static void fndef(int ret, int rstr) /* rstr: the return type is bstr */ if (!accept(")")) { do { t = 0; ptag = 0; pstr[np & 15] = 0; - if (optype() >= 0) { t = ptag == 1 ? 1 : ptag == 2 ? 2 : 0; pstr[np & 15] = ptstr; } /* the type is read and dropped */ + if (optype() >= 0) { /* the type is read and dropped */ + if (ptag == 3) die("a parameter tag is .m or .d"); /* the compiler's message: .u is only a return tag */ + t = ptag == 1 ? 1 : ptag == 2 ? 2 : 0; pstr[np & 15] = ptstr; + } else if (accept(".")) { /* .m name, .d name */ if (is("m")) t = 1; else if (is("d")) t = 2; else die("a parameter tag is .m or .d"); next(); @@ -980,12 +1012,13 @@ static void embeddecl(int local) } } else { int count; w = embed_width(ty, star); - if (local) die("zc0 embeds an array at the top level, not in a function"); if (!w) die("embed declares a bstr, a char*, a number or an array of numbers"); if (len % w) die("the embedded file's size is not a whole number of elements"); count = (int)(len / w); if (arr >= 0 && count > arr) die("the embedded file is larger than the array it is declared as"); if (arr >= 0) count = arr; + /* in a function the elements sit in the code, jumped over, and the local holds their address */ + if (local) { j = here; lit(0); op(O_JMP); } a = here; for (i = 0; i < count; i++) { uint64_t u = 0; int k; @@ -995,7 +1028,8 @@ static void embeddecl(int local) emit((int64_t)u); } if (!count) emit(0); - add(n, K_GARR, a); + if (local) { setlit(j, here); l = newloc(n); lit(a); laddr(l->slot); op(O_ST); } + else add(n, K_GARR, a); } free(buf); } diff --git a/tests/conformance/1-source/lit_string_over_4095_bytes.zc b/tests/conformance/1-source/lit_string_over_4095_bytes.zc new file mode 100644 index 0000000..1de5b3d --- /dev/null +++ b/tests/conformance/1-source/lit_string_over_4095_bytes.zc @@ -0,0 +1,10 @@ +// expect: 5000 122/5001 121/ +include rt; +// a string literal and a byte string literal longer than 4095 bytes (zc0 used to stop at 4095). +int slen(char* s) { int n = 0; while (s[n]) n++; return n; } +void main() { + char* s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz"; + bstr t = b"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqy"; + rt.put_n(slen(s)); rt.put_c(32); rt.put_n(s[4999]); rt.put_c(10); + rt.put_n(len(t)); rt.put_c(32); rt.put_n(t[5000]); rt.put_c(10); +} diff --git a/tests/conformance/3-expressions/cast_as_pointer_type.zc b/tests/conformance/3-expressions/cast_as_pointer_type.zc new file mode 100644 index 0000000..5ebc696 --- /dev/null +++ b/tests/conformance/3-expressions/cast_as_pointer_type.zc @@ -0,0 +1,15 @@ +// expect: 4/5/1/ +// spec: the type after `as` is a whole type, stars included (zc0 used to read one name) +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +int[3] a; +fn main() { + a[1] = 4; a[2] = 5; + word w = a; + int* q = w as int*; + char** r = 0 as char**; + pn((q as int*)[1]); + pn(q[2]); + pn(r == 0); + return 0; +} diff --git a/tests/conformance/5-declarations/fn_param_tag_u_rejected.zc b/tests/conformance/5-declarations/fn_param_tag_u_rejected.zc new file mode 100644 index 0000000..858e142 --- /dev/null +++ b/tests/conformance/5-declarations/fn_param_tag_u_rejected.zc @@ -0,0 +1,6 @@ +// expect error: a parameter tag is .m or .d +// spec: .u tags a return, never a parameter (zc0 used to accept int.u x silently) +include rt; +int f(int* .u x) { return 0; } +fn main() { return f(0); } +// zc0: error diff --git a/tests/conformance/known.txt b/tests/conformance/known.txt index 13ef43c..9bec99b 100644 --- a/tests/conformance/known.txt +++ b/tests/conformance/known.txt @@ -17,13 +17,6 @@ 9-appendix-b/b2_15_duplicate_case.zc zy c appendix b.2.15 confirmed; 4.7.2 says duplicates are allowed 9-appendix-b/b2_16_local_const_in_const_expr.zc zy c appendix b.2.16 confirmed; 3.14.2 documents it 1-source/ident_tags_as_variables_glued_star.zc zc0 b u*d with visible u and d is read as a recast (no code); zy follows 1.6.3 -1-source/lit_hex.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_hex_wide.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_hex_wraps.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_int_max.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_int_wraps.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_int_zero_and_leading_zeros.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_minus_folded.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) 2-types/conv_argument_and_return.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) 2-types/conv_assignment_to_float.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) 2-types/conv_f32_rounds.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) @@ -50,7 +43,3 @@ 3-expressions/prec_as_binds_tight.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) 4-statements/return_value_converted_float.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) 4-statements/return_value_converted_int.zc zc0 b types are read and dropped: no conversion, no sized cut (appendix a) -9-appendix-b/b1_11_zc0_octal.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -9-appendix-b/b1_11_zc0_saturation.zc zc0 b literals read with strtoll base 0: octal and saturation (appendix b.1.11) -1-source/lit_hex_no_digits_is_zero.zc zc0 b 0x with no digits is rejected (strtoll) -1-source/lit_int_octal_is_decimal.zc zc0 b 08 is rejected (strtoll base 0 octal) diff --git a/tests/programs/embed_local_array.zc b/tests/programs/embed_local_array.zc new file mode 100644 index 0000000..0e2b7b8 --- /dev/null +++ b/tests/programs/embed_local_array.zc @@ -0,0 +1,11 @@ +include rt; +// embed of an array type inside a function (zc0 used to embed arrays only at the top level) +fn main() { + embed "tests/data/embed/bytes.bin" as u8[] bytes; + embed "tests/data/embed/bytes.bin" as i8[8] signed; + embed "tests/data/embed/shorts.bin" as u16[] shorts; + rt.put_n(bytes[4]); rt.put_c(32); + rt.put_n(signed[4]); rt.put_c(32); rt.put_n(signed[7]); rt.put_c(32); + rt.put_n(shorts[0] + shorts[1] * 10 + shorts[2] * 100); rt.put_c(10); + return 0; +} |
