From a819a85209646cb7dba87c49e904dd47cc804133 Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Fri, 12 Aug 2022 21:17:45 -0700 Subject: Chapter 27.2 --- clox/src/compiler.c | 90 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 38 deletions(-) (limited to 'clox/src/compiler.c') 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 = ¤t->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 = ¤t->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 = ¤t->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 = ¤t->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); -- cgit v1.2.3-54-g00ecf