summaryrefslogtreecommitdiff
path: root/typeutils.h
diff options
context:
space:
mode:
authorÁkos Kőrösi <korakos99@gmail.com>2026-05-12 16:28:30 +0200
committerÁkos Kőrösi <korakos99@gmail.com>2026-05-12 16:28:30 +0200
commit89625d33abbdb99659ad6d8fa3df0de0b7a72f10 (patch)
treed26a70c2f342f1f2dcaf3c9847723cbbfba7be51 /typeutils.h
parent32babee5145bb0248566960a69b674484deb3f94 (diff)
fix bugs in lex/parse, add ugly print util
Diffstat (limited to 'typeutils.h')
-rw-r--r--typeutils.h119
1 files changed, 78 insertions, 41 deletions
diff --git a/typeutils.h b/typeutils.h
index d83217d..e7aee6f 100644
--- a/typeutils.h
+++ b/typeutils.h
@@ -8,57 +8,94 @@
#include <stdio.h>
-#define DECLARE_VEC(T, Name) \
- typedef struct { \
- T* items; \
- size_t count; \
- size_t cap; \
- size_t incr_step; \
- } Name; \
- static inline Name make_##Name(size_t step) { \
- return (Name) { \
- .items = malloc(step* sizeof(T)), \
- .count = 0, \
- .cap = step, \
- .incr_step = step, \
- }; \
- } \
- static inline T* push_to_##Name(Name* vec, T item) { \
- if (vec->count == vec->cap) { \
- vec->cap += vec->incr_step; \
- vec->items = realloc( \
- vec->items, \
- vec->cap * sizeof(T) \
- ); \
- } \
- vec->items[vec->count] = item; \
- T* ptr = &vec->items[vec->count]; \
- vec->count++; \
- return ptr; \
- }
+#define DECLARE_VEC(T, Name) \
+ typedef struct { \
+ T **blocks; \
+ size_t count; \
+ size_t used; \
+ size_t cap; \
+ size_t block_size; \
+ } Name; \
+ \
+ static inline Name make_##Name(size_t block_size) { \
+ return (Name){ \
+ .blocks = NULL, \
+ .count = 0, \
+ .used = 0, \
+ .cap = 0, \
+ .block_size = block_size, \
+ }; \
+ } \
+ \
+ static inline T *push_to_##Name(Name *vec, T item) { \
+ size_t block_index = vec->count / vec->block_size; \
+ size_t item_index = vec->count % vec->block_size; \
+ \
+ if (block_index == vec->used) { \
+ if (vec->used == vec->cap) { \
+ size_t new_cap = vec->cap \
+ ? vec->cap * 2 \
+ : 8; \
+ \
+ T **new_blocks = realloc( \
+ vec->blocks, \
+ new_cap * sizeof(T *) \
+ ); \
+ \
+ if (!new_blocks) abort(); \
+ \
+ vec->blocks = new_blocks; \
+ vec->cap = new_cap; \
+ } \
+ \
+ vec->blocks[vec->used] = \
+ malloc(vec->block_size * sizeof(T)); \
+ \
+ if (!vec->blocks[vec->used]) abort(); \
+ \
+ vec->used++; \
+ } \
+ \
+ T *ptr = &vec->blocks[block_index][item_index]; \
+ *ptr = item; \
+ \
+ vec->count++; \
+ return ptr; \
+ } \
+ \
+ static inline T* get_from_##Name(Name *vec, size_t index) { \
+ if (index >= vec->count) return NULL; \
+ \
+ return &vec->blocks \
+ [index / vec->block_size] \
+ [index % vec->block_size]; \
+ }
DECLARE_VEC(char, String);
-static void append_str_to_String(String* target, char* src_str) {
- size_t required_size =
- ((target->count + strlen(src_str)) / target->incr_step + 1) * target->incr_step;
- if (required_size > target->cap) {
- target->cap = required_size;
- target->items = realloc(target->items, required_size * sizeof(char));
+
+static void append_str_to_String(String* target, const char* src_str) {
+ size_t len = strlen(src_str);
+
+ for (size_t i = 0; i < len; i++) {
+ push_to_String(target, src_str[i]);
}
- memcpy(target->items + target->count, src_str, strlen(src_str));
- target->count += strlen(src_str);
}
-static inline char* inner(String str) {
- if (str.count == str.cap) {
- str.items = realloc(str.items, (str.cap+1)*sizeof(char));
+static inline char* inner(String* str) {
+ char *out = malloc(str->count + 1);
+ if (!out) abort();
+
+ for (size_t i = 0; i < str->count; i++) {
+ out[i] = *get_from_String(str, i);
}
- str.items[str.count] = '\0';
- return str.items;
+
+ out[str->count] = '\0';
+ return out;
}
+
#define DECLARE_MAYBE(T) \
typedef struct { \
bool some; \