diff options
| author | eunhhu <[email protected]> | 2026-10-13 07:40:30 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-13 07:40:30 +0100 |
| commit | 8481b12fb794690cce0d9c54032ffba3de1fe31d (patch) | |
| tree | 55a7f3c74b8521b84262acb4cf444ddda9ef5070 /core/module.h | |
| parent | d83ccb2e3b3d276577c61b30a4a323909a654690 (diff) | |
| download | pure-8481b12fb794690cce0d9c54032ffba3de1fe31d.tar.gz pure-8481b12fb794690cce0d9c54032ffba3de1fe31d.zip | |
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)
Diffstat (limited to 'core/module.h')
| -rw-r--r-- | core/module.h | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/core/module.h b/core/module.h index 01bbb53..52cd4d8 100644 --- a/core/module.h +++ b/core/module.h @@ -45,6 +45,7 @@ typedef enum { PURE_OP_LOOP, PURE_OP_BREAK, PURE_OP_I64_BITS, PURE_OP_BYTE_AT, PURE_OP_BYTES_OF, PURE_OP_INDEX_AT, PURE_OP_BYTES_SLICE, PURE_OP_BYTE, PURE_OP_BYTES_LOAD, PURE_OP_BYTES_STORE, + PURE_OP_LIST_VALUE, PURE_OP_LIST_BIND, PURE_OP_APPEND_IN, PURE_OP_NUM_PARSE, PURE_OP_COUNT } PureOpcode; /* A bool is its own type (docs/design/016-bool-and-i64.md), held as a @@ -90,6 +91,22 @@ typedef enum { PURE_BITS_AND, PURE_BITS_OR, PURE_BITS_XOR, PURE_BITS_LEFT, PURE_ * after the point of FIXED. A form of an integer takes an i64 or a whole * number (else LIMIT), in its base with a sign; FIXED takes a number. */ enum { PURE_MODULE_HELD = 32, PURE_HELD_TEXT = 16, PURE_HELD_APPEND = 1 << 8 }; +/* 027's stage 2b: lists in records. A record field of type LIST holds a list + * of the record its default names (an event's alone: an event's lists, and + * the lists in their items, are the only ones that may hold one). The value + * is the list's number among the event's lists made so (0: an empty one), + * an i64 in its cell, so moves and reads (ITEM_GET) are an integer's; such + * lists go as the event or a view's body ends. A list is a value: storing + * one in a second cell shares it, and a list shared or bound is copied + * before it changes (so no other value sees the change). + * LIST_VALUE pushes the value of an event's list state (the argument): a + * copy of its items. LIST_BIND gives the bound list state (a register: an + * event's list flagged PURE_LIST_BOUND, read and walked, never changed by + * code) the list on the stack. APPEND_IN appends an item (its fields on the + * stack after an index) to the list in field (bits 16-31) of the item the + * index names in list (bits 0-15), an event's list. NUM_PARSE reads a text + * written as a JSON number as the nearest number (failing as LIMIT on any + * other text, or a value past the finite ones). */ typedef enum { PURE_FORMAT_PLAIN, PURE_FORMAT_DECIMAL, PURE_FORMAT_HEX, PURE_FORMAT_HEX_UPPER, PURE_FORMAT_BINARY, PURE_FORMAT_OCTAL, PURE_FORMAT_FIXED } PureFormat; enum { PURE_FORMAT_WIDTH = 8, PURE_FORMAT_ZEROS = 1 << 16, PURE_FORMAT_FORM = 17, PURE_FORMAT_DIGITS = 20 }; @@ -187,7 +204,7 @@ static inline uint8_t pure_value_kind(uint8_t state_type) { state_type == PURE_STATE_I64 ? PURE_CELL_INTEGER : 0xFF; } /* A record field: a number, a text (its default a constant), a bool or an i64. */ -typedef enum { PURE_RECORD_NUMBER = 0, PURE_RECORD_TEXT = 1, PURE_RECORD_BOOL = 2, PURE_RECORD_I64 = 3 } PureRecordType; +typedef enum { PURE_RECORD_NUMBER = 0, PURE_RECORD_TEXT = 1, PURE_RECORD_BOOL = 2, PURE_RECORD_I64 = 3, PURE_RECORD_LIST = 4 } PureRecordType; /* A value's 8 bytes: a number (a bool's 0 or 1, a cursor's or an index's * position too), or an integer. What a value is its state's or field's type * says, and the verifier keeps to it: moves copy the bytes, and only what @@ -199,7 +216,7 @@ typedef union { double num; int64_t i64; } PureValue; * let.name): it is emptied when every event ends, and it is never saved * nor logged for undoing. A message's rows field fills the one its path * names (unkeyed) as the message arrives; code fills a let's (docs/design/018). */ -enum { PURE_CURSOR_STAYS = 1, PURE_LIST_ROWS = 256 }; +enum { PURE_CURSOR_STAYS = 1, PURE_LIST_ROWS = 256, PURE_LIST_BOUND = 512 }; /* A transient state (bit 8 of its type word in a module, a bit of * PureModule.transient): the app holds it while it runs, and undoes it with * a failed event, but never saves it: each start begins it at its initial @@ -327,7 +344,9 @@ typedef struct { PureRecord record[PURE_MODULE_RECORDS]; char record_field_names[PURE_MODULE_RECORD_FIELDS][PURE_MODULE_NAME]; uint8_t record_field_type[PURE_MODULE_RECORD_FIELDS]; /* PureRecordType */ - PureValue record_field_default[PURE_MODULE_RECORD_FIELDS]; /* a number (a bool's 0 or 1), an i64, or a text constant's index */ + PureValue record_field_default[PURE_MODULE_RECORD_FIELDS]; /* a number (a bool's 0 or 1), an i64, a text constant's index + * or a list's record (LIST, its i64) */ + bool record_nested[PURE_MODULE_RECORDS]; /* a record with a LIST field (set at load) */ } PureModule; /* Whether a state of m is transient (PURE_STATE_TRANSIENT). */ @@ -522,6 +541,10 @@ typedef struct { bool reading; /* a reader: its states are a snapshot's */ /* The values an event or a view's body holds by name (BYTES_STORE): emptied as it begins. */ struct { unsigned char *data; size_t size, capacity; } held[PURE_MODULE_HELD]; + /* The lists in records an event or a view's body made (LIST fields: a value is a number here, 1 on), how many + * values share each, and the bound lists' own (a register's list while another is bound to it). */ + struct { PureList **list; uint32_t *shared; size_t count, capacity; } nested; + PureList *unbound[PURE_MODULE_STATES]; } PureApp; PureResult pure_app_start(PureApp *, const PureModule *, PureData data); |
