Add list type, obj_free for compound types, and self-reference guard

- Implement OBJ_LIST with offset-based items array and capacity
- obj_free now releases child allocations (string buffer, list items)
- obj_print detects self-referencing lists to prevent infinite recursion
- Visualizer distinguishes freed blocks (JLANG_NOT_USE) from active ones
- JLANG_free now zeroes payload on release
This commit is contained in:
Jose Luis Montañes Ojados
2026-02-16 00:33:02 +01:00
parent 13c9d052a0
commit d14227efeb
3 changed files with 97 additions and 35 deletions

View File

@@ -15,7 +15,7 @@ typedef struct Object {
int length;
} string_val;
struct {
struct Object **items;
size_t items;
int count;
int capacity;
} list_val;
@@ -58,22 +58,39 @@ size_t obj_new_string(void *allocator, const char *str) {
return offset;
}
size_t obj_new_list(void *allocator) {
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) {
// if (obj->type == OBJ_STRING) {
// JLANG_free(allocator, obj->data.string_val.chars);
// }
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) {
void obj_print(void *allocator, size_t offset, const char *preffix) {
Object *obj = (Object *)JLANG_RESOLVE(allocator, offset);
switch (obj->type) {
@@ -83,15 +100,40 @@ void obj_print(void *allocator, size_t offset) {
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_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("<self:0x%zu>", 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;
}
};
}