From: Brendan Hansen Date: Tue, 12 May 2020 20:03:58 +0000 (-0500) Subject: Finished bh_arr X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=5ea28bbeee5639ac65d9fd20728f63f77b13ba1d;p=onyx.git Finished bh_arr --- diff --git a/bh.h b/bh.h index 16a51c87..c322aa80 100644 --- 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 6ea581cc..690a2c82 100755 Binary files a/onyx and b/onyx differ diff --git a/onyx.c b/onyx.c index 100dad99..d4b8f88e 100644 --- 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; } diff --git a/onyxlex.c b/onyxlex.c index a5945683..38c54c4c 100644 --- 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; diff --git a/onyxlex.h b/onyxlex.h index 01dc7fd6..8fb15967 100644 --- 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 {