#include <perms.h>

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

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

  //     2  %RECORDFORMAT F(%BYTE B1,B2,B3,B4)

  struct F {
    union {
      struct {
        unsigned char B1;
        unsigned char B2;
        unsigned char B3;
        unsigned char B4;
      };
    };
  };

  //     3  %RECORD(F)%ARRAY TRIPLES (0:9)

  struct F TRIPLES[10];
  struct _imp_dv TRIPLES_dv = {TRIPLES, sizeof(struct F) /*, dims, <bounds> */};

  //     4  %INTEGER I,J,K

  int I;
  int J;
  int K;

  //     5  %ROUTINE CHECK(%RECORD(F)%ARRAYNAME T)

  void CHECK(struct F * T) {
    auto void CHECKB2(int N);

    //     6  %ROUTINESPEC CHECKB2(%INTEGER N)
    //     7  %INTEGER Z

    int Z;

    //     8        %FOR Z=1,1,9 %CYCLE

    // %for Z = 1, 1, 9 %cycle
    {
      Z = 0;
    L_0001:
      if (Z == 9) goto L_0002;
      Z += 1;

      //     9           CHECKB2(Z)

      CHECKB2(Z);

      //    10        %REPEAT

      goto L_0001;
    }

  L_0002:;

  //    11  %ROUTINE CHECKB2(%INTEGER N)

    void CHECKB2(int N) {
      //    12  %INTEGER VAL

      int VAL;

      //    13        VAL=T(Z)_B2

      VAL = T[/*BUG*/ Z]->B2;

      //    14        %MONITOR %UNLESS N=VAL

      if (N == VAL) goto L_0004;
      /*_imp_monitor(__LINE__, __FILE__, PRETTY_FUNCTION);*/
    L_0004:;

    //    15  %END

      return;
    } /* end of CHECKB2 */

    //    16  %END

    return;
  } /* end of CHECK */

  //    17  %FOR I=0,1,9 %CYCLE

  // %for I = 0, 1, 9 %cycle
  {
    I = -1;
  L_0005:
    if (I == 9) goto L_0006;
    I += 1;

    //    18        TRIPLES(I)_B1=I+1

    TRIPLES[I].B1 = I + 1;

    //    19        TRIPLES(I)_B2=I

    TRIPLES[I].B2 = I;

    //    20  %REPEAT

    goto L_0005;
  }

L_0006:;

//    21        CHECK(TRIPLES)

  CHECK(TRIPLES);

  //    22        PRINTSTRING("TEST OK")

  _imp_PRINTSTRING(_imp_str_literal("TEST OK"));

  //    23  %ENDOFPROGRAM

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