diff options
Diffstat (limited to 'clox/src/compiler.c')
-rw-r--r-- | clox/src/compiler.c | 10 |
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 = ¤t->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 = ¤t->locals[current->localCount++]; local->name = name; local->depth = -1; + local->isCaptured = false; } static void declareVariable() { |