Chapter 23.3

This commit is contained in:
Tom Willemse 2022-01-12 23:09:36 -08:00
parent ba6ab6759e
commit 37ac05af6d
4 changed files with 36 additions and 0 deletions

View file

@ -27,6 +27,7 @@ typedef enum {
OP_PRINT,
OP_JUMP,
OP_JUMP_IF_FALSE,
OP_LOOP,
OP_RETURN,
} OpCode;

View file

@ -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();

View file

@ -92,6 +92,8 @@ int disassembleInstruction(Chunk *chunk, int offset) {
return jumpInstruction("OP_JUMP", 1, chunk, offset);
case OP_JUMP_IF_FALSE:
return jumpInstruction("OP_JUMP_IF_FALSE", 1, chunk, offset);
case OP_LOOP:
return jumpInstruction("OP_LOOP", -1, chunk, offset);
case OP_RETURN:
return simpleInstruction("OP_RETURN", offset);
default:

View file

@ -211,6 +211,11 @@ static InterpretResult run() {
vm.ip += offset;
break;
}
case OP_LOOP: {
uint16_t offset = READ_SHORT();
vm.ip -= offset;
break;
}
case OP_RETURN: {
/* The book said to remove this, but when I do I get an infinite loop and
then a segfault because it keeps trying to add the constant 1 to the