aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src/compiler.c
diff options
context:
space:
mode:
authorGravatar Tom Willemse2022-08-13 12:20:00 -0700
committerGravatar Tom Willemse2022-08-13 12:20:00 -0700
commit07f691425c95a53323229accd8a907c5dea7e530 (patch)
treef19d102a75daa1ac1d73208cbd19e5fbe471c300 /clox/src/compiler.c
parent4e77cfa61262a03055aeb273108fd9a49e8dfa4f (diff)
downloadcrafting-interpreters-07f691425c95a53323229accd8a907c5dea7e530.tar.gz
crafting-interpreters-07f691425c95a53323229accd8a907c5dea7e530.zip
Chapter 28.1
Diffstat (limited to 'clox/src/compiler.c')
-rw-r--r--clox/src/compiler.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/clox/src/compiler.c b/clox/src/compiler.c
index 6ab4855..31a7937 100644
--- a/clox/src/compiler.c
+++ b/clox/src/compiler.c
@@ -374,6 +374,15 @@ static void function(FunctionType type) {
}
}
+static void method() {
+ consume(TOKEN_IDENTIFIER, "Expect method name.");
+ uint8_t constant = identifierConstant(&parser.previous);
+
+ FunctionType type = TYPE_FUNCTION;
+ function(type);
+ emitBytes(OP_METHOD, constant);
+}
+
static bool identifiersEqual(Token *a, Token *b) {
if (a->length != b->length)
return false;
@@ -411,16 +420,46 @@ static void declareVariable() {
addLocal(*name);
}
+static void namedVariable(Token name, bool canAssign) {
+ uint8_t getOp, setOp;
+ int arg = resolveLocal(current, &name);
+
+ if (arg != -1) {
+ getOp = OP_GET_LOCAL;
+ setOp = OP_SET_LOCAL;
+ } else if ((arg = resolveUpvalue(current, &name)) != -1) {
+ getOp = OP_GET_UPVALUE;
+ setOp = OP_SET_UPVALUE;
+ } else {
+ arg = identifierConstant(&name);
+ getOp = OP_GET_GLOBAL;
+ setOp = OP_SET_GLOBAL;
+ }
+
+ if (canAssign && match(TOKEN_EQUAL)) {
+ expression();
+ emitBytes(setOp, arg);
+ } else {
+ emitBytes(getOp, arg);
+ }
+}
+
static void classDeclaration() {
consume(TOKEN_IDENTIFIER, "Expect class name");
+ Token className = parser.previous;
uint8_t nameConstant = identifierConstant(&parser.previous);
declareVariable();
emitBytes(OP_CLASS, nameConstant);
defineVariable(nameConstant);
+ namedVariable(className, false);
consume(TOKEN_LEFT_BRACE, "Expect '{' before class body.");
+ while (!check(TOKEN_RIGHT_BRACE) && !check(TOKEN_EOF)) {
+ method();
+ }
consume(TOKEN_RIGHT_BRACE, "Expect '}' after class body.");
+ emitByte(OP_POP);
}
static void markInitialized() {
@@ -643,30 +682,6 @@ static void string(bool canAssign) {
copyString(parser.previous.start + 1, parser.previous.length - 2)));
}
-static void namedVariable(Token name, bool canAssign) {
- uint8_t getOp, setOp;
- int arg = resolveLocal(current, &name);
-
- if (arg != -1) {
- getOp = OP_GET_LOCAL;
- setOp = OP_SET_LOCAL;
- } else if ((arg = resolveUpvalue(current, &name)) != -1) {
- getOp = OP_GET_UPVALUE;
- setOp = OP_SET_UPVALUE;
- } else {
- arg = identifierConstant(&name);
- getOp = OP_GET_GLOBAL;
- setOp = OP_SET_GLOBAL;
- }
-
- if (canAssign && match(TOKEN_EQUAL)) {
- expression();
- emitBytes(setOp, arg);
- } else {
- emitBytes(getOp, arg);
- }
-}
-
static void variable(bool canAssign) {
namedVariable(parser.previous, canAssign);
}