#include <perms.h>

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

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

  //     2
  //     3    ! the example in https://www.ancientgeek.org.uk/EMAS/EMAS_Papers/The_IMP_language_and_compiler.pdf
  //     4    %integer i, j, k, n

  int I;
  int J;
  int K;
  int N;

  //     5
  //     6    n = 42 ; ! a little initialisation has been added which was not explicit in the paper to avoid runtime errors.

  N = 42;

  //     7
  //     8    %integer %array a(0:100), b(0:n)

  int A[101];
  int B[N + 1];

  //     9
  //    10    a(n) = n %for n = 0, 1, 100

  // %for N = 0, 1, 100 %cycle
  {
    N = -1;
  L_0001:
    if (N == 100) goto L_0002;
    N += 1;
    A[N] = N;
    goto L_0001;
  }

L_0002:;

//    11    b(n) = n %for n = 0, 1, 42

// %for N = 0, 1, 42 %cycle
  {
    N = -1;
  L_0004:
    if (N == 42) goto L_0005;
    N += 1;
    B[N] = N;
    goto L_0004;
  }

L_0005:;

//    12    write(n,3); newline

  _imp_WRITE(N, 3);
  _imp_NEWLINE();

  //    13
  //    14    n = 42

  N = 42;

  //    15
  //    16    j = 0; k = 0;

  J = 0;
  K = 0;

  //    17
  //    18    %cycle i = 1, 1, n

  // %for I = 1, 1, N %cycle
  {
    int _final = N;
    if (invalid_for_loop(1, 1, _final)) _imp_signal(5, 1, 0, "Illegal cycle I = 1, 1, N");
    I = 0;
  L_0006:
    if (I == _final) goto L_0007;
    I += 1;

    //    19      j = j + a(i)

    J = J + A[I];

    //    20      k = k + b(i+1)        ;! should cause a runtime error since i+1 == n+1 and array b is 0:n ...

    K = K + B[I + 1];

    //    21    %repeat

    goto L_0006;
  }

L_0007:;

//    22
//    23    write(j, 5); write(k, 5); newline

  _imp_WRITE(J, 5);
  _imp_WRITE(K, 5);
  _imp_NEWLINE();

  //    24
  //    25  %endofprogram

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