Implemented bucket memory structure for custom allocators

This commit is contained in:
2024-09-07 19:42:50 +10:00
parent 023cf9c8b5
commit 81417e7f32
13 changed files with 275 additions and 44 deletions

2
source/toy_ast.c Normal file
View File

@@ -0,0 +1,2 @@
#include "toy_ast.h"

9
source/toy_ast.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include "toy_common.h"
typedef enum Toy_AstType {
TOY_AST_PASS,
TOY_AST_ERROR,
} Toy_AstType;

View File

@@ -1,24 +0,0 @@
#include "toy_chunk.h"
#include "toy_memory.h"
void Toy_initChunk(Toy_Chunk* chunk) {
chunk->count = 0;
chunk->capacity = 0;
chunk->code = NULL;
}
void Toy_pushChunk(Toy_Chunk* chunk, uint8_t byte) {
if (chunk->count +1 > chunk->capacity) {
int oldCapacity = chunk->capacity;
chunk->capacity = TOY_GROW_CAPACITY(oldCapacity);
chunk->code = TOY_GROW_ARRAY(uint8_t, chunk->code, oldCapacity, chunk->capacity);
}
chunk->code[chunk->count++] = byte;
}
void Toy_freeChunk(Toy_Chunk* chunk) {
TOY_FREE_ARRAY(uint8_t, chunk->code, chunk->capacity);
Toy_initChunk(chunk);
}

View File

@@ -1,13 +0,0 @@
#pragma once
#include "toy_common.h"
typedef struct Toy_Chunk {
int count;
int capacity;
uint8_t* code;
} Toy_Chunk;
TOY_API void Toy_initChunk(Toy_Chunk* chunk);
TOY_API void Toy_pushChunk(Toy_Chunk* chunk, uint8_t byte);
TOY_API void Toy_freeChunk(Toy_Chunk* chunk);

View File

@@ -23,7 +23,7 @@ const Toy_KeywordTypeTuple Toy_private_keywords[] = {
{TOY_TOKEN_KEYWORD_ASSERT, "assert"},
{TOY_TOKEN_KEYWORD_BREAK, "break"},
{TOY_TOKEN_KEYWORD_CLASS, "class"},
{TOY_TOKEN_KEYWORD_CONST, "const"}, //TODO: investigate the constness of types
{TOY_TOKEN_KEYWORD_CONST, "const"},
{TOY_TOKEN_KEYWORD_CONTINUE, "continue"},
{TOY_TOKEN_KEYWORD_DO, "do"},
{TOY_TOKEN_KEYWORD_ELSE, "else"},

View File

@@ -19,4 +19,69 @@ void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize) {
}
return result;
}
}
//buckets of fun
void Toy_initBucket(Toy_Bucket** bucketHandle, size_t capacity) {
if (capacity == 0) {
fprintf(stderr, TOY_CC_ERROR "[internal] ERROR: Cannot init a bucket with zero capacity\n" TOY_CC_RESET);
exit(1);
}
(*bucketHandle) = malloc(sizeof(Toy_Bucket));
if ((*bucketHandle) == NULL) {
fprintf(stderr, TOY_CC_ERROR "[internal] ERROR: Failed to allocate space for a bucket\n" TOY_CC_RESET);
exit(1);
}
//initialize the bucket
(*bucketHandle)->next = NULL;
(*bucketHandle)->contents = NULL; //leave until the first partition
(*bucketHandle)->capacity = capacity;
(*bucketHandle)->count = 0;
}
void* Toy_partBucket(Toy_Bucket** bucketHandle, size_t space) {
if ((*bucketHandle) == NULL) {
fprintf(stderr, TOY_CC_ERROR "[internal] ERROR: Expected bucket, received NULL\n" TOY_CC_RESET);
exit(1);
}
//if out of space in the current bucket
if ((*bucketHandle)->capacity < (*bucketHandle)->count + space) {
//move to the next bucket
Toy_Bucket* tmp = NULL;
Toy_initBucket(&tmp, (*bucketHandle)->capacity);
tmp->next = (*bucketHandle);
(*bucketHandle) = tmp;
}
//if no space allocated for the current bucket
if ((*bucketHandle)->contents == NULL) {
//allocate space for the current bucket
(*bucketHandle)->contents = malloc((*bucketHandle)->capacity);
//double check
if ((*bucketHandle)->contents == NULL) {
fprintf(stderr, TOY_CC_ERROR "[internal] ERROR: Failed to allocate space for bucket contents\n" TOY_CC_RESET);
exit(1);
}
}
//track the new count, and return the specified memory space
(*bucketHandle)->count += space;
return ((*bucketHandle)->contents + (*bucketHandle)->count - space);
}
void Toy_freeBucket(Toy_Bucket** bucketHandle) {
while ((*bucketHandle) != NULL) {
//run down the chain
Toy_Bucket* ptr = (*bucketHandle);
(*bucketHandle) = (*bucketHandle)->next;
//clear the previous bucket from memory
free(ptr->contents);
free(ptr);
}
}

View File

@@ -2,13 +2,45 @@
#include "toy_common.h"
//standard movable array for general use
#define TOY_GROW_CAPACITY(capacity) \
((capacity) < 8 ? 8 : (capacity) * 2)
#define TOY_ALLOCATE(type, count) \
(type*)Toy_reallocate(NULL, 0, sizeof(type)*(count))
#define TOY_FREE(type, pointer) \
(type*)Toy_reallocate(pointer, sizeof(type), 0)
#define TOY_GROW_ARRAY(type, pointer, oldSize, newSize) \
(type*)Toy_reallocate(pointer, sizeof(type)*oldSize, sizeof(type)*newSize)
#define TOY_SHRINK_ARRAY(type, pointer, oldCount, count) \
(type*)Toy_reallocate((type*)pointer, sizeof(type)*(oldCount), sizeof(type)*(count))
#define TOY_FREE_ARRAY(type, pointer, oldSize) \
(type*)Toy_reallocate(pointer, sizeof(type)*oldSize, 0)
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
//immobile "bucket" memory structure for custom allocators
typedef struct Toy_Bucket {
struct Toy_Bucket* next;
void* contents;
int capacity;
int count;
} Toy_Bucket;
TOY_API void Toy_initBucket(Toy_Bucket** bucketHandle, size_t capacity);
TOY_API void* Toy_partBucket(Toy_Bucket** bucketHandle, size_t space);
TOY_API void Toy_freeBucket(Toy_Bucket** bucketHandle);
#define TOY_BUCKET_INIT(type, bucket, capacity) \
Toy_initBucket(&(bucket), sizeof(type)*(capacity))
#define TOY_BUCKET_PART(type, bucket) \
Toy_partBucket(&(bucket), sizeof(type))
#define TOY_BUCKET_FREE(bucket) \
Toy_freeBucket(&(bucket))

View File

@@ -1,5 +1,8 @@
#pragma once
typedef enum Toy_OpcodeType {
TOY_OPCODE_RETURN,
TOY_OPCODE_PASS,
TOY_OPCODE_ERROR,
TOY_OPCODE_EOF,
} Toy_OpcodeType;

View File

@@ -14,6 +14,7 @@ typedef enum Toy_ValueType {
TOY_VALUE_OPAQUE,
} Toy_ValueType;
//4 bytes in size
typedef struct Toy_Value {
union {
bool boolean; //1
@@ -26,7 +27,7 @@ typedef struct Toy_Value {
//TODO: opaque
} as; //4
Toy_ValueType type; //4 bytes
Toy_ValueType type; //4
} Toy_Value;
#define TOY_VALUE_IS_NULL(value) ((value).type == TOY_VALUE_NULL)