Chapter 19.5
This commit is contained in:
parent
d5f352e577
commit
8ec9137561
6 changed files with 83 additions and 5 deletions
|
@ -1,14 +1,36 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "memory.h"
|
#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) {
|
if (newSize == 0) {
|
||||||
free(pointer);
|
free(pointer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* result = realloc(pointer, newSize);
|
void *result = realloc(pointer, newSize);
|
||||||
if (result == NULL) exit(1);
|
if (result == NULL)
|
||||||
|
exit(1);
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,13 @@
|
||||||
#define clox_memory_h
|
#define clox_memory_h
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "object.h"
|
||||||
|
|
||||||
#define ALLOCATE(type, count) \
|
#define ALLOCATE(type, count) \
|
||||||
(type *)reallocate(NULL, 0, sizeof(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_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity)*2)
|
||||||
|
|
||||||
#define GROW_ARRAY(type, pointer, oldCount, newCount) \
|
#define GROW_ARRAY(type, pointer, oldCount, newCount) \
|
||||||
|
@ -16,5 +19,6 @@
|
||||||
reallocate(pointer, sizeof(type) * (oldCount), 0)
|
reallocate(pointer, sizeof(type) * (oldCount), 0)
|
||||||
|
|
||||||
void *reallocate(void *pointer, size_t oldSize, size_t newSize);
|
void *reallocate(void *pointer, size_t oldSize, size_t newSize);
|
||||||
|
void freeObjects();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
45
clox/src/object.c
Normal file
45
clox/src/object.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ typedef enum {
|
||||||
|
|
||||||
struct Obj {
|
struct Obj {
|
||||||
ObjType type;
|
ObjType type;
|
||||||
|
struct Obj *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjString {
|
struct ObjString {
|
||||||
|
|
|
@ -26,9 +26,12 @@ static void runtimeError(const char *format, ...) {
|
||||||
resetStack();
|
resetStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initVM() { resetStack(); }
|
void initVM() {
|
||||||
|
resetStack();
|
||||||
|
vm.objects = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void freeVM() {}
|
void freeVM() { freeObjects(); }
|
||||||
|
|
||||||
void push(Value value) {
|
void push(Value value) {
|
||||||
*vm.stackTop = value;
|
*vm.stackTop = value;
|
||||||
|
|
|
@ -11,6 +11,7 @@ typedef struct {
|
||||||
uint8_t *ip;
|
uint8_t *ip;
|
||||||
Value stack[STACK_MAX];
|
Value stack[STACK_MAX];
|
||||||
Value *stackTop;
|
Value *stackTop;
|
||||||
|
Obj *objects;
|
||||||
} VM;
|
} VM;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -19,6 +20,8 @@ typedef enum {
|
||||||
INTERPRET_RUNTIME_ERROR
|
INTERPRET_RUNTIME_ERROR
|
||||||
} InterpretResult;
|
} InterpretResult;
|
||||||
|
|
||||||
|
extern VM vm;
|
||||||
|
|
||||||
void initVM();
|
void initVM();
|
||||||
void freeVM();
|
void freeVM();
|
||||||
InterpretResult interpret(const char *source);
|
InterpretResult interpret(const char *source);
|
||||||
|
|
Loading…
Reference in a new issue