aboutsummaryrefslogtreecommitdiffstats
path: root/core/module.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/module.h')
-rw-r--r--core/module.h64
1 files changed, 43 insertions, 21 deletions
diff --git a/core/module.h b/core/module.h
index 2cac3b3..0634ed1 100644
--- a/core/module.h
+++ b/core/module.h
@@ -8,7 +8,7 @@
#include <stddef.h>
#include <stdint.h>
-/* Pure module format v5 (docs/design/008-module-format.md). A toolchain such
+/* Pure module format v6 (docs/design/008-module-format.md). A toolchain such
* as aup produces it; Pure verifies it completely before anything executes:
* operand types (including which text a cursor and which list an index
* belongs to), stack heights and the stack at every join, forward-only
@@ -42,9 +42,16 @@ typedef enum {
PURE_OP_LOCAL_LOAD, PURE_OP_LOCAL_STORE,
PURE_OP_COUNT
} PureOpcode;
+/* A bool is its own type (docs/design/016-bool-and-i64.md), held as a
+ * number 0 or 1 while it runs: comparisons (LT to NE, TEXT_COMPARE) and
+ * LIST_HAS push one, AND, OR and NOT work on them, JZ and REQUIRE take one,
+ * and EQ and NE compare two bools as they compare two numbers. CONST with
+ * argument 1 pushes a bool (its value 0 or 1); LOAD and STORE work on a
+ * number or a bool state as its type says; NUM_TEXT with argument 1 makes
+ * a bool text (true, false). */
/* A local: one of an event's PURE_MODULE_LOCALS slots, 0 when the event
* begins and never saved. LOCAL_LOAD and LOCAL_STORE name the slot (bits
- * 0-7), what it holds (bits 8-15: 0 a number, 1 an index) and an index's
+ * 0-7), what it holds (bits 8-15: 0 a number, 1 an index, 2 a bool) and an index's
* list (bits 16-31); a handler uses a slot for one of them. A handler, the
* walks in it and the folds in those read locals; the handler and its walks
* store them. */
@@ -56,10 +63,10 @@ enum { PURE_MODULE_LOCALS = 64 };
* (an item it removes, or one before it, moves the walk with it). */
/* FOLD's argument: the kind (bits 0-7), the list state (8-15) and the length
* of the block that follows (16-31), run once per item as a column of that
- * list. count counts the items whose block leaves a non-zero number; sum,
- * max, min and distinct take a value and an include flag from their block
- * (distinct counts the different values, -0 as 0); first gives the index of
- * the first item whose block leaves a non-zero number. */
+ * list. count counts the items whose block leaves true; sum, max, min and
+ * distinct take a number and whether to include it (a bool) from their
+ * block (distinct counts the different values, -0 as 0); first gives the
+ * index of the first item whose block leaves true. */
typedef enum { PURE_FOLD_COUNT, PURE_FOLD_SUM, PURE_FOLD_MAX, PURE_FOLD_MIN, PURE_FOLD_FIRST, PURE_FOLD_DISTINCT } PureFold;
/* A slice: a fold whose kind has PURE_FOLD_SLICED, or a walk whose argument
* has PURE_EACH_SLICED, first takes two numbers, a low and a high key, and
@@ -82,19 +89,31 @@ typedef enum { PURE_KIND_KEY = 1, PURE_KIND_MESSAGE = 2, PURE_KIND_TEXT = 3, PUR
enum { PURE_TIMER_LONGEST = 86400000, PURE_SOURCE = 64 };
/* The largest number a delivery may have: it is kept as a binary64. */
#define PURE_SEQ_MOST (UINT64_C(1) << 53)
-/* A message field: a u32le or a binary64 (fixed, at its offset in the
- * payload's prefix), or bytes, text or rows of any length. The prefix also
- * holds each variable field's u32le length but the last one's (its offset is
- * PURE_FIELD_REST), which takes what follows the others; the variable
- * fields' bytes follow the prefix in declaration order. A text is UTF-8 and
- * a number finite, or the message fails. Rows are records of a list of a
- * message's rows (rows, a list state), laid out as a list's stored form: a
- * message fills that list with them, and fails when they are not whole. */
+/* A message field: a u32le, a binary64 or a bool's one byte (fixed, at its
+ * offset in the payload's prefix), or bytes, text or rows of any length. The
+ * prefix also holds each variable field's u32le length but the last one's
+ * (its offset is PURE_FIELD_REST), which takes what follows the others; the
+ * variable fields' bytes follow the prefix in declaration order. A text is
+ * UTF-8, a number finite and a bool 0 or 1, or the message fails. Rows are
+ * records of a list of a message's rows (rows, a list state), laid out as a
+ * list's stored form: a message fills that list with them, and fails when
+ * they are not whole. */
typedef enum { PURE_FIELD_U32 = 1, PURE_FIELD_BYTES = 2, PURE_FIELD_NUMBER = 3, PURE_FIELD_TEXT = 4,
- PURE_FIELD_ROWS = 5 } PureFieldType;
+ PURE_FIELD_ROWS = 5, PURE_FIELD_BOOL = 6 } PureFieldType;
enum { PURE_FIELD_REST = UINT32_MAX };
+/* A field held in its payload's prefix (a u32, a number, a bool), and the bytes it takes there. */
+static inline bool pure_field_fixed(uint8_t type) {
+ return type == PURE_FIELD_U32 || type == PURE_FIELD_NUMBER || type == PURE_FIELD_BOOL;
+}
+static inline uint32_t pure_field_size(uint8_t type) {
+ return type == PURE_FIELD_NUMBER ? 8 : type == PURE_FIELD_BOOL ? 1 : 4;
+}
+/* A number as a bool: 0 (of either sign) is false, 1 true, any other the
+ * default given. A state or field that becomes a bool keeps its value so. */
+static inline double pure_as_bool(double value, double otherwise) { return value == 0 ? 0 : value == 1 ? 1 : otherwise; }
typedef enum {
- PURE_STATE_NUM = 0, PURE_STATE_TEXT = 1, PURE_STATE_CURSOR = 2, PURE_STATE_LIST = 3, PURE_STATE_INDEX = 4
+ PURE_STATE_NUM = 0, PURE_STATE_TEXT = 1, PURE_STATE_CURSOR = 2, PURE_STATE_LIST = 3, PURE_STATE_INDEX = 4,
+ PURE_STATE_BOOL = 5
} PureStateType;
/* A cursor that stays before text inserted at it (a mark); other cursors go
* after it (a caret). A list of a message's rows (its state's flags hold
@@ -103,9 +122,9 @@ typedef enum {
* every event ends, and it is never saved nor logged for undoing. */
enum { PURE_CURSOR_STAYS = 1, PURE_LIST_ROWS = 256 };
/* A table view has one row per item of a list, or per item its filter
- * keeps; its columns are number or text views evaluated for one row at a
- * time. */
-typedef enum { PURE_VIEW_NUM = 0, PURE_VIEW_TEXT = 1, PURE_VIEW_TABLE = 2 } PureViewType;
+ * keeps; its columns are number, bool or text views evaluated for one row at
+ * a time. */
+typedef enum { PURE_VIEW_NUM = 0, PURE_VIEW_TEXT = 1, PURE_VIEW_TABLE = 2, PURE_VIEW_BOOL = 3 } PureViewType;
typedef enum { PURE_UNIT_CHAR = 0, PURE_UNIT_LINE = 1 } PureUnit;
typedef enum { PURE_EDGE_DOWN, PURE_EDGE_UP } PureEdge;
/* EXISTS: an item with that key is already in the keyed list (the event
@@ -198,7 +217,8 @@ typedef struct {
PureRecord record[PURE_MODULE_RECORDS];
char record_field_names[PURE_MODULE_RECORD_FIELDS][PURE_MODULE_NAME];
uint8_t record_field_text[PURE_MODULE_RECORD_FIELDS];
- double record_field_default[PURE_MODULE_RECORD_FIELDS]; /* number, or text constant index */
+ uint8_t record_field_bool[PURE_MODULE_RECORD_FIELDS]; /* a bool: a number field (0 or 1) as lists go */
+ double record_field_default[PURE_MODULE_RECORD_FIELDS]; /* number (a bool's 0 or 1), or text constant index */
} PureModule;
/* Decode and verify into out, which must be zeroed (a static one is) or hold
@@ -422,7 +442,8 @@ PureResult pure_app_message_fields(PureApp *, uint32_t input, const char *key, i
* next event (deferred: copy it before a later save too). */
PureResult pure_app_reply(const PureApp *, bool (*visit)(void *, PureSpan), void *context);
void pure_app_finish(PureApp *);
-/* A number view; false for a text view or a failed evaluation. */
+/* A number view, or a bool view (0 or 1: its type says which); false for a
+ * text view or a failed evaluation. */
bool pure_app_view(PureApp *, uint32_t view, double *out);
/* A text view, lent in order until the next view evaluation. */
PureResult pure_app_view_text(PureApp *, uint32_t view, bool (*visit)(void *, PureSpan), void *context);
@@ -444,6 +465,7 @@ unsigned pure_app_passes(const PureApp *);
* its filter leaves the item out). Without a filter both are the identity. */
bool pure_app_row_item(PureApp *, uint32_t table, size_t row, size_t *item);
bool pure_app_item_row(PureApp *, uint32_t table, size_t item, size_t *row);
+/* A number or bool column's cell (as pure_app_view), or a text column's. */
bool pure_app_cell(PureApp *, uint32_t column, size_t row, double *out);
PureResult pure_app_cell_text(PureApp *, uint32_t column, size_t row, bool (*visit)(void *, PureSpan), void *context);
/* Switch to another verified module. States keep their value by name (text