Skip to content

Commit a51a586

Browse files
committed
Add loops test with separate exit and continue boundaries
Note that this does not rewrite to labeled returns yet because of some inlining limitations.
1 parent fbc8077 commit a51a586

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

tests/run/loops-alt.scala

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import scala.util.{boundary, break}
2+
import boundary.Label
3+
import java.util.concurrent.TimeUnit
4+
5+
object loop:
6+
opaque type ExitLabel = Label[Unit]
7+
opaque type ContinueLabel = Label[Unit]
8+
9+
inline def apply(inline op: (ExitLabel, ContinueLabel) ?=> Unit): Unit =
10+
boundary { exitLabel ?=>
11+
while true do
12+
boundary { continueLabel ?=>
13+
op(using exitLabel, continueLabel)
14+
}
15+
}
16+
end apply
17+
18+
inline def exit()(using ExitLabel): Unit =
19+
break()
20+
21+
inline def continue()(using ContinueLabel): Unit =
22+
break()
23+
end loop
24+
25+
def testLoop(xs: List[Int]) =
26+
var current = xs
27+
var sum = 0
28+
loop:
29+
// This should be convertible to labeled returns but isn't, since
30+
// the following code is still passed as a closure to `boundary`.
31+
// That's probably due to the additional facade operations necessary
32+
// for opaque types.
33+
if current.isEmpty then loop.exit()
34+
val hd = current.head
35+
current = current.tail
36+
if hd == 0 then loop.exit()
37+
if hd < 0 then loop.continue()
38+
sum += hd
39+
sum
40+
41+
@main def Test =
42+
assert(testLoop(List(1, 2, 3, -2, 4, -3, 0, 1, 2, 3)) == 10)
43+
assert(testLoop(List()) == 0)
44+
assert(testLoop(List(-2, -3, 0, 1)) == 0)
45+
46+

0 commit comments

Comments
 (0)