diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-22 13:58:02 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-22 13:58:02 +0200 |
commit | 9ce9a7f510e6ba407c2e14d3eae4d603b38edde7 (patch) | |
tree | aaca7e34058761ae4d4f58e7567f126c5dc9a3a5 | |
parent | 6fd244cb04cf1972e9d7dcc5635bf5cfe8194402 (diff) | |
download | bdl-9ce9a7f510e6ba407c2e14d3eae4d603b38edde7.tar.gz bdl-9ce9a7f510e6ba407c2e14d3eae4d603b38edde7.zip |
Prepare compilation pipeline
-rw-r--r-- | src/bytecode/compiler.h | 34 | ||||
-rw-r--r-- | src/bytecode/main.c | 30 | ||||
-rw-r--r-- | src/bytecode/vm.h | 35 |
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 | |||
7 | typedef struct Visitor { | ||
8 | Token *tokens; | ||
9 | size_t current; | ||
10 | } Visitor; | ||
11 | |||
12 | // Mimics the functionality in the Scanner functions, but for entire tokens. | ||
13 | Token next_token(Visitor *visitor); | ||
14 | Token peek_token(const Visitor *visitor); | ||
15 | bool has_next_token(const Visitor *visitor); | ||
16 | |||
17 | Chunk * compile(Token *tokens); | ||
18 | |||
19 | Chunk * | ||
20 | compile(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 | ||
23 | void | 24 | void |
24 | init(void) { | 25 | init(void) { |
25 | vm = vm_init(); | 26 | vm_init(&vm); |
26 | } | 27 | } |
27 | 28 | ||
28 | void | 29 | void |
29 | halt(void) { | 30 | halt(void) { |
30 | vm_free(vm); | 31 | vm_free(&vm); |
31 | } | 32 | } |
32 | 33 | ||
33 | void | 34 | void |
34 | process_source(const StringView *source) { | 35 | process_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 | ||
21 | VM vm_init(void); | 21 | void vm_init(VM *vm); |
22 | void vm_free(VM vm); | 22 | void vm_free(VM *vm); |
23 | void vm_interpret(VM vm); | 23 | void vm_reset(VM *vm); |
24 | void vm_interpret(VM vm, Chunk *chunk); | ||
24 | 25 | ||
25 | VM | 26 | void |
26 | vm_init(void) { | 27 | vm_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; | 32 | void |
33 | vm_free(VM *vm) { | ||
34 | array_free(vm->stack); | ||
32 | } | 35 | } |
33 | 36 | ||
34 | void | 37 | void |
35 | vm_free(VM vm) { | 38 | vm_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 | ||
40 | void | 43 | void |
41 | vm_interpret(VM vm) { | 44 | vm_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 |