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