#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  ! second test
//     2  %begin

int main(int argc, char **argv) { /*%begin*/
  _imp_initialise(argc, argv);

  //     3    %routine test(%name param)         ;! ia1          ia2

  void TEST(_imp_name * PARAM) {
    //     4      write(addr(param),0)  ; newline  ;! 2145833816   2145833816     same address again!

    _imp_WRITE(_imp_ADDR(PARAM), 0);
    _imp_NEWLINE();

    //     5      write(sizeof(param),0); newline  ;! 4            4              sizeof  %integer

    _imp_WRITE(_imp_SIZEOF(PARAM), 0);
    _imp_NEWLINE();

    //     6      write(typeof(param),0); newline  ;! 1            1              typeof  %integer

    _imp_WRITE(_imp_TYPEOF(PARAM), 0);
    _imp_NEWLINE();

    //     7    %end

    return;
  } /* end of TEST */

  //     8
  //     9    %integerarray ia1(3:5)

  int IA1[3];
  struct _imp_dv IA1_dv = {IA1, sizeof(int) /*, dims, <bounds> */};

  //    10    %integerarray ia2(2:4,3:6)

  int IA2[3][4];
  struct _imp_dv IA2_dv = {IA2, sizeof(int) /*, dims, <bounds> */};

  //    11
  //    12    write(addr(ia1),0); newline     ;! 2145833816     Note it is the same address as written in test(ia1) and test (ia2)!

  _imp_WRITE(_imp_ADDR(IA1), 0);
  _imp_NEWLINE();

  //    13    write(addr(ia1(3)),0); newline  ;! 2145833744

  _imp_WRITE(_imp_ADDR(/*?*/ &IA1[0]), 0);
  _imp_NEWLINE();

  //    14    write(sizeof(ia1),0); newline   ;! 4

  _imp_WRITE(_imp_SIZEOF(IA1), 0);
  _imp_NEWLINE();

  //    15    write(typeof(ia1),0); newline   ;! 1

  _imp_WRITE(_imp_TYPEOF(IA1), 0);
  _imp_NEWLINE();

  //    16
  //    17    test(ia1)

  TEST(IA1);

  //    18
  //    19
  //    20    write(addr(ia2),0); newline       ;! 2145833816   Same address as ia1 above!!!  that was unexpected.

  _imp_WRITE(_imp_ADDR(IA2), 0);
  _imp_NEWLINE();

  //    21    write(addr(ia2(2,3)),0); newline  ;! 2145833756   This is 12 bytes after address of first element of ia1, i.e. ia1(3)

  _imp_WRITE(_imp_ADDR(/*?*/ &IA2[0][0]), 0);
  _imp_NEWLINE();

  //    22                                       !              (Note ia1 is 3 elements of 4 bytes per element)
  //    23    write(sizeof(ia2),0); newline     ;! 4

  _imp_WRITE(_imp_SIZEOF(IA2), 0);
  _imp_NEWLINE();

  //    24    write(typeof(ia2),0); newline     ;! 1

  _imp_WRITE(_imp_TYPEOF(IA2), 0);
  _imp_NEWLINE();

  //    25
  //    26    test(ia2)

  TEST(IA2);

  //    27
  //    28  %endofprogram

  _imp_stop(0);
  return 0;
end_0:;
}