-- The Great Computer Language Shootout
-- http://shootout.alioth.debian.org/
--
-- contributed by Adam Sampson <ats@offog.org>

#INCLUDE "course.module"

PROC main (CHAN BYTE in?, out!)
  VAL []BYTE from IS "ACBDGHKMNSRUTWVYacbdghkmnsrutwvy":
  VAL []BYTE to   IS "TGVHCDMKNSYAAWBRTGVHCDMKNSYAAWBR":
  [256]BYTE lookup:
  MOBILE []BYTE buf:
  INITIAL INT len IS 0:
  INITIAL BOOL running IS TRUE:
  SEQ
    buf := MOBILE [42]BYTE
    SEQ i = 0 FOR 256
      lookup[i] := BYTE i
    SEQ i = 0 FOR SIZE from
      lookup[INT from[i]] := to[i]
    WHILE running
      BYTE b:
      SEQ
        in ? b
        CASE b
          END.OF.FILE, '>'
            INITIAL INT count IS 0:
            SEQ
              SEQ ii = 0 FOR len
                VAL INT i IS (len - ii) - 1:
                SEQ
                  out ! lookup[INT buf[i]]
                  IF
                    count = 59
                      SEQ
                        out ! '*n'
                        count := 0
                    TRUE
                      count := count + 1
              IF
                count <> 0
                  out ! '*n'
                TRUE
                  SKIP
              len := 0
              IF
                b = END.OF.FILE
                  running := FALSE
                TRUE
                  SEQ
                    WHILE (b <> '*n') AND (b <> END.OF.FILE)
                      SEQ
                        out ! b
                        in ? b
                    out ! '*n'
          ELSE
            WHILE (b <> '*n') AND (b <> END.OF.FILE)
              SEQ
                INITIAL INT sb IS SIZE buf:
                IF
                  len = sb
                    MOBILE []BYTE new.buf:
                    SEQ
                      new.buf := MOBILE [2 * sb]BYTE
                      SEQ i = 0 FOR sb
                        new.buf[i] := buf[i]
                      buf := new.buf
                  TRUE
                    SKIP
                buf[len] := b
                len := len + 1
                in ? b
:
