From d9474f1d7c0c6674179fd0f27cd1c084c8227ed5 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 22 Oct 2021 12:05:41 +0200 Subject: Add interpretation function for VM --- src/bytecode/errors.c | 2 ++ src/bytecode/errors.h | 5 +++++ src/bytecode/main.c | 13 ++++++++++--- src/bytecode/vm.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) (limited to 'src/bytecode') diff --git a/src/bytecode/errors.c b/src/bytecode/errors.c index d957cfa..c2ab77f 100644 --- a/src/bytecode/errors.c +++ b/src/bytecode/errors.c @@ -15,6 +15,8 @@ static const char* error_msgs[] = { [ERR_TOO_MANY_ARGS] = "error: too many arguments", [ERR_WRONG_ARG_TYPE] = "error: wrong argument type", [ERR_DIVISION_BY_ZERO] = "error: division by zero", + [ERR_PC_OOB] = "error: pc out of bounds", + [ERR_EMPTY_CHUNK] = "error: empty chunk", }; static Error errors[ERR_MAX_NUMBER]; diff --git a/src/bytecode/errors.h b/src/bytecode/errors.h index 7916f4a..c54d1f4 100644 --- a/src/bytecode/errors.h +++ b/src/bytecode/errors.h @@ -2,6 +2,7 @@ #define BDL_ERRORS_H typedef enum ErrorType { + ERR_TYPE_OK, ERR_TYPE_LEXER, ERR_TYPE_PARSER, ERR_TYPE_RUNTIME, @@ -22,6 +23,10 @@ typedef enum ErrorValue { ERR_TOO_MANY_ARGS, ERR_WRONG_ARG_TYPE, ERR_DIVISION_BY_ZERO, + + // Bytecode interpreter. + ERR_PC_OOB, + ERR_EMPTY_CHUNK, } ErrorValue; typedef struct Error { diff --git a/src/bytecode/main.c b/src/bytecode/main.c index ca1f441..9a81aaa 100644 --- a/src/bytecode/main.c +++ b/src/bytecode/main.c @@ -4,8 +4,13 @@ #include #include -#include "vm.h" +// +// Config. +// + +// #define DEBUG_TRACE_EXECUTION +#include "vm.h" #include "ops.h" #include "debug.h" #include "errors.c" @@ -39,8 +44,10 @@ process_source(const StringView *source) { add_code(vm.chunk, const_idx, 1, 1); add_code(vm.chunk, OP_RETURN, 1, 1); - // Disassemble the chunk. - disassemble_chunk(vm.chunk, "test chunk"); + vm_interpret(vm); + if (errors_n != 0) { + disassemble_chunk(vm.chunk, "test chunk"); + } array_free(tokens); } diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 36547cb..d53fcf9 100644 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h @@ -2,14 +2,19 @@ #define BDL_VM_H #include "types.h" +#include "errors.h" #include "chunk.h" +#include "ops.h" +#include "debug.h" typedef struct VM { Chunk *chunk; + u8 *pc; } VM; VM vm_init(void); void vm_free(VM vm); +void vm_interpret(VM vm); VM vm_init(void) { @@ -24,4 +29,51 @@ vm_free(VM vm) { chunk_free(vm.chunk); } +void +vm_interpret(VM vm) { + if (vm.chunk->code == NULL || array_size(vm.chunk->code) == 0) { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_EMPTY_CHUNK, + }); + return; + } + + vm.pc = vm.chunk->code; + u8 *last = vm.chunk->code + array_size(vm.chunk->code); + while (vm.pc < last) { +#ifdef DEBUG_TRACE_EXECUTION + disassemble_instruction(vm.chunk, (vm.pc - vm.chunk->code)); +#endif + u8 instruction = *vm.pc++; + switch (instruction) { + case OP_CONSTANT: { + u8 constant = *vm.pc++; + Object obj = vm.chunk->constants[constant]; + display(obj); + printf("\n"); + } break; + case OP_RETURN: { + return; + } break; + default: { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_NOT_IMPLEMENTED, + .line = vm.chunk->lines[0].line, + .col = vm.chunk->lines[0].col, + }); + return; + } break; + } + } + + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_PC_OOB, + .line = vm.chunk->lines[0].line, + .col = vm.chunk->lines[0].col, + }); +} + #endif // BDL_VM_H -- cgit v1.2.1