aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src
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
parent63527558a72fb56d11d1166ce958dcfc8a765482 (diff)
downloadcrafting-interpreters-a819a85209646cb7dba87c49e904dd47cc804133.tar.gz
crafting-interpreters-a819a85209646cb7dba87c49e904dd47cc804133.zip
Chapter 27.2
Diffstat (limited to 'clox/src')
-rw-r--r--clox/src/chunk.h1
-rw-r--r--clox/src/compiler.c90
-rw-r--r--clox/src/debug.c2
-rw-r--r--clox/src/vm.c3
4 files changed, 58 insertions, 38 deletions
diff --git a/clox/src/chunk.h b/clox/src/chunk.h
index e992c04..ae0ab72 100644
--- a/clox/src/chunk.h
+++ b/clox/src/chunk.h
@@ -34,6 +34,7 @@ typedef enum {
OP_CLOSURE,
OP_CLOSE_UPVALUE,
OP_RETURN,
+ OP_CLASS,
} OpCode;
typedef struct {
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);
diff --git a/clox/src/debug.c b/clox/src/debug.c
index 750fdb9..a2c2c53 100644
--- a/clox/src/debug.c
+++ b/clox/src/debug.c
@@ -122,6 +122,8 @@ int disassembleInstruction(Chunk *chunk, int offset) {
return simpleInstruction("OP_CLOSE_UPVALUE", offset);
case OP_RETURN:
return simpleInstruction("OP_RETURN", offset);
+ case OP_CLASS:
+ return constantInstruction("OP_CLASS", chunk, offset);
default:
printf("Unknown opcode %d\n", instruction);
return offset + 1;
diff --git a/clox/src/vm.c b/clox/src/vm.c
index 601b128..37bf2d4 100644
--- a/clox/src/vm.c
+++ b/clox/src/vm.c
@@ -384,6 +384,9 @@ static InterpretResult run() {
frame = &vm.frames[vm.frameCount - 1];
break;
}
+ case OP_CLASS:
+ push(OBJ_VAL(newClass(READ_STRING())));
+ break;
}
}