![]() |
|
||||
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
|||||
|
|
|||||
| Prerequisite Concepts | Related Topics | ||||
Coroutines |
|||||
OmniMark can execute multiple computations concurrently by interleaving the execution of their actions. The interleaved computations are called coroutines.
Coroutines are an important ingredient of the streaming programming paradigm. Every coroutine in OmniMark either produces a stream or consumes it. There are four types of coroutines:
string source coroutines that produce a stream of textual data,
string sink coroutines which consume a stream of textual data,
markup source coroutines, producing a stream of parsed markup, and
markup sink coroutines that consume a stream of parsed markup.
Another feature of coroutines in OmniMark is that they always exist in pairs. A string source producer
coroutine is always paired with a string sink consumer coroutine, and vice versa. The same relationship
exists between the coroutines of markup source and markup sink type; they are always paired
together as well. The data stream produced by one coroutine, which it outputs into its #current-output, is
fed to and consumed by the other coroutine through its #current-input.
To define a coroutine, use define function syntax with one of the four types listed above: for
example, define string sink function. OmniMark will create a new coroutine pair whenever the function
is called. The following example will serve to demonstrate some of the concepts behind coroutines in OmniMark:
define string source function
producer
as
using output as #main-output & #current-output
repeat for integer count
output "4fkd" % count || "%n"
again
process
local integer total
output "The numbers that add up to more than 100 are:%n"
repeat scan producer
match white-space* digit+ => n
set total to total + n
exit
when total > 100
again
output "----%n"
output "4fkd" % total || "%n"
In this example, the function producer defines a coroutine producing a string source. When
the function is called, OmniMark creates a coroutine pair out of producer and the repeat scan
loop that acts as the consumer. After that, the following things happen in order:
repeat scan begins
to run.
match clause attempts to match a pattern against #current-input. Since there is
nothing there yet, the consumer suspends and hands control over to producer. If the consumer
terminated without trying to consume its input, the producer would not have run at all.
repeat for loop, outputs the first number (both to
the consumer and to #main-output where we can see it) and suspends.
match clause consumes the first number, adds it to total, and loops.
repeat for and repeat scan, alternate in producing and consuming the
numbers …
repeat scan loop is exited and the consumer terminates.
process rule continues to execute and outputs the final
total.
The output of the program is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
----
105
The two coroutines in a pair form a coroutine scope: OmniMark guarantees that they have the same lifetime by synchronizing their initialization and termination.
The use of coroutines has three principal advantages:
For the most part, you do not need to concern yourself with the mechanics of coroutines. OmniMark handles all the details for you. However, there are some important restrictions you need to be aware of:
save and save-clear operations are specific to the coroutine in which they
occur, if performed on a global declared with the domain-bound qualifier.
using nested-referents can only be used in one coroutine at a time.
If you write code that depends on the interaction between two coroutines, you may need to be aware of the rules OmniMark uses when switching from one coroutine to another.
string source function that feeds do xml-parse, you can test to determine what the current element
is in the parsing routine using the element is test.
output
action, except as follows.
#markup-parser, there will be no context switch for the
duration of a repeat over loop or a using block applied to the
attributes shelf, the data-attributes shelf, or a list-valued attribute shelf.
|
Prerequisite Concepts
|
Related Topics
|
Copyright © Stilo International plc, 1988-2010.