9.5. Coroutines and additional generator support

The COROUTINES module provides coroutine infrastructure including the [coroutine] function annotation, yield_from for delegating to sub-coroutines, and co_await for composing asynchronous generators. Coroutines produce values lazily via yield and can be iterated with for.

See Iterators and Generators for a hands-on tutorial.

All functions and symbols are in “coroutines” module, use require to get access to it.

require daslib/coroutines

Example:

require daslib/coroutines

[coroutine]
def fibonacci() : int {
    var a = 0
    var b = 1
    while (true) {
        yield a
        let next = a + b
        a = b
        b = next
    }
}

[export]
def main() {
    var count = 0
    for (n in fibonacci()) {
        print("{n} ")
        count ++
        if (count >= 10) {
            break
        }
    }
    print("\n")
}
// output:
// 0 1 1 2 3 5 8 13 21 34

9.5.1. Type aliases

Coroutine = iterator<bool>

A coroutine is a generator that yields bool to indicate if it is still running.

Coroutines = array<iterator<bool>>

An array of coroutines.

9.5.2. Function annotations

coroutine

This macro converts coroutine function into generator, adds return false.

9.5.3. Call macros

co_continue

This macro converts co_continue to yield true. The idea is that coroutine without specified type is underneath a coroutine which yields bool. That way co_continue() does not distract from the fact that it is a generator<bool>.

co_await

This macro converts co_await(sub_coroutine) into equivalent inline code.

yeild_from

This macro converts a yeild_from(THAT) expression into equivalent inline code.

9.5.4. Top level coroutine evaluation

cr_run(a: Coroutine )

This function runs coroutine until it is finished.

Arguments:
cr_run_all(a: Coroutines )

This function runs all coroutines until they are finished.

Arguments: