mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Implemented bucket memory structure for custom allocators
This commit is contained in:
2
source/toy_ast.c
Normal file
2
source/toy_ast.c
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "toy_ast.h"
|
||||
|
||||
9
source/toy_ast.h
Normal file
9
source/toy_ast.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_common.h"
|
||||
|
||||
typedef enum Toy_AstType {
|
||||
TOY_AST_PASS,
|
||||
TOY_AST_ERROR,
|
||||
} Toy_AstType;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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"},
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum Toy_OpcodeType {
|
||||
TOY_OPCODE_RETURN,
|
||||
TOY_OPCODE_PASS,
|
||||
TOY_OPCODE_ERROR,
|
||||
TOY_OPCODE_EOF,
|
||||
} Toy_OpcodeType;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user