From 67f0debc923dc97fd79554678435f113c9f761d1 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 27 Oct 2021 15:15:04 +0200 Subject: Fix an issue with reading local variables when nested --- src/bytecode/compiler.h | 23 ++++++++++++++++------- src/bytecode/debug.h | 5 ----- src/bytecode/vm.h | 7 +++++-- 3 files changed, 21 insertions(+), 14 deletions(-) (limited to 'src') 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) { return; } break; case TOKEN_SYMBOL: { - Scope *scope = get_current_scope(compiler); - ssize_t idx = find_local_index(scope, tok); - if (idx < 0) { + size_t depth = compiler->scope_depth - 1; + ssize_t idx = -1; + do { + Scope *scope = &compiler->scopes[depth]; + idx = find_local_index(scope, tok); + if (idx >= 0) { + break; + } + depth--; + } while (depth > 0); + + if (idx >= 0) { + emit_constant(chunk, tok, FIXNUM_VAL(depth)); + emit_constant(chunk, tok, FIXNUM_VAL(idx)); + add_code(chunk, OP_LOCAL, tok.line, tok.column); + } else { Object obj = make_symbol(tok.value); emit_constant(chunk, tok, obj); add_code(chunk, OP_GET, tok.line, tok.column); - return; } - - add_code(chunk, OP_LOCAL, tok.line, tok.column); - add_code(chunk, idx, tok.line, tok.column); return; } break; 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) { } u8 instruction = chunk->code[offset]; switch (instruction) { - case OP_LOCAL: { - u8 local = chunk->code[offset + 1]; - printf("%-16s %4d\n", ops_str[instruction], local); - return offset + 2; - } break; case OP_CONSTANT: { u8 constant = chunk->code[offset + 1]; 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) { u8 instruction = *vm->pc++; switch (instruction) { case OP_LOCAL: { - u8 local = *vm->pc++; - array_push(vm->stack, vm->stack[frame->stack_offset + local]); + ssize_t idx = AS_FIXNUM(array_pop(vm->stack)); + ssize_t depth = AS_FIXNUM(array_pop(vm->stack)); + CallFrame frame = vm->frames[depth]; + array_push(vm->stack, vm->stack[frame.stack_offset + idx]); + } break; case OP_CONSTANT: { u8 constant = *vm->pc++; -- cgit v1.2.1