From 8481b12fb794690cce0d9c54032ffba3de1fe31d Mon Sep 17 00:00:00 2001 From: eunhhu Date: Tue, 13 Oct 2026 07:40:30 +0100 Subject: Module format and executor: 027's stage 2b, lists in records: a record field of type LIST (its items' record in its default) holds a list the event made, its number an i64 in the cell (0 an empty one), so lists keep their inside, batches and the JIT as they were (the JIT's append fast path leaves such records alone); LIST_VALUE (a copy of an event's list, nothing made for an empty one), LIST_BIND (a register, an event's list flagged PURE_LIST_BOUND, read and walked, never changed by code), APPEND_IN (an item into the list in a field of an event's list's item, copied first when another value shares it or a register is bound to it), sharing counted where cells take them; such records only in event lists (no stored, transient or message list, no key); the event's lists go as each event or view's body begins, registers given back their own; record field names may be paths (at.x: records in records, flattened by aup); NUM_PARSE (a text written as a JSON number, its nearest double, core's pure_parse_number); unit tests (values copied, shared then appended, a bound register seeing what it was bound to, three events alike, 6 refused; under ASan and UBSan too, which found the record kinds' missing LIST) --- core/module-text.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'core/module-text.c') diff --git a/core/module-text.c b/core/module-text.c index 4ce1769..f09cb75 100644 --- a/core/module-text.c +++ b/core/module-text.c @@ -59,6 +59,30 @@ size_t pure_utf8_newlines(PureSpan span) { return count; } +bool pure_parse_number(const unsigned char *text, size_t size, double *value) { + size_t i = 0; + if (i < size && text[i] == '-') ++i; + if (i == size || text[i] < '0' || text[i] > '9') return false; + if (text[i++] != '0') while (i < size && text[i] >= '0' && text[i] <= '9') ++i; + if (i < size && text[i] == '.') { + if (++i == size || text[i] < '0' || text[i] > '9') return false; + while (i < size && text[i] >= '0' && text[i] <= '9') ++i; + } + if (i < size && (text[i] == 'e' || text[i] == 'E')) { + if (++i < size && (text[i] == '+' || text[i] == '-')) ++i; + if (i == size || text[i] < '0' || text[i] > '9') return false; + while (i < size && text[i] >= '0' && text[i] <= '9') ++i; + } + if (i != size) return false; + char small[64], *digits = size < sizeof(small) ? small : malloc(size + 1); /* strtod rounds to nearest, ties to even */ + if (!digits) return false; + memcpy(digits, text, size); + digits[size] = 0; + *value = strtod(digits, NULL); + if (digits != small) free(digits); + return isfinite(*value); +} + size_t pure_format_number(double value, char out[32]) { if (value == 0) { memcpy(out, "0", 2); return 1; } if (value == floor(value) && fabs(value) < 1e15) { -- cgit v1.2.3