diff --git a/run.exe b/run.exe index 99be10f..cb1ae37 100644 Binary files a/run.exe and b/run.exe differ diff --git a/src/main.c b/src/main.c index 2512cdb..698031e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -#include "memory/allocator.h" +#include "objects/object.h" int main() { JLANG_memory_allocator *allocPtr = JLANG_CreateAllocator(); @@ -7,12 +7,24 @@ int main() { printf("memoryPtr=%p\n", allocPtr->memory); printf("size=%zu\n", allocPtr->size); - JLANG_visualize(allocPtr); + // Create object + Object *intVar1 = obj_new_int(allocPtr, 66); + obj_print(intVar1); - void *var1 = JLANG_malloc(allocPtr, 512); - printf("var1Ptr=%p\n", var1); + Object *stringVar1 = obj_new_string(allocPtr, "\nHello world!\n"); + obj_print(stringVar1); JLANG_visualize(allocPtr); - + + for (int i = 0; i < 10; i++) { + Object *intVar1 = obj_new_int(allocPtr, 66); + obj_print(intVar1); + } + + obj_free(allocPtr, intVar1); + void* newPtr = JLANG_malloc(allocPtr, 8); + + obj_print(stringVar1); + JLANG_visualize(allocPtr); return 0; } \ No newline at end of file diff --git a/src/memory/allocator.h b/src/memory/allocator.h index e8c1ff1..b3d3cb5 100644 --- a/src/memory/allocator.h +++ b/src/memory/allocator.h @@ -1,11 +1,12 @@ -#include #include +#include #include /* Custom Memory Allocator - Implementacion custom de un memory allocator que opera sobre un array de bytes usandolo como "heap" + Implementacion custom de un memory allocator que opera sobre un array de + bytes usandolo como "heap" */ #define JLANG_OK 0 @@ -15,99 +16,106 @@ #define JLANG_PAYLOAD 2 /* - La estructura de Metadata se encarga de almacenar el tamaño del bloque y si está en uso. - Se añadirá al principio de cada bloque - [BLOCK_METADATA] + [BLOCK_BYTES] + La estructura de Metadata se encarga de almacenar el tamaño del bloque y si + está en uso. Se añadirá al principio de cada bloque [BLOCK_METADATA] + + [BLOCK_BYTES] */ -typedef struct -{ - size_t size; // 8 bytes - int in_use; // 4 bytes - // --- aquí el compilador mete 4 bytes invisibles --- +typedef struct { + size_t size; // 8 bytes + int in_use; // 4 bytes + // --- aquí el compilador mete 4 bytes invisibles --- } JLANG_metadata; /* - La estructura de Memory Allocator se encarga de almancenar el array de memoria y el tamaño de esta. + La estructura de Memory Allocator se encarga de almancenar el array de + memoria y el tamaño de esta. */ -typedef struct -{ - char *memory; // 8 bytes - size_t size; // 8 bytes +typedef struct { + char *memory; // 8 bytes + size_t size; // 8 bytes } JLANG_memory_allocator; -void *JLANG_CreateAllocator() -{ - // Allocate memory in heap for JLANG_memory_allocator - JLANG_memory_allocator *allocator = (JLANG_memory_allocator *)malloc(sizeof(JLANG_memory_allocator)); +void *JLANG_CreateAllocator() { + // Allocate memory in heap for JLANG_memory_allocator + JLANG_memory_allocator *allocator = + (JLANG_memory_allocator *)malloc(sizeof(JLANG_memory_allocator)); - // Assign default free bytes - allocator->memory = (char *)malloc(1 * 1024); - allocator->size = 1 * 1024; + // Assign default free bytes + allocator->memory = (char *)malloc(1 * 1024); + allocator->size = 1 * 1024; - // ensure all memory is zero - for (int i = 0; i < 1 * 1024; i++) - { - allocator->memory[i] = 0; - } + // ensure all memory is zero + for (int i = 0; i < 1 * 1024; i++) { + allocator->memory[i] = 0; + } - return allocator; + return allocator; } -size_t JLANG_used(void *ptr) -{ - JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; +size_t JLANG_used(void *ptr) { + JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; - // Iterate memory parsing only metadata - JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; - size_t used = 0; - while (currentHeader->in_use != 0 && used < allocPtr->size) - { - used += sizeof(JLANG_metadata) + currentHeader->size; + // Iterate memory parsing only metadata + JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; + size_t used = 0; + while (currentHeader->in_use != 0 && used < allocPtr->size) { + used += sizeof(JLANG_metadata) + currentHeader->size; - // Current block is in_use, jump to next block - currentHeader = (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + currentHeader->size); - } + // Current block is in_use, jump to next block + currentHeader = + (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + + currentHeader->size); + } - return used; + return used; } -void *JLANG_last_free(void *ptr) -{ - JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; +void *JLANG_last_free(void *ptr) { + JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; - // Iterate memory parsing only metadata - JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; - size_t used = 0; - while (currentHeader->in_use != 0 && used < allocPtr->size) - { - used += sizeof(JLANG_metadata) + currentHeader->size; + // Iterate memory parsing only metadata + JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; + size_t used = 0; + while (currentHeader->in_use != 0 && used < allocPtr->size) { + used += sizeof(JLANG_metadata) + currentHeader->size; - // Current block is in_use, jump to next block - currentHeader = (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + currentHeader->size); - } + // Current block is in_use, jump to next block + currentHeader = + (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + + currentHeader->size); + } - return currentHeader; + return currentHeader; } -void *JLANG_malloc(void *ptr, size_t size) -{ - JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; +void *JLANG_malloc(void *ptr, size_t size) { + JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; - // 1. Hay bloques disponibles?? - size_t used = JLANG_used(ptr); - size_t available = allocPtr->size - used; + // 1. Hay bloques disponibles?? + size_t used = JLANG_used(ptr); + size_t available = allocPtr->size - used; - // chequear si hay suficiente espacio libre - if (available > size + sizeof(JLANG_metadata)) - { - JLANG_metadata *freeHeader = (JLANG_metadata *)JLANG_last_free(ptr); - freeHeader->size = size; - freeHeader->in_use = 1; + // chequear si hay suficiente espacio libre + if (available > size + sizeof(JLANG_metadata)) { + JLANG_metadata *freeHeader = (JLANG_metadata *)JLANG_last_free(ptr); + freeHeader->size = size; + freeHeader->in_use = 1; - return (char *)freeHeader + sizeof(JLANG_metadata); - } + return (char *)freeHeader + sizeof(JLANG_metadata); + } - return NULL; // TODO + return NULL; // TODO +} + +void JLANG_free(void *ptr, void *blockPtr) { + JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; + + // Get block header + JLANG_metadata *blockHeader = + (JLANG_metadata *)((char *)blockPtr - sizeof(JLANG_metadata)); + + // Set block as not_used + blockHeader->in_use = 0; } /* @@ -116,101 +124,91 @@ void *JLANG_malloc(void *ptr, size_t size) [FF FF FF FF FF FF FF ] */ -int _ceil(float v) -{ - int n = (int)v; - float r = v - n; +int _ceil(float v) { + int n = (int)v; + float r = v - n; - if (r > 0) - { - return n + 1; - } - return n; + if (r > 0) { + return n + 1; + } + return n; } -void JLANG_visualize(void *ptr) -{ - JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; +void JLANG_visualize(void *ptr) { + JLANG_memory_allocator *allocPtr = (JLANG_memory_allocator *)ptr; - // Step 1. Get byte type - char *byteMapPtr = (char *)malloc(allocPtr->size); - memset(byteMapPtr, 0, allocPtr->size); + // Step 1. Get byte type + char *byteMapPtr = (char *)malloc(allocPtr->size); + memset(byteMapPtr, 0, allocPtr->size); - JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; - long used = 0; - while (used < allocPtr->size) - { - long blockIndex = (char *)currentHeader - (char *)allocPtr->memory; - printf("blockIndex=%u\n", blockIndex); - used += sizeof(JLANG_metadata) + currentHeader->size; - - /* - HEADER - blockIndex + sizeof(JLANG_metadata) - */ + JLANG_metadata *currentHeader = (JLANG_metadata *)allocPtr->memory; + long used = 0; + while (used < allocPtr->size) { + long blockIndex = (char *)currentHeader - (char *)allocPtr->memory; + used += sizeof(JLANG_metadata) + currentHeader->size; - if (currentHeader->size > 0) - { - byteMapPtr[blockIndex] = JLANG_HEADER; - for (int i = 0; i < sizeof(JLANG_metadata); i++) - { - byteMapPtr[blockIndex + i] = JLANG_HEADER; - } + /* + HEADER + blockIndex + sizeof(JLANG_metadata) + */ - /* - PAYLOAD - */ - for (int i = 0; i < currentHeader->size; i++) - { - byteMapPtr[blockIndex + sizeof(JLANG_metadata) + i] = JLANG_PAYLOAD; - } - } else { - break; - } + if (currentHeader->size > 0) { + byteMapPtr[blockIndex] = JLANG_HEADER; + for (int i = 0; i < sizeof(JLANG_metadata); i++) { + byteMapPtr[blockIndex + i] = JLANG_HEADER; + } - // Jump to next block - currentHeader = (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + currentHeader->size); + /* + PAYLOAD + */ + for (int i = 0; i < currentHeader->size; i++) { + byteMapPtr[blockIndex + sizeof(JLANG_metadata) + i] = JLANG_PAYLOAD; + } + } else { + break; } - // Step 2. Draw + // Jump to next block + currentHeader = + (JLANG_metadata *)((char *)currentHeader + sizeof(JLANG_metadata) + + currentHeader->size); + } - int bytePerRow = 40; - int totalRows = _ceil(allocPtr->size / bytePerRow); - printf("totalRows=%d\n", totalRows); + // Step 2. Draw - char *currentMemPtr = allocPtr->memory; + int bytePerRow = 40; + int totalRows = _ceil(allocPtr->size / bytePerRow); + printf("totalRows=%d\n", totalRows); - for (int i = 0; i < totalRows; i++) - { - printf("["); - for (int n = 0; n < bytePerRow; n++) - { + char *currentMemPtr = allocPtr->memory; - int index = n + i * bytePerRow; + for (int i = 0; i < totalRows; i++) { + printf("["); + for (int n = 0; n < bytePerRow; n++) { - switch (byteMapPtr[index]) - { - case JLANG_HEADER: - printf("\033[46m"); - break; - case JLANG_FREE: - printf("\033[32m"); - break; - default: - printf("\033[41m"); - break; - } + int index = n + i * bytePerRow; - printf("%.2x", (unsigned char) *(currentMemPtr + (n + i * bytePerRow))); + switch (byteMapPtr[index]) { + case JLANG_HEADER: + printf("\033[46m"); + break; + case JLANG_FREE: + printf("\033[32m"); + break; + default: + printf("\033[41m"); + break; + } - if (n < bytePerRow - 1) - { - printf(" "); - } + printf("%.2x", (unsigned char)*(currentMemPtr + (n + i * bytePerRow))); - printf("\033[0m"); - } + if (n < bytePerRow - 1) { + printf(" "); + } - printf("]\n"); + printf("\033[0m"); } + + printf("]\n"); + } } diff --git a/src/objects/object.h b/src/objects/object.h new file mode 100644 index 0000000..118666f --- /dev/null +++ b/src/objects/object.h @@ -0,0 +1,101 @@ +#include "../memory/allocator.h" + +typedef enum +{ + OBJ_INT, + OBJ_FLOAT, + OBJ_STRING, + OBJ_LIST, + OBJ_NONE +} ObjectType; + +typedef struct Object +{ + ObjectType type; + union + { + int int_val; + double float_val; + struct + { + char *chars; + int length; + } string_val; + struct + { + struct Object **items; + int count; + int capacity; + } list_val; + } data; +} Object; + +Object *obj_new_int(void *allocator, int value) +{ + Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object)); + objPtr->type = OBJ_INT; + objPtr->data.int_val = value; + return objPtr; +} + +Object *obj_new_float(void *allocator, float value) +{ + Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object)); + objPtr->type = OBJ_FLOAT; + objPtr->data.float_val = value; + return objPtr; +} + +Object *obj_new_string(void *allocator, const char *str) +{ + Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object)); + objPtr->type = OBJ_STRING; + + int len = strlen(str); + char *buffer = (char *)JLANG_malloc(allocator, len + 1); + memcpy(buffer, str, len + 1); + + objPtr->data.string_val.chars = buffer; + objPtr->data.string_val.length = len; + + return objPtr; +} + +Object *obj_new_list(void *allocator) +{ + Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object)); + objPtr->type = OBJ_LIST; + return objPtr; +} + +void obj_free(void *allocator, Object* obj) { + if (obj->type == OBJ_STRING) { + JLANG_free(allocator, obj->data.string_val.chars); + } + + JLANG_free(allocator, obj); +} + +void obj_print(Object *obj) +{ + switch (obj->type) + { + case OBJ_INT: + printf("%d", obj->data.int_val); + break; + case OBJ_FLOAT: + printf("%f", obj->data.float_val); + break; + case OBJ_LIST: + for (int i = 0; i < obj->data.list_val.count; i++) + { + obj_print(obj->data.list_val.items[i]); + } + break; + case OBJ_STRING: + printf("%s", obj->data.string_val.chars); + break; + default: + break; + } +}