diff options
| author | 2026-10-14 16:19:20 +0330 | |
|---|---|---|
| committer | 2026-10-14 16:19:20 +0330 | |
| commit | 9c163931d6e9ed5d3770b2313b4775a2d189964f (patch) | |
| tree | 28d1d4d75085af33fd879a8d4f8ad549d3dc28be /src | |
| parent | zc0: embed of an array type inside a function (diff) | |
zc0: integer literals as the compiler reads them (010 is 10, 0x is 0, values wrap modulo 2^64)
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/zc0.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/src/tools/zc0.c b/src/tools/zc0.c index 51ea9f8..782d548 100644 --- a/src/tools/zc0.c +++ b/src/tools/zc0.c @@ -145,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; @@ -165,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]; @@ -198,7 +216,7 @@ 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] == '_') { tsroom((size_t)i + 2); ts[i++] = src[pos++]; } |
