OmniMark provides five types of looping constructs: repeat
, repeat for
, repeat
to
, repeat over
, and repeat scan
.
You can use a repeat
loop to perform a series of actions repeatedly. You must explicitly exit a
repeat
loop using either a throw
or an exit
:
process local integer i initial { 1 } repeat output "i is " || "d" % i || "%n" increment i by i exit when i > 20 again
This program will create the following output:
i is 1 i is 2 i is 4 i is 8 i is 16
You can use a repeat to
to repeat a block of code a specific number of times. The loop will repeat
the number of times specified by an integer
expression following the to
:
process repeat to 5 output "X" again
The integer
expression following the keyword to
must evaluate to a value greater than 0 for the loop body to execute at all.
You can use a repeat for
loop to repeat over a block of code a specific number of times. The repeat for
loop provides an alias for the loop iteration and allows you to control the starting and ending
values of the alias, as well as the increment it is changed by:
process repeat for integer i from 9 to 27 by 3 output "d" % i || " " again
In the first interation, i will be equal to the integer
expression heralded by from
.
In successive iterations, at the beginning of each iteration i will by incremented by the integer
expression heralded by by
, until it surpasses the integer
expression heralded by to
, at which point the loop terminates. The starting value can be greater than the ending value, in which case
the increment must be negative; otherwise the loop will terminate without executing.
You can use a repeat over
loop to perform the same action on each item of a shelf in turn:
global string guys variable initial { "Bob", "Doug", "Andy", "Greg" } process repeat over guys output guys || "%n" again
An alias can be used to access the iteration's current item:
global string guys variable initial { "Bob", "Doug", "Andy", "Greg" } process repeat over guys as g output g || "%n" again
The alias is optional when iterating over a shelf, but required when iterating over a record
field
, a shelf literal, or a shelf-class function
The reversed
keyword can be used to indicate that loop should begin from the last item on the shelf and
iterate to the first item on the shelf:
global string guys variable initial { "Bob", "Doug", "Andy", "Greg" } process repeat over reversed guys as g output g || "%n" again
Multiple shelves can be specified in the header of a repeat over
loop. However, their sizes must match at run-time:
global string guys variable initial { "Bob", "Doug", "Andy", "Greg" } global integer ages variable initial { 36, 23, 45, 65 } process repeat over guys as g & ages as a output g || " is " || "d" % a || " years old.%n" again
When repeating over multiple shelves, the qualifier reversed
applies only to the shelf immediately
following it:
global string guys variable initial { "Bob", "Doug", "Andy", "Greg" } global integer ages variable initial { 36, 23, 45, 65 } process repeat over guys as g & reversed ages as a output g || " is " || "d" % a || " years old.%n" again
You can use a repeat scan
to scan a data stream. The repeat scan
loop will continue to
match data from the source until the source is exhausted or it encounters data that is not matched by any of its
alternatives:
process local string guesses initial { "sufklbp" } repeat scan "abcdefghijklmnopqrstuvwxyz" match any => l do unless guesses matches any ** l output l else output "*" done again