Loops¶
Minilang has several looping constructs:
Loop expressions¶
The simplest looping expression in Minilang is the loop
-expression which repeatedly evaluates a block of code until the loop is exited using an exit
-expression somewhere in the body of the loop.
The loop returns the value of the expression after exit
, or nil
if the expression in omitted.
A next
-expression causes the loop to move onto its next iteration immediately.
Normally, exit
-expressions are used within conditional expressions such as if
-expressions or with and
or or
. For convenience, Minilang provides while
-expressions and until
-expressions.
If the first expression after while
evaluates to nil
then the loop exits with the value of the second expression, or nil
is the second expression is omitted. Otherwise, the while
-expression evaluates to the result of the first expression.
1while X, Y
2:> behaves like
3if let Temp := X then Temp else exit Y end
4
5while X
6:> behaves like
7if let Temp := X then Temp else exit Temp :<nil>: end
If the first expression after until
evaluates to anything other than nil
then the loop exits with the value of the second expression, or the value of the first expression if the second expression is omitted. Otherwise, the until
-expression evaluates to nil
.
1until X, Y
2:> behaves like
3if let Temp := X then exit Y else nil end
4
5until X
6:> behaves like
7if let Temp := X then exit Temp else nil end
Exiting nested loops¶
The optional expression passed to exit
is evaluated in the context of the surrounding loop. For example, to exit 2 loops at once, exit exit Value
can be used. Likewise, to skip to the start of the surrounding loop, exit next
can be used.
1let (I, J, K) := for I in 1 .. 10 do
2 for J in 1 .. 10 do
3 let K := math::sqrt((I * I) + (J * J))
4 if K in integer then
5 exit exit (I, J, K)
6 end
7 end
8end
9
10print('I = {I}, J = {J}, K = {K}\n')
I = 3, J = 4, K = 5
Named loops¶
If it is required to exit or restart deeply nested loops, using multiple exit
's can be inconvenient and error prone. Minilang allows loops (both loop
and for
) to be named and then referred to in a exit
or next
expression.
1main :- for I in 1 .. 10 do
2 for J in 1 .. 10 do
3 if I * J = 9 then
4 main :- next
5 end
6 if (I * I) + (J * J) = (5 * 5) then
7 main :- exit '{I}^2 + {J}^2 = {5}^2'
8 end
9 end
10end
4^2 + 3^2 = 5^2
For expressions¶
A for
-expressions loops over a sequence, binding the generated keys and values to local variables and evaluating a block of code for each iteration. The loop stops when the sequence is exhausted, or if a exit
expression is used to exit the loop.
If a for
-expression exhausts its sequence without exiting, the else
-block will be evaluated and the returned as the value of the for
-expression. If the else
-block is omitted (usually the case), the value of the for
-expression will be nil
.
A next
-expression can also be used in a for
-expression which will advance to the next iteration of the sequence.
1for I in 1 .. 10 do
2 I = 3 and next
3 print('I = {I}\n')
4 I = 8 and exit "Done!"
5end
I = 1
I = 2
I = 4
I = 5
I = 6
I = 7
I = 8
Done!
Each expressions¶
An each
-expression simply loops over a sequence.
1each X
2:> behaves like
3for Temp in X do end