diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bytecode/errors.c | 2 | ||||
-rw-r--r-- | src/bytecode/errors.h | 5 | ||||
-rw-r--r-- | src/bytecode/main.c | 13 | ||||
-rw-r--r-- | src/bytecode/vm.h | 52 |
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 | ||
20 | static Error errors[ERR_MAX_NUMBER]; | 22 | 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 @@ | |||
2 | #define BDL_ERRORS_H | 2 | #define BDL_ERRORS_H |
3 | 3 | ||
4 | typedef enum ErrorType { | 4 | typedef 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 | ||
27 | typedef struct Error { | 32 | 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 @@ | |||
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 | ||
7 | typedef struct VM { | 10 | typedef struct VM { |
8 | Chunk *chunk; | 11 | Chunk *chunk; |
12 | u8 *pc; | ||
9 | } VM; | 13 | } VM; |
10 | 14 | ||
11 | VM vm_init(void); | 15 | VM vm_init(void); |
12 | void vm_free(VM vm); | 16 | void vm_free(VM vm); |
17 | void vm_interpret(VM vm); | ||
13 | 18 | ||
14 | VM | 19 | VM |
15 | vm_init(void) { | 20 | vm_init(void) { |
@@ -24,4 +29,51 @@ vm_free(VM vm) { | |||
24 | chunk_free(vm.chunk); | 29 | chunk_free(vm.chunk); |
25 | } | 30 | } |
26 | 31 | ||
32 | void | ||
33 | vm_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 |