aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-22 13:58:02 +0200
committerBad Diode <bd@badd10de.dev>2021-10-22 13:58:02 +0200
commit9ce9a7f510e6ba407c2e14d3eae4d603b38edde7 (patch)
treeaaca7e34058761ae4d4f58e7567f126c5dc9a3a5 /src/bytecode
parent6fd244cb04cf1972e9d7dcc5635bf5cfe8194402 (diff)
downloadbdl-9ce9a7f510e6ba407c2e14d3eae4d603b38edde7.tar.gz
bdl-9ce9a7f510e6ba407c2e14d3eae4d603b38edde7.zip
Prepare compilation pipeline
Diffstat (limited to 'src/bytecode')
-rw-r--r--src/bytecode/compiler.h34
-rw-r--r--src/bytecode/main.c30
-rw-r--r--src/bytecode/vm.h35
3 files changed, 67 insertions, 32 deletions
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 @@
1#ifndef BDL_COMPILER_H
2#define BDL_COMPILER_H
3
4#include "chunk.h"
5#include "lexer.h"
6
7typedef struct Visitor {
8 Token *tokens;
9 size_t current;
10} Visitor;
11
12// Mimics the functionality in the Scanner functions, but for entire tokens.
13Token next_token(Visitor *visitor);
14Token peek_token(const Visitor *visitor);
15bool has_next_token(const Visitor *visitor);
16
17Chunk * compile(Token *tokens);
18
19Chunk *
20compile(Token *tokens) {
21 Chunk *chunk = NULL;
22 chunk = chunk_init();
23 size_t const_a = add_constant(chunk, 7);
24 add_code(chunk, OP_CONSTANT, 1, 1);
25 add_code(chunk, const_a, 1, 1);
26 size_t const_b = add_constant(chunk, 2);
27 add_code(chunk, OP_CONSTANT, 1, 2);
28 add_code(chunk, const_b, 1, 2);
29 add_code(chunk, OP_MOD, 1, 3);
30 add_code(chunk, OP_RETURN, 1, 1);
31 return chunk;
32}
33
34#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 @@
11#define DEBUG_TRACE_EXECUTION 11#define DEBUG_TRACE_EXECUTION
12 12
13#include "vm.h" 13#include "vm.h"
14#include "compiler.h"
14#include "ops.h" 15#include "ops.h"
15#include "debug.h" 16#include "debug.h"
16#include "errors.c" 17#include "errors.c"
@@ -22,43 +23,38 @@ static VM vm;
22 23
23void 24void
24init(void) { 25init(void) {
25 vm = vm_init(); 26 vm_init(&vm);
26} 27}
27 28
28void 29void
29halt(void) { 30halt(void) {
30 vm_free(vm); 31 vm_free(&vm);
31} 32}
32 33
33void 34void
34process_source(const StringView *source) { 35process_source(const StringView *source) {
36 // Read tokens.
35 Token *tokens = tokenize(source); 37 Token *tokens = tokenize(source);
36 if (errors_n != 0) { 38 if (errors_n != 0) {
37 array_free(tokens); 39 array_free(tokens);
38 return; 40 return;
39 } 41 }
40 42
41 for (size_t i = 0; i < array_size(tokens); i++) { 43 // Compile chunk.
42 print_token(tokens[i]); 44 Chunk *chunk = compile(tokens);
45 if (errors_n != 0) {
46 chunk_free(chunk);
47 array_free(tokens);
48 return;
43 } 49 }
44 50
45 size_t const_a = add_constant(vm.chunk, 7); 51 // Interpret chunk.
46 add_code(vm.chunk, OP_CONSTANT, 1, 1); 52 vm_interpret(vm, chunk);
47 add_code(vm.chunk, const_a, 1, 1);
48 size_t const_b = add_constant(vm.chunk, 2);
49 add_code(vm.chunk, OP_CONSTANT, 1, 2);
50 add_code(vm.chunk, const_b, 1, 2);
51
52 // Arithmetic.
53 add_code(vm.chunk, OP_MOD, 1, 3);
54
55 add_code(vm.chunk, OP_RETURN, 1, 1);
56
57 vm_interpret(vm);
58 if (errors_n != 0) { 53 if (errors_n != 0) {
59 disassemble_chunk(vm.chunk, "test chunk"); 54 disassemble_chunk(vm.chunk, "test chunk");
60 } 55 }
61 56
57 chunk_free(chunk);
62 array_free(tokens); 58 array_free(tokens);
63} 59}
64 60
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 {
18 Object *stack; 18 Object *stack;
19} VM; 19} VM;
20 20
21VM vm_init(void); 21void vm_init(VM *vm);
22void vm_free(VM vm); 22void vm_free(VM *vm);
23void vm_interpret(VM vm); 23void vm_reset(VM *vm);
24void vm_interpret(VM vm, Chunk *chunk);
24 25
25VM 26void
26vm_init(void) { 27vm_init(VM *vm) {
27 VM vm = { 28 *vm = (VM){0};
28 .chunk = chunk_init(), 29 array_init(vm->stack, VM_STACK_CAP);
29 }; 30}
30 array_init(vm.stack, VM_STACK_CAP); 31
31 return vm; 32void
33vm_free(VM *vm) {
34 array_free(vm->stack);
32} 35}
33 36
34void 37void
35vm_free(VM vm) { 38vm_reset(VM *vm) {
36 chunk_free(vm.chunk); 39 vm_free(vm);
37 array_free(vm.stack); 40 vm_init(vm);
38} 41}
39 42
40void 43void
41vm_interpret(VM vm) { 44vm_interpret(VM vm, Chunk *chunk) {
45 vm.chunk = chunk;
46 vm.pc = vm.chunk->code;
47
42 if (vm.chunk->code == NULL || array_size(vm.chunk->code) == 0) { 48 if (vm.chunk->code == NULL || array_size(vm.chunk->code) == 0) {
43 error_push((Error){ 49 error_push((Error){
44 .type = ERR_TYPE_RUNTIME, 50 .type = ERR_TYPE_RUNTIME,
@@ -47,7 +53,6 @@ vm_interpret(VM vm) {
47 return; 53 return;
48 } 54 }
49 55
50 vm.pc = vm.chunk->code;
51 u8 *last = vm.chunk->code + array_size(vm.chunk->code); 56 u8 *last = vm.chunk->code + array_size(vm.chunk->code);
52 while (vm.pc < last) { 57 while (vm.pc < last) {
53#ifdef DEBUG_TRACE_EXECUTION 58#ifdef DEBUG_TRACE_EXECUTION