#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  ! File of externals followed by a main program.
//     2
//     3  %recordformat rf ( %integer i, %real r, %integer rf)  ;! Are record format vars in a sub-scope?  Or is it just that formats are in a different name space?

struct RF {
  union {
    struct {
      int I;
      float R;
      int RF;
    };
  };
};

//     4
//     5  ! owns and externals are simpler declarations
//     6  %externalinteger xi1

int XI1;

//     7  %externalintegername xin1

int *XIN1;

//     8  %externalreal xr1

float XR1;

//     9  %externalinteger xi2,xi3

int XI2;
int XI3;

//    10  %externalreal xcr1 = 3.1415

float XCR1 = 3.1415;

//    11  %externalrealarray xra1(0:9)

float XRA1[10];

//    12  %externalrealarrayname xran1

float *XRAN1;

//    13  %externallongreal xclr1 = 3.1415

double XCLR1 = 3.1415;

//    14  %externallongrealarray xlra1(0:9)

double XLRA1[10];

//    15  %externallongrealarrayname xlran1

double *XLRAN1;

//    16  %externalintegernamearray xina1(0:9)

int *XINA1[10];

//    17  %externalintegernamearrayname xinan1

int **XINAN1;

//    18  %externalstring(82) xs1

_imp_string82 XS1;

//    19  %externalstring(82)%name xsn1

_imp_string82 *XSN1;

//    20  %externalstring(82)%array xsa1(4:7)

_imp_string82 XSA1[4];

//    21  %externalstring(82)%arrayname xsan1

_imp_string82 *XSAN1;

//    22  %externalstring(82)%namearray xsna1(4:7)

_imp_string82 *XSNA1[4];

//    23  %externalstring(82)%namearrayname xsnan1

_imp_string82 **XSNAN1;

//    24  %externalrecord (rf) xrec1

struct RF XREC1;

//    25  %externalrecord (rf) %name xrecn1

struct RF *XRECN1;

//    26  %externalrecord (rf) %array xreca1(2:3)

struct RF XRECA1[2];

//    27  %externalrecord (rf) %array %name xrecan1

struct RF *XRECAN1;

//    28  %externalrecord (rf) %name %array xrecna1(2:3)

struct RF *XRECNA1[2];

//    29  %externalrecord (rf) %name %array %name xrecnan1

struct RF **XRECNAN1;

//    30
//    31  %externalintegerfn ifn1

int IFN1(void) {
  //    32    %result = xi1

  return XI1;

  //    33  %end

} /* end of IFN1 */

//    34  %externalintegermap imap1

int *IMAP1(void)
{

  //    35    %result == xi1

  return /*?*/ &XI1;

  //    36  %end

} /* end of IMAP1 */

//    37  %externalroutine rt1

void RT1(void) {
  //    38    %integer i1

  int I1;

  //    39    %routine rt1

  void RT1(void) {
    //    40    %end

    return;
  } /* end of RT1 */

  //    41  %end

  return;
} /* end of RT1 */

// ?RT1 unused
// ?I1 unused
//    42  %externalpredicate test1

int TEST1(void) {
  //    43    %true

  return 1 /*TRUE*/;

  //    44  %end

} /* end of TEST1 */

//    45
//    46  %begin

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

  //    47    %integermapspec imap1
  //    48    %integer i1

  int I1;

  //    49    %integername in1

  int *IN1;

  //    50    %shortinteger si1

  short int SI1;

  //    51    %shortintegername sin1

  short int *SIN1;

  //    52    %byteinteger bi1

  unsigned char BI1;

  //    53    %byteintegername bin1

  unsigned char *BIN1;

  //    54    %real r1

  float R1;

  //    55    %realslong
  //    56    %real qr1

  double QR1;

  //    57    %realsnormal
  //    58    %constreal cr1 = 3.1415

  const float CR1 = 3.1415;

  //    59    %longreal lr1

  double LR1;

  //    60    %constlongreal clr1 = 3.1415

  const double CLR1 = 3.1415;

  //    61    %integerfn ifn1

  int IFN1(void) {
    //    62      %result = i1

    return I1;

    //    63    %end

  } /* end of IFN1 */

  //    64    %integermap imap1

  int *IMAP1(void)
  {

    //    65      %result == i1

    return /*?*/ &I1;

    //    66    %end

  } /* end of IMAP1 */

  //    67    %routine rt1

  void RT1(void) {
    //    68      %integer i1

    int I1;

    //    69      %integer local1

    int LOCAL1;

    //    70      %routine rt1

    void RT1(void) {
      //    71        %integer local1

      int LOCAL1;

      //    72        local1 = 1

      LOCAL1 = 1;

      //    73        i1 = 1

      I1 = 1;

      //    74      %end

      return;
    } /* end of RT1 */

    //    75      local1 = 2

    LOCAL1 = 2;

    //    76      i1 = 2

    I1 = 2;

    //    77    %end

    return;
  } /* end of RT1 */

  // ?RT1 unused
  //    78    %predicate test1

  int TEST1(void) {
    //    79      %false

    return 0 /*FALSE*/;

    //    80    %end

  } /* end of TEST1 */

  //    81    %realarray ra1, ra1b(0:9), ra2, ra2b(10:19)

  float RA1[10];
  float RA1B[10];
  float RA2[10];
  float RA2B[10];

  //    82    %realarrayname ran1, ran2

  float *RAN1;
  float *RAN2;

  //    83    %longrealarray lra1, lra1b(0:9), lra2, lra2b(10:19)

  double LRA1[10];
  double LRA1B[10];
  double LRA2[10];
  double LRA2B[10];

  //    84    %longrealarrayname lran1, lran2

  double *LRAN1;
  double *LRAN2;

  //    85    %integernamearray ina1, ina1b(0:9), ina2, ina2b(10:19)

  int *INA1[10];
  int *INA1B[10];
  int *INA2[10];
  int *INA2B[10];

  //    86    %integernamearrayname inan1, inan2

  int **INAN1;
  int **INAN2;

  //    87    %string(82) s1, s2

  _imp_string82 S1;
  _imp_string82 S2;

  //    88    %string(82)%name sn1, sn2

  _imp_string82 *SN1;
  _imp_string82 *SN2;

  //    89    %string(82)%array sa1, sa1b(4:7), sa2, sa2b(9:10), sa3(1:100)

  _imp_string82 SA1[4];
  _imp_string82 SA1B[4];
  _imp_string82 SA2[2];
  _imp_string82 SA2B[2];
  _imp_string82 SA3[100];

  //    90    %string(82)%arrayname san1, san2, san3

  _imp_string82 *SAN1;
  _imp_string82 *SAN2;
  _imp_string82 *SAN3;

  //    91    %string(82)%namearray sna1, sna2(4:7), sna3(1:2)

  _imp_string82 *SNA1[4];
  _imp_string82 *SNA2[4];
  _imp_string82 *SNA3[2];

  //    92    %string(82)%namearrayname snan1, snan2

  _imp_string82 **SNAN1;
  _imp_string82 **SNAN2;

  //    93    %record (rf) rec1, rec2

  struct RF REC1;
  struct RF REC2;

  //    94    %record (rf) %name recn1, recn2

  struct RF *RECN1;
  struct RF *RECN2;

  //    95    %record (rf) %array reca1,reca2(2:3),reca3(4:5)

  struct RF RECA1[2];
  struct RF RECA2[2];
  struct RF RECA3[2];

  //    96    %record (rf) %array %name recan1,recan2

  struct RF *RECAN1;
  struct RF *RECAN2;

  //    97    %record (rf) %name %array recna1,recna2(2:3),recna3(1:2)

  struct RF *RECNA1[2];
  struct RF *RECNA2[2];
  struct RF *RECNA3[2];

  //    98    %record (rf) %name %array %name recnan1,recnan2

  struct RF **RECNAN1;
  struct RF **RECNAN2;

  //    99
  //   100    ! owns and externals are simpler declarations
  //   101    %owninteger oi1

  static int OI1;

  //   102    %ownintegername oin1

  static int *OIN1;

  //   103    %ownreal or1

  static float OR1;

  //   104    %ownlongreal olr1

  static double OLR1;

  //   105    %owninteger oi2,oi3

  static int OI2;
  static int OI3;

  //   106    %ownreal ocr1 = 3.1415

  static float OCR1 = 3.1415;

  //   107    %ownlongreal oclr1 = 3.1415

  static double OCLR1 = 3.1415;

  //   108    %ownrealarray ora1(0:9)

  static float ORA1[10];

  //   109    %ownrealarrayname oran1

  static float *ORAN1;

  //   110    %ownlongrealarray olra1(0:9)

  static double OLRA1[10];

  //   111    %ownlongrealarrayname olran1

  static double *OLRAN1;

  //   112    %ownintegernamearray oina1(0:9)

  static int *OINA1[10];

  //   113    %ownintegernamearrayname oinan1

  static int **OINAN1;

  //   114    %ownstring(82) os1

  static _imp_string82 OS1;

  //   115    %ownstring(82)%name osn1

  static _imp_string82 *OSN1;

  //   116    %ownstring(82)%array osa1(4:7)

  static _imp_string82 OSA1[4];

  //   117    %ownstring(82)%arrayname osan1

  static _imp_string82 *OSAN1;

  //   118    %ownstring(82)%namearray osna1(4:7)

  static _imp_string82 *OSNA1[4];

  //   119    %ownstring(82)%namearrayname osnan1

  static _imp_string82 **OSNAN1;

  //   120    %ownrecord (rf) orec1

  static struct RF OREC1;

  //   121    %ownrecord (rf) %name orecn1

  static struct RF *ORECN1;

  //   122    %ownrecord (rf) %array oreca1(2:3)

  static struct RF ORECA1[2];

  //   123    %ownrecord (rf) %array %name orecan1

  static struct RF *ORECAN1;

  //   124    %ownrecord (rf) %name %array orecna1(2:3)

  static struct RF *ORECNA1[2];

  //   125    %ownrecord (rf) %name %array %name orecnan1

  static struct RF **ORECNAN1;

  //   126
  //   127    %switch sw1(0:255), sw2('a':'z')

  int SW1_index;
  int SW1_line;
  char *SW1_file;
  static const void *SW1[256] = {
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing, &&case_SW1_missing,
      &&case_SW1_missing};

  int SW2_index;
  int SW2_line;
  char *SW2_file;
  static const void *SW2[26] = {&&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing,
                                &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing,
                                &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing,
                                &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing,
                                &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing,
                                &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing, &&case_SW2_missing,
                                &&case_SW2_missing, &&case_SW2_missing};

  //   128
  //   129    %integer %array ia3, ia4(1:10), ia5(2:11,0:1,0:2)

  int IA3[10];
  int IA4[10];
  int IA5[10][2][3];

  //   130
  //   131    %integernamearray in3a1(2:11,0:1,0:2)

  int *IN3A1[10][2][3];

  //   132
  //   133    i1 = 1

  I1 = 1;

  //   134
  //   135    !!!!!!!!!!!!!!!!!!!
  //   136
  //   137    xi1 = 1

  XI1 = 1;

  //   138    xin1 == xi1

  XIN1 = (int *)/*?*/ &XI1;

  //   139    xin1 = 1

  *XIN1 = 1;

  //   140    xr1 = 3.1

  XR1 = 3.1;

  //   141    xi2 = xi3

  XI2 = XI3;

  //   142    xcr1 = 3.1415

  XCR1 = 3.1415;

  //   143    xra1(5) = xcr1

  XRA1[5] = XCR1;

  //   144    xran1 == xra1

  XRAN1 = (float *)XRA1;

  //   145    xclr1 = 3.1415

  XCLR1 = 3.1415;

  //   146    xlra1(2) = 3.1

  XLRA1[2] = 3.1;

  //   147    xlran1 == xlra1

  XLRAN1 = (double *)XLRA1;

  //   148    xlran1(2) = 3.2

  [/*BUG*/ 0] = 3.2;

  //   149    xina1(9) == xi1

  XINA1[9] = (int *)/*?*/ &XI1;

  //   150    xinan1 == xina1

  XINAN1 = (int *)XINA1;

  //   151
  //   152  %endofprogram

  _imp_stop(0);
  return 0;

case_SW1_dispatch:
  if (SW1_index < 0 || SW1_index > 255)
    _imp_signalf(6, 3, SW1_index, "->SW1(%d) out of bounds at %s line %d", SW1_index, SW1_file, SW1_line);
  goto *SW1[SW1_index - 0];

case_SW1_missing:
  _imp_signalf(8, 2, SW1_index, "switch jump to undefined label SW1(%d): at %s line %d", SW1_index, SW1_file, SW1_line);

case_SW2_dispatch:
  if (SW2_index < 97 || SW2_index > 122)
    _imp_signalf(6, 3, SW2_index, "->SW2(%d) out of bounds at %s line %d", SW2_index, SW2_file, SW2_line);
  goto *SW2[SW2_index - 97];

case_SW2_missing:
  _imp_signalf(8, 2, SW2_index, "switch jump to undefined label SW2(%d): at %s line %d", SW2_index, SW2_file, SW2_line);
end_0:;
}