diff options
Diffstat (limited to 'clox/src/vm.c')
-rw-r--r-- | clox/src/vm.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/clox/src/vm.c b/clox/src/vm.c index fb359c2..4b0fe48 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -108,6 +108,10 @@ static bool call(ObjClosure *closure, int argCount) { static bool callValue(Value callee, int argCount) { if (IS_OBJ(callee)) { switch (OBJ_TYPE(callee)) { + case OBJ_BOUND_METHOD: { + ObjBoundMethod *bound = AS_BOUND_METHOD(callee); + return call(bound->method, argCount); + } case OBJ_CLASS: { ObjClass *klass = AS_CLASS(callee); vm.stackTop[-argCount - 1] = OBJ_VAL(newInstance(klass)); @@ -130,6 +134,19 @@ static bool callValue(Value callee, int argCount) { return false; } +static bool bindMethod(ObjClass *klass, ObjString *name) { + Value method; + if (!tableGet(&klass->methods, name, &method)) { + runtimeError("Undefined property '%s'.", name->chars); + return false; + } + + ObjBoundMethod *bound = newBoundMethod(peek(0), AS_CLOSURE(method)); + pop(); + push(OBJ_VAL(bound)); + return true; +} + static ObjUpvalue *captureUpvalue(Value *local) { ObjUpvalue *prevUpvalue = NULL; ObjUpvalue *upvalue = vm.openUpvalues; @@ -305,8 +322,10 @@ static InterpretResult run() { break; } - runtimeError("Undefined property '%s'.", name->chars); - return INTERPRET_RUNTIME_ERROR; + if (!bindMethod(instance->klass, name)) { + return INTERPRET_RUNTIME_ERROR; + } + break; } case OP_SET_PROPERTY: { if (!IS_INSTANCE(peek(1))) { |