aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src/compiler.c
diff options
context:
space:
mode:
authorGravatar Tom Willemse2022-08-12 21:17:45 -0700
committerGravatar Tom Willemse2022-08-12 21:17:45 -0700
commita819a85209646cb7dba87c49e904dd47cc804133 (patch)
tree8d9e79304ce4a33d88d4405b0973ee0d8c5cf18f /clox/src/compiler.c
parent63527558a72fb56d11d1166ce958dcfc8a765482 (diff)
downloadcrafting-interpreters-a819a85209646cb7dba87c49e904dd47cc804133.tar.gz
crafting-interpreters-a819a85209646cb7dba87c49e904dd47cc804133.zip
Chapter 27.2
Diffstat (limited to 'clox/src/compiler.c')
-rw-r--r--clox/src/compiler.c90
1 files changed, 52 insertions, 38 deletions
diff --git a/clox/src/compiler.c b/clox/src/compiler.c
index f31d015..b21a53d 100644
--- a/clox/src/compiler.c
+++ b/clox/src/compiler.c
@@ -362,6 +362,55 @@ static void function(FunctionType type) {
}
}
+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 = -1;
+ local->isCaptured = false;
+}
+
+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 void classDeclaration() {
+ consume(TOKEN_IDENTIFIER, "Expect class name");
+ uint8_t nameConstant = identifierConstant(&parser.previous);
+ declareVariable();
+
+ emitBytes(OP_CLASS, nameConstant);
+ defineVariable(nameConstant);
+
+ consume(TOKEN_LEFT_BRACE, "Expect '{' before class body.");
+ consume(TOKEN_RIGHT_BRACE, "Expect '}' after class body.");
+}
+
static void markInitialized() {
if (current->scopeDepth == 0)
return;
@@ -518,7 +567,9 @@ static void synchronize() {
}
static void declaration() {
- if (match(TOKEN_FUN)) {
+ if (match(TOKEN_CLASS)) {
+ classDeclaration();
+ } else if (match(TOKEN_FUN)) {
funDeclaration();
} else if (match(TOKEN_VAR)) {
varDeclaration();
@@ -701,12 +752,6 @@ 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 int resolveLocal(Compiler *compiler, Token *name) {
for (int i = compiler->localCount - 1; i >= 0; i--) {
Local *local = &compiler->locals[i];
@@ -759,37 +804,6 @@ static int resolveUpvalue(Compiler *compiler, Token *name) {
return -1;
}
-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 = -1;
- local->isCaptured = false;
-}
-
-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);