Skip to content

Commit f80498f

Browse files
committed
add break and continue
1 parent 952a76c commit f80498f

File tree

5 files changed

+76
-14
lines changed

5 files changed

+76
-14
lines changed

examples/break_continue.cal

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
include "cores/select.cal"
2+
include "std/io.cal"
3+
4+
let cell i
5+
0 i !
6+
7+
while 1 do
8+
i @ 1 + i !
9+
i @ printdec new_line
10+
11+
if i @ 5 = then
12+
break
13+
end
14+
end
15+
16+
while 1 do
17+
break
18+
end

source/backends/linux86.d

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ private struct Word {
1616
Node[] inlineNodes;
1717
}
1818

19-
2019
private struct Type {
2120
ulong size;
2221
}
@@ -58,6 +57,7 @@ class BackendLinux86 : CompilerBackend {
5857
bool inScope;
5958
uint blockCounter;
6059
bool inWhile;
60+
uint currentLoop;
6161
Variable[] variables;
6262
Global[string] globals;
6363
Array[] arrays;
@@ -340,6 +340,7 @@ class BackendLinux86 : CompilerBackend {
340340
override void CompileWhile(WhileNode node) {
341341
++ blockCounter;
342342
uint blockNum = blockCounter;
343+
currentLoop = blockNum;
343344

344345
output ~= format("jmp __while_%d_condition\n", blockNum);
345346
output ~= format("__while_%d:\n", blockNum);
@@ -351,6 +352,8 @@ class BackendLinux86 : CompilerBackend {
351352
foreach (ref inode ; node.doWhile) {
352353
inWhile = true;
353354
compiler.CompileNode(inode);
355+
356+
currentLoop = blockNum;
354357
}
355358

356359
// restore scope
@@ -359,15 +362,14 @@ class BackendLinux86 : CompilerBackend {
359362
}
360363
variables = oldVars;
361364

365+
inWhile = false;
366+
362367
output ~= format("__while_%d_condition:\n", blockNum);
363368

364369
foreach (ref inode ; node.condition) {
365-
inWhile = true;
366370
compiler.CompileNode(inode);
367371
}
368372

369-
inWhile = false;
370-
371373
output ~= "sub r15, 8\n";
372374
output ~= "mov rax, [r15]\n";
373375
output ~= "cmp rax, 0\n";
@@ -553,4 +555,20 @@ class BackendLinux86 : CompilerBackend {
553555
NewConst(format("%s.max", node.name), node.values.maxElement());
554556
NewConst(format("%s.sizeof", node.name), types[node.name].size);
555557
}
558+
559+
override void CompileBreak(WordNode node) {
560+
if (!inWhile) {
561+
Error(node.error, "Not in while loop");
562+
}
563+
564+
output ~= format("jmp __while_%d_end\n", currentLoop);
565+
}
566+
567+
override void CompileContinue(WordNode node) {
568+
if (!inWhile) {
569+
Error(node.error, "Not in while loop");
570+
}
571+
572+
output ~= format("jmp __while_%d_condition\n", currentLoop);
573+
}
556574
}

source/backends/rm86.d

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class BackendRM86 : CompilerBackend {
6060
Array[] arrays;
6161
string thisFunc;
6262
bool inWhile;
63+
uint currentLoop;
6364

6465
this() {
6566
types["u8"] = Type(1);
@@ -295,6 +296,7 @@ class BackendRM86 : CompilerBackend {
295296
override void CompileWhile(WhileNode node) {
296297
++ blockCounter;
297298
uint blockNum = blockCounter;
299+
currentLoop = blockNum;
298300

299301
output ~= format("jmp __while_%d_condition\n", blockNum);
300302
output ~= format("__while_%d:\n", blockNum);
@@ -306,6 +308,8 @@ class BackendRM86 : CompilerBackend {
306308
foreach (ref inode ; node.doWhile) {
307309
inWhile = true;
308310
compiler.CompileNode(inode);
311+
312+
currentLoop = blockNum;
309313
}
310314

311315
// restore scope
@@ -314,15 +318,14 @@ class BackendRM86 : CompilerBackend {
314318
}
315319
variables = oldVars;
316320

321+
inWhile = false;
322+
317323
output ~= format("__while_%d_condition:\n", blockNum);
318324

319325
foreach (ref inode ; node.condition) {
320-
inWhile = true;
321326
compiler.CompileNode(inode);
322327
}
323328

324-
inWhile = false;
325-
326329
output ~= "sub si, 2\n";
327330
output ~= "mov ax, [si]\n";
328331
output ~= "cmp ax, 0\n";
@@ -514,4 +517,20 @@ class BackendRM86 : CompilerBackend {
514517
NewConst(format("%s.max", node.name), node.values.maxElement());
515518
NewConst(format("%s.sizeof", node.name), types[node.name].size);
516519
}
520+
521+
override void CompileBreak(WordNode node) {
522+
if (!inWhile) {
523+
Error(node.error, "Not in while loop");
524+
}
525+
526+
output ~= format("jmp __while_%d_end\n", currentLoop);
527+
}
528+
529+
override void CompileContinue(WordNode node) {
530+
if (!inWhile) {
531+
Error(node.error, "Not in while loop");
532+
}
533+
534+
output ~= format("jmp __while_%d_condition\n", currentLoop);
535+
}
517536
}

source/backends/y16.d

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,4 +351,12 @@ class BackendY16 : CompilerBackend {
351351
NewConst(format("%s.max", node.name), node.values.maxElement());
352352
NewConst(format("%s.sizeof", node.name), types[node.name].size);
353353
}
354+
355+
override void CompileBreak(WordNode node) {
356+
assert(0);
357+
}
358+
359+
override void CompileContinue(WordNode node) {
360+
assert(0);
361+
}
354362
}

source/compiler.d

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class CompilerBackend {
3737
abstract void CompileReturn(WordNode node);
3838
abstract void CompileConst(ConstNode node);
3939
abstract void CompileEnum(EnumNode node);
40+
abstract void CompileBreak(WordNode node);
41+
abstract void CompileContinue(WordNode node);
4042

4143
final void Error(Char, A...)(ErrorInfo error, in Char[] fmt, A args) {
4244
ErrorBegin(error);
@@ -73,13 +75,10 @@ class Compiler {
7375
auto node = cast(WordNode) inode;
7476

7577
switch (node.name) {
76-
case "return": {
77-
backend.CompileReturn(node);
78-
break;
79-
}
80-
default: {
81-
backend.CompileWord(node);
82-
}
78+
case "return": backend.CompileReturn(node); break;
79+
case "continue": backend.CompileContinue(node); break;
80+
case "break": backend.CompileBreak(node); break;
81+
default: backend.CompileWord(node);
8382
}
8483
break;
8584
}

0 commit comments

Comments
 (0)