#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  ! check that sizeof/typeof was giving the expected value
//     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

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

    //     5      write(sizeof(param),0); newline  ;! 1            8             1 is sizeof %byte, 8 is sizeof %longreal

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

    //     6      write(typeof(param),0); newline  ;! 5            8             5 is typeof %byte, 8 is typeof %longreal

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

    //     7    %end

    return;
  } /* end of TEST */

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

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

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

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

  //    11
  //    12    printstring( "Testing ia1"); newline

  _imp_PRINTSTRING(_imp_str_literal("Testing ia1"));
  _imp_NEWLINE();

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

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

  //    14    write(addr(ia1(3)),0); newline  ;! 2145833704

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

  //    15    write(sizeof(ia1),0); newline   ;! 1                sizeof %btre

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

  //    16    write(typeof(ia1),0); newline   ;! 5                typeof %byte

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

  //    17    test(ia1)

  TEST(IA1);

  //    18
  //    19    printstring( "Testing ia2"); newline

  _imp_PRINTSTRING(_imp_str_literal("Testing ia2"));
  _imp_NEWLINE();

  //    20    write(addr(ia2),0); newline      ;! 2145833816

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

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

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

  //    22                                      !                 which is 3 %byteinteger elements of 1 byte each, aligned to next 4 bytes.
  //    23    write(sizeof(ia2),0); newline    ;! 8               sizeof %longreal

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

  //    24    write(typeof(ia2),0); newline    ;! 8               typeof %longreal

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

  //    25    test(ia2)

  TEST(IA2);

  //    26
  //    27  %endofprogram

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