Chapter 22.3

This commit is contained in:
Tom Willemse 2021-10-21 20:54:35 -07:00
parent 42a7e26292
commit 9de87f4495

View file

@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "compiler.h"
@ -151,7 +152,15 @@ static void endCompiler() {
static void beginScope() { current->scopeDepth++; }
static void endScope() { current->scopeDepth--; }
static void endScope() {
current->scopeDepth--;
while (current->localCount > 0 &&
current->locals[current->localCount - 1].depth > current->scopeDepth) {
emitByte(OP_POP);
current->localCount--;
}
}
static void expression();
static void statement();
@ -419,12 +428,57 @@ static uint8_t identifierConstant(Token *name) {
return makeConstant(OBJ_VAL(copyString(name->start, name->length)));
}
static bool identifiersEqual(Token *a, Token *b) {
if (a->length != b->length)
return false;
return memcmp(a->start, b->start, a->length) == 0;
}
static void addLocal(Token name) {
if (current->localCount == UINT8_COUNT) {
error("Too many local variables in function.");
return;
}
Local *local = &current->locals[current->localCount++];
local->name = name;
local->depth = current->scopeDepth;
}
static void declareVariable() {
if (current->scopeDepth == 0)
return;
Token *name = &parser.previous;
for (int i = current->localCount - 1; i >= 0; i--) {
Local *local = &current->locals[i];
if (local->depth != -1 && local->depth < current->scopeDepth) {
break;
}
if (identifiersEqual(name, &local->name)) {
error("Already a variable with this name in this scope.");
}
}
addLocal(*name);
}
static uint8_t parseVariable(const char *errorMessage) {
consume(TOKEN_IDENTIFIER, errorMessage);
declareVariable();
if (current->scopeDepth > 0)
return 0;
return identifierConstant(&parser.previous);
}
static void defineVariable(uint8_t global) {
if (current->scopeDepth > 0) {
return;
}
emitBytes(OP_DEFINE_GLOBAL, global);
}