Added break and continue support to for loops

This commit is contained in:
2026-05-24 18:53:45 +10:00
parent f11bc95833
commit 95362ed6fc
4 changed files with 43 additions and 6 deletions
+1 -1
View File
@@ -289,7 +289,7 @@ int inspect_instruction(unsigned char* bytecode, unsigned int pc, unsigned int j
return 8;
case TOY_OPCODE_ESCAPE:
printf(MARKER TOY_CC_DEBUG "ESCAPE relative %s%d (GOTO %u) and pop %d\n" TOY_CC_RESET, MARKER_VALUE(pc, unsigned char),
printf(MARKER TOY_CC_DEBUG "ESCAPE relative %s%d (GOTO %u) and pop %d scopes\n" TOY_CC_RESET, MARKER_VALUE(pc, unsigned char),
(*(int*)(bytecode + pc + 4)) > 0 ? "+" : "", //show a + sign when positive
(*(int*)(bytecode + pc + 4)),
(*(int*)(bytecode + pc + 4)) + pc + 12,
+2 -2
View File
@@ -1,10 +1,10 @@
var array = ["foo", "bar"];
var array = ["foo", "bar", "buzz", "fizz"];
for (var i in array) {
if (i == "buzz") break; //use break or continue
print i;
break;
}
print "done";
+35
View File
@@ -784,6 +784,41 @@ static unsigned int writeInstructionForThen(Toy_Bytecode** mb, Toy_AstForThen as
//end of the loop, overwrite the parameter
OVERWRITE_INT(mb, code, thenParamAddr, CURRENT_ADDRESS(mb, code) - (thenParamAddr + 4));
//set the break & continue data
while ((*mb)->breakEscapes->count > 0) {
//extract
unsigned int addr = (*mb)->breakEscapes->data[(*mb)->breakEscapes->count - 1].addr;
unsigned int depth = (*mb)->breakEscapes->data[(*mb)->breakEscapes->count - 1].depth;
unsigned int diff = depth - (*mb)->currentScopeDepth;
OVERWRITE_INT(mb, code, addr, CURRENT_ADDRESS(mb, code) - (addr + 8)); //tell break to come here AFTER reading the instruction
OVERWRITE_INT(mb, code, addr, diff);
//tick down
(*mb)->breakEscapes->count--;
}
while ((*mb)->continueEscapes->count > 0) {
//extract
unsigned int addr = (*mb)->continueEscapes->data[(*mb)->continueEscapes->count - 1].addr;
unsigned int depth = (*mb)->continueEscapes->data[(*mb)->continueEscapes->count - 1].depth;
unsigned int diff = depth - (*mb)->currentScopeDepth;
OVERWRITE_INT(mb, code, addr, beginAddr - (addr + 8)); //tell continue to return to the start AFTER reading the instruction
OVERWRITE_INT(mb, code, addr, diff);
//tick down
(*mb)->continueEscapes->count--;
}
//eliminate the value & counter from within the bytecode, so they're cleaned up after breaks
EMIT_BYTE(mb, code,TOY_OPCODE_ELIMINATE);
EMIT_BYTE(mb, code, 2);
EMIT_BYTE(mb, code, 0);
EMIT_BYTE(mb, code, 0);
return 0;
}
+5 -3
View File
@@ -499,9 +499,11 @@ static void processIterate(Toy_VM* vm) {
//check out-of-bounds
if (index >= array->count) {
Toy_freeValue(counter);
Toy_freeValue(compound);
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL()); //force a jump
//DON'T free the iterable & counter, that's embedded in the bytecode
Toy_pushStack(&vm->stack, compound);
Toy_pushStack(&vm->stack, counter);
//force a jump then exit
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL());
processJump(vm);
return;
}