Posted to tcl by silas at Thu May 24 23:25:19 GMT 2018view raw

  1. # Just a coroutine to generate sequential odd numbers
  2. proc next_number {} {
  3. yield
  4. set n 10000001
  5. while {1} {
  6. yield $n
  7. incr n 2
  8. }
  9. }
  10. coroutine next next_number
  11. next
  12.  
  13. # Check if $n is prime
  14. proc is_prime {n} {
  15. set max [expr {$n / 2}]
  16. if {$max % 2 == 0} {
  17. incr max
  18. }
  19. for {set i 3} {$i < $max} {incr i 2} {
  20. if {$n % $i == 0} {
  21. return no
  22. }
  23. }
  24. return yes
  25. }
  26.  
  27. # Our coroutine. It "delivers" to [recv]: the number; whether or not it is
  28. # prime; and the coroutine
  29. proc prime {} {
  30. set n [next]
  31. while {1} {
  32. set is_prime [is_prime $n]
  33. after idle [list recv $n $is_prime [info coro]]
  34. set n [yield]
  35. }
  36. }
  37.  
  38. # Receive coroutine result and call it again with the next number
  39. proc recv {n is_prime caller} {
  40. if {$is_prime} {
  41. puts "$caller: $n"
  42. }
  43. set n [next]
  44. $caller $n
  45. }
  46.  
  47. # Instantiate $maxcoro coroutines
  48. set maxcoro 10
  49. set n 10000001
  50. for {set i 0} {$i < $maxcoro} {incr i} {
  51. coroutine p($i) prime
  52. p($i) [next]
  53. }
  54.  
  55. vwait forever
  56.