diff options
Diffstat (limited to 'clox/src/vm.c')
-rw-r--r-- | clox/src/vm.c | 78 |
1 files changed, 64 insertions, 14 deletions
diff --git a/clox/src/vm.c b/clox/src/vm.c index 7dd79a3..0d8d638 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -23,10 +23,18 @@ static void runtimeError(const char *format, ...) { va_end(args); fputs("\n", stderr); - CallFrame *frame = &vm.frames[vm.frameCount - 1]; - size_t instruction = frame->ip - frame->function->chunk.code - 1; - int line = frame->function->chunk.lines[instruction]; - fprintf(stderr, "[line %d] in script\n", line); + for (int i = vm.frameCount; i >= 0; i--) { + CallFrame *frame = &vm.frames[i]; + ObjFunction *function = frame->function; + size_t instruction = frame->ip - function->chunk.code - 1; + fprintf(stderr, "[line %d] in ", function->chunk.lines[instruction]); + if (function->name == NULL) { + fprintf(stderr, "script\n"); + } else { + fprintf(stderr, "%s()\n", function->name->chars); + } + } + resetStack(); } @@ -56,6 +64,38 @@ Value pop() { static Value peek(int distance) { return vm.stackTop[-1 - distance]; } +static bool call(ObjFunction *function, int argCount) { + if (argCount != function->arity) { + runtimeError("Expected %d argumetns but got %d.", function->arity, + argCount); + return false; + } + + if (vm.frameCount == FRAMES_MAX) { + runtimeError("Stack overflow."); + return false; + } + + CallFrame *frame = &vm.frames[vm.frameCount++]; + frame->function = function; + frame->ip = function->chunk.code; + frame->slots = vm.stackTop - argCount - 1; + return true; +} + +static bool callValue(Value callee, int argCount) { + if (IS_OBJ(callee)) { + switch (OBJ_TYPE(callee)) { + case OBJ_FUNCTION: + return call(AS_FUNCTION(callee), argCount); + default: + break; + } + } + runtimeError("Can only call functions && classes."); + return false; +} + static bool isFalsey(Value value) { return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value)); } @@ -226,13 +266,26 @@ static InterpretResult run() { frame->ip -= offset; break; } + case OP_CALL: { + int argCount = READ_BYTE(); + if (!callValue(peek(argCount), argCount)) { + return INTERPRET_RUNTIME_ERROR; + } + frame = &vm.frames[vm.frameCount - 1]; + break; + } case OP_RETURN: { - /* The book said to remove this, but when I do I get an infinite loop and - then a segfault because it keeps trying to add the constant 1 to the - stack. */ - printValue(pop()); - printf("\n"); - return INTERPRET_OK; + Value result = pop(); + vm.frameCount--; + if (vm.frameCount == 0) { + pop(); + return INTERPRET_OK; + } + + vm.stackTop = frame->slots; + push(result); + frame = &vm.frames[vm.frameCount - 1]; + break; } } } @@ -250,10 +303,7 @@ InterpretResult interpret(const char *source) { return INTERPRET_COMPILE_ERROR; push(OBJ_VAL(function)); - CallFrame *frame = &vm.frames[vm.frameCount++]; - frame->function = function; - frame->ip = function->chunk.code; - frame->slots = vm.stack; + call(function, 0); return run(); } |