Posted to tcl by evilotto at Mon Jun 17 22:25:51 GMT 2013view pretty
package require Tcl 8.6 package require struct::queue set pipes [dict create] proc pipeproc {cmd} { yield eval $cmd writepipe EOF } proc pipecmds {pscript} { set plist {} foreach pcmd [split $pscript "\n"] { set pcmd [string trim $pcmd] if {$pcmd eq ""} continue if {[string match "#*" $pcmd]} continue lappend plist $pcmd } return $plist } proc dopipe {pscript} { runpipe [pipecmds $pscript] } proc runpipe {plist} { set pi 0 set in {} foreach p $plist { set pn pipe[incr pi] dict set ::pipes ::$pn reader $in dict set ::pipes ::$pn writer [struct::queue] coroutine $pn pipeproc $p set in [dict get $::pipes ::$pn writer] } while {[llength [dict keys $::pipes]] > 0} { foreach p [dict keys $::pipes] { if {[info commands $p] eq $p} { $p } else { dict unset ::pipes $p } } } } proc writepipe {v} { [dict get $::pipes [info coroutine] writer] put $v yield } proc readpipe {var} { upvar 1 $var v set q [dict get $::pipes [info coroutine] reader] while {1} { if {[$q size] > 0} { set v [$q get] if {$v == "EOF"} { return false } else { return true } } else { yield } } } proc generate {} { for {set x 0} {$x < 100} {incr x} { writepipe "generate $x" } } proc transform {a b} { while {[readpipe v]} { writepipe "transform: [string map [list $a $b] $v]" } } proc out {} { while {[readpipe v]} { puts "out: $v" } } dopipe { generate transform gener MAKE # transform MAKE "" out }