
#INCLUDE "course.module"
#INCLUDE "file.module"
#INCLUDE "convert.module"

VAL INT elements IS 256:

PROC element (CHAN INT this?, next!)
  INITIAL INT token IS 1:
  WHILE token <> 0
    SEQ
      this ? token
      IF
        token > 0
          next ! (token + 1)
        TRUE
          next ! token
:

PROC root (VAL INT cycles, CHAN INT this?, next!, CHAN BYTE scr!)
  INITIAL INT cycles IS cycles:
  INT token:
  SEQ
    next ! 1
    this ? token
  
    out.string ("start*n", 0, scr!)
    scr ! FLUSH

    WHILE cycles > 0
      SEQ
        next ! (token + 1)
        this ? token
        cycles := cycles - 1

    out.string ("end*n", 0, scr!)
    scr ! FLUSH

    out.int (token, 0, scr!)
    scr ! '*n'

    next ! 0
    this ? token
:

PROC ring (CHAN BYTE kyb?, scr!, err!)
  INITIAL INT cycles IS 0:
  SEQ
    CHAN GETOPT opts:
    PAR
      file.get.options ("", opts!)
      INITIAL BOOL done IS FALSE:
      WHILE NOT done
        opts ? CASE
          MOBILE []BYTE s:
          arg; s
            BOOL error:
            SEQ
              STRINGTOINT (error, cycles, s)
              ASSERT (NOT error)
          done
            done := TRUE

    [elements]CHAN INT c:
    PAR
      PAR i = 1 FOR (elements - 1)
        element (c[i], c[(i + 1) \ (SIZE c)])
      root (cycles, c[0], c[1], scr!)
:
