summaryrefslogtreecommitdiff
path: root/include/lcq
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2026-06-29 22:59:28 -0400
committerLLLL Colonq <llll@colonq>2026-06-29 22:59:28 -0400
commit1d4447bcd888dd0bd20cf4b6dd7f9192145debf0 (patch)
treeee17e782943bed78bdf461c7fe876712127a0d28 /include/lcq
parent8909986b89eaac74bb4cd8dc7019f96e4f650470 (diff)
Refactor data structures
Diffstat (limited to 'include/lcq')
-rw-r--r--include/lcq/pit.h11
-rw-r--r--include/lcq/pit/arena.h45
-rw-r--r--include/lcq/pit/runtime.h34
-rw-r--r--include/lcq/pit/utils.h47
-rw-r--r--include/lcq/pit/vec.h48
5 files changed, 133 insertions, 52 deletions
diff --git a/include/lcq/pit.h b/include/lcq/pit.h
new file mode 100644
index 0000000..3afce9f
--- /dev/null
+++ b/include/lcq/pit.h
@@ -0,0 +1,11 @@
+#ifndef LCOLONQ_PIT_H
+#define LCOLONQ_PIT_H
+
+#include <lcq/pit/types.h>
+#include <lcq/pit/utils.h>
+#include <lcq/pit/lexer.h>
+#include <lcq/pit/parser.h>
+#include <lcq/pit/runtime.h>
+#include <lcq/pit/library.h>
+
+#endif
diff --git a/include/lcq/pit/arena.h b/include/lcq/pit/arena.h
new file mode 100644
index 0000000..fcaca55
--- /dev/null
+++ b/include/lcq/pit/arena.h
@@ -0,0 +1,45 @@
+#ifndef LCOLONQ_PIT_ARENA_H
+#define LCOLONQ_PIT_ARENA_H
+
+#include <lcq/pit/types.h>
+
+typedef i64 pit_arena_index;
+
+static inline uintptr_t pit_align_down(uintptr_t addr, uintptr_t align) {
+ return addr & ~(align - 1); /* easy! just zero the low bits */
+}
+static inline uintptr_t pit_align_up(uintptr_t addr, uintptr_t align) {
+ return (addr + align - 1) /* increment past the next aligned address... */
+ & ~(align - 1); /* ...and then zero the low bits */
+}
+typedef struct {
+ i64 elem_size, /* size of one element */
+ capacity, /* capacity in of data in bytes - only used to reset */
+ next, /* index (in elements) of next element to insert */
+ back; /* index (in bytes) one past the end of data. */
+ /* back starts at capacity, and decreases as you alloc_back */
+ u8 data[];
+} pit_arena;
+
+/* create a new arena in a buffer of buf_len size in bytes that stores elements of elem_size */
+pit_arena *pit_arena_new(u8 *buf, i64 buf_len, i64 elem_size);
+
+/* remove all elements from an array */
+void pit_arena_reset(pit_arena *a);
+
+/* allocate space for one or multiple elements, and return the index of the first element */
+pit_arena_index pit_arena_alloc_index(pit_arena *a);
+pit_arena_index pit_arena_alloc_array_index(pit_arena *a, i64 num);
+
+/* allocate space for one or multiple elements, and return a pointer */
+void *pit_arena_alloc(pit_arena *a);
+void *pit_arena_alloc_array(pit_arena *a, i64 num);
+
+/* retrieve a pointer to the element(s) at a given index */
+void *pit_arena_get(pit_arena *a, pit_arena_index idx);
+
+/* allocate arbitrary bytes on the "back" of the arena.
+ this can be an arbitrary size in bytes */
+void *pit_arena_alloc_back(pit_arena *a, i64 sz);
+
+#endif
diff --git a/include/lcq/pit/runtime.h b/include/lcq/pit/runtime.h
index da93dda..da3cbdd 100644
--- a/include/lcq/pit/runtime.h
+++ b/include/lcq/pit/runtime.h
@@ -3,6 +3,8 @@
#include <lcq/pit/types.h>
#include <lcq/pit/utils.h>
+#include <lcq/pit/vec.h>
+#include <lcq/pit/arena.h>
#include <lcq/pit/lexer.h>
struct pit_runtime;
@@ -23,13 +25,7 @@ typedef u64 pit_value;
enum pit_value_sort pit_value_sort(pit_value v);
u64 pit_value_data(pit_value v);
-typedef struct {
- i64 capacity, next;
- pit_value data[];
-} pit_values;
-pit_values *pit_values_new(u8 *buf, i64 buf_len);
-void pit_values_push(struct pit_runtime *rt, pit_values *s, pit_value x);
-pit_value pit_values_pop(struct pit_runtime *rt, pit_values *s);
+PIT_DECLARE_VEC(pit_value)
typedef pit_value (*pit_nativefunc)(struct pit_runtime *rt, pit_value args, void *data);
typedef struct { /* "heavy" values, the targets of refs */
@@ -65,21 +61,17 @@ typedef struct {
/* "programs"; vectors of "instructions" for a very simple VM used by the evaluator */
typedef struct {
enum {
- EVAL_PROGRAM_ENTRY_LITERAL,
- EVAL_PROGRAM_ENTRY_APPLY
+ PIT_RUNTIME_EVAL_INS_LITERAL,
+ PIT_RUNTIME_EVAL_INS_APPLY
} sort;
union {
pit_value literal;
i64 apply; /* arity of application */
} in;
-} pit_runtime_eval_program_entry;
-typedef struct {
- i64 capacity, next;
- pit_runtime_eval_program_entry data[];
-} pit_runtime_eval_program;
-pit_runtime_eval_program *pit_runtime_eval_program_new(u8 *buf, i64 buf_len);
-void pit_runtime_eval_program_push_literal(struct pit_runtime *rt, pit_runtime_eval_program *s, pit_value x);
-void pit_runtime_eval_program_push_apply(struct pit_runtime *rt, pit_runtime_eval_program *s, i64 arity);
+} pit_runtime_eval_ins;
+PIT_DECLARE_VEC(pit_runtime_eval_ins)
+void pit_runtime_eval_program_push_literal(struct pit_runtime *rt, pit_vec(pit_runtime_eval_ins) *s, pit_value x);
+void pit_runtime_eval_program_push_apply(struct pit_runtime *rt, pit_vec(pit_runtime_eval_ins) *s, i64 arity);
/* annotation attached to (some) heavy values detaiking things like line numbers */
typedef struct {
@@ -106,10 +98,10 @@ typedef struct pit_runtime {
pit_arena *symtab; i64 symtab_len; /* all symbols - effectively an array of pit_symtab_entry */
/* temporary/"scratch" memory */
pit_arena *scratch; /* temporary arena used during parsing and evaluation */
- pit_values *saved_bindings; /* stack used to save old values of bindings to be restored ("shallow binding") */
- pit_values *expr_stack; /* stack of subexpressions to evaluate during evaluation */
- pit_values *result_stack; /* stack of intermediate values during evaluation */
- pit_runtime_eval_program *program; /* intermediate stack-based program constructed during evaluation */
+ pit_vec(pit_value) *saved_bindings; /* stack used to save old values of bindings to be restored ("shallow binding") */
+ pit_vec(pit_value) *expr_stack; /* stack of subexpressions to evaluate during evaluation */
+ pit_vec(pit_value) *result_stack; /* stack of intermediate values during evaluation */
+ pit_vec(pit_runtime_eval_ins) *program; /* intermediate stack-based program constructed during evaluation */
/* bookkeeping */
/* "frozen" values offsets: values before these offsets are immutable, and we can reset here later */
i64 frozen_values, frozen_symtab;
diff --git a/include/lcq/pit/utils.h b/include/lcq/pit/utils.h
index b864637..ee51518 100644
--- a/include/lcq/pit/utils.h
+++ b/include/lcq/pit/utils.h
@@ -4,50 +4,35 @@
#include <stdarg.h>
#include <lcq/pit/types.h>
+/* macro helpers */
+#define PIT_CONCAT(a, b) a ## b
+#define PIT_STRSTR(x) #x
+#define PIT_STR(x) PIT_STRSTR(x)
+
+/* implementations of needed libc functions */
/* ctype */
-static inline bool pit_ctype_isdigit(int a) { return a >= '0' && a <= '9'; }
-static inline bool pit_ctype_islower(int a) { return a >= 'a' && a <= 'z'; }
-static inline bool pit_ctype_isupper(int a) { return a >= 'A' && a <= 'Z'; }
-static inline bool pit_ctype_isalpha(int a) { return pit_ctype_islower(a) || pit_ctype_isupper(a); }
-static inline bool pit_ctype_isprint(int a) { return a >= 0x20 && a <= 0x7f; }
-static inline bool pit_ctype_isspace(int a) { return a == ' ' || a == '\r' || a == '\n' || a == '\t'; }
+static inline bool pit_libc_ctype_isdigit(int a) { return a >= '0' && a <= '9'; }
+static inline bool pit_libc_ctype_islower(int a) { return a >= 'a' && a <= 'z'; }
+static inline bool pit_libc_ctype_isupper(int a) { return a >= 'A' && a <= 'Z'; }
+static inline bool pit_libc_ctype_isalpha(int a) { return pit_libc_ctype_islower(a) || pit_libc_ctype_isupper(a); }
+static inline bool pit_libc_ctype_isprint(int a) { return a >= 0x20 && a <= 0x7f; }
+static inline bool pit_libc_ctype_isspace(int a) { return a == ' ' || a == '\r' || a == '\n' || a == '\t'; }
/* string */
-static inline size_t pit_string_strlen(char *s) {
+static inline size_t pit_libc_string_strlen(char *s) {
size_t idx = 0;
while (s[idx] != 0) ++idx;
return idx;
}
-static inline u8 *pit_string_memcpy(u8 *dest, u8 *src, size_t n) {
+static inline u8 *pit_libc_string_memcpy(u8 *dest, u8 *src, size_t n) {
size_t i = 0;
for (; i < n; ++i) dest[i] = src[i];
return dest;
}
-int pit_string_vsnprintf(char *str, size_t size, char *format, va_list ap);
-int pit_string_snprintf(char *buf, size_t len, char *format, ...);
+int pit_libc_string_vsnprintf(char *str, size_t size, char *format, va_list ap);
+int pit_libc_string_snprintf(char *buf, size_t len, char *format, ...);
/* assorted utilities and debugging tools */
#define pit_mul(result, a, b) *result = (i64) (a) * (i64) (b)
-/* arenas */
-static inline uintptr_t pit_align_down(uintptr_t addr, uintptr_t align) {
- return addr & ~(align - 1); /* easy! just zero the low bits */
-}
-static inline uintptr_t pit_align_up(uintptr_t addr, uintptr_t align) {
- return (addr + align - 1) /* increment past the next aligned address... */
- & ~(align - 1); /* ...and then zero the low bits */
-}
-typedef struct {
- i64 elem_size, capacity, next, back;
- u8 data[];
-} pit_arena;
-pit_arena *pit_arena_new(u8 *buf, i64 buf_len, i64 elem_size);
-void pit_arena_reset(pit_arena *a);
-i64 pit_arena_alloc_idx(pit_arena *a);
-i64 pit_arena_alloc_bulk_idx(pit_arena *a, i64 num);
-void *pit_arena_get(pit_arena *a, i64 idx);
-void *pit_arena_alloc(pit_arena *a);
-void *pit_arena_alloc_bulk(pit_arena *a, i64 num);
-void *pit_arena_alloc_back(pit_arena *a, i64 sz);
-
#endif
diff --git a/include/lcq/pit/vec.h b/include/lcq/pit/vec.h
new file mode 100644
index 0000000..646f2e0
--- /dev/null
+++ b/include/lcq/pit/vec.h
@@ -0,0 +1,48 @@
+#ifndef LCOLONQ_PIT_VEC_H
+#define LCOLONQ_PIT_VEC_H
+
+#include <lcq/pit/types.h>
+#include <lcq/pit/utils.h>
+
+#define pit_vec(ty) pit_vec__ ## ty ## __type
+#define pit_vec_new(ty) pit_vec__ ## ty ## __new
+#define pit_vec_get(ty) pit_vec__ ## ty ## __get
+#define pit_vec_push(ty) pit_vec__ ## ty ## __push
+#define pit_vec_pop(ty) pit_vec__ ## ty ## __pop
+
+#define PIT_DECLARE_VEC(ty) \
+ typedef struct { \
+ i64 capacity, next; \
+ u8 data[]; \
+ } pit_vec(ty); \
+ static __attribute__ ((unused)) pit_vec(ty) *pit_vec_new(ty)(u8 *buf, i64 buf_len) { \
+ uintptr_t base = (uintptr_t) buf; \
+ uintptr_t aligned = pit_align_up(base, sizeof(void *)); \
+ pit_vec(ty) *ret = (pit_vec(ty) *) aligned; \
+ uintptr_t data = aligned + (i64) sizeof(pit_vec(ty)); \
+ i64 offset = (i64) data - (i64) base; \
+ i64 remaining = (i64) (buf_len - offset); \
+ ret->next = 0; \
+ ret->capacity = remaining; \
+ if ((ret->next + 1) * (i64) sizeof(ty) > ret->capacity) return NULL; \
+ return ret; \
+ } \
+ static __attribute__ ((unused)) ty *pit_vec_get(ty)(pit_vec(ty) *s, i64 i) { \
+ i64 idx = i * (i64) sizeof(ty); \
+ if (idx + (i64) sizeof(ty) > s->capacity) return NULL; \
+ return (ty *) &s->data[idx]; \
+ } \
+ static __attribute__ ((unused)) i64 pit_vec_push(ty)(pit_vec(ty) *s, ty x) { \
+ i64 idx = s->next++ * (i64) sizeof(ty); \
+ if (idx + (i64) sizeof(ty) > s->capacity) { return -1; } \
+ *((ty *) &s->data[idx]) = x; \
+ return s->next - 1; \
+ } \
+ static __attribute__ ((unused)) i64 pit_vec_pop(ty)(pit_vec(ty) *s, ty *v) { \
+ i64 idx = (s->next - 1) * (i64) sizeof(ty); \
+ if (s->next == 0 || idx + (i64) sizeof(ty) > s->capacity) return -1; \
+ *v = *((ty *) &s->data[idx]); \
+ return --s->next; \
+ }
+
+#endif