From f4185577e56a893b9375bc94d71bef5f9eb51891 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Fri, 12 Aug 2022 23:18:02 -0700 Subject: [PATCH] Chapter 27.3 --- clox/src/memory.c | 12 ++++++++++++ clox/src/object.c | 10 ++++++++++ clox/src/object.h | 11 +++++++++++ clox/src/vm.c | 5 +++++ 4 files changed, 38 insertions(+) diff --git a/clox/src/memory.c b/clox/src/memory.c index 677feed..8c32386 100644 --- a/clox/src/memory.c +++ b/clox/src/memory.c @@ -95,6 +95,12 @@ static void blackenObject(Obj *object) { markArray(&function->chunk.constants); break; } + case OBJ_INSTANCE: { + ObjInstance *instance = (ObjInstance *)object; + markObject((Obj *)instance->klass); + markTable(&instance->fields); + break; + } case OBJ_UPVALUE: markValue(((ObjUpvalue *)object)->closed); break; @@ -126,6 +132,12 @@ static void freeObject(Obj *object) { FREE(ObjFunction, object); break; } + case OBJ_INSTANCE: { + ObjInstance *instance = (ObjInstance *)object; + freeTable(&instance->fields); + FREE(ObjInstance, object); + break; + } case OBJ_NATIVE: FREE(ObjNative, object); break; diff --git a/clox/src/object.c b/clox/src/object.c index 935a258..a431314 100644 --- a/clox/src/object.c +++ b/clox/src/object.c @@ -53,6 +53,13 @@ ObjFunction *newFunction() { return function; } +ObjInstance *newInstance(ObjClass *klass) { + ObjInstance *instance = ALLOCATE_OBJ(ObjInstance, OBJ_INSTANCE); + instance->klass = klass; + initTable(&instance->fields); + return instance; +} + ObjNative *newNative(NativeFn function) { ObjNative *native = ALLOCATE_OBJ(ObjNative, OBJ_NATIVE); native->function = function; @@ -131,6 +138,9 @@ void printObject(Value value) { case OBJ_FUNCTION: printFunction(AS_FUNCTION(value)); break; + case OBJ_INSTANCE: + printf("%s instance", AS_INSTANCE(value)->klass->name->chars); + break; case OBJ_NATIVE: printf(""); break; diff --git a/clox/src/object.h b/clox/src/object.h index 44de6ed..1cef631 100644 --- a/clox/src/object.h +++ b/clox/src/object.h @@ -3,6 +3,7 @@ #include "chunk.h" #include "common.h" +#include "table.h" #include "value.h" #define OBJ_TYPE(value) (AS_OBJ(value)->type) @@ -10,12 +11,14 @@ #define IS_CLASS(value) isObjType(value, OBJ_CLASS) #define IS_CLOSURE(value) isObjType(value, OBJ_CLOSURE) #define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION) +#define IS_INSTANCE(value) isObjType(value, OBJ_INSTANCE) #define IS_NATIVE(value) isObjType(value, OBJ_NATIVE) #define IS_STRING(value) isObjType(value, OBJ_STRING) #define AS_CLASS(value) ((ObjClass *)AS_OBJ(value)) #define AS_CLOSURE(value) ((ObjClosure *)AS_OBJ(value)) #define AS_FUNCTION(value) ((ObjFunction *)AS_OBJ(value)) +#define AS_INSTANCE(value) ((ObjInstance *)AS_OBJ(value)) #define AS_NATIVE(value) (((ObjNative *)AS_OBJ(value))->function) #define AS_STRING(value) ((ObjString *)AS_OBJ(value)) #define AS_CSTRING(value) (((ObjString *)AS_OBJ(value))->chars) @@ -24,6 +27,7 @@ typedef enum { OBJ_CLASS, OBJ_CLOSURE, OBJ_FUNCTION, + OBJ_INSTANCE, OBJ_NATIVE, OBJ_STRING, OBJ_UPVALUE, @@ -76,9 +80,16 @@ typedef struct { ObjString *name; } ObjClass; +typedef struct { + Obj obj; + ObjClass *klass; + Table fields; +} ObjInstance; + ObjClass *newClass(ObjString *name); ObjClosure *newClosure(ObjFunction *function); ObjFunction *newFunction(); +ObjInstance *newInstance(ObjClass *klass); ObjNative *newNative(NativeFn function); ObjString *takeString(char *chars, int length); ObjString *copyString(const char *chars, int length); diff --git a/clox/src/vm.c b/clox/src/vm.c index eab8c47..c1f0b90 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -108,6 +108,11 @@ static bool call(ObjClosure *closure, int argCount) { static bool callValue(Value callee, int argCount) { if (IS_OBJ(callee)) { switch (OBJ_TYPE(callee)) { + case OBJ_CLASS: { + ObjClass *klass = AS_CLASS(callee); + vm.stackTop[-argCount - 1] = OBJ_VAL(newInstance(klass)); + return true; + } case OBJ_CLOSURE: return call(AS_CLOSURE(callee), argCount); case OBJ_NATIVE: {