diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-24 12:04:06 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-24 12:04:06 +0200 |
commit | 8f9a84345c147da5d398331548753d1e350ce846 (patch) | |
tree | d9dba538e0c7bc5c2a2e16e0bcbf59167121b9da | |
parent | 6e27b20d10306d53cd838ef375fe80571dfe91ff (diff) | |
download | bdl-8f9a84345c147da5d398331548753d1e350ce846.tar.gz bdl-8f9a84345c147da5d398331548753d1e350ce846.zip |
Add globals and OP_DEF operation
-rwxr-xr-x | src/bytecode/compiler.h | 50 | ||||
-rwxr-xr-x | src/bytecode/debug.h | 1 | ||||
-rwxr-xr-x | src/bytecode/main.c | 14 | ||||
-rwxr-xr-x | src/bytecode/objects.h | 16 | ||||
-rwxr-xr-x | src/bytecode/ops.h | 1 | ||||
-rwxr-xr-x | src/bytecode/vm.h | 10 |
6 files changed, 87 insertions, 5 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h index ec51942..8f3fa81 100755 --- a/src/bytecode/compiler.h +++ b/src/bytecode/compiler.h | |||
@@ -177,6 +177,52 @@ compile_list_simple_op(Chunk *chunk, Visitor *vs, Token start, Ops op) { | |||
177 | } | 177 | } |
178 | 178 | ||
179 | void | 179 | void |
180 | compile_define_op(Chunk *chunk, Visitor *vs, Token start) { | ||
181 | Token name = peek_token(vs); | ||
182 | if (name.type != TOKEN_SYMBOL) { | ||
183 | error_push((Error){ | ||
184 | .type = ERR_TYPE_COMPILER, | ||
185 | .value = ERR_WRONG_ARG_TYPE, | ||
186 | .line = start.line, | ||
187 | .col = start.column, | ||
188 | }); | ||
189 | return; | ||
190 | } | ||
191 | parse_tree(chunk, vs); | ||
192 | Token expr = peek_token(vs); | ||
193 | if (name.type == TOKEN_EOF || expr.type == TOKEN_EOF) { | ||
194 | error_push((Error){ | ||
195 | .type = ERR_TYPE_COMPILER, | ||
196 | .value = ERR_UNBALANCED_PAREN, | ||
197 | .line = start.line, | ||
198 | .col = start.column, | ||
199 | }); | ||
200 | return; | ||
201 | } | ||
202 | if (name.type == TOKEN_RPAREN || expr.type == TOKEN_RPAREN) { | ||
203 | error_push((Error){ | ||
204 | .type = ERR_TYPE_COMPILER, | ||
205 | .value = ERR_NOT_ENOUGH_ARGS, | ||
206 | .line = start.line, | ||
207 | .col = start.column, | ||
208 | }); | ||
209 | return; | ||
210 | } | ||
211 | parse_tree(chunk, vs); | ||
212 | if (peek_token(vs).type != TOKEN_RPAREN) { | ||
213 | error_push((Error){ | ||
214 | .type = ERR_TYPE_COMPILER, | ||
215 | .value = ERR_TOO_MANY_ARGS, | ||
216 | .line = start.line, | ||
217 | .col = start.column, | ||
218 | }); | ||
219 | return; | ||
220 | } | ||
221 | next_token(vs); | ||
222 | add_code(chunk, OP_DEF, start.line, start.column); | ||
223 | } | ||
224 | |||
225 | void | ||
180 | parse_list(Chunk *chunk, Visitor *vs, Token start) { | 226 | parse_list(Chunk *chunk, Visitor *vs, Token start) { |
181 | if (!has_next_token(vs)) { | 227 | if (!has_next_token(vs)) { |
182 | error_push((Error){ | 228 | error_push((Error){ |
@@ -205,6 +251,7 @@ parse_list(Chunk *chunk, Visitor *vs, Token start) { | |||
205 | case TOKEN_PRINT: { compile_list_unary_op(chunk, vs, start, OP_PRINT); } break; | 251 | case TOKEN_PRINT: { compile_list_unary_op(chunk, vs, start, OP_PRINT); } break; |
206 | case TOKEN_DISPLAY: { compile_list_unary_op(chunk, vs, start, OP_DISPLAY); } break; | 252 | case TOKEN_DISPLAY: { compile_list_unary_op(chunk, vs, start, OP_DISPLAY); } break; |
207 | case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break; | 253 | case TOKEN_NEWLINE: { compile_list_simple_op(chunk, vs, start, OP_NEWLINE); } break; |
254 | case TOKEN_DEF: { compile_define_op(chunk, vs, start); } break; | ||
208 | default: { | 255 | default: { |
209 | error_push((Error){ | 256 | error_push((Error){ |
210 | .type = ERR_TYPE_COMPILER, | 257 | .type = ERR_TYPE_COMPILER, |
@@ -219,6 +266,9 @@ parse_list(Chunk *chunk, Visitor *vs, Token start) { | |||
219 | void | 266 | void |
220 | parse_tree(Chunk *chunk, Visitor *vs) { | 267 | parse_tree(Chunk *chunk, Visitor *vs) { |
221 | Token tok = next_token(vs); | 268 | Token tok = next_token(vs); |
269 | if (errors_n != 0) { | ||
270 | return; | ||
271 | } | ||
222 | switch (tok.type) { | 272 | switch (tok.type) { |
223 | case TOKEN_FIXNUM: { | 273 | case TOKEN_FIXNUM: { |
224 | parse_fixnum(chunk, tok); | 274 | parse_fixnum(chunk, tok); |
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h index 52cf431..52b237a 100755 --- a/src/bytecode/debug.h +++ b/src/bytecode/debug.h | |||
@@ -9,6 +9,7 @@ size_t disassemble_instruction(Chunk *chunk, size_t offset); | |||
9 | static const char* ops_str[] = { | 9 | static const char* ops_str[] = { |
10 | // Load/store ops. | 10 | // Load/store ops. |
11 | [OP_CONSTANT] = "OP_CONSTANT", | 11 | [OP_CONSTANT] = "OP_CONSTANT", |
12 | [OP_DEF] = "OP_DEF", | ||
12 | // Arithmetic ops. | 13 | // Arithmetic ops. |
13 | [OP_SUM] = "OP_SUM", | 14 | [OP_SUM] = "OP_SUM", |
14 | [OP_SUB] = "OP_SUB", | 15 | [OP_SUB] = "OP_SUB", |
diff --git a/src/bytecode/main.c b/src/bytecode/main.c index f7d1f74..85882b3 100755 --- a/src/bytecode/main.c +++ b/src/bytecode/main.c | |||
@@ -8,13 +8,15 @@ | |||
8 | // Config. | 8 | // Config. |
9 | // | 9 | // |
10 | 10 | ||
11 | // #define DEBUG_TRACE_EXECUTION | 11 | #ifdef DEBUG |
12 | #define DEBUG_TRACE_EXECUTION | ||
13 | #endif | ||
12 | 14 | ||
13 | #include "vm.h" | 15 | #include "vm.h" |
16 | #include "errors.c" | ||
14 | #include "compiler.h" | 17 | #include "compiler.h" |
15 | #include "ops.h" | 18 | #include "ops.h" |
16 | #include "debug.h" | 19 | #include "debug.h" |
17 | #include "errors.c" | ||
18 | #include "lexer.c" | 20 | #include "lexer.c" |
19 | #include "read_line.c" | 21 | #include "read_line.c" |
20 | #include "string_view.c" | 22 | #include "string_view.c" |
@@ -48,12 +50,14 @@ process_source(const StringView *source) { | |||
48 | return; | 50 | return; |
49 | } | 51 | } |
50 | 52 | ||
53 | #ifdef DEBUG | ||
54 | disassemble_chunk(chunk, "current chunk"); | ||
55 | #endif | ||
56 | |||
51 | // Interpret chunk. | 57 | // Interpret chunk. |
52 | vm_interpret(&vm, chunk); | 58 | vm_interpret(&vm, chunk); |
53 | if (errors_n != 0) { | ||
54 | disassemble_chunk(vm.chunk, "current chunk"); | ||
55 | } | ||
56 | 59 | ||
60 | // Free resources. | ||
57 | chunk_free(chunk); | 61 | chunk_free(chunk); |
58 | array_free(tokens); | 62 | array_free(tokens); |
59 | } | 63 | } |
diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h index fc5e069..9744071 100755 --- a/src/bytecode/objects.h +++ b/src/bytecode/objects.h | |||
@@ -159,4 +159,20 @@ object_equal(Object a, Object b) { | |||
159 | return true; | 159 | return true; |
160 | } | 160 | } |
161 | 161 | ||
162 | Object | ||
163 | object_copy(Object src) { | ||
164 | switch (src.type) { | ||
165 | case OBJ_TYPE_SYMBOL: | ||
166 | case OBJ_TYPE_STRING: { | ||
167 | Object copy = src; | ||
168 | copy.text = NULL; | ||
169 | array_init(copy.text, array_size(src.text)); | ||
170 | array_insert(copy.text, src.text, array_size(src.text)); | ||
171 | return copy; | ||
172 | } break; | ||
173 | default: { break; } break; | ||
174 | } | ||
175 | return src; | ||
176 | } | ||
177 | |||
162 | #endif // BDL_OBJECTS_H | 178 | #endif // BDL_OBJECTS_H |
diff --git a/src/bytecode/ops.h b/src/bytecode/ops.h index 348df84..63442ac 100755 --- a/src/bytecode/ops.h +++ b/src/bytecode/ops.h | |||
@@ -4,6 +4,7 @@ | |||
4 | typedef enum Ops { | 4 | typedef enum Ops { |
5 | // Load/store ops. | 5 | // Load/store ops. |
6 | OP_CONSTANT, | 6 | OP_CONSTANT, |
7 | OP_DEF, | ||
7 | // Arithmetic ops. | 8 | // Arithmetic ops. |
8 | OP_SUM, | 9 | OP_SUM, |
9 | OP_SUB, | 10 | OP_SUB, |
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index f1886ec..23370bb 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #include "chunk.h" | 6 | #include "chunk.h" |
7 | #include "ops.h" | 7 | #include "ops.h" |
8 | #include "debug.h" | 8 | #include "debug.h" |
9 | #include "hashtable.h" | ||
9 | 10 | ||
10 | #define VM_STACK_CAP 1024 | 11 | #define VM_STACK_CAP 1024 |
11 | 12 | ||
@@ -16,6 +17,8 @@ typedef struct VM { | |||
16 | u8 *pc; | 17 | u8 *pc; |
17 | // Stack. | 18 | // Stack. |
18 | Object *stack; | 19 | Object *stack; |
20 | // Global variables. | ||
21 | HashTable *globals; | ||
19 | } VM; | 22 | } VM; |
20 | 23 | ||
21 | void vm_init(VM *vm); | 24 | void vm_init(VM *vm); |
@@ -27,11 +30,13 @@ void | |||
27 | vm_init(VM *vm) { | 30 | vm_init(VM *vm) { |
28 | *vm = (VM){0}; | 31 | *vm = (VM){0}; |
29 | array_init(vm->stack, VM_STACK_CAP); | 32 | array_init(vm->stack, VM_STACK_CAP); |
33 | vm->globals = ht_init(); | ||
30 | } | 34 | } |
31 | 35 | ||
32 | void | 36 | void |
33 | vm_free(VM *vm) { | 37 | vm_free(VM *vm) { |
34 | array_free(vm->stack); | 38 | array_free(vm->stack); |
39 | ht_free(vm->globals); | ||
35 | } | 40 | } |
36 | 41 | ||
37 | void | 42 | void |
@@ -142,6 +147,11 @@ vm_interpret(VM *vm, Chunk *chunk) { | |||
142 | Object obj = vm->chunk->constants[constant]; | 147 | Object obj = vm->chunk->constants[constant]; |
143 | array_push(vm->stack, obj); | 148 | array_push(vm->stack, obj); |
144 | } break; | 149 | } break; |
150 | case OP_DEF: { | ||
151 | Object value = array_pop(vm->stack); | ||
152 | Object name = array_pop(vm->stack); | ||
153 | ht_insert(vm->globals, name, value); | ||
154 | } break; | ||
145 | case OP_SUM: { FIXNUM_ARITHMETIC_OP(+); } break; | 155 | case OP_SUM: { FIXNUM_ARITHMETIC_OP(+); } break; |
146 | case OP_SUB: { FIXNUM_ARITHMETIC_OP(-); } break; | 156 | case OP_SUB: { FIXNUM_ARITHMETIC_OP(-); } break; |
147 | case OP_MUL: { FIXNUM_ARITHMETIC_OP(*); } break; | 157 | case OP_MUL: { FIXNUM_ARITHMETIC_OP(*); } break; |