aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src/compiler.c
diff options
context:
space:
mode:
authorGravatar Tom Willemse2022-06-02 22:27:43 -0700
committerGravatar Tom Willemse2022-06-02 22:27:43 -0700
commit57ed9226c06b5fbe016e62857fe9662c51da3dfd (patch)
treef8bdae71c33f92ba1e105612ee848fcf168d3777 /clox/src/compiler.c
parente74cbddb0463e93f5d9742accc20bbed027d0b9b (diff)
downloadcrafting-interpreters-57ed9226c06b5fbe016e62857fe9662c51da3dfd.tar.gz
crafting-interpreters-57ed9226c06b5fbe016e62857fe9662c51da3dfd.zip
Chapter 25.3 & 25.4
Diffstat (limited to 'clox/src/compiler.c')
-rw-r--r--clox/src/compiler.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/clox/src/compiler.c b/clox/src/compiler.c
index 6e98b5e..75ed697 100644
--- a/clox/src/compiler.c
+++ b/clox/src/compiler.c
@@ -42,6 +42,7 @@ typedef struct {
typedef struct {
Token name;
int depth;
+ bool isCaptured;
} Local;
typedef struct {
@@ -197,6 +198,7 @@ static void initCompiler(Compiler *compiler, FunctionType type) {
Local *local = &current->locals[current->localCount++];
local->depth = 0;
+ local->isCaptured = false;
local->name.start = "";
local->name.length = 0;
}
@@ -224,7 +226,11 @@ static void endScope() {
while (current->localCount > 0 &&
current->locals[current->localCount - 1].depth > current->scopeDepth) {
- emitByte(OP_POP);
+ if (current->locals[current->localCount - 1].isCaptured) {
+ emitByte(OP_CLOSE_UPVALUE);
+ } else {
+ emitByte(OP_POP);
+ }
current->localCount--;
}
}
@@ -740,6 +746,7 @@ static int resolveUpvalue(Compiler *compiler, Token *name) {
int local = resolveLocal(compiler->enclosing, name);
if (local != -1) {
+ compiler->enclosing->locals[local].isCaptured = true;
return addUpvalue(compiler, (uint8_t)local, true);
}
@@ -760,6 +767,7 @@ static void addLocal(Token name) {
Local *local = &current->locals[current->localCount++];
local->name = name;
local->depth = -1;
+ local->isCaptured = false;
}
static void declareVariable() {