From 0285f462a0941c2c3b6e679eb239f1fe9cfa3b0e Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 26 Oct 2021 14:33:14 +0200 Subject: Fix global name resolution inside functions --- src/bytecode/compiler.h | 48 ++++++++++++++++++++++++++++++++++-------------- src/bytecode/vm.h | 1 + 2 files changed, 35 insertions(+), 14 deletions(-) (limited to 'src') 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) { return compiler->current < array_size(compiler->tokens); } +ssize_t +find_local_index(Chunk *chunk, Token tok) { + // NOTE: This is dumb and potentially slow. + for (size_t i = 0; i < array_size(chunk->params); i++) { + if (sv_equal(&tok.value, &chunk->params[i])) { + return i; + } + } + return -1; +} + void emit_constant(Chunk *chunk, Token tok, Object obj) { size_t prev_size = array_size(chunk->constants); @@ -106,6 +117,12 @@ compile_list_binary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { break; } parse_tree(chunk, compiler); + if (tok.type == TOKEN_SYMBOL) { + ssize_t idx = find_local_index(chunk, tok); + if (idx < 0) { + add_code(chunk, OP_GET, tok.line, tok.column); + } + } n++; } emit_constant(chunk, start, FIXNUM_VAL(n)); @@ -139,6 +156,12 @@ compile_list_unary_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { return; } parse_tree(chunk, compiler); + if (tok.type == TOKEN_SYMBOL) { + ssize_t idx = find_local_index(chunk, tok); + if (idx < 0) { + add_code(chunk, OP_GET, tok.line, tok.column); + } + } add_code(chunk, op, start.line, start.column); n++; if (n > 1) { @@ -205,8 +228,8 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { return; } parse_tree(chunk, compiler); - Token expr = peek_token(compiler); - if (name.type == TOKEN_EOF || expr.type == TOKEN_EOF) { + Token tok = peek_token(compiler); + if (name.type == TOKEN_EOF || tok.type == TOKEN_EOF) { error_push((Error){ .type = ERR_TYPE_COMPILER, .value = ERR_UNBALANCED_PAREN, @@ -215,7 +238,7 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { }); return; } - if (name.type == TOKEN_RPAREN || expr.type == TOKEN_RPAREN) { + if (name.type == TOKEN_RPAREN || tok.type == TOKEN_RPAREN) { error_push((Error){ .type = ERR_TYPE_COMPILER, .value = ERR_NOT_ENOUGH_ARGS, @@ -225,6 +248,12 @@ compile_declare_op(Chunk *chunk, Compiler *compiler, Token start, Ops op) { return; } parse_tree(chunk, compiler); + if (tok.type == TOKEN_SYMBOL) { + ssize_t idx = find_local_index(chunk, tok); + if (idx < 0) { + add_code(chunk, OP_GET, tok.line, tok.column); + } + } if (peek_token(compiler).type != TOKEN_RPAREN) { error_push((Error){ .type = ERR_TYPE_COMPILER, @@ -500,17 +529,8 @@ parse_tree(Chunk *chunk, Compiler *compiler) { return; } break; case TOKEN_SYMBOL: { - bool found = false; - size_t idx = 0; - // NOTE: This is dumb and potentially slow. - for (size_t i = 0; i < array_size(chunk->params); i++) { - if (sv_equal(&tok.value, &chunk->params[i])) { - found = true; - idx = i; - break; - } - } - if (!found) { + ssize_t idx = find_local_index(chunk, tok); + if (idx < 0) { Object obj = make_symbol(tok.value); emit_constant(chunk, tok, obj); 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) { } break; case OP_CALL: { Object proc = array_pop(vm->stack); + // disassemble_chunk(proc.chunk); // Tail-call optimization. if (proc.chunk != frame->chunk || *vm->pc != OP_RETURN) { -- cgit v1.2.1