Support 'else' blocks on for and while loops
This commit is contained in:
parent
ece7da299a
commit
4a052191de
@ -1879,6 +1879,23 @@ static void continueStatement(void) {
|
|||||||
current->continues[current->continueCount++] = (struct LoopExit){emitJump(OP_JUMP),parser.previous};
|
current->continues[current->continueCount++] = (struct LoopExit){emitJump(OP_JUMP),parser.previous};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void optionalElse(size_t blockWidth) {
|
||||||
|
KrkScanner scannerBefore = krk_tellScanner();
|
||||||
|
Parser parserBefore = parser;
|
||||||
|
if (blockWidth == 0 || (check(TOKEN_INDENTATION) && (parser.current.length == blockWidth))) {
|
||||||
|
if (blockWidth) advance();
|
||||||
|
if (match(TOKEN_ELSE)) {
|
||||||
|
consume(TOKEN_COLON, "Expected ':' after 'else'.");
|
||||||
|
beginScope();
|
||||||
|
block(blockWidth,"else");
|
||||||
|
endScope();
|
||||||
|
} else {
|
||||||
|
krk_rewindScanner(scannerBefore);
|
||||||
|
parser = parserBefore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void whileStatement(void) {
|
static void whileStatement(void) {
|
||||||
size_t blockWidth = (parser.previous.type == TOKEN_INDENTATION) ? parser.previous.length : 0;
|
size_t blockWidth = (parser.previous.type == TOKEN_INDENTATION) ? parser.previous.length : 0;
|
||||||
advance();
|
advance();
|
||||||
@ -1900,6 +1917,7 @@ static void whileStatement(void) {
|
|||||||
emitLoop(loopStart);
|
emitLoop(loopStart);
|
||||||
patchJump(exitJump);
|
patchJump(exitJump);
|
||||||
emitByte(OP_POP);
|
emitByte(OP_POP);
|
||||||
|
optionalElse(blockWidth);
|
||||||
patchBreaks(loopStart);
|
patchBreaks(loopStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1992,8 +2010,8 @@ static void forStatement(void) {
|
|||||||
emitLoop(loopStart);
|
emitLoop(loopStart);
|
||||||
patchJump(exitJump);
|
patchJump(exitJump);
|
||||||
emitByte(OP_POP);
|
emitByte(OP_POP);
|
||||||
|
optionalElse(blockWidth);
|
||||||
patchBreaks(loopStart);
|
patchBreaks(loopStart);
|
||||||
|
|
||||||
endScope();
|
endScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
test/testLoopElse.krk
Normal file
32
test/testLoopElse.krk
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
def func(breakPoint):
|
||||||
|
let j = 0
|
||||||
|
for i in range(20):
|
||||||
|
if i == breakPoint:
|
||||||
|
break
|
||||||
|
j += 1
|
||||||
|
else:
|
||||||
|
print('finished for')
|
||||||
|
print('out of for')
|
||||||
|
return j
|
||||||
|
|
||||||
|
print(func(20))
|
||||||
|
print(func(15))
|
||||||
|
print(func(20))
|
||||||
|
print(func(15))
|
||||||
|
|
||||||
|
def func2(breakPoint):
|
||||||
|
let i = 0
|
||||||
|
while i < 20:
|
||||||
|
if i == breakPoint:
|
||||||
|
break
|
||||||
|
i++
|
||||||
|
else:
|
||||||
|
print('finished while')
|
||||||
|
print('out of while')
|
||||||
|
return i
|
||||||
|
|
||||||
|
print(func2(20))
|
||||||
|
print(func2(15))
|
||||||
|
print(func2(20))
|
||||||
|
print(func2(15))
|
20
test/testLoopElse.krk.expect
Normal file
20
test/testLoopElse.krk.expect
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
finished for
|
||||||
|
out of for
|
||||||
|
20
|
||||||
|
out of for
|
||||||
|
15
|
||||||
|
finished for
|
||||||
|
out of for
|
||||||
|
20
|
||||||
|
out of for
|
||||||
|
15
|
||||||
|
finished while
|
||||||
|
out of while
|
||||||
|
20
|
||||||
|
out of while
|
||||||
|
15
|
||||||
|
finished while
|
||||||
|
out of while
|
||||||
|
20
|
||||||
|
out of while
|
||||||
|
15
|
Loading…
Reference in New Issue
Block a user