From 89625d33abbdb99659ad6d8fa3df0de0b7a72f10 Mon Sep 17 00:00:00 2001 From: Ákos Kőrösi Date: Tue, 12 May 2026 16:28:30 +0200 Subject: fix bugs in lex/parse, add ugly print util --- typeutils.h | 119 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 41 deletions(-) (limited to 'typeutils.h') diff --git a/typeutils.h b/typeutils.h index d83217d..e7aee6f 100644 --- a/typeutils.h +++ b/typeutils.h @@ -8,57 +8,94 @@ #include -#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; \ -- cgit v1.2.3