aboutsummaryrefslogtreecommitdiffstats
path: root/clox/src/compiler.c
diff options
context:
space:
mode:
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);
}