Guido van Rossum | f4e13a4 | 2000-11-08 15:17:49 +0000 | [diff] [blame] | 1 | # Coroutine example: general coroutine transfers |
| 2 | # |
| 3 | # The program is a variation of a Simula 67 program due to Dahl & Hoare, |
Guido van Rossum | 27f9b84 | 2001-03-22 13:36:11 +0000 | [diff] [blame] | 4 | # (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972) |
Guido van Rossum | f4e13a4 | 2000-11-08 15:17:49 +0000 | [diff] [blame] | 5 | # who in turn credit the original example to Conway. |
| 6 | # |
| 7 | # We have a number of input lines, terminated by a 0 byte. The problem |
| 8 | # is to squash them together into output lines containing 72 characters |
| 9 | # each. A semicolon must be added between input lines. Runs of blanks |
| 10 | # and tabs in input lines must be squashed into single blanks. |
| 11 | # Occurrences of "**" in input lines must be replaced by "^". |
| 12 | # |
| 13 | # Here's a test case: |
| 14 | |
| 15 | test = """\ |
| 16 | d = sqrt(b**2 - 4*a*c) |
| 17 | twoa = 2*a |
| 18 | L = -b/twoa |
| 19 | R = d/twoa |
| 20 | A1 = L + R |
| 21 | A2 = L - R\0 |
| 22 | """ |
| 23 | |
| 24 | # The program should print: |
| 25 | |
| 26 | # d = sqrt(b^2 - 4*a*c);twoa = 2*a; L = -b/twoa; R = d/twoa; A1 = L + R; |
| 27 | #A2 = L - R |
| 28 | #done |
| 29 | |
| 30 | # getline: delivers the next input line to its invoker |
| 31 | # disassembler: grabs input lines from getline, and delivers them one |
| 32 | # character at a time to squasher, also inserting a semicolon into |
| 33 | # the stream between lines |
| 34 | # squasher: grabs characters from disassembler and passes them on to |
| 35 | # assembler, first replacing "**" with "^" and squashing runs of |
| 36 | # whitespace |
| 37 | # assembler: grabs characters from squasher and packs them into lines |
| 38 | # with 72 character each, delivering each such line to putline; |
| 39 | # when it sees a null byte, passes the last line to putline and |
| 40 | # then kills all the coroutines |
| 41 | # putline: grabs lines from assembler, and just prints them |
| 42 | |
| 43 | from Coroutine import * |
| 44 | |
| 45 | def getline(text): |
| 46 | for line in string.splitfields(text, '\n'): |
Guido van Rossum | 27f9b84 | 2001-03-22 13:36:11 +0000 | [diff] [blame] | 47 | co.tran(codisassembler, line) |
Guido van Rossum | f4e13a4 | 2000-11-08 15:17:49 +0000 | [diff] [blame] | 48 | |
| 49 | def disassembler(): |
| 50 | while 1: |
| 51 | card = co.tran(cogetline) |
| 52 | for i in range(len(card)): |
| 53 | co.tran(cosquasher, card[i]) |
| 54 | co.tran(cosquasher, ';') |
| 55 | |
| 56 | def squasher(): |
| 57 | while 1: |
| 58 | ch = co.tran(codisassembler) |
| 59 | if ch == '*': |
| 60 | ch2 = co.tran(codisassembler) |
| 61 | if ch2 == '*': |
| 62 | ch = '^' |
| 63 | else: |
| 64 | co.tran(coassembler, ch) |
| 65 | ch = ch2 |
| 66 | if ch in ' \t': |
| 67 | while 1: |
| 68 | ch2 = co.tran(codisassembler) |
| 69 | if ch2 not in ' \t': |
| 70 | break |
| 71 | co.tran(coassembler, ' ') |
| 72 | ch = ch2 |
| 73 | co.tran(coassembler, ch) |
| 74 | |
| 75 | def assembler(): |
| 76 | line = '' |
| 77 | while 1: |
| 78 | ch = co.tran(cosquasher) |
| 79 | if ch == '\0': |
| 80 | break |
| 81 | if len(line) == 72: |
| 82 | co.tran(coputline, line) |
| 83 | line = '' |
| 84 | line = line + ch |
| 85 | line = line + ' ' * (72 - len(line)) |
| 86 | co.tran(coputline, line) |
| 87 | co.kill() |
| 88 | |
| 89 | def putline(): |
| 90 | while 1: |
| 91 | line = co.tran(coassembler) |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame^] | 92 | print(line) |
Guido van Rossum | f4e13a4 | 2000-11-08 15:17:49 +0000 | [diff] [blame] | 93 | |
| 94 | import string |
| 95 | co = Coroutine() |
| 96 | cogetline = co.create(getline, test) |
| 97 | coputline = co.create(putline) |
| 98 | coassembler = co.create(assembler) |
| 99 | codisassembler = co.create(disassembler) |
| 100 | cosquasher = co.create(squasher) |
| 101 | |
| 102 | co.tran(coputline) |
Collin Winter | 6f2df4d | 2007-07-17 20:59:35 +0000 | [diff] [blame^] | 103 | print('done') |
Guido van Rossum | f4e13a4 | 2000-11-08 15:17:49 +0000 | [diff] [blame] | 104 | |
| 105 | # end of example |