-- version control marker $Id: cgtest15.occ,v 1.4 1995/10/10 12:57:33 djb1 Exp $
-- Multiple assignment, functions

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

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

  SEQ
    init ("CG test 15", "Functions and multiple assignment")
    --{{{  multiple assignment                       M001 - M050 & Ma00 - Ma17
    PROC multi.assign()
      INT a, b, c, d, e:
      [5]INT x:
      INT i, j:
      SEQ
        --{{{  swap two variables                            M001 - M002
        a := 1
        b := 2
        a, b := b, a
        check(a, 2, "M001")
        check(b, 1, "M002")
        --}}} 
        --{{{  reverse four variables                        M003 - M006
        a := 1
        b := 2
        c := 3
        d := 4
        e := 5
        a, b, c, d := d, c, b, a
        check (a, 4, "M003")
        check (b, 3, "M004")
        check (c, 2, "M005")
        check (d, 1, "M006")
        --}}} 
        --{{{  left- and right- 5 cycles                     M007 - M016
        a, b, c, d, e := e, a, b, c, d
        check (a, 5, "M007")
        check (b, 4, "M008")
        check (c, 3, "M009")
        check (d, 2, "M010")
        check (e, 1, "M011")
        a, b, c, d, e := b, c, d, e, a
        check (a, 4, "M012")
        check (b, 3, "M013")
        check (c, 2, "M014")
        check (d, 1, "M015")
        check (e, 5, "M016")
        --}}} 
        --{{{  reverse with a subscript                      M017 - M020
        a, b, c, d, e := 1, 2, 3, 4, 5
        SEQ i = 0 FOR SIZE x
          x[i] := i
        i, j := 2, 2
        a, b, c, x[i] := x[j], c, b, a
        check(a, 2, "M017")
        check(b, 3, "M018")
        check(c, 2, "M019")
        check(x[2], 1, "M020")
        --}}} 
        --{{{  various load and store orders without temps   M021 - M035
        INT FUNCTION f(VAL INT x) IS 2 * x :
        SEQ
          a, b, c := f(d), c, b
          check(a, 8, "M021")
          check(b, 2, "M022")
          check(c, 3, "M023")
          a, b, c := b, a, f(d)
          check(a, 2, "M024")
          check(b, 8, "M025")
          check(c, 8, "M026")
          a, b, c := b, (b + c) + (b + c), f(a)
          check(a, 8, "M027")
          check(b, 32, "M028")
          check(c, 4, "M029")
          a, b, c := b, c, f(a)
          check(a, 32, "M030")
          check(b, 4, "M031")
          check(c, 16, "M032")
          a, b, c := b, b + c, f(a)
          check(a, 4, "M033")
          check(b, 20, "M034")
          check(c, 64, "M035")
        --}}} 
        --{{{  two param. function with aliasing             M036 - M038
        a, b, c := 2, 8, 8
        INT FUNCTION F(VAL INT x, y) IS x - y :
        a, b, c := F(b, c), F(c, a), F(a, b)
        check(a, 0, "M036")
        check(b, 6, "M037")
        check(c, -6, "M038")
        --}}} 
        --{{{  exchanging elements of an array               M039 - M046
        SEQ i = 0 FOR SIZE x
          x[i] := i
        x[0], x[1], x[2], x[3] := x[3], x[2], x[1], x[0]
        check(x[0], 3, "M039")
        check(x[1], 2, "M040")
        check(x[2], 1, "M041")
        check(x[3], 0, "M042")
        x[0], x[1], x[2], x[3] := x[3], x[0], x[1], x[2]
        check(x[0], 0, "M039")
        check(x[1], 3, "M040")
        check(x[2], 2, "M041")
        check(x[3], 1, "M042")
        x[0], x[1], x[2], x[3] := x[1], x[2], x[3], x[0]
        check(x[0], 3, "M043")
        check(x[1], 2, "M044")
        check(x[2], 1, "M045")
        check(x[3], 0, "M046")
        --}}} 
        --{{{  aliasing in multi-result INT function         M047 - M050
        a, b, c, d := 1, 2, 3, 4
        INT, INT, INT, INT FUNCTION f() IS a + 1, a + 2, a + 3, a + 4 :
        b, c, d, a := f()
        check(a, 5, "M047")
        check(b, 2, "M048")
        check(c, 3, "M049")
        check(d, 4, "M050")
        --}}} 
        --{{{  aliasing in multi-result INT16 function       Ma00 - Ma04
        INT x :
        [5]INT16 array :
        INT16, INT16 FUNCTION f(VAL INT16 a) IS a + 998(INT16), a + 999(INT16) :
        INT16, INT16, INT16 FUNCTION g(VAL INT16 a) IS a + 998(INT16), a + 999(INT16), a+1000(INT16) :
        SEQ
          x := 1
          SEQ i = 0 FOR SIZE array
            array[i] := INT16 i
          array[1], array[3] := f(array[x])
          check(0,   INT array[0], "Ma00")
          check(999, INT array[1], "Ma01") -- bug 777
          check(2,   INT array[2], "Ma02")
          check(1000,INT array[3], "Ma03")
          check(4,   INT array[4], "Ma04")
          array[0], array[2], array[4] := g(array[x])
          check(INT array[0], 1997, "B777A")
          check(INT array[1],  999, "B777B")
          check(INT array[2], 1998, "B777C")
          check(INT array[3], 1000, "B777D")
          check(INT array[4], 1999, "B777E")
        --}}}
        --{{{  aliasing in multi-result BYTE function        Ma05 - Ma09
        INT x :
        [5]BYTE array :
        BYTE, BYTE FUNCTION f(VAL BYTE a) IS BYTE((INT a) + 42), BYTE((INT a)+43) :
        SEQ
          x := 1
          SEQ i = 0 FOR SIZE array
            array[i] := BYTE i
          array[1], array[3] := f(array[x])
          check(INT array[0],  0, "Ma05")
          check(INT array[1], 43, "Ma06")
          check(INT array[2],  2, "Ma07")
          check(INT array[3], 44, "Ma08")
          check(INT array[4],  4, "Ma09")
        --}}}
        --{{{  aliasing in multiple INT16 assignment         Ma10 - Ma13
        [5]INT16 array :
        SEQ
          SEQ i = 0 FOR SIZE array
            array[i] := INT16 i
          array[2], array[1], array[0] := array[0], array[4], array[2]
          check(2, INT array[0], "Ma10")
          check(4, INT array[1], "Ma11")
          check(0, INT array[2], "Ma12")
          check(3, INT array[3], "Ma13")
        --}}}
        --{{{  aliasing in multiple INT64 assignment         Ma14 - Ma17
        [5]INT64 array :
        SEQ
          SEQ i = 0 FOR SIZE array
            array[i] := INT64 i
          array[2], array[1], array[0] := array[0], array[4], array[2]
          check(2, INT array[0], "Ma14")
          check(4, INT array[1], "Ma15")
          check(0, INT array[2], "Ma16")
          check(3, INT array[3], "Ma17")
        --}}}
    :
    multi.assign()
    --}}} 
    --{{{  functions with awkward parameters         M051 - M061
    PROC awkward.params()
      INT FUNCTION F(VAL INT w, x, y, z) IS w + (x + (y + z)) :
      PROC P(INT v, w, x, VAL INT y, INT z)
        SEQ
          v := y + v
          w := y + w
          x := y + x
          z := y + z
      :
      INT a, b, c, d, e, f, g, h :
      INT r1, r2, r3, r4 :
      SEQ
        a, b, c, d, e, f, g, h := 1, 2, 3, 4, 5, 6, 7, 8
        r1, r2, r3, r4 := 1, 2, 3, 4
        --{{{  M051 to M054
        P(r1, r2, r3, F(f, g, h, ((a + a) + (a + a)) + ((a + a) + (a + a))), r4)
        check(r1, 30, "M051")
        check(r2, 31, "M052")
        check(r3, 32, "M053")
        check(r4, 33, "M054")
        --}}} 
        --{{{  M055 and M056
        PROC P(VAL INT v, INT w, x, VAL INT y, z)
          SEQ
            w := w + (v + (y + z))
            x := x + (v + (y + z))
        :
        INT FUNCTION G(VAL INT v, w, x, y, z) IS v + (w + (x + (y + z))) :
        SEQ
          a, b, c, d, e := 1, 2, 3, 4, 5
          r1, r2 := 1, 2
          P(F(a, b, c, d), r1, r2, G(a, b, c, d, e), F(a, b, c, d))
          check (r1, 36, "M055")
          check (r2, 37, "M056")
        --}}} 
        --{{{  M057 and M058
        PROC P(VAL INT x, INT y, z)
          SEQ
            y := y + x
            z := z + x
        :
        SEQ
          a, b, c, d := 1, 2, 3, 4
          r1, r2 := 1, 2
          P(F(a, b, c, d), r1, r2)
          check(r1, 11, "M057")
          check(r2, 12, "M058")
        --}}} 
        --{{{  M059 and M060
        INT res:
        PROC P(VAL INT x, y, z)
          res := x + (y + z)
        :
        SEQ
          res := 0
          P(F(a, b, c, d), a, b + b)
          check(res, 15, "M059")
          P(F(a, b, c, d), a + a, b + b)
          check(res, 16, "M060")
        --}}} 
        --{{{  M061
        INT res:
        PROC P(VAL INT w, x, y, z)
          res := w + (x + (y + z))
        :
        SEQ
          P(F(a, b, c, d), a, b, ((a + a) + (a + a)) + ((a + a) + (a + a)))
          check(res, 21, "M061")
        --}}} 
    :
    awkward.params()
    --}}} 
    --{{{  multi-valued functions                    M062 - M088
    PROC multi.valued.functions()
      -- Storing three register results
      INT a, b, c, d:
      [5]INT e, f, g :
      INT, INT, INT FUNCTION F(VAL INT x) IS x + 1, x + 2, x + 3 :
      SEQ
        a, b, c, d := 1, 2, 3, 4
        --{{{  basic                    M062 - M064
        a, b, c := F(d)
        check(a, 5, "M062")
        check(b, 6, "M063")
        check(c, 7, "M064")
        --}}} 
        --{{{  aliases a                M065 - M067
        a := 5
        a, b, c := F(a)   -- alias of a
        check(a, 6, "M065")
        check(b, 7, "M066")
        check(c, 8, "M067")
        --}}} 
        --{{{  no temps required        M068 - M079
        a, e[0], c := F(d)   -- no temps required
        check (a, 5, "M068")
        check(e[0], 6, "M069")
        check(c, 7, "M070")
        a := 1
        e[a], b, c := F(d)  -- no temps required
        check(e[1], 5, "M071")
        check(b, 6, "M072")
        check(c, 7, "M073")
        b := 1
        a, e[b], c := F(d)   -- no temps required
        check(a, 5, "M074")
        check(e[1], 6, "M075")
        check(c, 7, "M076")
        a, b, e[0] := F(d)    -- no temps required
        check(a, 5, "M077")
        check(b, 6, "M078")
        check(e[0], 7, "M079")
        --}}} 
        --{{{  one register to temp     M080 - M088
        a, e[0], e[1] := F(d)  -- store Areg to temp (if vector space)
        check(a, 5, "M080")
        check(e[0], 6, "M081")
        check(e[1], 7, "M082")
        b, c := 1, 2
        a, e[b], f[c] := F(d)  -- store Areg to temp
        check(a, 5, "M083")
        check(e[1], 6, "M084")
        check(f[2], 7, "M085")
        a, b, c := 1, 2, 3
        e[a], f[b], g[c] := F(d) -- store Areg and Breg to temps
        check(e[1], 5, "M086")
        check(f[2], 6, "M087")
        check(g[3], 7, "M088")
        --}}} 
        --{{{  all registers to temp    M086 - M088  (repeated!!!!!)
        [5][5]INT er, fr, gr :
        SEQ
          a, b, c := 1, 2, 3
          er[a][b], fr[b][a], gr[a][c] := F(d) -- store all regs to temps
          check(er[1][2], 5, "M086")
          check(fr[2][1], 6, "M087")
          check(gr[1][3], 7, "M088")
        --}}} 
    :
    multi.valued.functions()
    --}}} 
    --{{{  aliasing in functions                     M089 - M116
    PROC aliasing.in.functions()
      SEQ
        --{{{  a is a free variable of F   M089 - M092
        INT a:
        INT, INT, INT, INT FUNCTION F() IS a + 1, 2, 3, 4 :
        INT b, c, d:
        SEQ
          a, b, c, d := 5, 10, 15, 20
          b, c, d, a := F()
          check(a, 4, "M089")
          check(b, 6, "M090")
          check(c, 2, "M091")
          check(d, 3, "M092")
        --}}} 
        INT, INT, INT, INT FUNCTION F(VAL INT x) IS x + 1, x + 2, x + 3, x + 4:
        INT a, b, c, d:
        SEQ
          a, b, c, d := 1, 2, 3, 10
          --{{{  d is aliased in a call of F  M093 - M096
          a, b, c, d := F(d)
          check(a, 11, "M093")
          check(b, 12, "M094")
          check(c, 13, "M095")
          check(d, 14, "M096")
          --}}} 
          --{{{  e is aliased in a call of F  M097 - M100
          [5]INT e :
          INT i, j:
          SEQ
            i, j := 2, 3
            e[i] := 20
            e[j] := 30
            a, b, c, e[i] := F(e[j])
            check(a, 31, "M097")
            check(b, 32, "M098")
            check(c, 33, "M099")
            check(e[2], 34, "M100")
          --}}} 
        --{{{  two results are aliased        M101 - M105
        INT, INT, INT, INT, INT FUNCTION F (VAL INT x, y) IS x + y,
          (x + y) + 1, (x + y) + 2, (x + y) + 3, (x + y) + 4 :
        INT a, b, c, d, e :
        SEQ
          a, b, c, d, e := 5, 10, 15, 20, 25
          a, b, c, d, e := F(d, e)
          check(a, 45, "M101")
          check(b, 46, "M102")
          check(c, 47, "M103")
          check(d, 48, "M104")
          check(e, 49, "M105")
        --}}} 
        --{{{  array e is a free variable     M106 - M109
        [5]INT e :
        INT, INT, INT, INT FUNCTION F() IS e[0], e[1], e[2], e[3] :
        INT a, b, c :
        INT i :
        SEQ
          SEQ i = 0 FOR SIZE e
            e[i] := i
          a, b, c, i := 1, 2, 3, 1
          a, b, c, e[i] := F()
          check(a, 0, "M106")
          check(b, 1, "M107")
          check(c, 2, "M108")
          check(e[1], 3, "M109")
        --}}} 
        --{{{  i is a free variable           M110 - M113
        INT i :
        INT, INT, INT, INT FUNCTION F(VAL []INT e) IS e[i], e[i + 1], e[i + 2],
                                                      e[i + 3] :
        [5]INT ar:
        INT a, b, c :
        SEQ
          SEQ i = 0 FOR SIZE ar
            ar[i] := i
          a, b, c, i := 5, 10, 15, 1
          a, b, c, i := F(ar)
          check(a, 1, "M110")
          check(b, 2, "M111")
          check(c, 3, "M112")
          check(i, 4, "M113")
        --}}} 
        --{{{  check aliasing INT16           M114 - M116
        INT16 x :
        [3]INT16 array :
        INT16 FUNCTION f(VAL INT16 a) IS a + 998(INT16) :
        SEQ
          SEQ i = 0 FOR SIZE array
            array[i] := INT16 i
          array[1] := f(array[1])
          check(0,   INT array[0], "M114")
          check(999, INT array[1], "M115")
          check(2,   INT array[2], "M116")
        
        --}}}
    :
    aliasing.in.functions()
    
    --}}}
    --{{{  bugs                                      M120 - M129
    PROC bugs()
      SEQ
        --{{{  bug 238
        PROC p (INT a, b)
          a, b := b, a
        :
        INT a, b :
        SEQ  -- Check for bug 238 in buglist 6/3/90
          a, b := 910, 373
          p (a, b)
          check (a, 373, "M120")
          check (b, 910, "M121")
        
        --}}}
        --{{{  bug 114
        -- check for bug 114 in buglist
        INT a, b, c, d, e, f, g, h, i, j, k, l, m :
        SEQ
          a, b, c, d, e, f, g, h, i, j, k, l, m := 1,2,3,4,5,6,7,8,9,10,11,12,13
          a, b, c, d, e, f, g, h, i, j, k, l, m := b,c,d,e,f,g,h,i,j,k,l,m,a
          check (a, 2, "B114a")
          check (b, 3, "B114b")
          check (c, 4, "B114c")
          check (d, 5, "B114d")
          check (e, 6, "B114e")
          check (f, 7, "B114f")
          check (g, 8, "B114g")
          check (h, 9, "B114h")
          check (i, 10, "B114i")
          check (j, 11, "B114j")
          check (k, 12, "B114k")
          check (l, 13, "B114l")
          check (m,  1, "B114m")
        --}}}
        --{{{  bug 255
        
        -- check for bug 255 in buglist
        -- (basically getting the types of the pointers on the resultlist reversed)
        -- This would make INT16 <-> REAL64, INT <-> REAL32, INT32 <-> INT64
        BOOL, BYTE, INT, INT16, INT, INT32, INT64, REAL32, REAL64 FUNCTION f ()
          VALOF
            SKIP
            RESULT TRUE, 'a', 88, 16(INT16), 99, 32(INT32), 64(INT64),
                   32.0(REAL32), 64.0(REAL64)
        :
        INT, INT, INT, INT32, REAL64 FUNCTION g ()
          INT64 i64 :
          INT32 i32 :
          REAL64 r64 :
          VALOF
            i32, r64 := 22(INT32), 99.99(REAL64)
            RESULT 1, 2, 3, i32, r64
        :
        BOOL bool :
        BYTE byte :
        INT i, j, k :
        INT16 i16 :
        INT32 i32 :
        INT64 i64 :
        REAL32 r32 :
        REAL64 r64 :
        SEQ
          bool, byte, i, i16, j, i32, i64, r32, r64 :=
            TRUE, '*#FF', -1, -1(INT16), -1, -1(INT32), -1(INT64),
            12345.6252(REAL32), -26263.238282(REAL64)
          bool, byte, i, i16, j, i32, i64, r32, r64 := f()
          check (INT bool, INT TRUE, "B255a")
          check (INT byte, INT 'a' , "B255b")
          check (INT i,    88, "B255c")
          check (INT i16,  16, "B255d")
          check (INT j,    99, "B255e")
          check (INT i32,  32, "B255f")
          check (INT i64,  64, "B255g")
          check (INT ROUND r32, 32, "B255h")
          check (INT ROUND r64, 64, "B255i")
          i, j, k, i32, r64 := -1, -2, -3, -1(INT32), 12345.67890(REAL64)
          i, j, k, i32, r64 := g ()
          check (i, 1, "B225j")
          check (j, 2, "B225k")
          check (k, 3, "B225l")
          check (INT i32, 22, "B225m")
          check (INT ROUND r64, 100, "B225n")
        --}}}
        --{{{  bug 278
        PROC bug.278 ()
          [10][2]INT a :
          SEQ
            SEQ i = 0 FOR SIZE a
              a[i][0], a[i][1] := 1, 2
            SEQ i = 0 FOR SIZE a
              PAR
                a[i][0] := 1
                a[i][1] := 2
            check (a[1][0], 1, "B278a")
        :
        bug.278 ()
        --}}}
    :
    bugs()
    --}}}
    #IF NOT DEFINED (COMPILER.TOCK)
    --{{{  bug 1002
    PROC bug.1002()
      SEQ
        INT a, b, c, d :
        SEQ
          c, d := 1(INT), 2(INT)
          a, b := (VALOF
                     SKIP
                     RESULT c*c
                  ), (VALOF
                        SKIP
                        RESULT d*d
                     )
          check.INT(a, 1(INT), "B1002a")
          check.INT(b, 4(INT), "B1002b")
        INT16 a, b, c, d :
        SEQ
          c, d := 1(INT16), 2(INT16)
          a, b := (VALOF
                     SKIP
                     RESULT c*c
                  ), (VALOF
                        SKIP
                        RESULT d*d
                     )
          check.INT16(a, 1(INT16), "B1002c")
          check.INT16(b, 4(INT16), "B1002d")
        INT32 a, b, c, d :
        SEQ
          c, d := 1(INT32), 2(INT32)
          a, b := (VALOF
                     SKIP
                     RESULT c*c
                  ), (VALOF
                        SKIP
                        RESULT d*d
                     )
          check.INT32(a, 1(INT32), "B1002e")
          check.INT32(b, 4(INT32), "B1002f")
        INT64 a, b, c, d :
        SEQ
          c, d := 1(INT64), 2(INT64)
          a, b := (VALOF
                     SKIP
                     RESULT c*c
                  ), (VALOF
                        SKIP
                        RESULT d*d
                     )
          check.INT64(a, 1(INT64), "B1002g")
          check.INT64(b, 4(INT64), "B1002h")
        REAL32 a, b, c, d :
        SEQ
          c, d := 1.0(REAL32), 2.0(REAL32)
          a, b := (VALOF
                     SKIP
                     RESULT c*c
                  ), (VALOF
                        SKIP
                        RESULT d*d
                     )
          check.REAL32(a, 1.0(REAL32), "B1002i")
          check.REAL32(b, 4.0(REAL32), "B1002j")
        REAL64 a, b, c, d :
        SEQ
          c, d := 1.0(REAL64), 2.0(REAL64)
          a, b := (VALOF
                     SKIP
                     RESULT c*c
                  ), (VALOF
                        SKIP
                        RESULT d*d
                     )
          check.REAL64(a, 1.0(REAL64), "B1002k")
          check.REAL64(b, 4.0(REAL64), "B1002l")
    :
    bug.1002()
    --}}}
    #ENDIF
    --{{{  multi word size function tests            M200 - M250
    PROC multi.word.size.tests()
      SEQ
        --{{{  Aliasing INT64  ( M200 - M203 )
        -- result a must be aliased, otherwise return will store 3 in a
        -- then return 3+1 not 1+1.
        
        INT64 a, b :
        INT64, INT64 FUNCTION f(VAL INT64 x) IS 3(INT64), x + 1(INT64) :
        SEQ
          a, b := 1(INT64), 2(INT64)
          a, b := f(a)
          check(INT a, 3, "M200") -- bug 1012
          check(INT b, 2, "M201")
        
        -- Similarly a, although free, must be aliased
        INT64 a, b :
        INT64, INT64 FUNCTION f() IS 3(INT64), a + 1(INT64) :
        SEQ
          a, b := 1(INT64), 2(INT64)
          a, b := f()
          check(INT a, 3, "M202") -- bug 1012
          check(INT b, 2, "M203")
        
        --}}}
        --{{{  Aliasing REAL64 ( M210 - M213 )
        -- result a must be aliased, otherwise return will store 3 in a
        -- then return 3+1 not 1+1.
        
        REAL64 a, b :
        REAL64, REAL64 FUNCTION f(VAL REAL64 x) IS 3.0(REAL64), x + 1.0(REAL64) :
        SEQ
          a, b := 1.0(REAL64), 2.0(REAL64)
          a, b := f(a)
          check(INT TRUNC a, 3, "M210") -- bug 1012
          check(INT TRUNC b, 2, "M211")
        
        -- Similarly a, although free, must be aliased
        REAL64 a, b :
        REAL64, REAL64 FUNCTION f() IS 3.0(REAL64), a + 1.0(REAL64) :
        SEQ
          a, b := 1.0(REAL64), 2.0(REAL64)
          a, b := f()
          check(INT TRUNC a, 3, "M212") -- bug 1012
          check(INT TRUNC b, 2, "M213")
        --}}}
    :
    multi.word.size.tests()
    --}}}
    --{{{  Parameters involving calc                 M300 - M399
    --{{{  output title
    title ("Testing complex parameters to PROCs and FNs")
    -- Here complex means that it requires evaluation
    --}}}
    
    --{{{  4 parameters, BOOL   array subscripts (M300 - M303)
    PROC M300()
      VAL []BOOL array IS [ TRUE, FALSE, FALSE, TRUE ] :
      PROC p(VAL BOOL w, x, y, z)
        SEQ
          check(INT w, INT TRUE,  "M300")
          check(INT x, INT FALSE, "M301")
          check(INT y, INT FALSE, "M302")
          check(INT z, INT TRUE,  "M303")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M300()
    --}}}
    --{{{  4 parameters, BYTE   array subscripts (M310 - M313)
    PROC M310()
      VAL []BYTE array IS [ 1(BYTE), 2(BYTE), 3(BYTE), 4(BYTE) ] :
      PROC p(VAL BYTE w, x, y, z)
        SEQ
          check(INT w, 1, "M310")
          check(INT x, 2, "M311")
          check(INT y, 3, "M312")
          check(INT z, 4, "M313")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M310()
    --}}}
    --{{{  4 parameters, INT    array subscripts (M320 - M323)
    PROC M320()
      VAL []INT array IS [ 1, 2, 3, 4 ] :
      PROC p(VAL INT w, x, y, z)
        SEQ
          check(w, 1, "M310")
          check(x, 2, "M311")
          check(y, 3, "M312")
          check(z, 4, "M313")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M320()
    --}}}
    --{{{  4 parameters, INT16  array subscripts (M330 - M333)
    PROC M330()
      VAL []INT16 array IS [ 1(INT16), 2(INT16), 3(INT16), 4(INT16) ] :
      PROC p(VAL INT16 w, x, y, z)
        SEQ
          check(INT w, 1, "M300")
          check(INT x, 2, "M301")
          check(INT y, 3, "M302")
          check(INT z, 4, "M303")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M330()
    --}}}
    --{{{  4 parameters, INT32  array subscripts (M340 - M343)
    PROC M340()
      VAL []INT32 array IS [ 1(INT32), 2(INT32), 3(INT32), 4(INT32) ] :
      PROC p(VAL INT32 w, x, y, z)
        SEQ
          check(INT w, 1, "M300")
          check(INT x, 2, "M301")
          check(INT y, 3, "M302")
          check(INT z, 4, "M303")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M340()
    --}}}
    --{{{  4 parameters, INT64  array subscripts (M350 - M353)
    PROC M350()
      VAL []INT64 array IS [ 1(INT64), 2(INT64), 3(INT64), 4(INT64) ] :
      PROC p(VAL INT64 w, x, y, z)
        SEQ
          check(INT w, 1, "M300")
          check(INT x, 2, "M301")
          check(INT y, 3, "M302")
          check(INT z, 4, "M303")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M350()
    --}}}
    --{{{  4 parameters, REAL32 array subscripts (M360 - M363)
    PROC M360()
      VAL []REAL32 array IS [ 1.0(REAL32), 2.0(REAL32), 3.0(REAL32), 4.0(REAL32) ] :
      PROC p(VAL REAL32 w, x, y, z)
        SEQ
          check(INT TRUNC w, 1, "M300")
          check(INT TRUNC x, 2, "M301")
          check(INT TRUNC y, 3, "M302")
          check(INT TRUNC z, 4, "M303")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M360()
    --}}}
    --{{{  4 parameters, REAL64 array subscripts (M370 - M373)
    PROC M370()
      VAL []REAL64 array IS [ 1.0(REAL64), 2.0(REAL64), 3.0(REAL64), 4.0(REAL64) ] :
      PROC p(VAL REAL64 w, x, y, z)
        SEQ
          check(INT TRUNC w, 1, "M300")
          check(INT TRUNC x, 2, "M301")
          check(INT TRUNC y, 3, "M302")
          check(INT TRUNC z, 4, "M303")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 0, 1, 2, 3
        p(array[a], array[b], array[c], array[d])
    :
    M370()
    --}}}
    --{{{  4 INT parameters involving calculations (M380 - M383)
    PROC M380()
      VAL []INT ia IS [ 1(INT), 2(INT), 3(INT), 4(INT) ] :
      PROC p(VAL INT w, x, y, z)
        SEQ
          check(INT w, 6,  "M380")
          check(INT x, 1,  "M381")
          check(INT y, 24, "M382")
          check(INT z, 9,  "M383")
      :
      INT a, b, c, d :
      SEQ
        a, b, c, d := 1, 2, 3, 4
        p((a+b) + c, (a+1) / b, c * (d*b), b + (c + d))
    :
    M380()
    --}}}
    --}}}
    --{{{  more aliasing                             M400 - M499
    PROC more.aliasing()
      SEQ
        --{{{  INT                                   INT-00 - INT-99
        INT globally.visible :
        INT FUNCTION no.params.INT() IS globally.visible :
        INT FUNCTION one.param.INT(VAL INT x) IS x*id.INT(2(INT)) :
        INT, INT FUNCTION swap.INT(VAL INT x, y) IS y, x :
        INT, INT FUNCTION mod.swap.INT(VAL INT x, y, zero) IS y+zero, x+zero :
        INT, INT FUNCTION glob.swap.INT(VAL INT x, y) IS y+globally.visible, x+globally.visible :
        INT x, y, zero :
        SEQ
          zero := id.INT(0(INT))
          globally.visible := id.INT(88(INT))
          x := 77(INT)
        
          x := no.params.INT()
          check.INT(x, 88(INT), "INT-00")
        
          globally.visible := no.params.INT()
          check.INT(globally.visible, 88(INT), "INT-01")
          globally.visible := id.INT(88(INT))
        
          y := one.param.INT(x)
          check.INT(y, 176(INT), "INT-02")
        
          globally.visible := one.param.INT(x)
          check.INT(globally.visible, 176(INT), "INT-03")
          globally.visible := one.param.INT(globally.visible)
          check.INT(globally.visible, 352(INT), "INT-04")
        
          x, y := swap.INT(x, y)
          check.INT(x, 176(INT), "INT-05")
          check.INT(y,  88(INT), "INT-06")
        
          y, x := swap.INT(x, y)
          check.INT(x, 176(INT), "INT-07")
          check.INT(y,  88(INT), "INT-08")
        
          x, y := mod.swap.INT(x, y, zero)
          check.INT(y, 176(INT), "INT-09")
          check.INT(x,  88(INT), "INT-10")
        
          y, x := mod.swap.INT(x, y, zero)
          check.INT(y, 176(INT), "INT-11")
          check.INT(x,  88(INT), "INT-12")
        
          globally.visible := id.INT(-1(INT))
          x, y := glob.swap.INT(x, y)
          check.INT(x, 175(INT), "INT-13")
          check.INT(y,  87(INT), "INT-14")
        
          y, x := glob.swap.INT(x, y)
          check.INT(x, 174(INT), "INT-15")
          check.INT(y,  86(INT), "INT-16")
        
          globally.visible, y := glob.swap.INT(x, y)
          check.INT(globally.visible, 85(INT), "INT-17")
          check.INT(y,  173(INT), "INT-18")
        
          y, globally.visible := glob.swap.INT(globally.visible, y)
          check.INT(globally.visible, 170(INT), "INT-19")
          check.INT(y,  258(INT), "INT-20")
        
        --}}}
        --{{{  INT16                                 INT16-00 - INT16-99
        INT16 globally.visible :
        INT16 FUNCTION no.params.INT16() IS globally.visible :
        INT16 FUNCTION one.param.INT16(VAL INT16 x) IS x*id.INT16(2(INT16)) :
        INT16, INT16 FUNCTION swap.INT16(VAL INT16 x, y) IS y, x :
        INT16, INT16 FUNCTION mod.swap.INT16(VAL INT16 x, y, zero) IS y+zero, x+zero :
        INT16, INT16 FUNCTION glob.swap.INT16(VAL INT16 x, y) IS y+globally.visible, x+globally.visible :
        INT16 x, y, zero :
        SEQ
          zero := id.INT16(0(INT16))
          globally.visible := id.INT16(88(INT16))
          x := 77(INT16)
        
          x := no.params.INT16()
          check.INT16(x, 88(INT16), "INT16-00")
        
          globally.visible := no.params.INT16()
          check.INT16(globally.visible, 88(INT16), "INT16-01")
          globally.visible := id.INT16(88(INT16))
        
          y := one.param.INT16(x)
          check.INT16(y, 176(INT16), "INT16-02")
        
          globally.visible := one.param.INT16(x)
          check.INT16(globally.visible, 176(INT16), "INT16-03")
          globally.visible := one.param.INT16(globally.visible)
          check.INT16(globally.visible, 352(INT16), "INT16-04")
        
          x, y := swap.INT16(x, y)
          check.INT16(x, 176(INT16), "INT16-05")
          check.INT16(y,  88(INT16), "INT16-06")
        
          y, x := swap.INT16(x, y)
          check.INT16(x, 176(INT16), "INT16-07")
          check.INT16(y,  88(INT16), "INT16-08")
        
          x, y := mod.swap.INT16(x, y, zero)
          check.INT16(y, 176(INT16), "INT16-09")
          check.INT16(x,  88(INT16), "INT16-10")
        
          y, x := mod.swap.INT16(x, y, zero)
          check.INT16(y, 176(INT16), "INT16-11")
          check.INT16(x,  88(INT16), "INT16-12")
        
          globally.visible := id.INT16(-1(INT16))
          x, y := glob.swap.INT16(x, y)
          check.INT16(x, 175(INT16), "INT16-13")
          check.INT16(y,  87(INT16), "INT16-14")
        
          y, x := glob.swap.INT16(x, y)
          check.INT16(x, 174(INT16), "INT16-15")
          check.INT16(y,  86(INT16), "INT16-16")
        
          globally.visible, y := glob.swap.INT16(x, y)
          check.INT16(globally.visible, 85(INT16), "INT16-17")
          check.INT16(y,  173(INT16), "INT16-18")
        
          y, globally.visible := glob.swap.INT16(globally.visible, y)
          check.INT16(globally.visible, 170(INT16), "INT16-19")
          check.INT16(y,  258(INT16), "INT16-20")
        
        --}}}
        --{{{  INT32                                 INT32-00 - INT32-99
        INT32 globally.visible :
        INT32 FUNCTION no.params.INT32() IS globally.visible :
        INT32 FUNCTION one.param.INT32(VAL INT32 x) IS x*id.INT32(2(INT32)) :
        INT32, INT32 FUNCTION swap.INT32(VAL INT32 x, y) IS y, x :
        INT32, INT32 FUNCTION mod.swap.INT32(VAL INT32 x, y, zero) IS y+zero, x+zero :
        INT32, INT32 FUNCTION glob.swap.INT32(VAL INT32 x, y) IS y+globally.visible, x+globally.visible :
        INT32 x, y, zero :
        SEQ
          zero := id.INT32(0(INT32))
          globally.visible := id.INT32(88(INT32))
          x := 77(INT32)
        
          x := no.params.INT32()
          check.INT32(x, 88(INT32), "INT32-00")
        
          globally.visible := no.params.INT32()
          check.INT32(globally.visible, 88(INT32), "INT32-01")
          globally.visible := id.INT32(88(INT32))
        
          y := one.param.INT32(x)
          check.INT32(y, 176(INT32), "INT32-02")
        
          globally.visible := one.param.INT32(x)
          check.INT32(globally.visible, 176(INT32), "INT32-03")
          globally.visible := one.param.INT32(globally.visible)
          check.INT32(globally.visible, 352(INT32), "INT32-04")
        
          x, y := swap.INT32(x, y)
          check.INT32(x, 176(INT32), "INT32-05")
          check.INT32(y,  88(INT32), "INT32-06")
        
          y, x := swap.INT32(x, y)
          check.INT32(x, 176(INT32), "INT32-07")
          check.INT32(y,  88(INT32), "INT32-08")
        
          x, y := mod.swap.INT32(x, y, zero)
          check.INT32(y, 176(INT32), "INT32-09")
          check.INT32(x,  88(INT32), "INT32-10")
        
          y, x := mod.swap.INT32(x, y, zero)
          check.INT32(y, 176(INT32), "INT32-11")
          check.INT32(x,  88(INT32), "INT32-12")
        
          globally.visible := id.INT32(-1(INT32))
          x, y := glob.swap.INT32(x, y)
          check.INT32(x, 175(INT32), "INT32-13")
          check.INT32(y,  87(INT32), "INT32-14")
        
          y, x := glob.swap.INT32(x, y)
          check.INT32(x, 174(INT32), "INT32-15")
          check.INT32(y,  86(INT32), "INT32-16")
        
          globally.visible, y := glob.swap.INT32(x, y)
          check.INT32(globally.visible, 85(INT32), "INT32-17")
          check.INT32(y,  173(INT32), "INT32-18")
        
          y, globally.visible := glob.swap.INT32(globally.visible, y)
          check.INT32(globally.visible, 170(INT32), "INT32-19")
          check.INT32(y,  258(INT32), "INT32-20")
        
        --}}}
        --{{{  INT64                                 INT64-00 - INT64-99
        INT64 globally.visible :
        INT64 FUNCTION no.params.INT64() IS globally.visible :
        INT64 FUNCTION one.param.INT64(VAL INT64 x) IS x*id.INT64(2(INT64)) :
        INT64, INT64 FUNCTION swap.INT64(VAL INT64 x, y) IS y, x :
        INT64, INT64 FUNCTION mod.swap.INT64(VAL INT64 x, y, zero) IS y+zero, x+zero :
        INT64, INT64 FUNCTION glob.swap.INT64(VAL INT64 x, y) IS y+globally.visible, x+globally.visible :
        INT64 x, y, zero :
        SEQ
          zero := id.INT64(0(INT64))
          globally.visible := id.INT64(88(INT64))
          x := 77(INT64)
        
          x := no.params.INT64()
          check.INT64(x, 88(INT64), "INT64-00")
        
          globally.visible := no.params.INT64()
          check.INT64(globally.visible, 88(INT64), "INT64-01")
          globally.visible := id.INT64(88(INT64))
        
          y := one.param.INT64(x)
          check.INT64(y, 176(INT64), "INT64-02")
        
          globally.visible := one.param.INT64(x)
          check.INT64(globally.visible, 176(INT64), "INT64-03")
          globally.visible := one.param.INT64(globally.visible)
          check.INT64(globally.visible, 352(INT64), "INT64-04")
        
          x, y := swap.INT64(x, y)
          check.INT64(x, 176(INT64), "INT64-05")
          check.INT64(y,  88(INT64), "INT64-06")
        
          y, x := swap.INT64(x, y)
          check.INT64(x, 176(INT64), "INT64-07")
          check.INT64(y,  88(INT64), "INT64-08")
        
          x, y := mod.swap.INT64(x, y, zero)
          check.INT64(y, 176(INT64), "INT64-09")
          check.INT64(x,  88(INT64), "INT64-10")
        
          y, x := mod.swap.INT64(x, y, zero)
          check.INT64(y, 176(INT64), "INT64-11")
          check.INT64(x,  88(INT64), "INT64-12")
        
          globally.visible := id.INT64(-1(INT64))
          x, y := glob.swap.INT64(x, y)
          check.INT64(x, 175(INT64), "INT64-13")
          check.INT64(y,  87(INT64), "INT64-14")
        
          y, x := glob.swap.INT64(x, y)
          check.INT64(x, 174(INT64), "INT64-15")
          check.INT64(y,  86(INT64), "INT64-16")
        
          globally.visible, y := glob.swap.INT64(x, y)
          check.INT64(globally.visible, 85(INT64), "INT64-17")
          check.INT64(y,  173(INT64), "INT64-18")
        
          y, globally.visible := glob.swap.INT64(globally.visible, y)
          check.INT64(globally.visible, 170(INT64), "INT64-19")
          check.INT64(y,  258(INT64), "INT64-20")
        
        --}}}
    :
    more.aliasing()
    --}}}
    --{{{  bug 1012
    PROC bug.1012()
      INT64 FUNCTION silly()    IS 999(INT64) :
      INT64, INT64 FUNCTION g() IS silly(), silly() :
      INT64 a, b :
      SEQ
        a, b := -1919(INT64), -154(INT64)
        a, b := g ()
        check(INT a, 999, "B1012a")
        check(INT b, 999, "B1012b")
    :
    bug.1012()
    --}}}
    --{{{  bug 1013
    PROC bug.1013()
      PROC check.local(VAL INT t3, t4, t5, t6)
        SEQ
          check(t3, 0, "B1013a")
          check(t4, 1, "B1013b")
          check(t5, 2, "B1013c")
          check(t6, 3, "B1013d")
      :
      [5]INT16 array :
      SEQ
        array[1] := 1(INT16)
        array[2] := 10(INT16) -- this is actually irrelevant, except to
        array[3] := 20(INT16) -- ditto,             avoid x overflowing
        check.local(0, INT array[1], 2, 3)
        -- This code only here to ensure temp vars allocated to highlight problem
        #IF DEFINED (COMPILER.TOCK)
        array[1] := INT16 ((INT (array[2] * array[3])) + (INT (array[2] * array[3])))
        #ELSE
        array[1] := (INT x:
                     VALOF
                       x := (INT (array[2] * array[3])) +
                            (INT (array[2] * array[3]))
                       RESULT INT16 x
                    )
        #ENDIF
    :
    bug.1013()
    PROC bug.1013e()
      INT FUNCTION f(VAL INT x) IS x :
      PROC q (VAL INT c, d, e )
        SEQ
          check(c,  999, "B1013e")
          check(d, 7992, "B1013f")
          check(e,  999, "B1013g")
      :
      INT a, b :
      SEQ
        a, b := 999, 101
        q (a,
           f((((a+b) + (a-b)) + ((a-b) + (a+b))) +
             (((a-b) + (a+b)) + ((a+b) + (a-b))) ),
           f(a))
    :
    bug.1013e()
    --}}}
    --{{{  bug 1606
    PROC bug.1606()
      INT, INT FUNCTION test(VAL INT X) IS X, X :
      PROC bug.1606a([]INT a, [][]INT b, [][][]INT c, INT x)
        SEQ
          a[0],       x := test(x)
          b[0][0],    x := test(x)
          c[0][0][0], x := test(x)
      :
      [2]INT A :
      [2][2]INT B :
      [2][2][2]INT C :
      INT X :
      VAL Y IS 33 :
      VAL Z IS 99 :
      SEQ
        X := Z
        SEQ I = 0 FOR 2
          SEQ
            A[I] := Y
            SEQ J = 0 FOR 2
              SEQ
                B[I][J] := Y
                SEQ K = 0 FOR 2
                  C[I][J][K] := Y
        bug.1606a(A, B, C, X)
        check(A[0],       Z, "B1606a")
        check(B[0][0],    Z, "B1606b")
        check(C[0][0][0], Z, "B1606c")
    :
    bug.1606()
    --}}}
    --{{{  bug INSdi03198
    PROC bug.INSdi03198()
      INT64 FUNCTION add(VAL INT64 x, y) IS x+y :
      INT64 x, y, z :
      SEQ
        x := id.INT64(88(INT64))
        y := id.INT64(-3(INT64))
        z := id.INT64(17(INT64))
        x, y, z := add(x, y), add(y, z), add(x, z)
        check.INT64(x,  85(INT64), "di3198a")
        check.INT64(y,  14(INT64), "di3198b")
        check.INT64(z, 105(INT64), "di3198c")
    :
    bug.INSdi03198()
    --}}}
    finish ()
:
