diff --git a/src/' b/src/' new file mode 100644 index 0000000..4780c8e --- /dev/null +++ b/src/' @@ -0,0 +1,47 @@ +#include "common.h" +#include "vm.h" + +VM vm; + +void newVM() { + +} + +void freeVM() { + +} + +static InterpretResult run() { +#define READ_BYTE() (*vm.ip++) +#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()]) + + for (;;) { +#ifdef DEBUG_TRACE_EXECUTION + disassembleInstruction(vm.chunk, + (int)(vm.ip - vm.chunk->code)); +#endif + + uint8_t instruction; + switch (instruction = READ_BYTE()) { + case OP_CONSTANT: { + Value constant = READ_CONSTANT(); + printValue(constant); + printf("\n"); + break; + } + case OP_RETURN: { + return INTERPRET_OK; + } + } + } + +#undef READ_BYTE +#undef READ_CONSTANT +} + +InterpretResult interpret(Chunk* chunk) { + vm.chunk = chunk; + vm.ip = vm.chunk->code; + return run(); +} + diff --git a/src/common.h b/src/common.h index 845c554..e5224fd 100644 --- a/src/common.h +++ b/src/common.h @@ -5,4 +5,6 @@ #include #include +#define DEBUG_TRACE_EXECUTION + #endif diff --git a/src/main.c b/src/main.c index 7765e3e..5a93d46 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,11 @@ #include "common.h" #include "chunk.h" #include "debug.h" +#include "vm.h" int main(int argc, const char** argv) { + newVM(); + Chunk chunk; newChunk(&chunk); @@ -13,6 +16,7 @@ int main(int argc, const char** argv) { writeChunk(&chunk, OP_RETURN, 1); disassembleChunk(&chunk, "test chunk"); + freeVM(); freeChunk(&chunk); return 0; } diff --git a/src/vm.c b/src/vm.c new file mode 100644 index 0000000..235e8c6 --- /dev/null +++ b/src/vm.c @@ -0,0 +1,72 @@ +#include "common.h" +#include "debug.h" +#include "vm.h" + +#include + +VM vm; + +static void resetStack() { + vm.stackTop = vm.stack; +} + +void newVM() { + resetStack(); +} + +void freeVM() { + +} + +void push(Value value) { + *vm.stackTop = value; + vm.stackTop++; +} + +Value pop() { + vm.stackTop--; + return *vm.stackTop; +} + +static InterpretResult run() { +#define READ_BYTE() (*vm.ip++) +#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()]) + + for (;;) { +#ifdef DEBUG_TRACE_EXECUTION + printf(" "); + for (Value* slot = vm.stack; slot < vm.stackTop; slot++) { + printf("[ "); + printValue(*slot); + printf(" ]"); + } + printf("\n"); + disassembleInstruction(vm.chunk, + (int)(vm.ip - vm.chunk->code)); +#endif + + uint8_t instruction; + switch (instruction = READ_BYTE()) { + case OP_CONSTANT: { + Value constant = READ_CONSTANT(); + push(constant); + break; + } + case OP_RETURN: { + printValue(pop()); + printf("\n"); + return INTERPRET_OK; + } + } + } + +#undef READ_BYTE +#undef READ_CONSTANT +} + +InterpretResult interpret(Chunk* chunk) { + vm.chunk = chunk; + vm.ip = vm.chunk->code; + return run(); +} + diff --git a/src/vm.h b/src/vm.h new file mode 100644 index 0000000..aeec3f2 --- /dev/null +++ b/src/vm.h @@ -0,0 +1,29 @@ +#ifndef ztl_vm_h +#define ztl_vm_h + +#include "chunk.h" +#include "value.h" + +#define STACK_MAX 256 + +typedef struct { + Chunk *chunk; + uint8_t *ip; + Value stack[STACK_MAX]; + Value *stackTop; +} VM; + +typedef enum { + INTERPRET_OK, + INTERPRET_COMPILE_ERROR, + INTERPRET_RUNTIME_ERROR +} InterpretResult; + +void newVM(); +void freeVM(); +InterpretResult interpret(Chunk *chunk); +void push(Value value); +Value pop(); + +#endif +