diff options
author | ubq323 <ubq323@ubq323.website> | 2024-06-25 15:23:44 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2024-06-25 15:23:44 +0100 |
commit | e48386449b1f50c9f9d9b0645c8c469c1d4cbe4a (patch) | |
tree | 633eadafb39f383899fa681aa68248f5b1f0a99e | |
parent | 6aef97b52844b8868e5ada38ce0936619c1077a7 (diff) |
allow local resolution into outer scopes
-rw-r--r-- | com.c | 32 | ||||
-rw-r--r-- | tests/vars3.bth | 6 | ||||
-rw-r--r-- | tests/vars3.out | 1 | ||||
-rw-r--r-- | todo | 3 |
4 files changed, 25 insertions, 17 deletions
@@ -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); diff --git a/tests/vars3.bth b/tests/vars3.bth new file mode 100644 index 0000000..19e82fa --- /dev/null +++ b/tests/vars3.bth @@ -0,0 +1,6 @@ +(do + (set x 1) + (set y 10) + (let (x 2) + (let (y 20) + (+ x y)))) diff --git a/tests/vars3.out b/tests/vars3.out new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/tests/vars3.out @@ -0,0 +1 @@ +22 @@ -1,5 +1,4 @@ -functions, returning -locals, lexical scoping, closures, upvalues +closures, upvalues lists, hashes, other useful types garbage collector macros |