#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  %begin

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

  //     2  %owninteger swopped =0

  static int SWOPPED = 0;

  //     3  %recordformat f1(%integer i %or %byte b0,b1,b2,b3 %or %string(3)s)

  struct F1 {
    union {
      struct {
        int I;
      };
      struct {
        unsigned char B0;
        unsigned char B1;
        unsigned char B2;
        unsigned char B3;
      };
      struct {
        _imp_string3 S;
      };
    };
  };

  //     4  %recordformat f2(%integer i,%record(f1)f)

  struct F2 {
    union {
      struct {
        int I;
        struct F1 F;
      };
    };
  };

  //     5  %recordformat f3(%integer k,%record(f2)f)

  struct F3 {
    union {
      struct {
        int K;
        struct F2 F;
      };
    };
  };

  //     6  %integer i,fail,j,k

  int I;
  int FAIL;
  int J;
  int K;

  //     7  %routine test(%integer exp,swexp,act)

  void TEST(int EXP, int SWEXP, int ACT) {
    //     8  %if swopped=0 %start

    if (SWOPPED != 0) goto L_0001;

      //     9        %if exp=act %then swopped=-1

    if (EXP != ACT) goto L_0002;
    SWOPPED = -1;
  L_0002:;

  //    10        %if swexp=act %then swopped=1

    if (SWEXP != ACT) goto L_0003;
    SWOPPED = 1;
  L_0003:;

  //    11  %finish

  L_0001:;

  //    12  %if swopped=-1 %and exp=act %then %return

    if (SWOPPED != -1) goto L_0004;
    if (EXP != ACT) goto L_0004;
    return;
  L_0004:;

  //    13  %if swopped=1 %and swexp=act %then %return

    if (SWOPPED != 1) goto L_0005;
    if (SWEXP != ACT) goto L_0005;
    return;
  L_0005:;

  //    14        printstring("expected="); write(exp,5)

    _imp_PRINTSTRING(_imp_str_literal("expected="));
    _imp_WRITE(EXP, 5);

    //    15        printstring(" actual="); write(act,5); newline

    _imp_PRINTSTRING(_imp_str_literal(" actual="));
    _imp_WRITE(ACT, 5);
    _imp_NEWLINE();

    //    16        fail=fail+1

    FAIL = FAIL + 1;

    //    17        %monitor

    /*_imp_monitor(__LINE__, __FILE__, PRETTY_FUNCTION);*/

    //    18  %end

    return;
  } /* end of TEST */

  //    19  %conststring(11) %array tx(-1:1)="","","(swopped)";

  const _imp_string11 TX[3] = {_imp_str_init(""), _imp_str_init(""), _imp_str_init("(swopped)")};

  //    20  %record(f1) r1

  struct F1 R1;

  //    21  %record(f2) r2

  struct F2 R2;

  //    22  %record(f3) r3

  struct F3 R3;

  //    23  fail=0

  FAIL = 0;

  //    24        j=0

  J = 0;

  //    25  l1:

U_1000:;

//    26  r1_i=0

  R1.I = 0;

  //    27  k=r1_I+j

  K = R1.I + J;

  //    28  r1_b3=5

  R1.B3 = 5;

  //    29  test(5,X'05000000',r1_i)

  TEST(5, 83886080, R1.I);

  //    30  test(5,x'05000000',r1_i+j)

  TEST(5, 83886080, R1.I + J);

  //    31  r2_f_i=1

  R2.F.I = 1;

  //    32  r2_f_b3=6

  R2.F.B3 = 6;

  //    33  test(6,x'06000001',r2_f_i)

  TEST(6, 100663297, R2.F.I);

  //    34  r3_f_f_i=1

  R3.F.F.I = 1;

  //    35  r3_f_f_b3=6

  R3.F.F.B3 = 6;

  //    36  test(6,x'06000001',r3_f_f_i)

  TEST(6, 100663297, R3.F.F.I);

  //    37  %if fail=0 %then printstring("Test ok ".tx(swopped))

  if (FAIL != 0) goto L_0006;
  _imp_PRINTSTRING(
      *({
        __typeof__(_imp_string255) tmp = *({
          _imp_string255 tmp =
              _imp_join((_imp_string *)/*?*/ _imp_str_literal_ptr("Test ok "), (_imp_string *)/*?*/ &TX[SWOPPED + 1]);
          (_imp_string255 *)&tmp;
        }) /*q*/;
        (_imp_string255 *)&tmp;
      })
  );
L_0006:;

//    38  %endofprogram

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