From e48386449b1f50c9f9d9b0645c8c469c1d4cbe4a Mon Sep 17 00:00:00 2001 From: ubq323 Date: Tue, 25 Jun 2024 15:23:44 +0100 Subject: allow local resolution into outer scopes --- com.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'com.c') diff --git a/com.c b/com.c index c5362cd..a3cc5a8 100644 --- a/com.c +++ b/com.c @@ -244,6 +244,16 @@ static void declare_local(Compiler *C, char *name) { l->slot = C->stack_cur - 1; // printf("declaring local %s at %d, stack_cur is %d\n",l->name, l->slot, C->stack_cur); } +static Local *locate_local(Compiler *C, char *name) { + for (Scope *sc = C->scope; sc != NULL; sc = sc->outer) { + for (int i = 0; i < sc->nlocals; i++) { + Local *loc = &sc->locals[i]; + if (0 == strcmp(loc->name, name)) + return loc; + } + } + return NULL; +} void let_form(Compiler *C, AstVec l, Op _) { CHECK(l.vals[1].ty == AST_LIST, "let's first argument must be list"); @@ -345,6 +355,8 @@ static BuiltinIdent builtin_idents[] = { { 0 }, }; + + static void compile_node(Compiler *C, AstNode a) { switch (a.ty) { case AST_IDENT:; @@ -358,21 +370,11 @@ static void compile_node(Compiler *C, AstNode a) { } } if (!found_builtin) { - // read local or global variable - bool found_local = false; - if (C->scope != NULL) { - Scope *sc = C->scope; - for (int i = 0; i < sc->nlocals; i++) { - Local loc = sc->locals[i]; - if (0 == strcmp(ident, loc.name)) { - compile_opcode(C, OP_GETLOCAL); - compile_byte(C, loc.slot); - found_local = true; - break; - } - } - } - if (!found_local) { + Local *loc = locate_local(C, ident); + if (loc != NULL) { + compile_opcode(C, OP_GETLOCAL); + compile_byte(C, loc->slot); + } else { // read global ObjString *o = objstring_copy_cstr(C->S, a.as.str); compile_opcode(C, OP_GETGLOBAL); -- cgit v1.2.3