Added break and continue support to for loops
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user