aboutsummaryrefslogtreecommitdiffstats
path: root/serve/serve.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-30 16:16:08 +0100
committereunhhu <[email protected]>2026-09-30 16:16:08 +0100
commit46c303a41e9dd9cd0e6bd50511e8d7253a0ef438 (patch)
tree7564bf80ac43ff0964c64acd6a15f7299fa48997 /serve/serve.c
parente02bfc916743a0327d76144b32b6ec6381e5907f (diff)
downloadpure-46c303a41e9dd9cd0e6bd50511e8d7253a0ef438.tar.gz
pure-46c303a41e9dd9cd0e6bd50511e8d7253a0ef438.zip
Give i64 its own type in modules, lists, stores and the host (016 stage 2)
An i64 is an int64_t in a value's 8 bytes, its own stack type: CONST and NUM_TEXT take argument 2 for one, eleven opcodes are appended (ADD, SUB and MUL fail as overflow past its range, DIV and MOD floor and fail as divide by zero, NEG, COMPARE with a relation, MIN, MAX, and I64_FROM and NUM_FROM, which convert only where the value fits and else fail as limit), and moves (LOAD, STORE, locals, items, FIELD, SEND) copy it as they copy a number. Type codes: state 6, record field 3, message field 7 (8 bytes), view 4, local 3. v6 stays: all of it is added. - Folds with PURE_FOLD_INTEGER sum (overflow fails), keep the most or least of, or count the different i64s; distinct's set keeps an i64's -1 apart from its free mark. Blocks with an i64 run item by item. - A list's kinds are its stored header's (number, text, bytes, bool, integer): integer columns are int64_t, ordered as integers as keys (found without guide keys for now), stored in 8 bytes and logged as zigzag varints of any size. Records name their fields' type in one array (record_field_type) in place of text and bool flags. - A number, a bool and an i64 carry over each other by one rule, pure_cell_as, wherever one becomes another: a module replaced, a stored value or item read by another module, a waiting send recast. A u32 field delivers to an i64 one. - The host reads i64 fields from JSON, rows and queries as integer digits in range and nothing else, and shows every digit in views, tables, deliveries and pure-run. Faults are named by one function, pure_fault_name, in place of three tables; overflow is new. test-module: 28 arithmetic cases at the range's ends, relations, conversions both ways, 14 refusals, a keyed i64 list app (order, a sum that overflows, a failed add undone, messages and sends of 8 bytes, every digit as text), recasts, replacement between numbers, bools and i64s, and three stored runs against memory with restarts (46 images written).
Diffstat (limited to 'serve/serve.c')
-rw-r--r--serve/serve.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/serve/serve.c b/serve/serve.c
index 43297c1..6d9d5d6 100644
--- a/serve/serve.c
+++ b/serve/serve.c
@@ -525,15 +525,12 @@ static void answer(Connection *c, PureOutcome result) {
if (!result.body.size) release_ticket(c);
}
-static const char *const fault_names[] = {"none", "divide", "non_finite", "clamp", "limit", "not_found", "encoding",
- "exists", "memory"};
-
/* An app route's answer: a view's value, or what an event replied. A failed
* event names its fault: 404 not_found, 409 exists, 503 memory (the app's
* budget: again later), 422 for the others; a view without a value is 404
* no_value. */
static void answer_app(Connection *c, PureOutcome result, bool view, PureFault fault, const char *type) {
- const char *named = fault != PURE_FAULT_NONE ? fault_names[fault] : NULL;
+ const char *named = fault != PURE_FAULT_NONE ? pure_fault_name(fault) : NULL;
if (result.status == PURE_OK) {
struct iovec extent = {(void *)result.body.data, result.body.size};
respond_typed(c, 200, "OK", "none", 0, type ? type : "application/octet-stream", &extent,
@@ -1225,6 +1222,12 @@ static void put_number(Output *o, double value) {
put_bytes(o, digits, pure_format_number(value, digits));
}
+/* An i64's every digit (a JSON number too: a reader keeping binary64s loses those past 2^53). */
+static void put_integer(Output *o, int64_t value) {
+ char digits[24];
+ put_bytes(o, digits, (size_t)snprintf(digits, sizeof(digits), "%" PRId64, value));
+}
+
/* A view's arguments from a query's name=value pairs (values %XX decoded;
* from and count page a table): a payload of their input's shape, the
* fixed fields in its prefix, the texts and bytes after it in order, each's
@@ -1303,7 +1306,12 @@ static PureResult show_given(PureApp *app, const Route *route, size_t available,
PureResult status = PURE_OK;
double value;
if (m->view_type[view] == PURE_VIEW_TABLE && !(o.bytes = malloc(o.capacity = 1024))) return PURE_ALLOCATION;
- if (m->view_type[view] == PURE_VIEW_NUM || m->view_type[view] == PURE_VIEW_BOOL) {
+ if (m->view_type[view] == PURE_VIEW_I64) {
+ int64_t integer;
+ *type = "text/plain; charset=utf-8";
+ if (!pure_app_view_i64(app, view, &integer)) status = PURE_NOT_FOUND;
+ else put_integer(&o, integer);
+ } else if (m->view_type[view] == PURE_VIEW_NUM || m->view_type[view] == PURE_VIEW_BOOL) {
*type = "text/plain; charset=utf-8";
if (!pure_app_view(app, view, &value)) status = PURE_NOT_FOUND;
else if (m->view_type[view] == PURE_VIEW_BOOL) put_bytes(&o, value ? "true" : "false", value ? 4 : 5);
@@ -1343,6 +1351,12 @@ static PureResult show_given(PureApp *app, const Route *route, size_t available,
for (unsigned k = 0; k < count; ++k) {
put_bytes(&o, columns[k].key + !k, columns[k].length - !k);
uint8_t kind = m->view_type[columns[k].view];
+ if (kind == PURE_VIEW_I64) {
+ int64_t integer;
+ if (!pure_app_cell_i64(app, columns[k].view, row, &integer)) put_bytes(&o, "null", 4);
+ else put_integer(&o, integer);
+ continue;
+ }
if (kind == PURE_VIEW_NUM || kind == PURE_VIEW_BOOL) {
if (!pure_app_cell(app, columns[k].view, row, &value)) put_bytes(&o, "null", 4);
else if (kind == PURE_VIEW_BOOL) put_bytes(&o, value ? "true" : "false", value ? 4 : 5);
@@ -1858,8 +1872,7 @@ static bool same_states(const PureModule *a, const PureModule *b) {
a->record[i].count != b->record[i].count)
return false;
for (uint32_t i = 0; i < a->record_fields; ++i)
- if (strcmp(a->record_field_names[i], b->record_field_names[i]) || a->record_field_text[i] != b->record_field_text[i] ||
- a->record_field_bool[i] != b->record_field_bool[i])
+ if (strcmp(a->record_field_names[i], b->record_field_names[i]) || a->record_field_type[i] != b->record_field_type[i])
return false;
for (uint32_t i = 0; i < a->collections; ++i)
if (strcmp(a->collection_names[i], b->collection_names[i])) return false;