Chapter 23.3
This commit is contained in:
parent
ba6ab6759e
commit
37ac05af6d
4 changed files with 36 additions and 0 deletions
|
@ -27,6 +27,7 @@ typedef enum {
|
|||
OP_PRINT,
|
||||
OP_JUMP,
|
||||
OP_JUMP_IF_FALSE,
|
||||
OP_LOOP,
|
||||
OP_RETURN,
|
||||
} OpCode;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue