aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'clox/src/vm.c')
-rw-r--r--clox/src/vm.c78
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();
}