Chapter 24.3
This commit is contained in:
parent
a52c55eb9a
commit
ce478b0b80
2 changed files with 41 additions and 26 deletions
|
@ -11,7 +11,10 @@
|
||||||
|
|
||||||
VM vm;
|
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, ...) {
|
static void runtimeError(const char *format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -20,8 +23,9 @@ static void runtimeError(const char *format, ...) {
|
||||||
va_end(args);
|
va_end(args);
|
||||||
fputs("\n", stderr);
|
fputs("\n", stderr);
|
||||||
|
|
||||||
size_t instruction = vm.ip - vm.chunk->code - 1;
|
CallFrame *frame = &vm.frames[vm.frameCount - 1];
|
||||||
int line = vm.chunk->lines[instruction];
|
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);
|
fprintf(stderr, "[line %d] in script\n", line);
|
||||||
resetStack();
|
resetStack();
|
||||||
}
|
}
|
||||||
|
@ -71,9 +75,14 @@ static void concatenate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static InterpretResult run() {
|
static InterpretResult run() {
|
||||||
#define READ_BYTE() (*vm.ip++)
|
CallFrame *frame = &vm.frames[vm.frameCount - 1];
|
||||||
#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
|
|
||||||
#define READ_SHORT() (vm.ip += 2, (uint16_t)((vm.ip[-2] << 8) | vm.ip[-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 READ_STRING() AS_STRING(READ_CONSTANT())
|
||||||
#define BINARY_OP(valueType, op) \
|
#define BINARY_OP(valueType, op) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -94,7 +103,8 @@ static InterpretResult run() {
|
||||||
printf(" ]");
|
printf(" ]");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
disassembleInstruction(vm.chunk, (int)(vm.ip - vm.chunk->code));
|
disassembleInstruction(&frame->function->chunk,
|
||||||
|
(int)(frame->ip - frame->function->chunk.code));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t instruction;
|
uint8_t instruction;
|
||||||
|
@ -118,12 +128,12 @@ static InterpretResult run() {
|
||||||
break;
|
break;
|
||||||
case OP_GET_LOCAL: {
|
case OP_GET_LOCAL: {
|
||||||
uint8_t slot = READ_BYTE();
|
uint8_t slot = READ_BYTE();
|
||||||
push(vm.stack[slot]);
|
push(frame->slots[slot]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_SET_LOCAL: {
|
case OP_SET_LOCAL: {
|
||||||
uint8_t slot = READ_BYTE();
|
uint8_t slot = READ_BYTE();
|
||||||
vm.stack[slot] = peek(0);
|
frame->slots[slot] = peek(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_GET_GLOBAL: {
|
case OP_GET_GLOBAL: {
|
||||||
|
@ -202,18 +212,18 @@ static InterpretResult run() {
|
||||||
}
|
}
|
||||||
case OP_JUMP: {
|
case OP_JUMP: {
|
||||||
uint16_t offset = READ_SHORT();
|
uint16_t offset = READ_SHORT();
|
||||||
vm.ip += offset;
|
frame->ip += offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_JUMP_IF_FALSE: {
|
case OP_JUMP_IF_FALSE: {
|
||||||
uint16_t offset = READ_SHORT();
|
uint16_t offset = READ_SHORT();
|
||||||
if (isFalsey(peek(0)))
|
if (isFalsey(peek(0)))
|
||||||
vm.ip += offset;
|
frame->ip += offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_LOOP: {
|
case OP_LOOP: {
|
||||||
uint16_t offset = READ_SHORT();
|
uint16_t offset = READ_SHORT();
|
||||||
vm.ip -= offset;
|
frame->ip -= offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
|
@ -235,19 +245,15 @@ static InterpretResult run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
InterpretResult interpret(const char *source) {
|
InterpretResult interpret(const char *source) {
|
||||||
Chunk chunk;
|
ObjFunction *function = compile(source);
|
||||||
initChunk(&chunk);
|
if (function != NULL)
|
||||||
|
|
||||||
if (!compile(source, &chunk)) {
|
|
||||||
freeChunk(&chunk);
|
|
||||||
return INTERPRET_COMPILE_ERROR;
|
return INTERPRET_COMPILE_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
vm.chunk = &chunk;
|
push(OBJ_VAL(function));
|
||||||
vm.ip = vm.chunk->code;
|
CallFrame *frame = &vm.frames[vm.frameCount++];
|
||||||
|
frame->function = function;
|
||||||
|
frame->ip = function->chunk.code;
|
||||||
|
frame->slots = vm.stack;
|
||||||
|
|
||||||
InterpretResult result = run();
|
return run();
|
||||||
|
|
||||||
freeChunk(&chunk);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,23 @@
|
||||||
#define clox_vm_h
|
#define clox_vm_h
|
||||||
|
|
||||||
#include "chunk.h"
|
#include "chunk.h"
|
||||||
|
#include "object.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
|
|
||||||
#define STACK_MAX 256
|
#define FRAMES_MAX 64
|
||||||
|
#define STACK_MAX (FRAMES_MAX * UINT8_COUNT)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Chunk *chunk;
|
ObjFunction *function;
|
||||||
uint8_t *ip;
|
uint8_t *ip;
|
||||||
|
Value *slots;
|
||||||
|
} CallFrame;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CallFrame frames[FRAMES_MAX];
|
||||||
|
int frameCount;
|
||||||
|
|
||||||
Value stack[STACK_MAX];
|
Value stack[STACK_MAX];
|
||||||
Value *stackTop;
|
Value *stackTop;
|
||||||
Table globals;
|
Table globals;
|
||||||
|
|
Loading…
Reference in a new issue