Skip to content

Commit

Permalink
Add named break and continue, closes #228
Browse files Browse the repository at this point in the history
This commit adds support for cases like this:

    i := 0;
    outer: while i<3 next i++ {  // loop named "outer"
        j := 0;
        inner: while j<3 next j++ {  // loop named "inner"
            std::cout << i << j << " ";
            if j == 1 {
                continue outer;  // continue the outer loop
            }
            std::cout << "inner ";
        }
        std::cout << "outer ";
    }
  • Loading branch information
hsutter committed Jan 16, 2023
1 parent a926a30 commit 8609922
Show file tree
Hide file tree
Showing 14 changed files with 780 additions and 26 deletions.
5 changes: 3 additions & 2 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,9 @@
#endif


#define CPP2_TYPEOF(x) std::remove_cvref_t<decltype(x)>
#define CPP2_FORWARD(x) std::forward<decltype(x)>(x)
#define CPP2_TYPEOF(x) std::remove_cvref_t<decltype(x)>
#define CPP2_FORWARD(x) std::forward<decltype(x)>(x)
#define CPP2_BREAK_CONTINUE(NAME) goto CONTINUE_##NAME; BREAK_##NAME: break; CONTINUE_##NAME: continue;


namespace cpp2 {
Expand Down
230 changes: 230 additions & 0 deletions regression-tests/pure2-break-continue.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@

main: () -> int =
{
std::cout << "while_continue_inner:\n "; while_continue_inner();
std::cout << "\nwhile_continue_outer:\n "; while_continue_outer();
std::cout << "\nwhile_break_inner:\n "; while_break_inner();
std::cout << "\nwhile_break_outer:\n "; while_break_outer();

std::cout << "\n\ndo_continue_inner:\n "; do_continue_inner();
std::cout << "\ndo_continue_outer:\n "; do_continue_outer();
std::cout << "\ndo_break_inner:\n "; do_break_inner();
std::cout << "\ndo_break_outer:\n "; do_break_outer();

std::cout << "\n\nfor_continue_inner:\n "; for_continue_inner();
std::cout << "\nfor_continue_outer:\n "; for_continue_outer();
std::cout << "\nfor_break_inner:\n "; for_break_inner();
std::cout << "\nfor_break_outer:\n "; for_break_outer();
}

while_continue_inner: () =
{
i := 0;
outer: while i<3 next i++ {
j := 0;
inner: while j<3 next j++ {
std::cout << i << j << " ";
if j == 1 {
continue inner;
}
std::cout << "inner ";
}
std::cout << "outer ";
}
}

while_continue_outer: () =
{
i := 0;
outer: while i<3 next i++ {
j := 0;
inner: while j<3 next j++ {
std::cout << i << j << " ";
if j == 1 {
continue outer;
}
std::cout << "inner ";
}
std::cout << "outer ";
}
}

while_break_inner: () =
{
i := 0;
outer: while i<3 next i++ {
j := 0;
inner: while j<3 next j++ {
std::cout << i << j << " ";
if j == 1 {
break inner;
}
std::cout << "inner ";
}
std::cout << "outer ";
}
}

while_break_outer: () =
{
i := 0;
outer: while i<3 next i++ {
j := 0;
inner: while j<3 next j++ {
std::cout << i << j << " ";
if j == 1 {
break outer;
}
std::cout << "inner ";
}
std::cout << "outer ";
}
}

do_continue_inner: () =
{
i := 0;
outer: do {
j := 0;
inner: do {
std::cout << i << j << " ";
if j == 1 {
continue inner;
}
std::cout << "inner ";
}
while j<3 next j++;

std::cout << "outer ";
}
while i<3 next i++;
}

do_continue_outer: () =
{
i := 0;
outer: do {
j := 0;
inner: do {
std::cout << i << j << " ";
if j == 1 {
continue outer;
}
std::cout << "inner ";
}
while j<3 next j++;

std::cout << "outer ";
}
while i<3 next i++;
}

do_break_inner: () =
{
i := 0;
outer: do {
j := 0;
inner: do {
std::cout << i << j << " ";
if j == 1 {
break inner;
}
std::cout << "inner ";
}
while j<3 next j++;

std::cout << "outer ";
}
while i<3 next i++;
}

do_break_outer: () =
{
i := 0;
outer: do {
j := 0;
inner: do {
std::cout << i << j << " ";
if j == 1 {
break outer;
}
std::cout << "inner ";
}
while j<3 next j++;

std::cout << "outer ";
}
while i<3 next i++;
}

for_continue_inner: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
outer: for vi next counter++ do :(i) = {
vj: std::vector = ( 0, 1, 2 );
inner: for vj do :(j) = {
std::cout << i << j << " ";
if j == 1 {
continue inner;
}
std::cout << "inner ";
}

std::cout << "outer ";
}
}

for_continue_outer: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
outer: for vi next counter++ do :(i) = {
vj: std::vector = ( 0, 1, 2 );
inner: for vj do :(j) = {
std::cout << i << j << " ";
if j == 1 {
continue outer;
}
std::cout << "inner ";
}

std::cout << "outer ";
}
}

for_break_inner: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
outer: for vi next counter++ do :(i) = {
vj: std::vector = ( 0, 1, 2 );
inner: for vj do :(j) = {
std::cout << i << j << " ";
if j == 1 {
break inner;
}
std::cout << "inner ";
}

std::cout << "outer ";
}
}

for_break_outer: () =
{
vi: std::vector = ( 0, 1, 2 );
counter := 0;
outer: for vi next counter++ do :(i) = {
vj: std::vector = ( 0, 1, 2 );
inner: for vj do :(j) = {
std::cout << i << j << " ";
if j == 1 {
break outer;
}
std::cout << "inner ";
}

std::cout << "outer ";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
while_continue_inner:
00 inner 01 02 inner outer 10 inner 11 12 inner outer 20 inner 21 22 inner outer
while_continue_outer:
00 inner 01 10 inner 11 20 inner 21
while_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer
while_break_outer:
00 inner 01

do_continue_inner:
00 inner 01 02 inner 03 inner outer 10 inner 11 12 inner 13 inner outer 20 inner 21 22 inner 23 inner outer 30 inner 31 32 inner 33 inner outer
do_continue_outer:
00 inner 01 10 inner 11 20 inner 21 30 inner 31
do_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer 30 inner 31 outer
do_break_outer:
00 inner 01

for_continue_inner:
00 inner 01 02 inner outer 10 inner 11 12 inner outer 20 inner 21 22 inner outer
for_continue_outer:
00 inner 01 10 inner 11 20 inner 21
for_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer
for_break_outer:
00 inner 01
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
while_continue_inner:
00 inner 01 02 inner outer 10 inner 11 12 inner outer 20 inner 21 22 inner outer
while_continue_outer:
00 inner 01 10 inner 11 20 inner 21
while_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer
while_break_outer:
00 inner 01

do_continue_inner:
00 inner 01 02 inner 03 inner outer 10 inner 11 12 inner 13 inner outer 20 inner 21 22 inner 23 inner outer 30 inner 31 32 inner 33 inner outer
do_continue_outer:
00 inner 01 10 inner 11 20 inner 21 30 inner 31
do_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer 30 inner 31 outer
do_break_outer:
00 inner 01

for_continue_inner:
00 inner 01 02 inner outer 10 inner 11 12 inner outer 20 inner 21 22 inner outer
for_continue_outer:
00 inner 01 10 inner 11 20 inner 21
for_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer
for_break_outer:
00 inner 01
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
while_continue_inner:
00 inner 01 02 inner outer 10 inner 11 12 inner outer 20 inner 21 22 inner outer
while_continue_outer:
00 inner 01 10 inner 11 20 inner 21
while_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer
while_break_outer:
00 inner 01

do_continue_inner:
00 inner 01 02 inner 03 inner outer 10 inner 11 12 inner 13 inner outer 20 inner 21 22 inner 23 inner outer 30 inner 31 32 inner 33 inner outer
do_continue_outer:
00 inner 01 10 inner 11 20 inner 21 30 inner 31
do_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer 30 inner 31 outer
do_break_outer:
00 inner 01

for_continue_inner:
00 inner 01 02 inner outer 10 inner 11 12 inner outer 20 inner 21 22 inner outer
for_continue_outer:
00 inner 01 10 inner 11 20 inner 21
for_break_inner:
00 inner 01 outer 10 inner 11 outer 20 inner 21 outer
for_break_outer:
00 inner 01
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pure2-break-continue.cpp
Loading

0 comments on commit 8609922

Please sign in to comment.