--
--	cgtest86.occ -- channel type tests
--	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 cgtest86 (CHAN OF BYTE keyb, scr, err)

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

  --{{{  tests
  --{{{  test0 -- simple PROTOCOLs
  PROC test0 ()
    CHAN TYPE FOO
      MOBILE RECORD
        CHAN INT i?:
        CHAN INT o!:
    :

    SEQ
      --{{{  unshared
      FOO! f.cli:
      FOO? f.svr:
      SEQ
        f.cli, f.svr := MOBILE FOO
        PAR
          --{{{  server process
          INT x:
          SEQ
            f.svr[i] ? x
            f.svr[o] ! id.INT (x)
            f.svr[o] ! id.INT (x + x)
          --}}}
          --{{{  client process
          INT v:
          SEQ
            v := 42
            f.cli[i] ! id.INT (v)
            f.cli[o] ? v
            check.INT (v, 42, "test0.0")
            f.cli[o] ? v
            check.INT (v, 84, "test0.1")
          --}}}
      --}}}
      --{{{  client shared
      SHARED FOO! f.cli:
      FOO? f.svr:
      SEQ
        f.cli, f.svr := MOBILE FOO
        PAR
          --{{{  server process
          INT x:
          SEQ
            f.svr[i] ? x
            f.svr[o] ! id.INT (x)
            f.svr[o] ! id.INT (x + x)
          --}}}
          --{{{  client process
          INT v:
          SEQ
            v := 42
            CLAIM f.cli
              SEQ
                f.cli[i] ! id.INT (v)
                f.cli[o] ? v
            check.INT (v, 42, "test0.2")
            CLAIM f.cli
              f.cli[o] ? v
            check.INT (v, 84, "test0.3")
          --}}}
      --}}}
      --{{{  server shared
      FOO! f.cli:
      SHARED FOO? f.svr:
      SEQ
        f.cli, f.svr := MOBILE FOO
        PAR
          --{{{  server process
          INT x:
          SEQ
            CLAIM f.svr
              f.svr[i] ? x
            CLAIM f.svr
              SEQ
                f.svr[o] ! id.INT (x)
                f.svr[o] ! id.INT (x + x)
          --}}}
          --{{{  client process
          INT v:
          SEQ
            v := 42
            f.cli[i] ! id.INT (v)
            f.cli[o] ? v
            check.INT (v, 42, "test0.4")
            f.cli[o] ? v
            check.INT (v, 84, "test0.5")
          --}}}
      --}}}
      --{{{  fully shared
      SHARED FOO! f.cli:
      SHARED FOO? f.svr:
      SEQ
        f.cli, f.svr := MOBILE FOO
        PAR
          --{{{  server process
          INT x:
          CLAIM f.svr
            SEQ
              f.svr[i] ? x
              f.svr[o] ! id.INT (x)
              f.svr[o] ! id.INT (x + x)
          --}}}
          --{{{  client process
          INT v:
          SEQ
            v := 42
            CLAIM f.cli
              SEQ
                f.cli[i] ! id.INT (v)
                f.cli[o] ? v
                check.INT (v, 42, "test0.6")
                f.cli[o] ? v
                check.INT (v, 84, "test0.7")
          --}}}
      --}}}
  :
  --}}}
  --{{{  test1 -- counted arrays, named PROTOCOLs
  PROC test1 ()
    PROTOCOL BLIP IS REAL64:
    CHAN TYPE FOO
      MOBILE RECORD
        CHAN INT::[]BYTE c?:
        CHAN BLIP d!:
    :

    FOO! f.cli:
    FOO? f.svr:
    REAL64 v.0, v.1:
    SEQ
      f.cli, f.svr := MOBILE FOO
      PAR
        SEQ
          f.cli[c] ! id.INT(5)::"Hello"
          f.cli[d] ? v.0
        INT len:
        [5]BYTE data:
        SEQ
          f.svr[c] ? len::data
          check.INT (len, SIZE data, "test1.0")
          v.1 := 99.0
          f.svr[d] ! id.REAL64 (v.1)
          check.BYTE (data[4], 'o', "test1.1")
      check.REAL64 (id.REAL64 (v.0), v.1, "test1.2")
  :
  --}}}
  --{{{  test2 -- assignment
  PROC test2 ()
    CHAN TYPE BAR
      MOBILE RECORD
        CHAN INT in?:
        CHAN INT out!:
    :

    BAR! bc.0, bc.1, bc.2:
    BAR? bs.0, bs.1, bs.2:
    INT x:
    SEQ
      bc.0, bs.0 := MOBILE BAR
      bc.1 := bc.0
      bc.0, bs.1 := MOBILE BAR
      bs.2 := bs.1
      bc.2, bs.1 := MOBILE BAR
      bc.0 := bc.1
      bc.2 := bc.0
      -- bc.2 should be connected to bs.0
      PAR
        bc.2[in] ! 99
        bs.0[in] ? x
      check.INT (x, 99, "test2.0")
  :
  --}}}
  --{{{  test3 -- communication
  PROC test3 ()
    CHAN TYPE FOO
      MOBILE RECORD
        CHAN INT c?:
        CHAN REAL64 d!:
    :
    CHAN TYPE BAR
      MOBILE RECORD
        CHAN FOO! cli!:
        CHAN FOO? svr!:
        CHAN SHARED FOO! s.cli!:
        CHAN SHARED FOO? s.svr!:
    :

    SHARED BAR! bar.cli:
    BAR? bar.svr:
    REAL64 v, w:
    INT x:
    SEQ
      bar.cli, bar.svr := MOBILE BAR
      PAR
        --{{{  BAR server
        FOO! foo.cli:
        FOO? foo.svr:
        SHARED FOO! foo.s.cli:
        SHARED FOO? foo.s.svr:
        SEQ
          foo.cli, foo.svr := MOBILE FOO
          PAR
            bar.svr[cli] ! foo.cli
            bar.svr[svr] ! foo.svr
          foo.s.cli, foo.s.svr := MOBILE FOO
          PAR
            bar.svr[s.cli] ! foo.s.cli
            bar.svr[s.svr] ! foo.s.svr
        --}}}
        --{{{  BAR client 1 (FOO client)
        FOO! cli:
        SEQ
          CLAIM bar.cli
            bar.cli[cli] ? cli
          cli[c] ! 1234
          cli[d] ? v
        --}}}
        --{{{  BAR client 2 (FOO server)
        FOO? svr:
        INT v:
        SEQ
          CLAIM bar.cli
            bar.cli[svr] ? svr
          svr[c] ? v
          check.INT (id.INT (v), 1234, "test3.0")
          svr[d] ! 44.0
        --}}}
        --{{{  BAR client 3 (shared FOO client)
        SHARED FOO! s.cli:
        SEQ
          CLAIM bar.cli
            bar.cli[s.cli] ? s.cli
          CLAIM s.cli
            SEQ
              s.cli[c] ! 4321
              s.cli[d] ? w
        --}}}
        --{{{  BAR client 4 (shared FOO server)
        SHARED FOO? s.svr:
        SEQ
          CLAIM bar.cli
            bar.cli[s.svr] ? s.svr
          CLAIM s.svr
            SEQ
              s.svr[c] ? x
              s.svr[d] ! 8765.4321
        --}}}
      check.REAL64 (v, 44.0, "test3.1")
      check.REAL64 (id.REAL64 (w), 8765.4321, "test3.2")
      check.INT (x, 4321, "test3.3")
  :
  --}}}
  --{{{  test4 -- recursive channel-types
  PROC test4 ()
    RECURSIVE CHAN TYPE FOO
      MOBILE RECORD
        CHAN INT c!:
        CHAN FOO! f.cli!:
        CHAN FOO? f.svr!:
        CHAN SHARED FOO! f.s.cli!:
        CHAN SHARED FOO? f.s.svr!:
    :

    FOO! foo.cli:
    FOO? foo.svr:
    SEQ
      foo.cli, foo.svr := MOBILE FOO
      PAR
        --{{{  foo server
        SEQ
          foo.svr[f.svr] ! foo.svr
        --}}}
        --{{{  foo client
        FOO? svr:
        INT v:
        SEQ
          foo.cli[f.svr] ? svr
          PAR
            foo.cli[c] ? v
            svr[c] ! 42
          check.INT (v, 42, "test4.0")
        --}}}
  :
  --}}}
  --{{{  test5 -- anonymous channel-types
  PROC test5 ()
    SEQ

      SHARED CHAN INT c:
      PAR
        CLAIM c!
          c ! 999
        INT v:
        SEQ
          CLAIM c?
            c ? v
          check.INT (v, id.INT (999), "test5.0")

      SHARED CHAN INT::[]BYTE c:
      PAR
        CLAIM c!
          c ! 5::"occam"
        INT v:
        [5]BYTE d:
        SEQ
          CLAIM c?
            c ? v::d
          check.INT (id.INT (v), SIZE d, "test5.1")
          check.BYTE (id.BYTE (d[0]), 'o', "test5.2")
          check.BYTE (id.BYTE (d[4]), 'm', "test5.3")

      SHARED CHAN MOBILE INT c:
      PAR
        MOBILE INT sv:
        SEQ
          sv := 20
          CLAIM c!
            c ! sv

        MOBILE INT cv:
        SEQ
          CLAIM c?
            c ? cv
          check.INT (cv, 20, "test5.4")

  :
  --}}}
  --}}}

  SEQ
    init ("CG test 86", "mobile channel types")
    title ("simple PROTOCOLs")
    test0 ()
    title ("counted arrays, named PROTOCOLs")
    test1 ()
    title ("assignment")
    test2 ()
    title ("communication")
    test3 ()
    title ("recursive channel types")
    test4 ()
    title ("anonymous channel types")
    test5 ()
    finish ()
:


