diff --git a/emit/c99/libundar.c b/emit/c99/libundar.c index 7e9ed34..92dbf08 100644 --- a/emit/c99/libundar.c +++ b/emit/c99/libundar.c @@ -70,6 +70,7 @@ typedef u8 bool; #define MAX_LEN_REAL32 12 #define MAX_LEN_INT32 11 +#define MAX_LEN_UINT32 10 const char radix_set[11] = "0123456789"; typedef struct arena_s Arena; @@ -79,22 +80,10 @@ struct arena_s { u32 capacity; }; -typedef struct node_s Node; -struct node_s { - struct node_s *next; -}; - -typedef struct list_s List; -struct list_s { - Node *head; - Node *tail; - u32 count; -}; - typedef bool (*compare_fn)(void *data, void *target); typedef bool (*list_iter_fn)(void *data); -void +static inline void mcpy(void *to, void *from, u32 length) { u8 *src, *dest; @@ -107,7 +96,7 @@ mcpy(void *to, void *from, u32 length) return; } -i32 +static inline i32 scpy(char *to, const char *from, u32 length) { u32 i; @@ -118,7 +107,7 @@ scpy(char *to, const char *from, u32 length) return 0; } -bool +static inline bool seq(const char *s1, const char *s2) { if(s1 == nil && s2 == nil) return true; @@ -133,7 +122,7 @@ seq(const char *s1, const char *s2) return (*s1 == '\0' && *s2 == '\0'); } -bool +static inline bool sleq(const char *s1, const char *s2, u32 length) { u32 i; @@ -151,7 +140,7 @@ sleq(const char *s1, const char *s2, u32 length) return (*s1 == '\0' && *s2 == '\0'); } -u32 +static inline u32 slen(const char *str) { u32 i; @@ -160,7 +149,7 @@ slen(const char *str) return i; } -u32 +static inline u32 snlen(const char *str, u32 max_len) { u32 i; @@ -169,7 +158,7 @@ snlen(const char *str, u32 max_len) return i; } -void * +static inline void * aalloc(Arena *arena, u32 size) { u32 pos; @@ -181,18 +170,28 @@ aalloc(Arena *arena, u32 size) return (void *)&arena->tape[pos]; } -void * +static inline void * areturn(Arena *arena, u32 checkpoint, const void *src, u32 size) { void *dest; if(arena == nil || src == nil) return nil; + u32 current = arena->count; + dest = (void *)&arena->tape[checkpoint]; if(src == dest) return dest; mcpy(dest, (void *)src, size); arena->count = checkpoint + size; + // This is better but slower + //for (u32 i = checkpoint + size; i < current; i++) { + // arena->tape[i] = 0; + //} + + // zero out the end of the memory copy (for strings mostly) + arena->tape[arena->count] = 0; + return dest; } @@ -202,37 +201,37 @@ areturn(Arena *arena, u32 checkpoint, const void *src, u32 size) #define ARENA_RETURN_ARRAY(arena, ckpt, src_ptr, type, count) \ return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type) * (count)) -r32 +static inline r32 int_to_real(i32 i) { return i << 16; } -i32 +static inline i32 real_to_int(r32 f) { return f >> 16; } -r32 +static inline r32 float_to_real(f32 f) { return FLOAT_TO_REAL(f); } -f32 +static inline f32 real_to_float(r32 r) { return REAL_TO_FLOAT(r); } -r32 +static inline r32 real_add(r32 a, r32 b) { return a + b; } -r32 +static inline r32 real_sub(r32 a, r32 b) { return a - b; } -r32 +static inline r32 real_mul(r32 a, r32 b) { @@ -250,7 +249,7 @@ real_mul(r32 a, r32 b) return result; } -r32 +static inline r32 real_div(r32 a, r32 b) { r32 result; @@ -266,48 +265,48 @@ real_div(r32 a, r32 b) return result; } -r32 +static inline r32 real_eq(r32 a, r32 b) { return a == b; } -r32 +static inline r32 real_ne(r32 a, r32 b) { return a != b; } -r32 +static inline r32 real_lt(r32 a, r32 b) { return a < b; } -r32 +static inline r32 real_le(r32 a, r32 b) { return a <= b; } -r32 +static inline r32 real_gt(r32 a, r32 b) { return a > b; } -r32 +static inline r32 real_ge(r32 a, r32 b) { return a >= b; } -r32 +static inline r32 real_neg(r32 f) { return -f; } -r32 +static inline r32 real_abs(r32 f) { return (f < 0) ? -f : f; } -char * +static inline char * ascpy(Arena *arena, const char *start, u32 length) { char *str; @@ -318,7 +317,7 @@ ascpy(Arena *arena, const char *start, u32 length) return str; } -void * +static inline void * amcpy(Arena *arena, void *from, u32 length) { void *ptr; @@ -329,10 +328,10 @@ amcpy(Arena *arena, void *from, u32 length) return ptr; } -char* +static inline char* int_to_string(Arena *arena, i32 v) { - char buffer[MAX_LEN_INT32]; + char buffer[MAX_LEN_INT32] = {0}; i32 n; u32 i = MAX_LEN_INT32; bool neg; @@ -349,13 +348,13 @@ int_to_string(Arena *arena, i32 v) /* Ensure at least one digit is written for 0 */ if(v == 0) buffer[--i] = '0'; - return (char*)amcpy(arena, buffer + i, MAX_LEN_INT32 - i); + return ascpy(arena, buffer + i, MAX_LEN_INT32 - i); } -char* +static inline char* nat_to_string(Arena *arena, u32 v) { - char buffer[MAX_LEN_INT32]; + char buffer[MAX_LEN_INT32] = {0}; u32 n; u32 i = MAX_LEN_INT32; n = v; @@ -367,13 +366,13 @@ nat_to_string(Arena *arena, u32 v) /* Ensure at least one digit is written for 0 */ if(v == 0) buffer[--i] = '0'; - return (char*)amcpy(arena, buffer + i, MAX_LEN_INT32 - i); + return ascpy(arena, buffer + i, MAX_LEN_INT32 - i); } -char* +static inline char* real_to_string(Arena *arena, r32 q) { - char buffer[MAX_LEN_REAL32]; + char buffer[MAX_LEN_REAL32] = {0}; bool neg; i32 int_part; u32 frac_part; @@ -402,11 +401,27 @@ real_to_string(Arena *arena, r32 q) if(neg) buffer[--i] = '-'; - return (char*)amcpy(arena, buffer + i, MAX_LEN_REAL32 - i); + return ascpy(arena, buffer + i, MAX_LEN_REAL32 - i); } +typedef struct node_s Node; +struct node_s { + u32 size; + struct node_s *next; +}; + +typedef struct list_s List; +struct list_s { + Node *head; + Node *tail; + u32 count; +}; + +typedef bool (*compare_fn)(void *data, void *target); +typedef bool (*list_iter_fn)(void *data); + List * -new_list(Arena *arena) +List_init(Arena *arena) { List *l = (List*)aalloc(arena, sizeof(List)); if (!l) return nil; @@ -425,7 +440,7 @@ node_value(Node *n) } void * -list_push(Arena *arena, List *list, void *data, u32 data_size) +List_push(Arena *arena, List *list, void *data, u32 data_size) { void *dest; void *ptr = aalloc(arena, sizeof(Node) + data_size); @@ -433,6 +448,7 @@ list_push(Arena *arena, List *list, void *data, u32 data_size) if (!node) return nil; + node->size = data_size; node->next = nil; if (!list->head) { @@ -453,7 +469,7 @@ list_push(Arena *arena, List *list, void *data, u32 data_size) } void -list_map(List *list, list_iter_fn func) +List_map(List *list, list_iter_fn func) { Node *curr; if (!list || !func) return; @@ -466,7 +482,7 @@ list_map(List *list, list_iter_fn func) } void * -list_get(List *list, u32 index) +List_get(List *list, u32 index) { u32 i; Node *curr; @@ -481,15 +497,15 @@ list_get(List *list, u32 index) } void -list_set(List *list, u32 index, void *data, u32 size) +List_set(List *list, u32 index, void *data, u32 size) { - void *target = list_get(list, index); + void *target = List_get(list, index); if (!target) return; mcpy(target, data, size); } void * -list_find(List *list, compare_fn compare, void *target) +List_find(List *list, compare_fn compare, void *target) { Node *curr; void *data; @@ -506,3 +522,75 @@ list_find(List *list, compare_fn compare, void *target) } return nil; } + +typedef struct strbuf_s StrBuf; +struct strbuf_s { + Node *head; + Node *tail; + u32 count; +}; + +StrBuf * +StrBuf_init(Arena *arena) +{ + StrBuf *l = (StrBuf*)aalloc(arena, sizeof(StrBuf)); + if (!l) return nil; + + l->head = nil; + l->tail = nil; + l->count = 0; + + return l; +} + +void * +StrBuf_append(Arena *arena, StrBuf *buf, char *str) +{ + u32 length = slen(str); + + void *dest; + void *ptr = aalloc(arena, sizeof(Node) + length); + Node *node = (Node *)ptr; + + if (!node) return nil; + + node->next = nil; + node->size = length; + + if (!buf->head) { + buf->head = buf->tail = node; + } else { + buf->tail->next = node; + buf->tail = node; + } + + buf->count++; + + dest = node_value(node); + if (str && length > 0) { + mcpy(dest, str, length); + } + + return dest; +} + +char * +StrBuf_toS(Arena *arena, StrBuf *buf) +{ + Node *curr; + char *tmp_str; + + i32 pos = arena->count; + char *str = (char *)&arena->tape[pos]; + + if (!buf || !str) return nil; + + curr = buf->head; + while (curr) { + tmp_str = node_value(curr); + amcpy(arena, tmp_str, curr->size); + curr = curr->next; + } + + return str; +} \ No newline at end of file diff --git a/test/plex.c b/test/plex.c index 53f4ac5..188ac22 100644 --- a/test/plex.c +++ b/test/plex.c @@ -70,6 +70,7 @@ typedef u8 bool; #define MAX_LEN_REAL32 12 #define MAX_LEN_INT32 11 +#define MAX_LEN_UINT32 10 const char radix_set[11] = "0123456789"; typedef struct arena_s Arena; @@ -79,18 +80,6 @@ struct arena_s { u32 capacity; }; -typedef struct node_s Node; -struct node_s { - struct node_s *next; -}; - -typedef struct list_s List; -struct list_s { - Node *head; - Node *tail; - u32 count; -}; - typedef bool (*compare_fn)(void *data, void *target); typedef bool (*list_iter_fn)(void *data); @@ -187,12 +176,22 @@ areturn(Arena *arena, u32 checkpoint, const void *src, u32 size) void *dest; if(arena == nil || src == nil) return nil; + u32 current = arena->count; + dest = (void *)&arena->tape[checkpoint]; if(src == dest) return dest; mcpy(dest, (void *)src, size); arena->count = checkpoint + size; + // This is better but slower + //for (u32 i = checkpoint + size; i < current; i++) { + // arena->tape[i] = 0; + //} + + // zero out the end of the memory copy (for strings mostly) + arena->tape[arena->count] = 0; + return dest; } @@ -332,7 +331,7 @@ amcpy(Arena *arena, void *from, u32 length) static inline char* int_to_string(Arena *arena, i32 v) { - char buffer[MAX_LEN_INT32]; + char buffer[MAX_LEN_INT32] = {0}; i32 n; u32 i = MAX_LEN_INT32; bool neg; @@ -349,13 +348,13 @@ int_to_string(Arena *arena, i32 v) /* Ensure at least one digit is written for 0 */ if(v == 0) buffer[--i] = '0'; - return (char*)amcpy(arena, buffer + i, MAX_LEN_INT32 - i); + return ascpy(arena, buffer + i, MAX_LEN_INT32 - i); } static inline char* nat_to_string(Arena *arena, u32 v) { - char buffer[MAX_LEN_INT32]; + char buffer[MAX_LEN_INT32] = {0}; u32 n; u32 i = MAX_LEN_INT32; n = v; @@ -367,13 +366,13 @@ nat_to_string(Arena *arena, u32 v) /* Ensure at least one digit is written for 0 */ if(v == 0) buffer[--i] = '0'; - return (char*)amcpy(arena, buffer + i, MAX_LEN_INT32 - i); + return ascpy(arena, buffer + i, MAX_LEN_INT32 - i); } static inline char* real_to_string(Arena *arena, r32 q) { - char buffer[MAX_LEN_REAL32]; + char buffer[MAX_LEN_REAL32] = {0}; bool neg; i32 int_part; u32 frac_part; @@ -402,11 +401,27 @@ real_to_string(Arena *arena, r32 q) if(neg) buffer[--i] = '-'; - return (char*)amcpy(arena, buffer + i, MAX_LEN_REAL32 - i); + return ascpy(arena, buffer + i, MAX_LEN_REAL32 - i); } -static inline List * -new_list(Arena *arena) +typedef struct node_s Node; +struct node_s { + u32 size; + struct node_s *next; +}; + +typedef struct list_s List; +struct list_s { + Node *head; + Node *tail; + u32 count; +}; + +typedef bool (*compare_fn)(void *data, void *target); +typedef bool (*list_iter_fn)(void *data); + +List * +List_init(Arena *arena) { List *l = (List*)aalloc(arena, sizeof(List)); if (!l) return nil; @@ -418,14 +433,14 @@ new_list(Arena *arena) return l; } -static inline void * +void * node_value(Node *n) { return (void *)((u8 *)n + sizeof(Node)); } -static inline void * -list_push(Arena *arena, List *list, void *data, u32 data_size) +void * +List_push(Arena *arena, List *list, void *data, u32 data_size) { void *dest; void *ptr = aalloc(arena, sizeof(Node) + data_size); @@ -433,6 +448,7 @@ list_push(Arena *arena, List *list, void *data, u32 data_size) if (!node) return nil; + node->size = data_size; node->next = nil; if (!list->head) { @@ -452,8 +468,8 @@ list_push(Arena *arena, List *list, void *data, u32 data_size) return dest; } -static inline void -list_map(List *list, list_iter_fn func) +void +List_map(List *list, list_iter_fn func) { Node *curr; if (!list || !func) return; @@ -465,8 +481,8 @@ list_map(List *list, list_iter_fn func) } } -static inline void * -list_get(List *list, u32 index) +void * +List_get(List *list, u32 index) { u32 i; Node *curr; @@ -480,16 +496,16 @@ list_get(List *list, u32 index) return node_value(curr); } -static inline void -list_set(List *list, u32 index, void *data, u32 size) +void +List_set(List *list, u32 index, void *data, u32 size) { - void *target = list_get(list, index); + void *target = List_get(list, index); if (!target) return; mcpy(target, data, size); } -static inline void * -list_find(List *list, compare_fn compare, void *target) +void * +List_find(List *list, compare_fn compare, void *target) { Node *curr; void *data; @@ -507,6 +523,78 @@ list_find(List *list, compare_fn compare, void *target) return nil; } +typedef struct strbuf_s StrBuf; +struct strbuf_s { + Node *head; + Node *tail; + u32 count; +}; + +StrBuf * +StrBuf_init(Arena *arena) +{ + StrBuf *l = (StrBuf*)aalloc(arena, sizeof(StrBuf)); + if (!l) return nil; + + l->head = nil; + l->tail = nil; + l->count = 0; + + return l; +} + +void * +StrBuf_append(Arena *arena, StrBuf *buf, char *str) +{ + u32 length = slen(str); + + void *dest; + void *ptr = aalloc(arena, sizeof(Node) + length); + Node *node = (Node *)ptr; + + if (!node) return nil; + + node->next = nil; + node->size = length; + + if (!buf->head) { + buf->head = buf->tail = node; + } else { + buf->tail->next = node; + buf->tail = node; + } + + buf->count++; + + dest = node_value(node); + if (str && length > 0) { + mcpy(dest, str, length); + } + + return dest; +} + +char * +StrBuf_toS(Arena *arena, StrBuf *buf) +{ + Node *curr; + char *tmp_str; + + i32 pos = arena->count; + char *str = (char *)&arena->tape[pos]; + + if (!buf || !str) return nil; + + curr = buf->head; + while (curr) { + tmp_str = node_value(curr); + amcpy(arena, tmp_str, curr->size); + curr = curr->next; + } + + return str; +} + #include typedef struct Point Point; @@ -526,13 +614,18 @@ Point_init(Arena *a, u32 x, u32 y) char* Point_toS(Arena *a, Point *this) -{ - char *s = (char*)amcpy(a, "[x:", 3); - nat_to_string(a, this->x); - amcpy(a, ", y:", 4); - nat_to_string(a, this->y); - amcpy(a, "]", 1); - return s; +{ + u32 __UNDAR_FN_CHECKPOINT_REF__ = a->count; + + StrBuf *buf = StrBuf_init(a); + StrBuf_append(a, buf, "[x:"); + StrBuf_append(a, buf,nat_to_string(a, this->x)); + StrBuf_append(a, buf, ", y:"); + StrBuf_append(a, buf,nat_to_string(a, this->y)); + StrBuf_append(a, buf, "]"); + + char *to_return = StrBuf_toS(a, buf); + ARENA_RETURN_ARRAY(a, __UNDAR_FN_CHECKPOINT_REF__, to_return, char, slen(to_return)); } typedef struct Rect Rect; @@ -557,16 +650,21 @@ Rect_init(Arena *a, Point *tl, Point *br, u32 width, u32 height) char* Rect_toS(Arena *a, Rect *this) { - char *s = (char*)amcpy(a, "[top_left: ", 11); - Point_toS(a, &this->top_left); - amcpy(a,", bottom_right: ", 16); - Point_toS(a, &this->bottom_right); - amcpy(a, ", width:", 8); - nat_to_string(a, this->width); - amcpy(a, ", height:", 9); - nat_to_string(a, this->height); - amcpy(a, "]", 1); - return s; + u32 __UNDAR_FN_CHECKPOINT_REF__ = a->count; + + StrBuf *buf = StrBuf_init(a); + StrBuf_append(a, buf, "[top_left: "); + StrBuf_append(a, buf,Point_toS(a, &this->top_left)); + StrBuf_append(a, buf,", bottom_right: "); + StrBuf_append(a, buf,Point_toS(a, &this->bottom_right)); + StrBuf_append(a, buf, ", width:"); + StrBuf_append(a, buf,nat_to_string(a, this->width)); + StrBuf_append(a, buf, ", height:"); + StrBuf_append(a, buf,nat_to_string(a, this->height)); + StrBuf_append(a, buf, "]"); + + char *to_return = StrBuf_toS(a, buf); + ARENA_RETURN_ARRAY(a, __UNDAR_FN_CHECKPOINT_REF__, to_return, char, slen(to_return)); } Rect *