diff --git a/next/language/fundamentals.md b/next/language/fundamentals.md index d9741bfe..e13849c4 100644 --- a/next/language/fundamentals.md +++ b/next/language/fundamentals.md @@ -779,6 +779,17 @@ A functional loop consumes arguments and returns a value. It is defined using th Currently in `loop exprs { ... }`, `exprs` is nonempty list, while `for { ... }` is accepted for infinite loop. ``` +### Labelled Continue/Break + +When a loop is labelled, it can be referenced from a `break` or `continue` from +within a nested loop. For example: + +```{literalinclude} /sources/language/src/controls/top.mbt +:language: moonbit +:start-after: start loop label +:end-before: end loop label +``` + ## Iterator An iterator is an object that traverse through a sequence while providing access diff --git a/next/sources/language/src/controls/top.mbt b/next/sources/language/src/controls/top.mbt index 768859cc..48fcbdbf 100644 --- a/next/sources/language/src/controls/top.mbt +++ b/next/sources/language/src/controls/top.mbt @@ -211,7 +211,6 @@ test { i += j } assert_eq!(i, 45) - let mut k = 0 for l in 0..=10 { k += l @@ -220,6 +219,40 @@ test { } // end for loop 10 +// start loop label +test "break label" { + let mut count = 0 + let xs = [1, 2, 3] + let ys = [4, 5, 6] + let res = outer~: for i in xs { + for j in ys { + count = count + i + break outer~ j + } + } else { + -1 + } + assert_eq!(res, 4) + assert_eq!(count, 1) +} + +test "continue label" { + let mut count = 0 + let init = 10 + let res =outer~: loop init { + 0 => 42 + i => { + for { + count = count + 1 + continue outer~ i - 1 + } + } + } + assert_eq!(res, 42) + assert_eq!(count, 10) +} +// end loop label + // start guard 1 fn guarded_get(array : Array[Int], index : Int) -> Int? { guard index >= 0 && index < array.length() else { None } @@ -277,4 +310,4 @@ fn decide_sport(weather : String, humidity : Int) -> String { test { assert_eq!(decide_sport("sunny", 0), "tennis") } -// end match 1 \ No newline at end of file +// end match 1