aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-24 12:04:06 +0200
committerBad Diode <bd@badd10de.dev>2021-10-24 12:04:06 +0200
commit8f9a84345c147da5d398331548753d1e350ce846 (patch)
treed9dba538e0c7bc5c2a2e16e0bcbf59167121b9da /src
parent6e27b20d10306d53cd838ef375fe80571dfe91ff (diff)
downloadbdl-8f9a84345c147da5d398331548753d1e350ce846.tar.gz
bdl-8f9a84345c147da5d398331548753d1e350ce846.zip
Add globals and OP_DEF operation
Diffstat (limited to 'src')
-rwxr-xr-xsrc/bytecode/compiler.h50
-rwxr-xr-xsrc/bytecode/debug.h1
-rwxr-xr-xsrc/bytecode/main.c14
-rwxr-xr-xsrc/bytecode/objects.h16
-rwxr-xr-xsrc/bytecode/ops.h1
-rwxr-xr-xsrc/bytecode/vm.h10
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
179void 179void
180compile_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
225void
180parse_list(Chunk *chunk, Visitor *vs, Token start) { 226parse_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) {
219void 266void
220parse_tree(Chunk *chunk, Visitor *vs) { 267parse_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);
9static const char* ops_str[] = { 9static 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
162Object
163object_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 @@
4typedef enum Ops { 4typedef 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
21void vm_init(VM *vm); 24void vm_init(VM *vm);
@@ -27,11 +30,13 @@ void
27vm_init(VM *vm) { 30vm_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
32void 36void
33vm_free(VM *vm) { 37vm_free(VM *vm) {
34 array_free(vm->stack); 38 array_free(vm->stack);
39 ht_free(vm->globals);
35} 40}
36 41
37void 42void
@@ -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;