#include "../memory/allocator.h" #define JLANG_RESOLVE(alloc, offset) \ ((void *)(((JLANG_memory_allocator *)(alloc))->memory + (offset))) 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 { size_t chars; int length; } string_val; struct { size_t items; int count; int capacity; } list_val; } data; } Object; size_t obj_new_int(void *allocator, int value) { // Object *objPtr = (Object *)JLANG_malloc(allocator, sizeof(Object)); size_t offset = JLANG_malloc(allocator, sizeof(Object)); Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset); objPtr->type = OBJ_INT; objPtr->data.int_val = value; return offset; } size_t obj_new_float(void *allocator, float value) { size_t offset = JLANG_malloc(allocator, sizeof(Object)); Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset); objPtr->type = OBJ_FLOAT; objPtr->data.float_val = value; return offset; } size_t obj_new_string(void *allocator, const char *str) { size_t offset = JLANG_malloc(allocator, sizeof(Object)); Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset); objPtr->type = OBJ_STRING; int len = strlen(str); // !! CUIDADO CON ESTE DOBLE MALLOC SI DISPARA EL GROW !! size_t bufferOffset = JLANG_malloc(allocator, len + 1); char *buffer = (char *)JLANG_RESOLVE(allocator, bufferOffset); memcpy(buffer, str, len + 1); objPtr->data.string_val.chars = bufferOffset; objPtr->data.string_val.length = len; return offset; } size_t obj_new_list(void *allocator, int capacity) { size_t offset = JLANG_malloc(allocator, sizeof(Object)); Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset); objPtr->type = OBJ_LIST; size_t itemsOffset = JLANG_malloc(allocator, capacity * sizeof(size_t)); // Re-resolver por si malloc disparó grow objPtr = (Object *)JLANG_RESOLVE(allocator, offset); objPtr->data.list_val.capacity = capacity; objPtr->data.list_val.items = itemsOffset; objPtr->data.list_val.count = 0; return offset; } void obj_list_append(void *allocator, size_t offset) {} void obj_free(void *allocator, size_t offset) { Object *obj = (Object *)JLANG_RESOLVE(allocator, offset); if (obj->type == OBJ_STRING) { JLANG_free(allocator, obj->data.string_val.chars); } if (obj->type == OBJ_LIST) { JLANG_free(allocator, obj->data.list_val.items); } JLANG_free(allocator, offset); } void obj_print(void *allocator, size_t offset, const char *preffix) { Object *obj = (Object *)JLANG_RESOLVE(allocator, offset); 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: { // Iterate items size_t *items = (size_t *)JLANG_RESOLVE(allocator, obj->data.list_val.items); printf("["); for (int i = 0; i < obj->data.list_val.capacity; i++) { // Check if the item is the list itself if (items[i] == offset) { printf("", offset); } else { obj_print(allocator, items[i], "\""); } if (i < obj->data.list_val.capacity - 1) { printf(", "); } } printf("]\n"); break; } case OBJ_STRING: if (strcmp(preffix, "") != 0) { printf("%s", preffix); } printf("%s", (char *)JLANG_RESOLVE(allocator, obj->data.string_val.chars)); if (strcmp(preffix, "") != 0) { printf("%s", preffix); } break; default: break; }; }