aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-27 15:15:04 +0200
committerBad Diode <bd@badd10de.dev>2021-10-27 15:15:04 +0200
commit67f0debc923dc97fd79554678435f113c9f761d1 (patch)
tree44bba6613ace1d42e6eaf6befe586e37921f65aa
parent9460f325d22fac3962a3452ce25a24b04d22e665 (diff)
downloadbdl-67f0debc923dc97fd79554678435f113c9f761d1.tar.gz
bdl-67f0debc923dc97fd79554678435f113c9f761d1.zip
Fix an issue with reading local variables when nested
-rwxr-xr-xsrc/bytecode/compiler.h23
-rwxr-xr-xsrc/bytecode/debug.h5
-rwxr-xr-xsrc/bytecode/vm.h7
3 files changed, 21 insertions, 14 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index f9e1da1..27ff312 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -608,17 +608,26 @@ parse_tree(Chunk *chunk, Compiler *compiler) {
608 return; 608 return;
609 } break; 609 } break;
610 case TOKEN_SYMBOL: { 610 case TOKEN_SYMBOL: {
611 Scope *scope = get_current_scope(compiler); 611 size_t depth = compiler->scope_depth - 1;
612 ssize_t idx = find_local_index(scope, tok); 612 ssize_t idx = -1;
613 if (idx < 0) { 613 do {
614 Scope *scope = &compiler->scopes[depth];
615 idx = find_local_index(scope, tok);
616 if (idx >= 0) {
617 break;
618 }
619 depth--;
620 } while (depth > 0);
621
622 if (idx >= 0) {
623 emit_constant(chunk, tok, FIXNUM_VAL(depth));
624 emit_constant(chunk, tok, FIXNUM_VAL(idx));
625 add_code(chunk, OP_LOCAL, tok.line, tok.column);
626 } else {
614 Object obj = make_symbol(tok.value); 627 Object obj = make_symbol(tok.value);
615 emit_constant(chunk, tok, obj); 628 emit_constant(chunk, tok, obj);
616 add_code(chunk, OP_GET, tok.line, tok.column); 629 add_code(chunk, OP_GET, tok.line, tok.column);
617 return;
618 } 630 }
619
620 add_code(chunk, OP_LOCAL, tok.line, tok.column);
621 add_code(chunk, idx, tok.line, tok.column);
622 return; 631 return;
623 } break; 632 } break;
624 case TOKEN_NIL: { 633 case TOKEN_NIL: {
diff --git a/src/bytecode/debug.h b/src/bytecode/debug.h
index e2e3756..e34b65f 100755
--- a/src/bytecode/debug.h
+++ b/src/bytecode/debug.h
@@ -77,11 +77,6 @@ disassemble_instruction(Chunk *chunk, size_t offset) {
77 } 77 }
78 u8 instruction = chunk->code[offset]; 78 u8 instruction = chunk->code[offset];
79 switch (instruction) { 79 switch (instruction) {
80 case OP_LOCAL: {
81 u8 local = chunk->code[offset + 1];
82 printf("%-16s %4d\n", ops_str[instruction], local);
83 return offset + 2;
84 } break;
85 case OP_CONSTANT: { 80 case OP_CONSTANT: {
86 u8 constant = chunk->code[offset + 1]; 81 u8 constant = chunk->code[offset + 1];
87 printf("%-16s %4d -> ", ops_str[instruction], constant); 82 printf("%-16s %4d -> ", ops_str[instruction], constant);
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 15a6b86..3c99131 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -175,8 +175,11 @@ vm_interpret(VM *vm) {
175 u8 instruction = *vm->pc++; 175 u8 instruction = *vm->pc++;
176 switch (instruction) { 176 switch (instruction) {
177 case OP_LOCAL: { 177 case OP_LOCAL: {
178 u8 local = *vm->pc++; 178 ssize_t idx = AS_FIXNUM(array_pop(vm->stack));
179 array_push(vm->stack, vm->stack[frame->stack_offset + local]); 179 ssize_t depth = AS_FIXNUM(array_pop(vm->stack));
180 CallFrame frame = vm->frames[depth];
181 array_push(vm->stack, vm->stack[frame.stack_offset + idx]);
182
180 } break; 183 } break;
181 case OP_CONSTANT: { 184 case OP_CONSTANT: {
182 u8 constant = *vm->pc++; 185 u8 constant = *vm->pc++;