diff --git a/clox/src/memory.c b/clox/src/memory.c index ead60c8..169d846 100644 --- a/clox/src/memory.c +++ b/clox/src/memory.c @@ -1,14 +1,36 @@ #include #include "memory.h" +#include "vm.h" -void* reallocate(void* pointer, size_t oldSize, size_t newSize) { +void *reallocate(void *pointer, size_t oldSize, size_t newSize) { if (newSize == 0) { free(pointer); return NULL; } - void* result = realloc(pointer, newSize); - if (result == NULL) exit(1); + void *result = realloc(pointer, newSize); + if (result == NULL) + exit(1); return result; } + +static void freeObject(Obj *object) { + switch (object->type) { + case OBJ_STRING: { + ObjString *string = (ObjString *)object; + FREE_ARRAY(char, string->chars, string->length + 1); + FREE(ObjString, object); + break; + } + } +} + +void freeObjects() { + Obj *object = vm.objects; + while (object != NULL) { + Obj *next = object->next; + freeObject(object); + object = next; + } +} diff --git a/clox/src/memory.h b/clox/src/memory.h index a810bd7..f7946f6 100644 --- a/clox/src/memory.h +++ b/clox/src/memory.h @@ -2,10 +2,13 @@ #define clox_memory_h #include "common.h" +#include "object.h" #define ALLOCATE(type, count) \ (type *)reallocate(NULL, 0, sizeof(type) * (count)) +#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0) + #define GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity)*2) #define GROW_ARRAY(type, pointer, oldCount, newCount) \ @@ -16,5 +19,6 @@ reallocate(pointer, sizeof(type) * (oldCount), 0) void *reallocate(void *pointer, size_t oldSize, size_t newSize); +void freeObjects(); #endif diff --git a/clox/src/object.c b/clox/src/object.c new file mode 100644 index 0000000..9622327 --- /dev/null +++ b/clox/src/object.c @@ -0,0 +1,45 @@ +#include +#include + +#include "memory.h" +#include "object.h" +#include "value.h" +#include "vm.h" + +#define ALLOCATE_OBJ(type, objectType) \ + (type *)allocateObject(sizeof(type), objectType) + +static Obj *allocateObject(size_t size, ObjType type) { + Obj *object = (Obj *)reallocate(NULL, 0, size); + object->type = type; + + object->next = vm.objects; + vm.objects = object; + return object; +} + +static ObjString *allocateString(char *chars, int length) { + ObjString *string = ALLOCATE_OBJ(ObjString, OBJ_STRING); + string->length = length; + string->chars = chars; + return string; +} + +ObjString *takeString(char *chars, int length) { + return allocateString(chars, length); +} + +ObjString *copyString(const char *chars, int length) { + char *heapChars = ALLOCATE(char, length + 1); + memcpy(heapChars, chars, length); + heapChars[length] = '\0'; + return allocateString(heapChars, length); +} + +void printObject(Value value) { + switch (OBJ_TYPE(value)) { + case OBJ_STRING: + printf("%s", AS_CSTRING(value)); + break; + } +} diff --git a/clox/src/object.h b/clox/src/object.h index a26077f..965b905 100644 --- a/clox/src/object.h +++ b/clox/src/object.h @@ -17,6 +17,7 @@ typedef enum { struct Obj { ObjType type; + struct Obj *next; }; struct ObjString { diff --git a/clox/src/vm.c b/clox/src/vm.c index fae0092..d253d67 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -26,9 +26,12 @@ static void runtimeError(const char *format, ...) { resetStack(); } -void initVM() { resetStack(); } +void initVM() { + resetStack(); + vm.objects = NULL; +} -void freeVM() {} +void freeVM() { freeObjects(); } void push(Value value) { *vm.stackTop = value; diff --git a/clox/src/vm.h b/clox/src/vm.h index a781647..6c6ada8 100644 --- a/clox/src/vm.h +++ b/clox/src/vm.h @@ -11,6 +11,7 @@ typedef struct { uint8_t *ip; Value stack[STACK_MAX]; Value *stackTop; + Obj *objects; } VM; typedef enum { @@ -19,6 +20,8 @@ typedef enum { INTERPRET_RUNTIME_ERROR } InterpretResult; +extern VM vm; + void initVM(); void freeVM(); InterpretResult interpret(const char *source);