PageRenderTime 310ms CodeModel.GetById 121ms app.highlight 7ms RepoModel.GetById 113ms app.codeStats 1ms

/Demo/threads/squasher.py

http://unladen-swallow.googlecode.com/
Python | 105 lines | 91 code | 1 blank | 13 comment | 0 complexity | 4b8a7c84cac5c00f9742d5cf871b38e0 MD5 | raw file
  1# Coroutine example:  general coroutine transfers
  2#
  3# The program is a variation of a Simula 67 program due to Dahl & Hoare,
  4# (Dahl/Dijkstra/Hoare, Structured Programming; Academic Press, 1972)
  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
 15test = """\
 16   d    =   sqrt(b**2  -  4*a*c)
 17twoa    =   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
 43from Coroutine import *
 44
 45def getline(text):
 46    for line in string.splitfields(text, '\n'):
 47        co.tran(codisassembler, line)
 48
 49def 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
 56def 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
 75def 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
 89def putline():
 90    while 1:
 91        line = co.tran(coassembler)
 92        print line
 93
 94import string
 95co = Coroutine()
 96cogetline = co.create(getline, test)
 97coputline = co.create(putline)
 98coassembler = co.create(assembler)
 99codisassembler = co.create(disassembler)
100cosquasher = co.create(squasher)
101
102co.tran(coputline)
103print 'done'
104
105# end of example