--
--	cgtest84.occ -- extended rendezvous
--	Copyright (C) 2002 Fred Barnes <frmb2@ukc.ac.uk>
--
--	This program is free software; you can redistribute it and/or modify
--	it under the terms of the GNU General Public License as published by
--	the Free Software Foundation; either version 2 of the License, or
--	(at your option) any later version.
--
--	This program is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--	GNU General Public License for more details.
--
--	You should have received a copy of the GNU General Public License
--	along with this program; if not, write to the Free Software
--	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--



PROC cgtest84 (CHAN OF BYTE keyb, scr, err)

  #INCLUDE "cgmain.occ"
  #INCLUDE "cgreal.occ"

  --{{{  tests
  PROC test0 ()
    CHAN INT c:
    PAR
      c ! 42
      INT x:
      c ?? x
        check.INT (id.INT (x), 42, "test0.0")
  :
  PROC test1 ()
    CHAN INT c, d:
    PAR
      c ! 42
      INT x:
      c ?? x
        d ! x
        d ! (x * 2)
      INT y:
      SEQ
        d ? y
        check.INT (id.INT (y), 42, "test1.0")
        d ? y
        check.INT (id.INT (y), 84, "test1.1")
  :
  PROC test2 ()
    PROTOCOL COUNTED.BYTES IS INT::[]BYTE:
    PROTOCOL SEQUENTIAL IS BYTE; BYTE; INT:
    CHAN COUNTED.BYTES c:
    CHAN SEQUENTIAL d:
    PAR
      VAL []BYTE str IS "hello world!":
      c ! (SIZE str)::str

      d ! 'f'; 'b'; 24

      SEQ
        INT len:
        [16]BYTE data:
        c ?? len::data
          SEQ
            check.INT (len, 12, "test2.0")
            check.BYTE (id.BYTE (data[4]), 'o', "test2.1")
          check.BYTE (id.BYTE (data[0]), 'h', "test2.2")
        INT v:
        BYTE b1, b2:
        d ?? b1; b2; v
          check.BYTE (id.BYTE (b2), 'b', "test2.3")
          check.INT (id.INT (v), 24, "test2.4")
  :
  PROC test3 ()
    PROTOCOL TAGGED
      CASE
        empty
        int; INT
        bytes; INT::[]BYTE
    :

    CHAN TAGGED c:
    PAR
      SEQ
        c ! int; 99
        c ! empty
        VAL []BYTE str IS "hello, new world!":
        c ! bytes; (SIZE str)::str
      INT saved.val:
      SEQ i = 0 FOR 3
        c ?? CASE
          empty
            check.INT (id.INT (saved.val), 111, "test3.0")
          int; saved.val
            check.INT (id.INT (saved.val), 99, "test3.1")
            saved.val := (saved.val + 12)
          INT len:
          [18]BYTE data:
          bytes; len::data
            check.INT (id.INT (len), 17, "test3.2")
            check.BYTE (id.BYTE (data[len - 1]), '!', "test3.3")
  :
  PROC test4 ()
    PROTOCOL T2
      CASE
        empty
        int; INT
    :

    CHAN T2 c:
    PAR
      c ! int; 99
      INT x:
      c ?? CASE int; x
        check.INT (id.INT (x), 99, "test4.0")
        check.INT (id.INT (x), 99, "test4.1")
  :
  PROC test5 ()
    CHAN INT c:
    CHAN REAL64 d:
    PAR
      SEQ
        c ! 42
        d ! 99.99
      SEQ i = 0 FOR 2
        ALT
          INT x:
          c ?? x
            check.INT (id.INT (x), 42, "test5.0")
            SKIP
          REAL64 y:
          d ?? y
            SKIP
            check.REAL64 (id.REAL64 (y), 99.99, "test5.1")
  :
  PROC test6 ()
    PROTOCOL COUNTED.BYTES IS INT::[]BYTE:
    PROTOCOL SEQUENTIAL IS BYTE; BYTE; INT:
    CHAN COUNTED.BYTES c:
    CHAN SEQUENTIAL d:
    PAR

      SEQ
        VAL []BYTE str IS "hello occam!":
        c ! SIZE str::str
        d ! 'o'; 'c'; MOSTNEG INT

      SEQ i = 0 FOR 2
        ALT
          INT len:
          [16]BYTE data:
          c ?? len::data
            check.INT (id.INT (len), 12, "test6.0")
            check.BYTE (id.BYTE (data[6]), 'o', "test6.1")
          BYTE v, w:
          INT x:
          d ?? v; w; x
            check.BYTE (id.BYTE (v), 'o', "test6.2")
            check.INT (id.INT (x), MOSTNEG INT, "test6.3")
  :
  PROC test7 ()
    PROTOCOL TAGGED
      CASE
        int; INT
        empty
        bytes; INT::[]BYTE
    :

    CHAN TAGGED c, d:
    PAR

      SEQ
        c ! int; 99
        c ! empty
        VAL []BYTE str IS "way down here":
        c ! bytes; SIZE str::str

      SEQ
        d ! int; 33

      INITIAL INT saved IS 0:
      SEQ i = 0 FOR 4
        ALT
          INT x:
          d ?? CASE int; x
            check.INT (x, 33, "test7.0")
            check.INT (id.INT (x), 33, "test7.1")
          c ?? CASE
            empty
              check.INT (saved, 99, "test7.2")
            INT z:
            int; z
              check.INT (z, 99, "test7.3")
              saved := z
            INT len:
            [16]BYTE data:
            bytes; len::data
              check.INT (id.INT (len), 13, "test7.4")
              check.BYTE (id.BYTE ([data FROM (len - 1) FOR 1][0]), 'e', "test7.5")
  :
  PROC test8 ()
    CHAN BYTE c, d, e:
    -- this should deadlock if things go wrong
    PAR

      SEQ
        PAR
          e ! 'c'
          SEQ
            c ! 'o'
            c ! 'a'
          SEQ
            d ! 'c'
            d ! 'm'

      BYTE b:
      c ?? b
        SEQ
          check.BYTE (b, 'o', "test8.0")
          SEQ i = 0 FOR 2
            ALT
              d ?? b
                check.BYTE (b, 'c', "test8.1")
                SKIP
              e ?? b
                check.BYTE (b, 'c', "test8.2")
                SKIP
        c ?? b
          check.BYTE (b, 'a', "test8.3")
          SEQ
            d ? b
            check.BYTE (b, 'm', "test8.4")
  :
  PROC test9 ()
    CHAN MOBILE INT c:
    PAR

      MOBILE INT x:
      SEQ
        x := 42
        c ! x
        x := MOSTPOS INT
        c ! CLONE x
        c ! x

      MOBILE INT y:
      SEQ
        c ?? y
          check.INT (id.INT (y), 42, "test9.0")
          SEQ
            c ? y
            check.INT (id.INT (y), MOSTPOS INT, "test9.1")
        c ? y
        check.INT (id.INT (y), MOSTPOS INT, "test9.2")
  :
  PROC test10 ()
    CHAN MOBILE []BYTE c:
    PAR

      MOBILE []BYTE buf:
      SEQ
        buf := "hello world!"
        c ! buf

      MOBILE []BYTE b:
      SEQ
        c ?? b
          check.INT (SIZE b, 12, "test10.0")
          check.BYTE (id.BYTE (b[4]), 'o', "test10.1")
  :
  --}}}  
  SEQ
    init ("CG test 84", "extended rendezvous")
    title ("simple input")
    test0 ()
    test1 ()
    test2 ()
    test3 ()
    test4 ()
    title ("inside alternatives")
    test5 ()
    test6 ()
    test7 ()
    -- this deadlocks...
    --title ("specific synchronisation")
    --test8 ()
    title ("mobiles")
    test9 ()
    test10 ()
    finish ()
:


