From 62858b60e43803477e898c7993e109a94701ce70 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Sun, 14 Aug 2022 19:56:32 -0700 Subject: Chapter 28.5 --- clox/src/vm.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'clox/src/vm.c') diff --git a/clox/src/vm.c b/clox/src/vm.c index d248609..b5cb1cc 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -146,6 +146,33 @@ static bool callValue(Value callee, int argCount) { return false; } +static bool invokeFromClass(ObjClass *klass, ObjString *name, int argCount) { + Value method; + if (!tableGet(&klass->methods, name, &method)) { + runtimeError("Undefined property '%s'.", name->chars); + return false; + } + return call(AS_CLOSURE(method), argCount); +} + +static bool invoke(ObjString *name, int argCount) { + Value receiver = peek(argCount); + + if (!IS_INSTANCE(receiver)) { + runtimeError("Only instances have methods."); + return false; + } + + ObjInstance *instance = AS_INSTANCE(receiver); + + Value value; + if (tableGet(&instance->fields, name, &value)) { + vm.stackTop[-argCount - 1] = value; + return callValue(value, argCount); + } + return invokeFromClass(instance->klass, name, argCount); +} + static bool bindMethod(ObjClass *klass, ObjString *name) { Value method; if (!tableGet(&klass->methods, name, &method)) { @@ -424,6 +451,15 @@ static InterpretResult run() { frame = &vm.frames[vm.frameCount - 1]; break; } + case OP_INVOKE: { + ObjString *method = READ_STRING(); + int argCount = READ_BYTE(); + if (!invoke(method, argCount)) { + return INTERPRET_RUNTIME_ERROR; + } + frame = &vm.frames[vm.frameCount - 1]; + break; + } case OP_CLOSURE: { ObjFunction *function = AS_FUNCTION(READ_CONSTANT()); ObjClosure *closure = newClosure(function); -- cgit v1.2.3-54-g00ecf