aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2022-01-23 15:58:35 -0800
committerGravatar Tom Willemse2022-01-23 15:58:35 -0800
commitce478b0b80af331b89813148df7b04d46968e328 (patch)
tree4662f97216d2b38d8aef71807242812b2d24bfeb
parenta52c55eb9af3e29a912d41a48071e830b0971fd5 (diff)
downloadcrafting-interpreters-ce478b0b80af331b89813148df7b04d46968e328.tar.gz
crafting-interpreters-ce478b0b80af331b89813148df7b04d46968e328.zip
Chapter 24.3
-rw-r--r--clox/src/vm.c54
-rw-r--r--clox/src/vm.h13
2 files changed, 41 insertions, 26 deletions
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;
- InterpretResult result = run();
+ push(OBJ_VAL(function));
+ CallFrame *frame = &vm.frames[vm.frameCount++];
+ frame->function = function;
+ frame->ip = function->chunk.code;
+ frame->slots = vm.stack;
- 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;