diff --git a/emit/c99/libundar.c b/emit/c99/libundar.c index 21ed0ac..7e9ed34 100644 --- a/emit/c99/libundar.c +++ b/emit/c99/libundar.c @@ -92,7 +92,7 @@ struct list_s { }; typedef bool (*compare_fn)(void *data, void *target); -typedef void (*list_iter_fn)(void *data); +typedef bool (*list_iter_fn)(void *data); void mcpy(void *to, void *from, u32 length) @@ -218,9 +218,9 @@ float_to_real(f32 f) return FLOAT_TO_REAL(f); } f32 -real_tor32oat(r32 f) +real_to_float(r32 r) { - return REAL_TO_FLOAT(f); + return REAL_TO_FLOAT(r); } r32 real_add(r32 a, r32 b) @@ -250,7 +250,6 @@ real_mul(r32 a, r32 b) return result; } - r32 real_div(r32 a, r32 b) { @@ -267,7 +266,6 @@ real_div(r32 a, r32 b) return result; } - r32 real_eq(r32 a, r32 b) { @@ -331,8 +329,8 @@ amcpy(Arena *arena, void *from, u32 length) return ptr; } -void -int_to_string(i32 v, char *str) +char* +int_to_string(Arena *arena, i32 v) { char buffer[MAX_LEN_INT32]; i32 n; @@ -351,11 +349,11 @@ int_to_string(i32 v, char *str) /* Ensure at least one digit is written for 0 */ if(v == 0) buffer[--i] = '0'; - scpy(str, buffer + i, MAX_LEN_INT32 - i); + return (char*)amcpy(arena, buffer + i, MAX_LEN_INT32 - i); } -void -nat_to_string(u32 v, char *str) +char* +nat_to_string(Arena *arena, u32 v) { char buffer[MAX_LEN_INT32]; u32 n; @@ -369,11 +367,11 @@ nat_to_string(u32 v, char *str) /* Ensure at least one digit is written for 0 */ if(v == 0) buffer[--i] = '0'; - scpy(str, buffer + i, MAX_LEN_INT32 - i); + return (char*)amcpy(arena, buffer + i, MAX_LEN_INT32 - i); } -void -real_to_string(r32 q, char *str) +char* +real_to_string(Arena *arena, r32 q) { char buffer[MAX_LEN_REAL32]; bool neg; @@ -404,13 +402,13 @@ real_to_string(r32 q, char *str) if(neg) buffer[--i] = '-'; - scpy(str, buffer + i, MAX_LEN_REAL32 - i); + return (char*)amcpy(arena, buffer + i, MAX_LEN_REAL32 - i); } List * new_list(Arena *arena) { - List *l = aalloc(arena, sizeof(List)); + List *l = (List*)aalloc(arena, sizeof(List)); if (!l) return nil; l->head = nil; @@ -455,14 +453,14 @@ list_push(Arena *arena, List *list, void *data, u32 data_size) } void -list_foreach(List *list, list_iter_fn func) +list_map(List *list, list_iter_fn func) { Node *curr; if (!list || !func) return; curr = list->head; while (curr) { - func(node_value(curr)); + if (!func(node_value(curr))) break; curr = curr->next; } } @@ -486,9 +484,8 @@ void list_set(List *list, u32 index, void *data, u32 size) { void *target = list_get(list, index); - if (target) { - mcpy(target, data, size); - } + if (!target) return; + mcpy(target, data, size); } void * diff --git a/test/plex.c b/test/plex.c index 5275eb6..53f4ac5 100644 --- a/test/plex.c +++ b/test/plex.c @@ -1,14 +1,522 @@ +#if defined(__has_include) +#if __has_include() +#define HAVE_STDINT 1 +#endif +#if __has_include() +#define HAVE_STDBOOL 1 +#endif +#if __has_include() +#define HAVE_STDDEF 1 +#endif +#endif -#include "undar.h" +#ifdef HAVE_STDINT +#include +typedef uint8_t u8; +typedef int8_t i8; +typedef uint16_t u16; +typedef int16_t i16; +typedef uint32_t u32; +typedef int32_t i32; +typedef int32_t r32; +typedef float f32; +#else +typedef unsigned char u8; +typedef signed char i8; +typedef unsigned short u16; +typedef signed short i16; +typedef unsigned int u32; +typedef signed int i32; +typedef signed int r32; +typedef float f32; +#endif + +#ifdef HAVE_STDBOOL +#include +#else +#define true 1 +#define false 0 +typedef u8 bool; +#endif + +#ifdef HAVE_STDDEF +#include +#define nil NULL +#else +#define nil ((void *)0) +#endif + +#define I8_MIN -128 +#define I8_MAX 127 +#define U8_MAX 255 + +#define I16_MIN -32768 +#define I16_MAX 32767 +#define U16_MAX 65535 + +#define I32_MIN -2147483648 +#define I32_MAX 2147483647 +#define U32_MAX 4294967295 + +#define FIXED_CONST 65536.0f + +#define AS_INT(v) ((i32)(v)) +#define AS_NAT(v) ((u32)(v)) +#define AS_REAL(v) ((r32)(v)) +#define FLOAT_TO_REAL(v) (((r32)(v)) * FIXED_CONST) +#define REAL_TO_FLOAT(v) (((f32)(v)) / FIXED_CONST) + +#define USED(x) ((void)(x)) + +#define MAX_LEN_REAL32 12 +#define MAX_LEN_INT32 11 +const char radix_set[11] = "0123456789"; + +typedef struct arena_s Arena; +struct arena_s { + u8 *tape; + u32 count; + 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); + +static inline void +mcpy(void *to, void *from, u32 length) +{ + u8 *src, *dest; + if(to == nil || from == nil) return; + + src = (u8 *)from; + dest = (u8 *)to; + + while(length-- > 0) *(dest++) = *(src++); + return; +} + +static inline i32 +scpy(char *to, const char *from, u32 length) +{ + u32 i; + if(to == nil || from == nil) return -1; + if(length == 0) return 0; + for(i = 0; i < length && from[i] != '\0'; i++) to[i] = from[i]; + to[i] = '\0'; + return 0; +} + +static inline bool +seq(const char *s1, const char *s2) +{ + if(s1 == nil && s2 == nil) return true; + if(s1 == nil || s2 == nil) return false; + + while(*s1 && *s2) { + if(*s1 != *s2) return false; + s1++; + s2++; + } + + return (*s1 == '\0' && *s2 == '\0'); +} + +static inline bool +sleq(const char *s1, const char *s2, u32 length) +{ + u32 i; + if(s1 == nil && s2 == nil) return true; + if(s1 == nil || s2 == nil) return false; + + i = 0; + while(i < length && *s1 && *s2) { + if(*s1 != *s2) return false; + s1++; + s2++; + i++; + } + if(i == length) return true; + return (*s1 == '\0' && *s2 == '\0'); +} + +static inline u32 +slen(const char *str) +{ + u32 i; + if(str == nil) return 0; + for(i = 0; str[i] != '\0'; i++); + return i; +} + +static inline u32 +snlen(const char *str, u32 max_len) +{ + u32 i; + if(str == nil) return 0; + for(i = 0; i < max_len && str[i] != '\0'; i++); + return i; +} + +static inline void * +aalloc(Arena *arena, u32 size) +{ + u32 pos; + if(arena == nil) return nil; + if(arena->count + size > arena->capacity) return nil; + + pos = arena->count; + arena->count += size; + return (void *)&arena->tape[pos]; +} + +static inline void * +areturn(Arena *arena, u32 checkpoint, const void *src, u32 size) +{ + void *dest; + if(arena == nil || src == nil) return nil; + + dest = (void *)&arena->tape[checkpoint]; + if(src == dest) return dest; + + mcpy(dest, (void *)src, size); + arena->count = checkpoint + size; + + return dest; +} + +#define ARENA_RETURN(arena, ckpt, src_ptr, type) \ + return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type)) + +#define ARENA_RETURN_ARRAY(arena, ckpt, src_ptr, type, count) \ + return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type) * (count)) + +static inline r32 +int_to_real(i32 i) +{ + return i << 16; +} +static inline i32 +real_to_int(r32 f) +{ + return f >> 16; +} +static inline r32 +float_to_real(f32 f) +{ + return FLOAT_TO_REAL(f); +} +static inline f32 +real_to_float(r32 r) +{ + return REAL_TO_FLOAT(r); +} +static inline r32 +real_add(r32 a, r32 b) +{ + return a + b; +} +static inline r32 +real_sub(r32 a, r32 b) +{ + return a - b; +} +static inline r32 +real_mul(r32 a, r32 b) +{ + + r32 src1_whole = (r32)a >> 16; + r32 src2_whole = (r32)b >> 16; + + r32 src1_decimal = (r32)a & 16; + r32 src2_decimal = (r32)b & 16; + + r32 result = 0; + result += (src1_whole * src2_whole) << 16; + result += (src1_whole * src2_decimal); + result += (src1_decimal * src2_whole); + result += ((src1_decimal * src2_decimal) >> 16) & 16; + + return result; +} +static inline r32 +real_div(r32 a, r32 b) +{ + r32 result; + + r32 src1_val = (r32)a; + r32 src2_val = (r32)b; + u32 src2_reciprocal = 1; + + src2_reciprocal <<= 31; + src2_reciprocal = (u32)(src2_reciprocal / src2_val); + result = src1_val * src2_reciprocal; + result <<= 1; + + return result; +} +static inline r32 +real_eq(r32 a, r32 b) +{ + return a == b; +} +static inline r32 +real_ne(r32 a, r32 b) +{ + return a != b; +} +static inline r32 +real_lt(r32 a, r32 b) +{ + return a < b; +} +static inline r32 +real_le(r32 a, r32 b) +{ + return a <= b; +} +static inline r32 +real_gt(r32 a, r32 b) +{ + return a > b; +} +static inline r32 +real_ge(r32 a, r32 b) +{ + return a >= b; +} +static inline r32 +real_neg(r32 f) +{ + return -f; +} +static inline r32 +real_abs(r32 f) +{ + return (f < 0) ? -f : f; +} + +static inline char * +ascpy(Arena *arena, const char *start, u32 length) +{ + char *str; + if(!start) return nil; + str = (char *)aalloc(arena, length + 1); + if(!str) return nil; + scpy(str, start, length); + return str; +} + +static inline void * +amcpy(Arena *arena, void *from, u32 length) +{ + void *ptr; + if(!from) return nil; + ptr = aalloc(arena, length); + if(!ptr) return nil; + mcpy(ptr, from, length); + return ptr; +} + +static inline char* +int_to_string(Arena *arena, i32 v) +{ + char buffer[MAX_LEN_INT32]; + i32 n; + u32 i = MAX_LEN_INT32; + bool neg; + n = v; + neg = n < 0; + + if(neg) n = -n; + + do { + buffer[--i] = radix_set[n % 10]; + n /= 10; + } while(n > 0); + if(neg) buffer[--i] = '-'; + /* 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); +} + +static inline char* +nat_to_string(Arena *arena, u32 v) +{ + char buffer[MAX_LEN_INT32]; + u32 n; + u32 i = MAX_LEN_INT32; + n = v; + + do { + buffer[--i] = radix_set[n % 10]; + n /= 10; + } while(n > 0); + /* 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); +} + +static inline char* +real_to_string(Arena *arena, r32 q) +{ + char buffer[MAX_LEN_REAL32]; + bool neg; + i32 int_part; + u32 frac_part; + u32 i = MAX_LEN_REAL32; + + if(q < 0) q = -q; + + int_part = q >> 16; + frac_part = q & 0xFFFF; + + do { + buffer[--i] = radix_set[frac_part % 10]; + frac_part /= 10; + } while(frac_part > 0); + + buffer[--i] = '.'; + + neg = int_part < 0; + + if(neg) int_part = -int_part; + + do { + buffer[--i] = radix_set[int_part % 10]; + int_part /= 10; + } while(int_part > 0); + + if(neg) buffer[--i] = '-'; + + return (char*)amcpy(arena, buffer + i, MAX_LEN_REAL32 - i); +} + +static inline List * +new_list(Arena *arena) +{ + List *l = (List*)aalloc(arena, sizeof(List)); + if (!l) return nil; + + l->head = nil; + l->tail = nil; + l->count = 0; + + return l; +} + +static inline 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 *dest; + void *ptr = aalloc(arena, sizeof(Node) + data_size); + Node *node = (Node *)ptr; + + if (!node) return nil; + + node->next = nil; + + if (!list->head) { + list->head = list->tail = node; + } else { + list->tail->next = node; + list->tail = node; + } + + list->count++; + + dest = node_value(node); + if (data && data_size > 0) { + mcpy(dest, data, data_size); + } + + return dest; +} + +static inline void +list_map(List *list, list_iter_fn func) +{ + Node *curr; + if (!list || !func) return; + + curr = list->head; + while (curr) { + if (!func(node_value(curr))) break; + curr = curr->next; + } +} + +static inline void * +list_get(List *list, u32 index) +{ + u32 i; + Node *curr; + if (!list || index >= list->count) return nil; + + curr = list->head; + for (i = 0; i < index; i++) { + curr = curr->next; + } + + return node_value(curr); +} + +static inline void +list_set(List *list, u32 index, void *data, u32 size) +{ + 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) +{ + Node *curr; + void *data; + + if (!list || !compare) return nil; + + curr = list->head; + while (curr) { + data = node_value(curr); + if (compare(data, target)) { + return data; + } + curr = curr->next; + } + return nil; +} + +#include typedef struct Point Point; struct Point { - unsigned int x; - unsigned int y; + u32 x; + u32 y; }; Point * -Point_new(Arena *a, unsigned int x, unsigned int y) +Point_init(Arena *a, u32 x, u32 y) { Point *this = (Point *)aalloc(a, sizeof(Point)); this->x = x; @@ -19,30 +527,28 @@ Point_new(Arena *a, unsigned int x, unsigned int y) char* Point_toS(Arena *a, Point *this) { - unsigned int ckpt = a->count; - char *s = (char*)&a->tape[a->count]; - int len = sprintf(s, "[x:%d, y:%d]", - this->x, - this->y); - s[len] = '\0'; - a->count += len + 1; - ARENA_RETURN_ARRAY(a, ckpt, s, char, len + 1); + 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; } typedef struct Rect Rect; struct Rect { Point top_left; Point bottom_right; - unsigned int width; - unsigned int height; + u32 width; + u32 height; }; Rect * -Rect_new(Arena *a, Point *tl, Point *br, unsigned int width, unsigned int height) +Rect_init(Arena *a, Point *tl, Point *br, u32 width, u32 height) { Rect *this = (Rect *)aalloc(a, sizeof(Rect)); - memcpy(&this->top_left, tl, sizeof(Point)); - memcpy(&this->bottom_right, br, sizeof(Point)); + mcpy(&this->top_left, tl, sizeof(Point)); + mcpy(&this->bottom_right, br, sizeof(Point)); this->width = width; this->height = height; return this; @@ -51,35 +557,28 @@ Rect_new(Arena *a, Point *tl, Point *br, unsigned int width, unsigned int height char* Rect_toS(Arena *a, Rect *this) { - unsigned int ckpt = a->count; - char *s1 = Point_toS(a, &this->top_left); - char *s2 = Point_toS(a, &this->bottom_right); - - char *s = (char*)&a->tape[a->count]; - int len = sprintf(s, "[top_left: %s, bottom_right: %s, width:%d, height:%d]", - s1, - s2, - this->width, - this->height); - s[len] = '\0'; - a->count += len + 1; - ARENA_RETURN_ARRAY(a, ckpt, s, char, len + 1); + 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; } Rect * create_geometry(Arena *a) { - unsigned int ckpt = a->count; - Rect *final_rect; - Point *temp_tl; - Point *temp_br; + u32 __UNDAR_FN_CHECKPOINT_REF__ = a->count; - temp_tl = Point_new(a, 10, 20); - temp_br = Point_new(a, 100, 200); + Point *tl = Point_init(a, 10, 20); + Point *br = Point_init(a, 100, 200); + Rect *final_rect = Rect_init(a, tl, br, 90, 180); - final_rect = Rect_new(a, temp_tl, temp_br, 90, 180); - - ARENA_RETURN(a, ckpt, final_rect, Rect); + ARENA_RETURN(a, __UNDAR_FN_CHECKPOINT_REF__, final_rect, Rect); } int main() { diff --git a/test/undar.h b/test/undar.h deleted file mode 100644 index 465deac..0000000 --- a/test/undar.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef UNDAR_H -#define UNDAR_H - -#include -#include - -typedef struct arena_s Arena; -struct arena_s { - unsigned char *tape; - unsigned int count; - unsigned int capacity; -}; - -static void *aalloc(Arena *arena, unsigned int size){ - unsigned int pos; - if(arena == NULL) return NULL; - if(arena->count + size > arena->capacity) return NULL; - - pos = arena->count; - arena->count += size; - return (void *)&arena->tape[pos]; -} - -static void * -areturn(Arena *arena, unsigned int checkpoint, const void *src, unsigned int size) -{ - void *dest; - if(arena == NULL || src == NULL) return NULL; - - dest = (void *)&arena->tape[checkpoint]; - if (src == dest) return dest; - - memmove(dest, src, size); - arena->count = checkpoint + size; - - return dest; -} - -#define ARENA_RETURN(arena, ckpt, src_ptr, type) \ - return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type)) - -#define ARENA_RETURN_ARRAY(arena, ckpt, src_ptr, type, count) \ - return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type) * (count)) - -#endif \ No newline at end of file