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.c28
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();