aboutsummaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 16:19:56 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 16:19:56 +0330
commit76fc2643d1df7da7c83f7b58fe7e8459f487b816 (patch)
tree11bdeca107f087b70d12a0523d04fdd848208297 /src/tools
parentconformance: appendix b items the spec body documents are class c (diff)
zc0: read integer literals like the compiler: decimal with leading zeros, 0x hex, wrapping (appendix b.1.11)
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/zc0.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/tools/zc0.c b/src/tools/zc0.c
index 5846e22..6c20e2a 100644
--- a/src/tools/zc0.c
+++ b/src/tools/zc0.c
@@ -133,6 +133,16 @@ 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 the way the compiler reads it (lex1): decimal even with leading zeros,
+// 0x hex (no digits is 0), both wrapping modulo 2^64 (appendix b.1.11; strtoll saturated and read octal)
+static int64_t zc0_int(const char *s, char **end) {
+ uint64_t v = 0; const char *p = s;
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+ p += 2;
+ for (;;) { int c = *p, d; if (c >= '0' && c <= '9') d = c - '0'; else if (c >= 'a' && c <= 'f') d = c - 'a' + 10; else if (c >= 'A' && c <= 'F') d = c - 'A' + 10; else break; v = v * 16 + (uint64_t)d; p++; }
+ } else while (*p >= '0' && *p <= '9') { v = v * 10 + (uint64_t)(*p - '0'); p++; }
+ *end = (char *)p; return (int64_t)v;
+}
static void next(void)
{
int ws = 0, i;
@@ -153,7 +163,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;
+ char *e; tv = zc0_int(src + pos, &e); memcpy(ts, src + pos, e - src - pos); ts[e - src - pos] = 0; pos = e - src; tk = T_NUM; return;
}
if (src[p] == '.') {
int nch = (unsigned char)src[p + 1];
@@ -186,7 +196,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; }
+ { char *e; tv = zc0_int(src + pos, &e); memcpy(ts, src + pos, e - src - pos); ts[e - src - pos] = 0; pos = e - src; tk = T_NUM; return; }
}
if (isalpha((unsigned char)src[pos]) || src[pos] == '_') {
i = 0; while (isalnum((unsigned char)src[pos]) || src[pos] == '_') ts[i++] = src[pos++];