# Coroutine example: general coroutine transfers## The program is a variation of a Simula 67 program due to Dahl & Hoare,# (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972)# 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 themfrom Coroutine import *def getline(text): for line in string.splitfields(text, '\n'): co.tran(codisassembler, line)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) print lineimport stringco = 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)print 'done'# end of example
# Coroutine example: general coroutine transfers
#
# The program is a variation of a Simula 67 program due to Dahl & Hoare,
# (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972)
# 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'):
co.tran(codisassembler, line)
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)
print line
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)
print 'done'
# end of example