aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-26 14:33:14 +0200
committerBad Diode <bd@badd10de.dev>2021-10-26 14:33:14 +0200
commit0285f462a0941c2c3b6e679eb239f1fe9cfa3b0e (patch)
tree4283a85a1c3023656383dc912bd9a694d86a824e
parentb33b00390c605c74426b8376b4a71e17af4754fc (diff)
downloadbdl-0285f462a0941c2c3b6e679eb239f1fe9cfa3b0e.tar.gz
bdl-0285f462a0941c2c3b6e679eb239f1fe9cfa3b0e.zip
Fix global name resolution inside functions
-rwxr-xr-xsrc/bytecode/compiler.h48
-rwxr-xr-xsrc/bytecode/vm.h1
2 files changed, 35 insertions, 14 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index 9389ab4..44f03fc 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -31,6 +31,17 @@ has_next_token(const Compiler *compiler) {
31 return compiler->current < array_size(compiler->tokens); 31 return compiler->current < array_size(compiler->tokens);
32} 32}
33 33
34ssize_t
35find_local_index(Chunk *chunk, Token tok) {
36 // NOTE: This is dumb and potentially slow.
37 for (size_t i = 0; i < array_size(chunk->params); i++) {
38 if (sv_equal(&tok.value, &chunk->params[i])) {
39 return i;
40 }
41 }
42 return -1;
43}
44
34void 45void
35emit_constant(Chunk *chunk, Token tok, Object obj) { 46emit_constant(Chunk *chunk, Token tok, Object obj) {
36 size_t prev_size = array_size(chunk->constants); 47 size_t prev_size = array_size(chunk->constants);
@@ -106,6 +117,12 @@ compile_list_binary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) {
106 break; 117 break;
107 } 118 }
108 parse_tree(chunk, compiler); 119 parse_tree(chunk, compiler);
120 if (tok.type == TOKEN_SYMBOL) {
121 ssize_t idx = find_local_index(chunk, tok);
122 if (idx < 0) {
123 add_code(chunk, OP_GET, tok.line, tok.column);
124 }
125 }
109 n++; 126 n++;
110 } 127 }
111 emit_constant(chunk, start, FIXNUM_VAL(n)); 128 emit_constant(chunk, start, FIXNUM_VAL(n));
@@ -139,6 +156,12 @@ compile_list_unary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) {
139 return; 156 return;
140 } 157 }
141 parse_tree(chunk, compiler); 158 parse_tree(chunk, compiler);
159 if (tok.type == TOKEN_SYMBOL) {
160 ssize_t idx = find_local_index(chunk, tok);
161 if (idx < 0) {
162 add_code(chunk, OP_GET, tok.line, tok.column);
163 }
164 }
142 add_code(chunk, op, start.line, start.column); 165 add_code(chunk, op, start.line, start.column);
143 n++; 166 n++;
144 if (n > 1) { 167 if (n > 1) {
@@ -205,8 +228,8 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) {
205 return; 228 return;
206 } 229 }
207 parse_tree(chunk, compiler); 230 parse_tree(chunk, compiler);
208 Token expr = peek_token(compiler); 231 Token tok = peek_token(compiler);
209 if (name.type == TOKEN_EOF || expr.type == TOKEN_EOF) { 232 if (name.type == TOKEN_EOF || tok.type == TOKEN_EOF) {
210 error_push((Error){ 233 error_push((Error){
211 .type = ERR_TYPE_COMPILER, 234 .type = ERR_TYPE_COMPILER,
212 .value = ERR_UNBALANCED_PAREN, 235 .value = ERR_UNBALANCED_PAREN,
@@ -215,7 +238,7 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) {
215 }); 238 });
216 return; 239 return;
217 } 240 }
218 if (name.type == TOKEN_RPAREN || expr.type == TOKEN_RPAREN) { 241 if (name.type == TOKEN_RPAREN || tok.type == TOKEN_RPAREN) {
219 error_push((Error){ 242 error_push((Error){
220 .type = ERR_TYPE_COMPILER, 243 .type = ERR_TYPE_COMPILER,
221 .value = ERR_NOT_ENOUGH_ARGS, 244 .value = ERR_NOT_ENOUGH_ARGS,
@@ -225,6 +248,12 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) {
225 return; 248 return;
226 } 249 }
227 parse_tree(chunk, compiler); 250 parse_tree(chunk, compiler);
251 if (tok.type == TOKEN_SYMBOL) {
252 ssize_t idx = find_local_index(chunk, tok);
253 if (idx < 0) {
254 add_code(chunk, OP_GET, tok.line, tok.column);
255 }
256 }
228 if (peek_token(compiler).type != TOKEN_RPAREN) { 257 if (peek_token(compiler).type != TOKEN_RPAREN) {
229 error_push((Error){ 258 error_push((Error){
230 .type = ERR_TYPE_COMPILER, 259 .type = ERR_TYPE_COMPILER,
@@ -500,17 +529,8 @@ parse_tree(Chunk *chunk, Compiler *compiler) {
500 return; 529 return;
501 } break; 530 } break;
502 case TOKEN_SYMBOL: { 531 case TOKEN_SYMBOL: {
503 bool found = false; 532 ssize_t idx = find_local_index(chunk, tok);
504 size_t idx = 0; 533 if (idx < 0) {
505 // NOTE: This is dumb and potentially slow.
506 for (size_t i = 0; i < array_size(chunk->params); i++) {
507 if (sv_equal(&tok.value, &chunk->params[i])) {
508 found = true;
509 idx = i;
510 break;
511 }
512 }
513 if (!found) {
514 Object obj = make_symbol(tok.value); 534 Object obj = make_symbol(tok.value);
515 emit_constant(chunk, tok, obj); 535 emit_constant(chunk, tok, obj);
516 return; 536 return;
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 6c44fc6..2bc5c8a 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -261,6 +261,7 @@ vm_interpret(VM *vm) {
261 } break; 261 } break;
262 case OP_CALL: { 262 case OP_CALL: {
263 Object proc = array_pop(vm->stack); 263 Object proc = array_pop(vm->stack);
264 // disassemble_chunk(proc.chunk);
264 265
265 // Tail-call optimization. 266 // Tail-call optimization.
266 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) { 267 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) {