cinap_lenrekadd hg and python4bb9e2215 years agoHistory
105 lines · 3.0 KB · Python
RawDownload
# 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 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