diff --git a/clox/src/vm.c b/clox/src/vm.c index c1c6941..7dd79a3 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -11,7 +11,10 @@ VM vm; -static void resetStack() { vm.stackTop = vm.stack; } +static void resetStack() { + vm.stackTop = vm.stack; + vm.frameCount = 0; +} static void runtimeError(const char *format, ...) { va_list args; @@ -20,8 +23,9 @@ static void runtimeError(const char *format, ...) { va_end(args); fputs("\n", stderr); - size_t instruction = vm.ip - vm.chunk->code - 1; - int line = vm.chunk->lines[instruction]; + 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); resetStack(); } @@ -71,9 +75,14 @@ static void concatenate() { } static InterpretResult run() { -#define READ_BYTE() (*vm.ip++) -#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()]) -#define READ_SHORT() (vm.ip += 2, (uint16_t)((vm.ip[-2] << 8) | vm.ip[-1])) + CallFrame *frame = &vm.frames[vm.frameCount - 1]; + +#define READ_BYTE() (*frame->ip++) + +#define READ_SHORT() \ + (frame->ip += 2, (uint16_t)((frame->ip[-2] << 8) | frame->ip[-1])) + +#define READ_CONSTANT() (frame->function->chunk.constants.values[READ_BYTE()]) #define READ_STRING() AS_STRING(READ_CONSTANT()) #define BINARY_OP(valueType, op) \ do { \ @@ -94,7 +103,8 @@ static InterpretResult run() { printf(" ]"); } printf("\n"); - disassembleInstruction(vm.chunk, (int)(vm.ip - vm.chunk->code)); + disassembleInstruction(&frame->function->chunk, + (int)(frame->ip - frame->function->chunk.code)); #endif uint8_t instruction; @@ -118,12 +128,12 @@ static InterpretResult run() { break; case OP_GET_LOCAL: { uint8_t slot = READ_BYTE(); - push(vm.stack[slot]); + push(frame->slots[slot]); break; } case OP_SET_LOCAL: { uint8_t slot = READ_BYTE(); - vm.stack[slot] = peek(0); + frame->slots[slot] = peek(0); break; } case OP_GET_GLOBAL: { @@ -202,18 +212,18 @@ static InterpretResult run() { } case OP_JUMP: { uint16_t offset = READ_SHORT(); - vm.ip += offset; + frame->ip += offset; break; } case OP_JUMP_IF_FALSE: { uint16_t offset = READ_SHORT(); if (isFalsey(peek(0))) - vm.ip += offset; + frame->ip += offset; break; } case OP_LOOP: { uint16_t offset = READ_SHORT(); - vm.ip -= offset; + frame->ip -= offset; break; } case OP_RETURN: { @@ -235,19 +245,15 @@ static InterpretResult run() { } InterpretResult interpret(const char *source) { - Chunk chunk; - initChunk(&chunk); - - if (!compile(source, &chunk)) { - freeChunk(&chunk); + ObjFunction *function = compile(source); + if (function != NULL) return INTERPRET_COMPILE_ERROR; - } - vm.chunk = &chunk; - vm.ip = vm.chunk->code; + push(OBJ_VAL(function)); + CallFrame *frame = &vm.frames[vm.frameCount++]; + frame->function = function; + frame->ip = function->chunk.code; + frame->slots = vm.stack; - InterpretResult result = run(); - - freeChunk(&chunk); - return result; + return run(); } diff --git a/clox/src/vm.h b/clox/src/vm.h index 0ab269b..170166b 100644 --- a/clox/src/vm.h +++ b/clox/src/vm.h @@ -2,14 +2,23 @@ #define clox_vm_h #include "chunk.h" +#include "object.h" #include "table.h" #include "value.h" -#define STACK_MAX 256 +#define FRAMES_MAX 64 +#define STACK_MAX (FRAMES_MAX * UINT8_COUNT) typedef struct { - Chunk *chunk; + ObjFunction *function; uint8_t *ip; + Value *slots; +} CallFrame; + +typedef struct { + CallFrame frames[FRAMES_MAX]; + int frameCount; + Value stack[STACK_MAX]; Value *stackTop; Table globals;