#include <perms.h>

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

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

  //     2  %RECORDFORMAT F1(%INTEGER I,J,K,L)

  struct F1 {
    union {
      struct {
        int I;
        int J;
        int K;
        int L;
      };
    };
  };

  //     3  %RECORDFORMAT F2(%INTEGER P,%RECORD(F1)%ARRAY A(0:8))

  struct F2 {
    union {
      struct {
        int P;
        struct F1 A[9];
      };
    };
  };

  //     4  %RECORD(F2) R,RP

  struct F2 R;
  struct F2 RP;

  //     5  %RECORD(F2)%NAME RR

  struct F2 *RR;

  //     6  %RECORD(F1)%NAME RN

  struct F1 *RN;

  //     7  %INTEGER I,J,K,L

  int I;
  int J;
  int K;
  int L;

  //     8  RR==RP

  RR = (struct F2 *)/*?*/ &RP;

  //     9  I=ADDR(R_A(0))

  I = _imp_ADDR(/*?*/ &R.A[0]);

  //    10  RN==R_A(0)

  RN = (struct F1 *)/*?*/ &R.A[0];

  //    11  J=ADDR(R_A(0)_K)

  J = _imp_ADDR(/*?*/ &R.A[0].K);

  //    12  K=ADDR(RR_A(0))

  K = _imp_ADDR(/*?*/ &RR->A[0]);

  //    13  L=ADDR(RR_A(0)_K)

  L = _imp_ADDR(/*?*/ &RR->A[0].K);

  //    14  RN==RR_A(0)

  RN = (struct F1 *)/*?*/ &RR->A[0];

  //    15  %IF I+8=J %AND ADDR(R)+4=I %AND K+8=L %C

  if (I + 8 != J) goto L_0001;
  if (_imp_ADDR(/*?*/ &R) + 4 != I) goto L_0001;
  if (K + 8 != L) goto L_0001;
  {
// Double-sided test on K (Part I)
    int tmp;
    if (_imp_ADDR(RR) + 4 != (tmp = K)) goto L_0001;
// Double-sided test on K (Part II)
    if (tmp != _imp_ADDR(RN)) goto L_0001;
  }
  _imp_PRINTSTRING(_imp_str_literal("\nTEST OK    (BYTE ADDRESS ANSWERS)\n"));
  _imp_stop(0);
L_0001:;

//    16+       %AND ADDR(RR)+4=K=ADDR(RN) %THEN PRINTSTRING("
//    17+ TEST OK    (BYTE ADDRESS ANSWERS)
//    18+ ") %AND %STOP
//    19  %IF I+4=J %AND ADDR(R)+2=I %AND K+4=L %C

  if (I + 4 != J) goto L_0002;
  if (_imp_ADDR(/*?*/ &R) + 2 != I) goto L_0002;
  if (K + 4 != L) goto L_0002;
  {
// Double-sided test on K (Part I)
    int tmp;
    if (_imp_ADDR(RR) + 2 != (tmp = K)) goto L_0002;
// Double-sided test on K (Part II)
    if (tmp != _imp_ADDR(RN)) goto L_0002;
  }
  _imp_PRINTSTRING(_imp_str_literal("\nTEST OK (WORD ADDRESS ANSWERS)\n"));
  _imp_stop(0);
L_0002:;

//    20+       %AND ADDR(RR)+2=K=ADDR(RN) %THEN PRINTSTRING("
//    21+ TEST OK (WORD ADDRESS ANSWERS)
//    22+ ")  %AND %STOP
//    23  PRINTSTRING("

  _imp_PRINTSTRING(_imp_str_literal("\nWRONG ANSWERS\n"));

  //    24+ WRONG ANSWERS
  //    25+ ")
  //    26  %ENDOFPROGRAM

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