aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2022-08-14 22:27:35 -0700
committerGravatar Tom Willemse2022-08-14 22:27:35 -0700
commit1bba129074b812a354eccfdd9cc69b233789dc6c (patch)
treea7857b95740303e7ad6d78afd81135b46b5f824b
parent726803c9d0c84bccc1d82d1c8aeadfc711752622 (diff)
downloadcrafting-interpreters-1bba129074b812a354eccfdd9cc69b233789dc6c.tar.gz
crafting-interpreters-1bba129074b812a354eccfdd9cc69b233789dc6c.zip
Chapter 29.2
-rw-r--r--clox/src/compiler.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/clox/src/compiler.c b/clox/src/compiler.c
index f14666c..599ad1b 100644
--- a/clox/src/compiler.c
+++ b/clox/src/compiler.c
@@ -71,6 +71,7 @@ typedef struct Compiler {
typedef struct ClassCompiler {
struct ClassCompiler *enclosing;
+ bool hasSuperclass;
} ClassCompiler;
static int resolveUpvalue(Compiler *, Token *);
@@ -478,6 +479,13 @@ static void variable(bool canAssign) {
namedVariable(parser.previous, canAssign);
}
+static Token syntheticToken(const char *text) {
+ Token token;
+ token.start = text;
+ token.length = (int)strlen(text);
+ return token;
+}
+
static void classDeclaration() {
consume(TOKEN_IDENTIFIER, "Expect class name");
Token className = parser.previous;
@@ -488,6 +496,7 @@ static void classDeclaration() {
defineVariable(nameConstant);
ClassCompiler classCompiler;
+ classCompiler.hasSuperclass = false;
classCompiler.enclosing = currentClass;
currentClass = &classCompiler;
@@ -499,8 +508,13 @@ static void classDeclaration() {
error("A class can't inherit from itself.");
}
+ beginScope();
+ addLocal(syntheticToken("super"));
+ defineVariable(0);
+
namedVariable(className, false);
emitByte(OP_INHERIT);
+ classCompiler.hasSuperclass = true;
}
namedVariable(className, false);
@@ -511,6 +525,10 @@ static void classDeclaration() {
consume(TOKEN_RIGHT_BRACE, "Expect '}' after class body.");
emitByte(OP_POP);
+ if (classCompiler.hasSuperclass) {
+ endScope();
+ }
+
currentClass = currentClass->enclosing;
}