aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-26 08:40:59 +0200
committerBad Diode <bd@badd10de.dev>2021-10-26 08:40:59 +0200
commit46356365270b71be94097b3c408d5f35a9ebd6ed (patch)
tree59ae01f6108a94e818670de1bda37ae12a5fa2fe
parentd54e595644fcaf6756d53d368213ad3129c49327 (diff)
downloadbdl-46356365270b71be94097b3c408d5f35a9ebd6ed.tar.gz
bdl-46356365270b71be94097b3c408d5f35a9ebd6ed.zip
Add initial function call procedure
-rwxr-xr-xsrc/bytecode/compiler.h46
-rwxr-xr-xsrc/bytecode/debug.h3
-rw-r--r--src/bytecode/hashtable.h8
-rw-r--r--src/bytecode/objects.c22
-rwxr-xr-xsrc/bytecode/objects.h8
-rwxr-xr-xsrc/bytecode/ops.h3
-rwxr-xr-xsrc/bytecode/vm.h19
7 files changed, 75 insertions, 34 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index 2c7827f..6dab1fe 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -291,6 +291,43 @@ compile_fun_op(Chunk *chunk, Compiler *compiler, Token start) {
291} 291}
292 292
293void 293void
294compile_call_op(Chunk *chunk, Compiler *compiler, Token start, Token name) {
295 if (name.type != TOKEN_SYMBOL) {
296 error_push((Error){
297 .type = ERR_TYPE_COMPILER,
298 .value = ERR_WRONG_ARG_TYPE,
299 .line = start.line,
300 .col = start.column,
301 });
302 return;
303 }
304
305 // FIXME: skipping arguments for now. Assuming nil.
306
307 // Compile body.
308 while (has_next_token(compiler)) {
309 Token tok = peek_token(compiler);
310 if (tok.type == TOKEN_EOF) {
311 error_push((Error){
312 .type = ERR_TYPE_COMPILER,
313 .value = ERR_UNBALANCED_PAREN,
314 .line = start.line,
315 .col = start.column,
316 });
317 return;
318 }
319 if (tok.type == TOKEN_RPAREN) {
320 next_token(compiler);
321 break;
322 }
323 }
324 Object obj = make_symbol(name.value);
325 emit_constant(chunk, start, obj);
326 add_code(chunk, OP_GET, start.line, start.column);
327 add_code(chunk, OP_CALL, start.line, start.column);
328}
329
330void
294compile_if_op(Chunk *chunk, Compiler *compiler, Token start) { 331compile_if_op(Chunk *chunk, Compiler *compiler, Token start) {
295 Token tok = peek_token(compiler); 332 Token tok = peek_token(compiler);
296 if (tok.type == TOKEN_EOF) { 333 if (tok.type == TOKEN_EOF) {
@@ -378,12 +415,9 @@ parse_list(Chunk *chunk, Compiler *compiler, Token start) {
378 case TOKEN_FUN: { compile_fun_op(chunk, compiler, start); } break; 415 case TOKEN_FUN: { compile_fun_op(chunk, compiler, start); } break;
379 case TOKEN_IF: { compile_if_op(chunk, compiler, start); } break; 416 case TOKEN_IF: { compile_if_op(chunk, compiler, start); } break;
380 default: { 417 default: {
381 error_push((Error){ 418 // TODO: Emit error if compiler knows there hasn't been
382 .type = ERR_TYPE_COMPILER, 419 // a function delcared with that name.
383 .value = ERR_OBJ_NOT_CALLABLE, 420 compile_call_op(chunk, compiler, start, tok);
384 .line = tok.line,
385 .col = tok.column,
386 });
387 } break; 421 } break;
388 } 422 }
389} 423}
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h
index 534ff80..1e0d4d6 100755
--- a/src/bytecode/debug.h
+++ b/src/bytecode/debug.h
@@ -36,7 +36,8 @@ static const char* ops_str[] = {
36 [OP_DISPLAY] = "OP_DISPLAY", 36 [OP_DISPLAY] = "OP_DISPLAY",
37 [OP_PRINT] = "OP_PRINT", 37 [OP_PRINT] = "OP_PRINT",
38 [OP_NEWLINE] = "OP_NEWLINE", 38 [OP_NEWLINE] = "OP_NEWLINE",
39 // Return. 39 // Procedures.
40 [OP_CALL] = "OP_CALL",
40 [OP_RETURN] = "OP_RETURN", 41 [OP_RETURN] = "OP_RETURN",
41}; 42};
42 43
diff --git a/src/bytecode/hashtable.h b/src/bytecode/hashtable.h
index 1f47666..81c841e 100644
--- a/src/bytecode/hashtable.h
+++ b/src/bytecode/hashtable.h
@@ -152,9 +152,7 @@ _ht_maybe_grow(HashTable *table) {
152 // Free old arrays. 152 // Free old arrays.
153 array_free(old_pairs); 153 array_free(old_pairs);
154 for (size_t i = 0; i < array_size(old_keys); i++) { 154 for (size_t i = 0; i < array_size(old_keys); i++) {
155 Object key = old_keys[i]; 155 object_free(old_keys[i]);
156 Object value = old_values[i];
157 object_free(key);
158 } 156 }
159 array_free(old_keys); 157 array_free(old_keys);
160 array_free(old_values); 158 array_free(old_values);
@@ -201,9 +199,7 @@ ht_free(HashTable *table) {
201 } 199 }
202 array_free(table->pairs); 200 array_free(table->pairs);
203 for (size_t i = 0; i < array_size(table->keys); i++) { 201 for (size_t i = 0; i < array_size(table->keys); i++) {
204 Object key = table->keys[i]; 202 object_free(table->keys[i]);
205 Object value = table->values[i];
206 object_free(key);
207 } 203 }
208 array_free(table->keys); 204 array_free(table->keys);
209 array_free(table->values); 205 array_free(table->values);
diff --git a/src/bytecode/objects.c b/src/bytecode/objects.c
index e446fb0..3b4a2eb 100644
--- a/src/bytecode/objects.c
+++ b/src/bytecode/objects.c
@@ -58,7 +58,8 @@ object_display(Object obj) {
58 // printf(")"); 58 // printf(")");
59 } break; 59 } break;
60 case OBJ_TYPE_LAMBDA: { 60 case OBJ_TYPE_LAMBDA: {
61 printf("#{procedure}"); 61 printf("#{procedure:%.*s}",
62 (int)array_size(obj.chunk->name), obj.chunk->name);
62 } break; 63 } break;
63 case OBJ_TYPE_ERR: { 64 case OBJ_TYPE_ERR: {
64 printf("#{error}"); 65 printf("#{error}");
@@ -102,6 +103,9 @@ object_equal(Object a, Object b) {
102 } 103 }
103 } 104 }
104 } break; 105 } break;
106 case OBJ_TYPE_LAMBDA: {
107 return a.chunk == b.chunk;
108 } break;
105 default: { 109 default: {
106 return false; 110 return false;
107 } break; 111 } break;
@@ -121,14 +125,14 @@ object_copy(Object src) {
121 return copy; 125 return copy;
122 } break; 126 } break;
123 case OBJ_TYPE_LAMBDA: { 127 case OBJ_TYPE_LAMBDA: {
124 Object copy = src; 128 // Object copy = src;
125 StringView name = (StringView){ 129 // StringView name = (StringView){
126 .start = src.chunk->name, 130 // .start = src.chunk->name,
127 .n = array_size(src.chunk->name), 131 // .n = array_size(src.chunk->name),
128 }; 132 // };
129 // TODO: copy full chunk? 133 // // TODO: copy full chunk?
130 // copy.chunk = chunk_init(name); 134 // // copy.chunk = chunk_init(name);
131 return copy; 135 // return copy;
132 } break; 136 } break;
133 default: { break; } break; 137 default: { break; } break;
134 } 138 }
diff --git a/src/bytecode/objects.h b/src/bytecode/objects.h
index 419a7f8..e0c72b0 100755
--- a/src/bytecode/objects.h
+++ b/src/bytecode/objects.h
@@ -26,9 +26,7 @@ typedef struct Object {
26 26
27 // OBJ_TYPE_STRING 27 // OBJ_TYPE_STRING
28 // OBJ_TYPE_SYMBOL 28 // OBJ_TYPE_SYMBOL
29 struct { 29 char *text;
30 char *text;
31 };
32 30
33 // OBJ_TYPE_PAIR 31 // OBJ_TYPE_PAIR
34 // struct { 32 // struct {
@@ -37,9 +35,7 @@ typedef struct Object {
37 // }; 35 // };
38 36
39 // OBJ_TYPE_LAMBDA 37 // OBJ_TYPE_LAMBDA
40 struct { 38 Chunk *chunk;
41 Chunk *chunk;
42 };
43 // struct { 39 // struct {
44 // struct Object *params; 40 // struct Object *params;
45 // struct Object *body; 41 // struct Object *body;
diff --git a/src/bytecode/ops.h b/src/bytecode/ops.h
index 5eacaea..d046ca2 100755
--- a/src/bytecode/ops.h
+++ b/src/bytecode/ops.h
@@ -30,7 +30,8 @@ typedef enum Ops {
30 OP_DISPLAY, 30 OP_DISPLAY,
31 OP_PRINT, 31 OP_PRINT,
32 OP_NEWLINE, 32 OP_NEWLINE,
33 // Return. 33 // Procedures.
34 OP_CALL,
34 OP_RETURN, 35 OP_RETURN,
35} Ops; 36} Ops;
36 37
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index f7852de..63eedfa 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -136,8 +136,9 @@ vm_reset(VM *vm) {
136 136
137void 137void
138vm_interpret(VM *vm) { 138vm_interpret(VM *vm) {
139 CallFrame *frame = &vm->frames[array_size(vm->frames) - 1]; 139 CallFrame *frame = &vm->frames[0];
140 vm->pc = frame->chunk->code; 140 vm->pc = frame->chunk->code;
141 frame->rp = NULL;
141 142
142 if (frame->chunk->code == NULL || array_size(frame->chunk->code) == 0) { 143 if (frame->chunk->code == NULL || array_size(frame->chunk->code) == 0) {
143 error_push((Error){ 144 error_push((Error){
@@ -252,12 +253,20 @@ vm_interpret(VM *vm) {
252 case OP_NEWLINE: { 253 case OP_NEWLINE: {
253 printf("\n"); 254 printf("\n");
254 } break; 255 } break;
256 case OP_CALL: {
257 Object proc = array_pop(vm->stack);
258 CallFrame new_frame = (CallFrame){proc.chunk, vm->pc};
259 array_push(vm->frames, new_frame);
260 frame = &vm->frames[array_size(vm->frames) - 1];
261 vm->pc = frame->chunk->code;
262 } break;
255 case OP_RETURN: { 263 case OP_RETURN: {
256 if (frame->rp != NULL) { 264 if (frame->rp == NULL) {
257 // TODO: restore previous call frame. 265 return;
258 vm->pc = frame->rp;
259 } 266 }
260 return; 267 vm->pc = frame->rp;
268 array_head(vm->frames)->size--;
269 frame = &vm->frames[array_size(vm->frames) - 1];
261 } break; 270 } break;
262 default: { 271 default: {
263 error_push((Error){ 272 error_push((Error){