From 9ce9a7f510e6ba407c2e14d3eae4d603b38edde7 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 22 Oct 2021 13:58:02 +0200 Subject: Prepare compilation pipeline --- src/bytecode/compiler.h | 34 ++++++++++++++++++++++++++++++++++ src/bytecode/main.c | 30 +++++++++++++----------------- src/bytecode/vm.h | 35 ++++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 32 deletions(-) create mode 100644 src/bytecode/compiler.h (limited to 'src/bytecode') diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h new file mode 100644 index 0000000..283d7a6 --- /dev/null +++ b/src/bytecode/compiler.h @@ -0,0 +1,34 @@ +#ifndef BDL_COMPILER_H +#define BDL_COMPILER_H + +#include "chunk.h" +#include "lexer.h" + +typedef struct Visitor { + Token *tokens; + size_t current; +} Visitor; + +// Mimics the functionality in the Scanner functions, but for entire tokens. +Token next_token(Visitor *visitor); +Token peek_token(const Visitor *visitor); +bool has_next_token(const Visitor *visitor); + +Chunk * compile(Token *tokens); + +Chunk * +compile(Token *tokens) { + Chunk *chunk = NULL; + chunk = chunk_init(); + size_t const_a = add_constant(chunk, 7); + add_code(chunk, OP_CONSTANT, 1, 1); + add_code(chunk, const_a, 1, 1); + size_t const_b = add_constant(chunk, 2); + add_code(chunk, OP_CONSTANT, 1, 2); + add_code(chunk, const_b, 1, 2); + add_code(chunk, OP_MOD, 1, 3); + add_code(chunk, OP_RETURN, 1, 1); + return chunk; +} + +#endif // BDL_COMPILER_H diff --git a/src/bytecode/main.c b/src/bytecode/main.c index 5661747..d6cb5d3 100644 --- a/src/bytecode/main.c +++ b/src/bytecode/main.c @@ -11,6 +11,7 @@ #define DEBUG_TRACE_EXECUTION #include "vm.h" +#include "compiler.h" #include "ops.h" #include "debug.h" #include "errors.c" @@ -22,43 +23,38 @@ static VM vm; void init(void) { - vm = vm_init(); + vm_init(&vm); } void halt(void) { - vm_free(vm); + vm_free(&vm); } void process_source(const StringView *source) { + // Read tokens. Token *tokens = tokenize(source); if (errors_n != 0) { array_free(tokens); return; } - for (size_t i = 0; i < array_size(tokens); i++) { - print_token(tokens[i]); + // Compile chunk. + Chunk *chunk = compile(tokens); + if (errors_n != 0) { + chunk_free(chunk); + array_free(tokens); + return; } - size_t const_a = add_constant(vm.chunk, 7); - add_code(vm.chunk, OP_CONSTANT, 1, 1); - add_code(vm.chunk, const_a, 1, 1); - size_t const_b = add_constant(vm.chunk, 2); - add_code(vm.chunk, OP_CONSTANT, 1, 2); - add_code(vm.chunk, const_b, 1, 2); - - // Arithmetic. - add_code(vm.chunk, OP_MOD, 1, 3); - - add_code(vm.chunk, OP_RETURN, 1, 1); - - vm_interpret(vm); + // Interpret chunk. + vm_interpret(vm, chunk); if (errors_n != 0) { disassemble_chunk(vm.chunk, "test chunk"); } + chunk_free(chunk); array_free(tokens); } diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 6c5dfa7..f9e64d1 100644 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h @@ -18,27 +18,33 @@ typedef struct VM { Object *stack; } VM; -VM vm_init(void); -void vm_free(VM vm); -void vm_interpret(VM vm); +void vm_init(VM *vm); +void vm_free(VM *vm); +void vm_reset(VM *vm); +void vm_interpret(VM vm, Chunk *chunk); -VM -vm_init(void) { - VM vm = { - .chunk = chunk_init(), - }; - array_init(vm.stack, VM_STACK_CAP); - return vm; +void +vm_init(VM *vm) { + *vm = (VM){0}; + array_init(vm->stack, VM_STACK_CAP); +} + +void +vm_free(VM *vm) { + array_free(vm->stack); } void -vm_free(VM vm) { - chunk_free(vm.chunk); - array_free(vm.stack); +vm_reset(VM *vm) { + vm_free(vm); + vm_init(vm); } void -vm_interpret(VM vm) { +vm_interpret(VM vm, Chunk *chunk) { + vm.chunk = chunk; + vm.pc = vm.chunk->code; + if (vm.chunk->code == NULL || array_size(vm.chunk->code) == 0) { error_push((Error){ .type = ERR_TYPE_RUNTIME, @@ -47,7 +53,6 @@ vm_interpret(VM vm) { return; } - vm.pc = vm.chunk->code; u8 *last = vm.chunk->code + array_size(vm.chunk->code); while (vm.pc < last) { #ifdef DEBUG_TRACE_EXECUTION -- cgit v1.2.1