// ARENA ALLOCATOR
typedef struct bh_arena {
bh_allocator backing;
- ptr memory;
- ptr next_allocation;
- isize size, total_size; // in bytes
+ ptr first_arena, current_arena;
+ isize size, arena_size; // in bytes
} bh_arena;
-void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize total_size);
+typedef struct bh__arena_internal {
+ ptr next_arena;
+ void* data; // Not actually a pointer, just used for the offset
+} bh__arena_internal;
+
+void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size);
void bh_arena_free(bh_arena* alloc);
bh_allocator bh_arena_allocator(bh_arena* alloc);
BH_ALLOCATOR_PROC(bh_arena_allocator_proc);
#define bh_arr_free(arr) (bh__arr_free((void**) &(arr)))
#define bh_arr_copy(allocator_, arr) (bh__arr_copy((allocator_), (arr), sizeof(*(arr))))
-#define bh_arr_grow(arr, cap) (bh__arr_grow((void **) &(arr), sizeof(*(arr)), cap))
+#define bh_arr_grow(arr, cap) (bh__arr_grow(bh_arr_allocator(arr), (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__arr_grow(bh_arr_allocator(arr), (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_grow((void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \
+ bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \
bh__arrhead(arr)->length += n)
#define bh_arr_push(arr, value) ( \
// ARENA ALLOCATOR IMPLEMENTATION
-void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize total_size) {
- ptr data = bh_alloc(backing, total_size);
+void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size) {
+ ptr data = bh_alloc(backing, arena_size);
alloc->backing = backing;
- alloc->total_size = total_size;
+ alloc->arena_size = arena_size;
alloc->size = 0;
- alloc->memory = data;
- alloc->next_allocation = data;
+ alloc->first_arena = data;
+ alloc->current_arena = data;
+
+ ((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL;
}
void bh_arena_free(bh_arena* alloc) {
- bh_free(alloc->backing, alloc->memory);
- alloc->memory = NULL;
- alloc->next_allocation = NULL;
- alloc->total_size = 0;
+ bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena;
+ bh__arena_internal *trailer = walker;
+ while (walker != NULL) {
+ walker = walker->next_arena;
+ bh_free(alloc->backing, trailer);
+ trailer = walker;
+ }
+
+ alloc->first_arena = NULL;
+ alloc->current_arena = NULL;
+ alloc->arena_size = 0;
alloc->size = 0;
}
}
BH_ALLOCATOR_PROC(bh_arena_allocator_proc) {
- bh_arena* alloc_nf = (bh_arena*) data;
+ bh_arena* alloc_arena = (bh_arena*) data;
ptr retval = NULL;
switch (action) {
case bh_allocator_action_alloc: {
- retval = alloc_nf->next_allocation;
- size = bh__align(size, alignment);
- alloc_nf->next_allocation = bh_pointer_add(alloc_nf->next_allocation, size);
-
- if (alloc_nf->size + size >= alloc_nf->total_size) {
- // Out of memory
- fprintf(stderr, "NoFree allocator out of memory\n");
+ // TODO: Do this better because right now bh__align is bad
+ // size = bh__align(size, alignment);
+ if (size > alloc_arena->arena_size) {
+ // Size too large for the arena
return NULL;
}
+
+ if (alloc_arena->size + size >= alloc_arena->arena_size) {
+ alloc_arena->size = sizeof(ptr);
+ bh__arena_internal* new_arena = (bh__arena_internal *) bh_alloc(alloc_arena->backing, alloc_arena->arena_size);
+
+ if (new_arena == NULL) {
+ fprintf(stderr, "Arena Allocator: couldn't allocate new arena");
+ return NULL;
+ }
+
+ ((bh__arena_internal *)alloc_arena->current_arena)->next_arena = new_arena;
+ alloc_arena->current_arena = new_arena;
+ }
- alloc_nf->size += size;
+ retval = alloc_arena->current_arena + alloc_arena->size;
+ alloc_arena->size += size;
} break;
case bh_allocator_action_resize: {
bh_file_contents fc = bh_file_read_contents(alloc, &source_file);
bh_file_close(&source_file);
- bh_hash(u16) symbol_count;
- bh_hash_init(alloc, symbol_count);
- bh_arr(OnyxToken) token_arr = onyx_parse_tokens(alloc, &fc, symbol_count);
+ bh_arr(OnyxToken) token_arr = onyx_parse_tokens(alloc, &fc);
printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr));
printf("%s '%c' (Line %ld, Col %ld)\n", onyx_get_token_type_name(*it), *(char *)it->token, it->line_number, it->line_column);
}
- bh_hash_iterator it = bh_hash_iter_setup(u16, symbol_count);
- while (bh_hash_iter_next(&it)) {
- const char* sym = bh_hash_iter_key(it);
- u16 count = bh_hash_iter_value(u16, it);
-
- printf("%s was seen %d times.\n", sym, count);
- }
-
bh_file_contents_delete(&fc);
bh_arr_free(token_arr);
- bh_hash_free(symbol_count);
return 0;
}
return tk;
}
-bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc, bh_hash(u16) symcount) {
+bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc) {
OnyxTokenizer tknizer = {
.start = fc->data,
.curr = fc->data,
.end = fc->data + fc->length,
.line_number = 1,
.line_start = fc->data,
- .symbol_count = symcount,
};
bh_arr(OnyxToken) token_arr = NULL;
OnyxToken tk;
do {
tk = onyx_get_token(&tknizer);
-
- if (tk.type == TOKEN_TYPE_SYMBOL) {
- u16 val = 0;
-
- char tmp = tk.token[tk.length];
- tk.token[tk.length] = '\0';
-
- if (bh_hash_has(u16, tknizer.symbol_count, tk.token)) {
- val = bh_hash_get(u16, tknizer.symbol_count, tk.token);
- }
-
- bh_hash_put(u16, tknizer.symbol_count, tk.token, val + 1);
-
- tk.token[tk.length] = tmp;
- }
-
bh_arr_push(token_arr, tk);
} while (tk.type != TOKEN_TYPE_END_STREAM);