| 
									
										
										
										
											2000-11-08 15:17:49 +00:00
										 |  |  | # Coroutine example:  general coroutine transfers | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # The program is a variation of a Simula 67 program due to Dahl & Hoare, | 
					
						
							| 
									
										
										
										
											2001-03-22 13:36:11 +00:00
										 |  |  | # (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972) | 
					
						
							| 
									
										
										
										
											2000-11-08 15:17:49 +00:00
										 |  |  | # who in turn credit the original example to Conway. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # We have a number of input lines, terminated by a 0 byte.  The problem | 
					
						
							|  |  |  | # is to squash them together into output lines containing 72 characters | 
					
						
							|  |  |  | # each.  A semicolon must be added between input lines.  Runs of blanks | 
					
						
							|  |  |  | # and tabs in input lines must be squashed into single blanks. | 
					
						
							|  |  |  | # Occurrences of "**" in input lines must be replaced by "^". | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Here's a test case: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test = """\
 | 
					
						
							|  |  |  |    d    =   sqrt(b**2  -  4*a*c) | 
					
						
							|  |  |  | twoa    =   2*a | 
					
						
							|  |  |  |    L    =   -b/twoa | 
					
						
							|  |  |  |    R    =   d/twoa | 
					
						
							|  |  |  |   A1    =   L + R | 
					
						
							|  |  |  |   A2    =   L - R\0 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # The program should print: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # d = sqrt(b^2 - 4*a*c);twoa = 2*a; L = -b/twoa; R = d/twoa; A1 = L + R; | 
					
						
							|  |  |  | #A2 = L - R | 
					
						
							|  |  |  | #done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # getline: delivers the next input line to its invoker | 
					
						
							|  |  |  | # disassembler: grabs input lines from getline, and delivers them one | 
					
						
							|  |  |  | #    character at a time to squasher, also inserting a semicolon into | 
					
						
							|  |  |  | #    the stream between lines | 
					
						
							|  |  |  | # squasher:  grabs characters from disassembler and passes them on to | 
					
						
							|  |  |  | #    assembler, first replacing "**" with "^" and squashing runs of | 
					
						
							|  |  |  | #    whitespace | 
					
						
							|  |  |  | # assembler: grabs characters from squasher and packs them into lines | 
					
						
							|  |  |  | #    with 72 character each, delivering each such line to putline; | 
					
						
							|  |  |  | #    when it sees a null byte, passes the last line to putline and | 
					
						
							|  |  |  | #    then kills all the coroutines | 
					
						
							|  |  |  | # putline: grabs lines from assembler, and just prints them | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from Coroutine import * | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def getline(text): | 
					
						
							|  |  |  |     for line in string.splitfields(text, '\n'): | 
					
						
							| 
									
										
										
										
											2001-03-22 13:36:11 +00:00
										 |  |  |         co.tran(codisassembler, line) | 
					
						
							| 
									
										
										
										
											2000-11-08 15:17:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def disassembler(): | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         card = co.tran(cogetline) | 
					
						
							|  |  |  |         for i in range(len(card)): | 
					
						
							|  |  |  |             co.tran(cosquasher, card[i]) | 
					
						
							|  |  |  |         co.tran(cosquasher, ';') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def squasher(): | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         ch = co.tran(codisassembler) | 
					
						
							|  |  |  |         if ch == '*': | 
					
						
							|  |  |  |             ch2 = co.tran(codisassembler) | 
					
						
							|  |  |  |             if ch2 == '*': | 
					
						
							|  |  |  |                 ch = '^' | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 co.tran(coassembler, ch) | 
					
						
							|  |  |  |                 ch = ch2 | 
					
						
							|  |  |  |         if ch in ' \t': | 
					
						
							|  |  |  |             while 1: | 
					
						
							|  |  |  |                 ch2 = co.tran(codisassembler) | 
					
						
							|  |  |  |                 if ch2 not in ' \t': | 
					
						
							|  |  |  |                     break | 
					
						
							|  |  |  |             co.tran(coassembler, ' ') | 
					
						
							|  |  |  |             ch = ch2 | 
					
						
							|  |  |  |         co.tran(coassembler, ch) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def assembler(): | 
					
						
							|  |  |  |     line = '' | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         ch = co.tran(cosquasher) | 
					
						
							|  |  |  |         if ch == '\0': | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         if len(line) == 72: | 
					
						
							|  |  |  |             co.tran(coputline, line) | 
					
						
							|  |  |  |             line = '' | 
					
						
							|  |  |  |         line = line + ch | 
					
						
							|  |  |  |     line = line + ' ' * (72 - len(line)) | 
					
						
							|  |  |  |     co.tran(coputline, line) | 
					
						
							|  |  |  |     co.kill() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def putline(): | 
					
						
							|  |  |  |     while 1: | 
					
						
							|  |  |  |         line = co.tran(coassembler) | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  |         print(line) | 
					
						
							| 
									
										
										
										
											2000-11-08 15:17:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import string | 
					
						
							|  |  |  | co = Coroutine() | 
					
						
							|  |  |  | cogetline = co.create(getline, test) | 
					
						
							|  |  |  | coputline = co.create(putline) | 
					
						
							|  |  |  | coassembler = co.create(assembler) | 
					
						
							|  |  |  | codisassembler = co.create(disassembler) | 
					
						
							|  |  |  | cosquasher = co.create(squasher) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | co.tran(coputline) | 
					
						
							| 
									
										
										
										
											2007-07-17 20:59:35 +00:00
										 |  |  | print('done') | 
					
						
							| 
									
										
										
										
											2000-11-08 15:17:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # end of example |