aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-27 17:15:48 +0200
committerBad Diode <bd@badd10de.dev>2021-10-27 17:15:48 +0200
commit4515d21211263a2c7367ec20ec01ce9efaae1d18 (patch)
tree9458dd1d5b7f066631c939f6039d95ed44b5de81
parent67f0debc923dc97fd79554678435f113c9f761d1 (diff)
downloadbdl-4515d21211263a2c7367ec20ec01ce9efaae1d18.tar.gz
bdl-4515d21211263a2c7367ec20ec01ce9efaae1d18.zip
Fix depth resolution on recursive calls
-rwxr-xr-xsrc/bytecode/compiler.h37
-rwxr-xr-xsrc/bytecode/vm.h5
2 files changed, 23 insertions, 19 deletions
diff --git a/src/bytecode/compiler.h b/src/bytecode/compiler.h
index 27ff312..124c345 100755
--- a/src/bytecode/compiler.h
+++ b/src/bytecode/compiler.h
@@ -608,26 +608,29 @@ parse_tree(Chunk *chunk, Compiler *compiler) {
608 return; 608 return;
609 } break; 609 } break;
610 case TOKEN_SYMBOL: { 610 case TOKEN_SYMBOL: {
611 size_t depth = compiler->scope_depth - 1; 611 if (compiler->scope_depth > 1) {
612 ssize_t idx = -1; 612 size_t depth = compiler->scope_depth - 1;
613 do { 613 ssize_t idx = -1;
614 Scope *scope = &compiler->scopes[depth]; 614 do {
615 idx = find_local_index(scope, tok); 615 Scope *scope = &compiler->scopes[depth];
616 idx = find_local_index(scope, tok);
617 if (idx >= 0) {
618 break;
619 }
620 depth--;
621 } while (depth > 0);
622
616 if (idx >= 0) { 623 if (idx >= 0) {
617 break; 624 emit_constant(chunk, tok, FIXNUM_VAL(depth));
625 emit_constant(chunk, tok, FIXNUM_VAL(idx));
626 add_code(chunk, OP_LOCAL, tok.line, tok.column);
627 return;
618 } 628 }
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 {
627 Object obj = make_symbol(tok.value);
628 emit_constant(chunk, tok, obj);
629 add_code(chunk, OP_GET, tok.line, tok.column);
630 } 629 }
630
631 Object obj = make_symbol(tok.value);
632 emit_constant(chunk, tok, obj);
633 add_code(chunk, OP_GET, tok.line, tok.column);
631 return; 634 return;
632 } break; 635 } break;
633 case TOKEN_NIL: { 636 case TOKEN_NIL: {
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h
index 3c99131..3fba3d7 100755
--- a/src/bytecode/vm.h
+++ b/src/bytecode/vm.h
@@ -177,9 +177,9 @@ vm_interpret(VM *vm) {
177 case OP_LOCAL: { 177 case OP_LOCAL: {
178 ssize_t idx = AS_FIXNUM(array_pop(vm->stack)); 178 ssize_t idx = AS_FIXNUM(array_pop(vm->stack));
179 ssize_t depth = AS_FIXNUM(array_pop(vm->stack)); 179 ssize_t depth = AS_FIXNUM(array_pop(vm->stack));
180 depth = array_size(vm->frames) - depth;
180 CallFrame frame = vm->frames[depth]; 181 CallFrame frame = vm->frames[depth];
181 array_push(vm->stack, vm->stack[frame.stack_offset + idx]); 182 array_push(vm->stack, vm->stack[frame.stack_offset + idx]);
182
183 } break; 183 } break;
184 case OP_CONSTANT: { 184 case OP_CONSTANT: {
185 u8 constant = *vm->pc++; 185 u8 constant = *vm->pc++;
@@ -300,8 +300,9 @@ vm_interpret(VM *vm) {
300 300
301#ifdef DEBUG 301#ifdef DEBUG
302 disassemble_chunk(proc.chunk); 302 disassemble_chunk(proc.chunk);
303 printf("n_locals: %ld\n", n_locals);
304 printf("n_params: %ld\n", n_params);
303#endif 305#endif
304
305 // Tail-call optimization. 306 // Tail-call optimization.
306 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) { 307 if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) {
307 // Prepare new call frame. 308 // Prepare new call frame.