diff options
Diffstat (limited to 'clox/src/compiler.c')
-rw-r--r-- | clox/src/compiler.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/clox/src/compiler.c b/clox/src/compiler.c index a773e97..4dded64 100644 --- a/clox/src/compiler.c +++ b/clox/src/compiler.c @@ -51,7 +51,12 @@ typedef struct { bool isLocal; } Upvalue; -typedef enum { TYPE_FUNCTION, TYPE_METHOD, TYPE_SCRIPT } FunctionType; +typedef enum { + TYPE_FUNCTION, + TYPE_INITIALIZER, + TYPE_METHOD, + TYPE_SCRIPT +} FunctionType; typedef struct Compiler { struct Compiler *enclosing; @@ -159,7 +164,12 @@ static int emitJump(uint8_t instruction) { } static void emitReturn() { - emitByte(OP_NIL); + if (current->type == TYPE_INITIALIZER) { + emitBytes(OP_GET_LOCAL, 0); + } else { + emitByte(OP_NIL); + } + emitByte(OP_RETURN); } @@ -389,6 +399,11 @@ static void method() { uint8_t constant = identifierConstant(&parser.previous); FunctionType type = TYPE_METHOD; + if (parser.previous.length == 4 && + memcmp(parser.previous.start, "init", 4) == 0) { + type = TYPE_INITIALIZER; + } + function(type); emitBytes(OP_METHOD, constant); } @@ -588,6 +603,10 @@ static void returnStatement() { if (match(TOKEN_SEMICOLON)) { emitReturn(); } else { + if (current->type == TYPE_INITIALIZER) { + error("Can't return a value from an initializer."); + } + expression(); consume(TOKEN_SEMICOLON, "Expect ';' after return value."); emitByte(OP_RETURN); |