diff options
author | Tom Willemse | 2022-08-14 16:11:39 -0700 |
---|---|---|
committer | Tom Willemse | 2022-08-14 16:11:39 -0700 |
commit | cb42c811218b30ff9ff1a194b18fe3d85ea68a50 (patch) | |
tree | 5d0b5d6388ab6cdda9323fddf96d49364a0dd8f8 /clox/src/compiler.c | |
parent | 7871383a400f0a37dbd8459755aa9f98e2742f7a (diff) | |
download | crafting-interpreters-cb42c811218b30ff9ff1a194b18fe3d85ea68a50.tar.gz crafting-interpreters-cb42c811218b30ff9ff1a194b18fe3d85ea68a50.zip |
Chapter 28.4
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); |