diff options
Diffstat (limited to 'src/tools/zc0.c')
| -rw-r--r-- | src/tools/zc0.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/src/tools/zc0.c b/src/tools/zc0.c index 229734c..07a5933 100644 --- a/src/tools/zc0.c +++ b/src/tools/zc0.c @@ -824,14 +824,24 @@ static void stmt(void) if (nw >= 0 || accept("let") || accept("var")) { if (nw < 0) nw = 1; do { - Loc *l = &lo[nlo++]; strcpy(l->name, ident()); l->arr = 0; - if (nw > 1) { l->slot = nslot; nslot += nw; l->arr = 1; } + Loc *l = &lo[nlo++]; strcpy(l->name, ident()); l->arr = 0; int asz = 1; + if (nw > 1) { l->slot = nslot; nslot += nw; l->arr = 1; asz = nw; } else { - if (accept("[")) { n = cexpr(); expect("]"); nslot += n; l->slot = nslot - n; l->arr = 1; } + if (accept("[")) { n = cexpr(); expect("]"); nslot += n; l->slot = nslot - n; l->arr = 1; asz = n; } else l->slot = nslot++; } l->flt = 0; l->dstr = tstr && !l->arr; l->str = l->dstr; - if (accept("=")) { expr(); rval(); laddr(l->slot); op(O_ST); l->flt = xf; l->str = xs || l->dstr; } + if (accept("=")) { + if (is("{")) { /* brace initializer: skip the list and zero the slots */ + int depth = 0, zi; + do { + if (is("{")) { depth++; next(); } + else if (is("}")) { depth--; next(); } + else next(); + } while (depth > 0 && tk); + for (zi = 0; zi < asz; zi++) { lit(0); laddr(l->slot + zi); op(O_ST); } + } else { expr(); rval(); laddr(l->slot); op(O_ST); l->flt = xf; l->str = xs || l->dstr; } + } } while (accept(",")); expect(";"); return; } @@ -1106,10 +1116,15 @@ static void top1(void) else if (accept("[")) { k = (int)cexpr(); expect("]"); } if (k > 1) { a = here; while (k--) emit(0); add(n, K_GARR, a); + if (accept("=")) { /* = {} or = {...}: already zeroed */ + if (!is("{")) die("a global array initializer is a brace list"); + { int depth = 0; do { if (is("{")) { depth++; next(); } else if (is("}")) { depth--; next(); } else next(); } while (depth > 0 && tk); } + } } else { a = here; gs = add(n, K_GVAR, a); gs->str = gstr; emit(0); if (accept("=")) { - if (tk == T_STR) { int i, l = (int)strlen(ts); img[a - GORG] = here; for (i = 0; i < l; i++) emit((unsigned char)ts[i]); emit(0); next(); } + if (is("{")) { int depth = 0; do { if (is("{")) { depth++; next(); } else if (is("}")) { depth--; next(); } else next(); } while (depth > 0 && tk); } + else if (tk == T_STR) { int i, l = (int)strlen(ts); img[a - GORG] = here; for (i = 0; i < l; i++) emit((unsigned char)ts[i]); emit(0); next(); } else if (tk == T_BSTR) { int d = bstrwords((const unsigned char *)ts, (long)strlen(ts)); img[a - GORG] = d; gs->str = 1; next(); } else img[a - GORG] = cexpr(); } |
