Files
j-lang/src/objects/object.h

180 lines
5.0 KiB
C
Raw Normal View History

#ifndef JLANG_OBJECT_H
#define JLANG_OBJECT_H
2026-02-15 22:12:19 +01:00
#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, OBJ_INSTANCE } 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;
struct {
int class_index; // indice en Chunk.classes[]
size_t field_names; // heap offset -> array de int
size_t field_values; // heap offset -> array de Value
int field_count;
int field_capacity;
} instance_val;
} data;
2026-02-15 22:12:19 +01:00
} Object;
size_t obj_new_instance(void *allocator, int class_index, int capacity, size_t value_size) {
size_t offset = JLANG_malloc(allocator, sizeof(Object));
Object *objPtr = (Object *)JLANG_RESOLVE(allocator, offset);
objPtr->type = OBJ_INSTANCE;
objPtr->data.instance_val.class_index = class_index;
objPtr->data.instance_val.field_count = 0;
objPtr->data.instance_val.field_capacity = capacity;
// alloc array de nombres
size_t namesOffset = JLANG_malloc(allocator, capacity * sizeof(int));
objPtr = (Object *) JLANG_RESOLVE(allocator, offset); // re-resolve
// alloc array de valores
size_t valuesOffset = JLANG_malloc(allocator, capacity * value_size);
objPtr = (Object *) JLANG_RESOLVE(allocator, offset); // re-resolve
objPtr->data.instance_val.field_names = namesOffset;
objPtr->data.instance_val.field_values = valuesOffset;
return offset;
}
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;
2026-02-15 22:12:19 +01:00
}
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;
2026-02-15 22:12:19 +01:00
}
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;
2026-02-15 22:12:19 +01:00
int len = strlen(str);
2026-02-15 22:12:19 +01:00
// !! 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);
2026-02-15 22:12:19 +01:00
objPtr->data.string_val.chars = bufferOffset;
objPtr->data.string_val.length = len;
return offset;
2026-02-15 22:12:19 +01:00
}
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;
2026-02-15 22:12:19 +01:00
}
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);
}
2026-02-15 22:12:19 +01:00
if (obj->type == OBJ_INSTANCE) {
JLANG_free(allocator, obj->data.instance_val.field_names);
JLANG_free(allocator, obj->data.instance_val.field_values);
}
JLANG_free(allocator, offset);
2026-02-15 22:12:19 +01:00
}
void obj_print(void *allocator, size_t offset, const char *preffix,
const char *suffix) {
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("<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(suffix, "") != 0) {
printf("%s", suffix);
}
break;
default:
break;
};
2026-02-15 22:12:19 +01:00
}
#endif