diff options
Diffstat (limited to 'clox/src/compiler.c')
-rw-r--r-- | clox/src/compiler.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/clox/src/compiler.c b/clox/src/compiler.c index d965f45..beda5d5 100644 --- a/clox/src/compiler.c +++ b/clox/src/compiler.c @@ -119,6 +119,17 @@ static void emitBytes(uint8_t byte1, uint8_t byte2) { emitByte(byte2); } +static void emitLoop(int loopStart) { + emitByte(OP_LOOP); + + int offset = currentChunk()->count - loopStart + 2; + if (offset > UINT16_MAX) + error("Loop body too large."); + + emitByte((offset >> 8) & 0xff); + emitByte(offset & 0xff); +} + static int emitJump(uint8_t instruction) { emitByte(instruction); emitByte(0xff); @@ -302,6 +313,21 @@ static void printStatement() { emitByte(OP_PRINT); } +static void whileStatement() { + int loopStart = currentChunk()->count; + consume(TOKEN_LEFT_PAREN, "Expect '(' after 'while'."); + expression(); + consume(TOKEN_RIGHT_PAREN, "Expect ')' after condition."); + + int exitJump = emitJump(OP_JUMP_IF_FALSE); + emitByte(OP_POP); + statement(); + emitLoop(loopStart); + + patchJump(exitJump); + emitByte(OP_POP); +} + static void synchronize() { parser.panicMode = false; @@ -342,6 +368,8 @@ static void statement() { printStatement(); } else if (match(TOKEN_IF)) { ifStatement(); + } else if (match(TOKEN_WHILE)) { + whileStatement(); } else if (match(TOKEN_LEFT_BRACE)) { beginScope(); block(); |