Finished bh_arr
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 12 May 2020 20:03:58 +0000 (15:03 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 12 May 2020 20:03:58 +0000 (15:03 -0500)
bh.h
onyx
onyx.c
onyxlex.c
onyxlex.h

diff --git a/bh.h b/bh.h
index 16a51c87f73b9dba048b42b5d7f5a8ce7d130227..c322aa80c9e501a7d725de771694f4b7590a6373 100644 (file)
--- a/bh.h
+++ b/bh.h
@@ -37,6 +37,13 @@ b32 char_in_range(const char lo, const char hi, const char a);
 char charset_contains(const char* charset, char ch);
 i64 chars_match(char* ptr1, char* ptr2);
 
+//-------------------------------------------------------------------------------------
+// Better math functions
+//-------------------------------------------------------------------------------------
+#define bh_max(a, b)           ((a) > (b) ? (a) : (b))
+#define bh_min(a, b)           ((a) < (b) ? (a) : (b))
+#define bh_clamp(v, a, b)      (bh_min((b), bh_max((a), (v))))
+
 //-------------------------------------------------------------------------------------
 // Better strings
 //-------------------------------------------------------------------------------------
@@ -155,35 +162,60 @@ bh_file_contents bh_file_read_contents_direct(const char* filename);
 i32 bh_file_contents_delete(bh_file_contents* contents);
 
 //-------------------------------------------------------------------------------------
-// Better arrays
+// Better dynamically-sized arrays
 //-------------------------------------------------------------------------------------
 typedef struct bh__arr {
        i32 length, capacity;
 } bh__arr;
 
+#ifndef BH_ARR_GROW_FORMULA
+#define BH_ARR_GROW_FORMULA(x)         ((x) > 0 ? ((x) << 1) : 4)
+#endif
+
 #define bh_arr(T)                                      T*
 #define bh__arrhead(arr)                       (((bh__arr *)(arr)) - 1)
 
 #define bh_arr_length(arr)                     (arr ? bh__arrhead(arr)->length : 0)
 #define bh_arr_capacity(arr)           (arr ? bh__arrhead(arr)->capacity : 0)
-#define bh_arr_valid(arr, i)           (arr ? (int)(i) < bh__arrhead(arr)->length : 0)
-
-#define bh_arr_set_length(arr, n)      (bh__arr_ensure_capacity((void **) &arr, sizeof(arr[0]), n), bh__arrhead(arr)->length = n)
+#define bh_arr_size(arr)                       (arr ? bh__arrhead(arr)->capacity * sizeof(*(arr)) : 0)
+#define bh_arr_valid(arr, i)           (arr ? (i32)(i) < bh__arrhead(arr)->length : 0)
 
 #define bh_arr_pop(arr)                                ((arr)[--bh__arrhead(arr)->length])
 #define bh_arr_last(arr)                       ((arr)[bh__arrhead(arr)->length - 1])
 #define bh_arr_end(arr, i)                     ((i) >= &(arr)[bh_arr_length(arr)])
 
-#define bh_arr_new(arr, cap)           (bh__arr_ensure_capacity((void**) &arr, sizeof(arr[0]), cap))
-#define bh_arr_free(arr)                       (bh__arr_free((void**) &arr))
-#define bh_arr_copy(arr)                       (bh__arr_copy(arr, sizeof(arr[0])))
+#define bh_arr_new(arr, cap)           (bh__arr_grow((void**) &arr, sizeof(*(arr)), cap))
+#define bh_arr_free(arr)                       (bh__arr_free((void**) &(arr)))
+#define bh_arr_copy(arr)                       (bh__arr_copy((arr), sizeof(*(arr))))
+
+#define bh_arr_grow(arr, cap)          (bh__arr_grow((void **) &(arr), sizeof(*(arr)), cap))
+#define bh_arr_shrink(arr, cap)                (bh__arr_shrink((void **) &(arr), sizeof(*(arr)), cap))
+#define bh_arr_set_length(arr, n)      ( \
+       bh__arr_grow((void **) &(arr), sizeof(*(arr)), n), \
+       bh__arrhead(arr)->length = n)
+
+#define bh_arr_insertn(arr, i, n)      (bh__arr_insertn((void **) &(arr), sizeof(*(arr)), i, n))
+
 #define bh_arr_insert_end(arr, n)      ( \
-       bh__arr_ensure_capacity((void**) &arr, sizeof(arr[0]), bh_arr_length(arr) + n), \
+       bh__arr_grow((void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \
        bh__arrhead(arr)->length += n)
 
-b32 bh__arr_ensure_capacity(void** arr, int elemsize, int cap);
+#define bh_arr_push(arr, value)        ( \
+       bh__arr_grow((void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + 1), \
+       arr[bh__arrhead(arr)->length++] = value)
+
+#define bh_arr_is_empty(arr)           (arr ? bh__arrhead(arr)->length == 0 : 1)
+#define bh_arr_clear(arr)                      (arr ? (bh__arrhead(arr)->length = 0) : 0)
+
+#define bh_arr_deleten(arr, i, n)      (bh__arr_deleten((void **) &(arr), sizeof(*(arr)), i, n))
+#define bh_arr_fastdelete(arr, i)      (arr[i] = arr[--bh__arrhead(arr)->length])
+
+b32 bh__arr_grow(void** arr, i32 elemsize, i32 cap);
+b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap);
 b32 bh__arr_free(void **arr);
-void* bh__arr_copy(void *arr, int elemsize);
+void* bh__arr_copy(void *arr, i32 elemsize);
+void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems);
+void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems);
 
 #ifdef BH_DEFINE
 #undef BH_DEFINE
@@ -302,7 +334,7 @@ void bh_string_replace_at_bh_string(bh_string* dest, bh_string* src, u64 offset)
 
 void bh_string_replace_at_cstr(bh_string* dest, const char* src, u64 offset) {
        if (offset > dest->length) return;
-       const int srclen = strlen(src);
+       const i32 srclen = strlen(src);
        if (!bh_string_ensure_capacity(dest, offset + srclen)) return;
 
        memcpy(dest->data + offset, src, srclen);
@@ -319,7 +351,7 @@ void bh_string_insert_at_bh_string(bh_string* dest, bh_string* src, u64 offset)
 }
 
 void bh_string_insert_at_cstr(bh_string* dest, const char* src, u64 offset) {
-       const int srclen = strlen(src);
+       const i32 srclen = strlen(src);
        if (!bh_string_ensure_capacity(dest, dest->length + srclen)) return;
 
        // TODO: Use something better. This copies to a seperate buffer first
@@ -542,7 +574,7 @@ b32 bh_file_contents_delete(bh_file_contents* contents) {
 // ARRAY IMPLEMENTATION
 //-------------------------------------------------------------------------------------
 
-b32 bh__arr_ensure_capacity(void** arr, int elemsize, int cap) {
+b32 bh__arr_grow(void** arr, i32 elemsize, i32 cap) {
        bh__arr* arrptr;
 
        if (*arr == NULL) {
@@ -558,8 +590,8 @@ b32 bh__arr_ensure_capacity(void** arr, int elemsize, int cap) {
 
                if (arrptr->capacity < cap) {
                        void* p;
-                       int newcap = arrptr->capacity ? arrptr->capacity : 4;
-                       while (newcap < cap) newcap <<= 1;
+                       i32 newcap = arrptr->capacity;
+                       while (newcap < cap) newcap = BH_ARR_GROW_FORMULA(newcap);
 
                        p = realloc(arrptr, sizeof(*arrptr) + elemsize * newcap);
 
@@ -576,11 +608,77 @@ b32 bh__arr_ensure_capacity(void** arr, int elemsize, int cap) {
        return 1;
 }
 
+b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap) {
+       if (*arr == NULL) return 0;
+
+       bh__arr* arrptr = bh__arrhead(*arr);
+       cap = bh_max(cap, arrptr->length);
+
+       if (arrptr->capacity > cap) {
+               void* p = realloc(arrptr, sizeof(*arrptr) + elemsize * cap);
+
+               if (p) {
+                       arrptr = (bh__arr *) p;
+                       arrptr->capacity = cap;
+               } else {
+                       return 0;
+               }
+       }
+
+       *arr = arrptr + 1;
+       return 1;
+}
+
 b32 bh__arr_free(void **arr) {
        bh__arr* arrptr = bh__arrhead(*arr);
        free(arrptr);
+       *arr = NULL;
+}
+
+void* bh__arr_copy(void *arr, i32 elemsize) {
+       bh__arr* arrptr = bh__arrhead(arr);
+
+       const i32 cap = arrptr->length;
+
+       void* newarr = NULL;
+       bh__arr_grow(&newarr, elemsize, cap);
+       bh__arrhead(newarr)->length = cap;
+       bh__arrhead(newarr)->capacity = cap;
+       memcpy(newarr, arr, elemsize * arrptr->length);
+
+       return newarr;
+}
+
+void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems) {
+       bh__arr* arrptr = bh__arrhead(*arr);    
+
+       if (index >= arrptr->length) return; // Can't delete past the end of the array
+       if (numelems <= 0) return; // Can't delete nothing
+
+       memmove(
+               (char *)(*arr) + elemsize * index,                                      // Target
+               (char *)(*arr) + elemsize * (index + numelems),         // Source
+               elemsize * (arrptr->length - (index + numelems)));      // Length
+       arrptr->length -= numelems;
 }
 
+void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) {
+       bh__arr* arrptr = bh__arrhead(*arr);
+
+       if (numelems) {
+               if (*arr == NULL) {
+                       bh__arr_grow(arr, elemsize, numelems); // Making a new array
+                       return;
+               }
+
+               if (!bh__arr_grow(arr, elemsize, arrptr->length + numelems)) return; // Fail case
+               memmove(
+                       (char *)(*arr) + elemsize * (index + numelems),
+                       (char *)(*arr) + elemsize * index,
+                       elemsize * (arrptr->length - index));
+               arrptr->length += numelems;
+       }
+}
 
 #endif // ifdef BH_DEFINE
 
diff --git a/onyx b/onyx
index 6ea581cce3958f127854e5c867d1f2b65076bbfa..690a2c823d61c7cd3aca2909c5a31d6a81f43638 100755 (executable)
Binary files a/onyx and b/onyx differ
diff --git a/onyx.c b/onyx.c
index 100dad99f2560717e5405ac4c335e8c60f9bb7b6..d4b8f88e8d78b99b0a1997a4ae9f4a9537a1bd54 100644 (file)
--- a/onyx.c
+++ b/onyx.c
@@ -5,29 +5,28 @@
 
 #include "onyxlex.h"
 
-int main(int argc, char const *argv[]) {
-       bh_arr(int) arr = NULL; // Must initialize to NULL
-       bh_arr_new(arr, 0);
-
-       bh_arr_set_length(arr, 10);
-       for (int i = 0; i < 10; i++)
-               arr[i] = i;
-       printf("Length: %d\nCapacity: %d\n", bh_arr_length(arr), bh_arr_capacity(arr));
-
-       bh_arr_set_length(arr, 0);
+bh_arr(Token) parse_tokens(bh_file_contents *fc) {
+       Tokenizer tknizer = {
+               .start                  = fc->data,
+               .curr                   = fc->data,
+               .end                    = fc->data + fc->length - 1,
+               .line_number    = 1,
+               .line_start     = fc->data,
+       };
 
-       printf("Length: %d\nCapacity: %d\n", bh_arr_length(arr), bh_arr_capacity(arr));
+       bh_arr(Token) token_arr = NULL;
+       bh_arr_grow(token_arr, 1024);
 
-       for (int* it = arr; !bh_arr_end(arr, it); it++) {
-               printf("%d ", *it);
-       }
-
-       bh_arr_free(arr);
+       Token tk;
+       do {
+               tk = get_token(&tknizer);
+               bh_arr_push(token_arr, tk);
+       } while (tk.type != TOKEN_TYPE_END_STREAM);
 
-       return 0;
+       return token_arr;
 }
 
-int main2(int argc, char *argv[]) {
+int main(int argc, char *argv[]) {
        bh_file source_file;
        bh_file_error err = bh_file_open(&source_file, argv[1]);
        if (err != BH_FILE_ERROR_NONE) {
@@ -38,25 +37,12 @@ int main2(int argc, char *argv[]) {
        bh_file_contents fc = bh_file_read_contents(&source_file);
        bh_file_close(&source_file);
 
-       Tokenizer tknizer = {
-               .start = fc.data,
-               .curr = fc.data,
-               .end = fc.data + fc.length - 1,
-               .line_number = 1,
-               .line_column = 1,
-       };
-
-       Token tk;
-       do {
-               tk = get_token(&tknizer);
-               char c = *(tk.token + tk.length);
-               *(tk.token + tk.length) = '\0';
-               printf("Line %ld, Column %ld: \n%s: %s\n", tk.line_number, tk.line_column, get_token_type_name(tk), tk.token);
-               *(tk.token + tk.length) = c;
-       } while (tk.type != TOKEN_TYPE_END_STREAM);
+       bh_arr(Token) token_arr = parse_tokens(&fc);
 
+       printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr));
 
        bh_file_contents_delete(&fc);
+       bh_arr_free(token_arr);
 
        return 0;
 }
index a59456830011b85ebd19827b3204f990f7923b3f..38c54c4cbd09d380fb4787f9e9370c7a3bfd2639 100644 (file)
--- a/onyxlex.c
+++ b/onyxlex.c
@@ -55,11 +55,11 @@ static const char* TokenTypeNames[] = {
 
 #ifndef INCREMENT_CURR_TOKEN
 #define INCREMENT_CURR_TOKEN(tkn) { \
-       tkn->curr++; \
-       tkn->line_column++; \
-       if (*tkn->curr == '\n') { \
-               tkn->line_number++; \
-               tkn->line_column = 1; \
+       (tkn)->curr++; \
+       while (*(tkn)->curr == '\n' && (tkn)->curr != (tkn)->end) { \
+               (tkn)->curr++; \
+               (tkn)->line_number++; \
+               (tkn)->line_start = (tkn)->curr; \
        } \
 }
 #endif
@@ -70,9 +70,10 @@ static b32 token_lit(Tokenizer* tokenizer, Token* tk, char* lit, TokenType type)
                tk->type = type;
                tk->token = tokenizer->curr;
                tk->length = len;
+               tk->line_number = tokenizer->line_number;
+               tk->line_column = (i32)(tokenizer->curr - tokenizer->line_start) + 1;
 
                tokenizer->curr += len;
-               tokenizer->line_column += len;
 
                return 1;
        }
@@ -94,7 +95,7 @@ Token get_token(Tokenizer* tokenizer) {
        tk.token = tokenizer->curr;
        tk.length = 1;
        tk.line_number = tokenizer->line_number;
-       tk.line_column = tokenizer->line_column;
+       tk.line_column = (i32)(tokenizer->curr - tokenizer->line_start) + 1;
 
        if (tokenizer->curr == tokenizer->end) {
                tk.type = TOKEN_TYPE_END_STREAM;
index 01dc7fd6552f9449629393d55297b9e8aa732c90..8fb15967af2217ec41600310314f9f61410c0db4 100644 (file)
--- a/onyxlex.h
+++ b/onyxlex.h
@@ -7,8 +7,8 @@ typedef struct Tokenizer {
        char *start, *curr, *end;
 
        // TODO: Fix the line number and column count
+       char* line_start;
        u64 line_number;
-       u64 line_column;
 } Tokenizer;
 
 typedef enum TokenType {