aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-22 12:05:41 +0200
committerBad Diode <bd@badd10de.dev>2021-10-22 12:05:41 +0200
commitd9474f1d7c0c6674179fd0f27cd1c084c8227ed5 (patch)
tree9ccad3b53388795e7cc03353f1860a0eddec593e /src/bytecode
parentab7d7c155fb1bec5eed8f97462fbb656ea27dbb5 (diff)
downloadbdl-d9474f1d7c0c6674179fd0f27cd1c084c8227ed5.tar.gz
bdl-d9474f1d7c0c6674179fd0f27cd1c084c8227ed5.zip
Add interpretation function for VM
Diffstat (limited to 'src/bytecode')
-rw-r--r--src/bytecode/errors.c2
-rw-r--r--src/bytecode/errors.h5
-rw-r--r--src/bytecode/main.c13
-rw-r--r--src/bytecode/vm.h52
4 files changed, 69 insertions, 3 deletions
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[] = {
15 [ERR_TOO_MANY_ARGS] = "error: too many arguments", 15 [ERR_TOO_MANY_ARGS] = "error: too many arguments",
16 [ERR_WRONG_ARG_TYPE] = "error: wrong argument type", 16 [ERR_WRONG_ARG_TYPE] = "error: wrong argument type",
17 [ERR_DIVISION_BY_ZERO] = "error: division by zero", 17 [ERR_DIVISION_BY_ZERO] = "error: division by zero",
18 [ERR_PC_OOB] = "error: pc out of bounds",
19 [ERR_EMPTY_CHUNK] = "error: empty chunk",
18}; 20};
19 21
20static Error errors[ERR_MAX_NUMBER]; 22static 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 @@
2#define BDL_ERRORS_H 2#define BDL_ERRORS_H
3 3
4typedef enum ErrorType { 4typedef enum ErrorType {
5 ERR_TYPE_OK,
5 ERR_TYPE_LEXER, 6 ERR_TYPE_LEXER,
6 ERR_TYPE_PARSER, 7 ERR_TYPE_PARSER,
7 ERR_TYPE_RUNTIME, 8 ERR_TYPE_RUNTIME,
@@ -22,6 +23,10 @@ typedef enum ErrorValue {
22 ERR_TOO_MANY_ARGS, 23 ERR_TOO_MANY_ARGS,
23 ERR_WRONG_ARG_TYPE, 24 ERR_WRONG_ARG_TYPE,
24 ERR_DIVISION_BY_ZERO, 25 ERR_DIVISION_BY_ZERO,
26
27 // Bytecode interpreter.
28 ERR_PC_OOB,
29 ERR_EMPTY_CHUNK,
25} ErrorValue; 30} ErrorValue;
26 31
27typedef struct Error { 32typedef 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 @@
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6 6
7#include "vm.h" 7//
8// Config.
9//
10
11// #define DEBUG_TRACE_EXECUTION
8 12
13#include "vm.h"
9#include "ops.h" 14#include "ops.h"
10#include "debug.h" 15#include "debug.h"
11#include "errors.c" 16#include "errors.c"
@@ -39,8 +44,10 @@ process_source(const StringView *source) {
39 add_code(vm.chunk, const_idx, 1, 1); 44 add_code(vm.chunk, const_idx, 1, 1);
40 add_code(vm.chunk, OP_RETURN, 1, 1); 45 add_code(vm.chunk, OP_RETURN, 1, 1);
41 46
42 // Disassemble the chunk. 47 vm_interpret(vm);
43 disassemble_chunk(vm.chunk, "test chunk"); 48 if (errors_n != 0) {
49 disassemble_chunk(vm.chunk, "test chunk");
50 }
44 51
45 array_free(tokens); 52 array_free(tokens);
46} 53}
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 @@
2#define BDL_VM_H 2#define BDL_VM_H
3 3
4#include "types.h" 4#include "types.h"
5#include "errors.h"
5#include "chunk.h" 6#include "chunk.h"
7#include "ops.h"
8#include "debug.h"
6 9
7typedef struct VM { 10typedef struct VM {
8 Chunk *chunk; 11 Chunk *chunk;
12 u8 *pc;
9} VM; 13} VM;
10 14
11VM vm_init(void); 15VM vm_init(void);
12void vm_free(VM vm); 16void vm_free(VM vm);
17void vm_interpret(VM vm);
13 18
14VM 19VM
15vm_init(void) { 20vm_init(void) {
@@ -24,4 +29,51 @@ vm_free(VM vm) {
24 chunk_free(vm.chunk); 29 chunk_free(vm.chunk);
25} 30}
26 31
32void
33vm_interpret(VM vm) {
34 if (vm.chunk->code == NULL || array_size(vm.chunk->code) == 0) {
35 error_push((Error){
36 .type = ERR_TYPE_RUNTIME,
37 .value = ERR_EMPTY_CHUNK,
38 });
39 return;
40 }
41
42 vm.pc = vm.chunk->code;
43 u8 *last = vm.chunk->code + array_size(vm.chunk->code);
44 while (vm.pc < last) {
45#ifdef DEBUG_TRACE_EXECUTION
46 disassemble_instruction(vm.chunk, (vm.pc - vm.chunk->code));
47#endif
48 u8 instruction = *vm.pc++;
49 switch (instruction) {
50 case OP_CONSTANT: {
51 u8 constant = *vm.pc++;
52 Object obj = vm.chunk->constants[constant];
53 display(obj);
54 printf("\n");
55 } break;
56 case OP_RETURN: {
57 return;
58 } break;
59 default: {
60 error_push((Error){
61 .type = ERR_TYPE_RUNTIME,
62 .value = ERR_NOT_IMPLEMENTED,
63 .line = vm.chunk->lines[0].line,
64 .col = vm.chunk->lines[0].col,
65 });
66 return;
67 } break;
68 }
69 }
70
71 error_push((Error){
72 .type = ERR_TYPE_RUNTIME,
73 .value = ERR_PC_OOB,
74 .line = vm.chunk->lines[0].line,
75 .col = vm.chunk->lines[0].col,
76 });
77}
78
27#endif // BDL_VM_H 79#endif // BDL_VM_H