Yield in BHL

May 21, 2026 ยท View on GitHub

The yield keyword in BHL is used for coroutine control flow, allowing functions to pause execution and resume later. This is particularly useful for game development, animations, and other scenarios requiring time-based control.

Basic Usage

Coroutine Functions

Functions using yield must be marked with the coro keyword:

// Valid: Function with yield is marked as coro
coro func example() {
    yield()  // Pause execution until next tick
}

// Invalid: Will cause compile error
func wrong() {
    yield()  // Error: function with yield calls must be coro
}

Empty Coroutines

Coroutine functions must contain at least one yield call:

// Invalid: Will cause compile error
coro func empty() {
    // Error: coro functions without yield calls not allowed
}

// Valid: Contains yield
coro func valid() {
    yield()
}

Yield Variants

1. Basic Yield

Pauses execution until the next tick:

coro func basic() {
    trace("Start")
    yield()  // Pause here
    trace("Resume")
}

2. Yield While

yield while pauses execution while a condition is true. It's commonly used in parallel blocks for synchronization:

coro func test() {
    int i = 0
    paral {
        // First branch: wait until i reaches 3
        yield while(i < 3)

        // Second branch: increment i
        while(true) {
            i = i + 1
            yield()
        }
    }
    return i
}

// Multiple yield whiles in parallel
coro func test2() {
    int i = 0
    paral {
        yield while(i < 5)  // First condition
        while(true) {
            yield while(i < 7)  // Second condition
        }
        while(true) {
            i = i + 1
            yield()
        }
    }
    return i
}

3. Yield with Coroutine Calls

You can yield other coroutine functions:

coro func subTask() {
    yield()
    return 42
}

coro func mainTask() {
    int result = yield subTask()  // Waits for subTask to complete
}

Class and Interface Integration

Methods

class Example {
    coro func process() {
        yield()
    }
}

coro func test() {
    var obj = new Example
    yield obj.process()  // Yield class method
}

Inheritance

class Base {
    coro func task() {
        yield()
    }
}

class Derived : Base {
    coro func process() {
        yield base.task()  // Yield base class method
    }
}

Interfaces

interface IProcessor {
    coro func process()
}

class Processor : IProcessor {
    coro func process() {
        yield()
    }
}

Restrictions

  • yield is not allowed inside defer blocks.
  • Only coroutine function pointers can be yielded โ€” coro func and func pointer types are not interchangeable.