Posted to tcl by colin at Thu Apr 15 03:00:39 GMT 2010view pretty

Assume a Coroutine which generates a command taking multiple args, and a coroutine as we have it implemented:

# Coroutine in coroutine:
proc Coroutine {name command args} {
    set ns [namespace qualifiers $name]
    if {$ns eq ""} {
	set ns [uplevel 1 {namespace current}]
    }
    set name [namespace tail $name]

    set coco [::coroutine ${ns}::C$name $command {*}args]
    trace add command ${ns}::_C$name delete "rename ${ns}::name {}"
    proc ${ns}::$name {args} {
	[lindex [info level 0] 0] $args
    }
}

proc coyield {args} {
    return [::yield $args]
}

proc yieldv {value args} {
    uplevel 1 [::yield $value] {*}$args
}

# coroutine in cocoroutine:
proc coroutine {name command args} {
    set ns [namespace qualifiers $name]
    if {$ns eq ""} {
	set ns [uplevel 1 {namespace current}]
    }
    set name [namespace tail $name]

    Coroutine ${ns}::$name $command {*}$args
}

proc ::yield2 {value} {
    return [lindex [::yield $value] 0]
}