// cc -o imp9-check imp9-check.c -g -O0 -Wno-discarded-qualifiers -I ~/src/compilers101/new-parser/imps ~/src/compilers101/new-parser/imps/perms.c imp9chk.c -lm
#include <perms.h>


// We have a problem with the overloading of ints containing either data or
// an address. This code assumes addresses are always positive.
// Look for '-Dpos' ...

// We *might* get away with the same trick we used in ECCE years ago -
// have a huge byte array for data and use indexes into the array in
// place of ADDR()

// I've fixed it temporarily by moving any arrays that would have been stored
// at a negative address to static space which is in the positive address range
// - at least on my linux machine.  Not very portable unfortunately.

#undef Addr
#define Addr(x) debug_Addr(&x, #x, __LINE__)
int debug_Addr(void *p, char *name, int Line) {
  if ((int)p <= 0) fprintf(stderr, "Addr(%s) at %p (%d) at line %d\n", name, p, (int)p, Line);
  return (int)p;
}


#undef Byteinteger
#define Byteinteger(x) debug_Byteinteger(x, #x, __LINE__)
unsigned char *debug_Byteinteger(int p, char *name, int Line) {
  if (p <= 0) fprintf(stderr, "Byteinteger(%s) at %08x at line %d\n", name, p, Line);
  return (unsigned char *)p;
}


#undef Shortinteger
#define Shortinteger(x) debug_Shortinteger(x, #x, __LINE__)
short *debug_Shortinteger(int p, char *name, int Line) {
  if (p <= 0) fprintf(stderr, "Shortinteger(%s) at %08x at line %d\n", name, p, Line);
  return (short *)p;
}


#undef Integer
#define Integer(x) debug_Integer(x, #x, __LINE__)
int *debug_Integer(int p, char *name, int Line) {
  if (p <= 0) fprintf(stderr, "Integer(%s) at %08x at line %d\n", name, p, Line);
  return (int *)p;
}

// Avoiding *String() ...
int imp_string_compare(int leftp, int rightp) {
  int i, leftLen, rightLen, len;
  leftLen = *Byteinteger(leftp); rightLen = *Byteinteger(rightp);

#ifdef NEVER
  fprintf(stderr, "Left: %d ", leftp);
  for (i = 1; i <= leftLen; i++) {
    fputc(*Byteinteger(leftp+i), stderr);
  }
  fprintf(stderr, "  Right: %d ", rightp);
  for (i = 1; i <= rightLen; i++) {
    fputc(*Byteinteger(rightp+i), stderr);
  }
  fputc('\n', stderr);
#endif

  len = (leftLen < rightLen ? leftLen : rightLen);
  for (i = 1; i <= len; i++) {
    if (*Byteinteger(leftp+i) != *Byteinteger(rightp+i)) {
      return *Byteinteger(leftp+i) - *Byteinteger(rightp+i);
    }
  }
  if (leftLen == rightLen) return 0;
  return leftLen-rightLen; // these may all be wrong signs but we really just care about ==0 ...
}



void Checkinner(int Fstart, int Fsize, int *Parm) {
  //double Cputime(void);
  double Time1;
  double Time2;
  const int Stringbit = 0x80;
  const int Realbits = 0x30;
  const int Intbit = 0x40;
  const int Numbits = 0x70;
  const int Appmask = 0xFF00;
  const int Exp = 1;
  const int Fn = 2;
  const int Recformat = 4;
  const int Routine = 6;
  const int Ref = 8;
  const int Var = 9;
  const int Map = 10;
  const int Lab = 12;
  const int Jumplab = 13;
  const int Switch = 0x10C;
  const int Imp1modes = 0b01000011111111000000000000000000;
  const int Impmodes  = 0b01000011111100000000000000000000;
  const int Destmodes = 0b00000000111100000000000000000000;
  const int Adrmodes  = 0b01000000111100000000000000000000;
  const int Expmodes  = 0b11110000111100000000000000000000;
  const int Fmatmodes = 0b00001000000000000000000000000000;
  const int Nlcode = 127;
  const int Ident = 1;
  const int Const = 2;
  const int Lb = 11;
  const int Comma = 10;
  const int Rb = 12;
  const int Terminator = 13;
  const int Jump = 15;
  const int Op3 = 6;
  const int Start = 53;
  const int Cycle = 54;
  const int Marker = 124;
  static int Stats = 0;
  static int Atoms = -54;
  static int Identifiers = -54;
  static int Numbers = 0;
  static int Loops = 0;
  static int Looks = 1;
  static int Times = 1;
  int I;
  int J;
  int Linebase;
  int Fpos;
  int Fpos1;
  int Printpos;
  int Line;
  int Nextline;
  int Fmax;
  int Faultnum;
  int Faultpos;
  int Symcode;
  int Skipmin;
  int Class;
  int G;
  int Atom;
  int Atomtype;
  int Atomval;
  int Decltype;
  int Modes;
  int Dimcount;
  int Constcount;
  int Stringsize;
  int Precision;
  int Lasttype;
  int Lastval;
  int Type;
  int Val;
  int Np;
  int Ntype[51 /*0:50*/];
  int Nval[51 /*0:50*/];
  int Linkmax;
  int Link[21 /*0:20*/];
  typedef struct Blockinf {
    int Stack;
    int Local;
    int Btype;
  } Blockinf;
  int Level;
  Blockinf C;
  Blockinf Hold[13 /*0:12*/];
  ;
  static int Index[256 /*0:255*/];
  int *Head;
  int Dpos;
  int Dlim;
  int Newdlim;
  int Dbound;
  int Idents;
  int Recidents;
  int Pidentpos;
  int Fidentpos;
  int Extind;
  int Condind;
  int Parmax;
  int Adgram0;
  int Link1;
  int Appcont;
  static int Partype[256 /*0:255*/] = {
      0,          0x00000069,       0x01000069, 0x02000069, 0x03000069,
      0x04000069, 0x05000069,       0x00000029, 0x01000029, 0x00000089,
      0x00000088, 0x000000F8,       0x02000029, 0x07000029, 0x01000088,
      0x02000088, [16 ... 251] = 0, 0xFD000069, 0xFE0001F8, 0x00000000,
      0xFF000069};
  static int Dict[4001 /*0:4000*/];
  const int Punctmin = 43;
  const int Skip1min = 86;
  const unsigned char Syminit[256 /*0:255*/] = {
      129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 255, 129, 129, 129, 129,
      129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
      129, 129, 0,   217, 127, 171, 129, 128, 173, 127, 175, 178, 214, 180, 182,
      184, 187, 189, 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  192, 221,
      194, 200, 203, 129, 129, 65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
      75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
      90,  129, 207, 129, 210, 212, 129, 65,  66,  67,  68,  69,  70,  71,  72,
      73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
      88,  89,  90,  129, 207, 129, 210, 212, 129, 129, 129, 129, 129, 129, 129,
      129, 129, 129, 255, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
      129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 0,   217, 127, 171, 129,
      128, 173, 127, 175, 178, 214, 180, 182, 184, 187, 189, 48,  49,  50,  51,
      52,  53,  54,  55,  56,  57,  192, 221, 194, 200, 203, 129, 129, 130, 132,
      134, 138, 139, 142, 129, 129, 146, 129, 129, 148, 150, 152, 154, 157, 158,
      159, 161, 167, 169, 129, 170, 129, 129, 129, 129, 207, 129, 210, 212, 129,
      130, 132, 134, 138, 139, 142, 129, 129, 146, 129, 129, 148, 150, 152, 154,
      157, 158, 159, 161, 167, 169, 129, 170, 129, 129, 129, 129, 207, 129, 210,
      212};
  const short Keydict[488 /*0:487*/] = {
      0,      5,      -26642, 6194,   -26523, 6329,   -26385, -26247, 0,
      0,      6585,   -26132, -26066, 6776,   -25887, -25815, -25746, 7151,
      -25562, 7342,   -25367, 7471,   -25247, 7599,   -25119, 7727,   -24978,
      -24782, 8119,   8178,   8245,   -24475, 8687,   -24024, -23959, -23888,
      -23820, -23625, 9209,   -23512, 9330,   9390,   9512,   512,    240,
      320,    64,     -23231, 704,    0,      786,    0,      384,    113,
      640,    0,      -23074, 384,    114,    384,    128,    -22961, 320,
      48,     1600,   1,      -22835, -22692, -22563, -22434, 512,    240,
      -22307, 576,    240,    -22179, -22050, 512,    240,    -21923, 448,
      68,     448,    68,     192,    0,      -21814, 320,    112,    -21695,
      -21559, 384,    67,     832,    1,      11364,  11506,  11559,  11636,
      -21075, 11758,  11875,  11950,  12019,  12068,  -20503, 12340,  12469,
      12526,  2496,   11,     12594,  1664,   3,      12788,  12851,  12910,
      12976,  13102,  13165,  13236,  -19419, 3264,   1,      2816,   0,
      13422,  13545,  13601,  -19103, -19037, -18969, -18896, -18829, 14004,
      14069,  14127,  14183,  14245,  -18463, -18385, 14450,  14505,  14579,
      14629,  14709,  -18004, 14836,  14889,  3008,   0,      960,    0,
      320,    64,     576,    0,      256,    64,     512,    240,    256,
      64,     896,    0,      512,    240,    256,    64,     512,    240,
      256,    112,    384,    68,     3072,   0,      2752,   0,      14945,
      15017,  15077,  15149,  -17549, 15284,  15340,  15393,  15461,  -17169,
      3712,   0,      15668,  -16987, 15858,  15916,  15977,  -16723, 3136,
      0,      16101,  16180,  16295,  2496,   3,      16425,  16485,  2880,
      0,      16630,  2048,   0,      16686,  16740,  16812,  17007,  17065,
      17125,  17205,  17269,  17332,  17394,  17454,  17507,  17650,  17712,
      17833,  17908,  17972,  18030,  18163,  18213,  18281,  18348,  18425,
      18606,  18729,  18789,  18868,  18994,  19045,  19181,  3328,   1,
      19238,  1024,   2,      19442,  19497,  19572,  19699,  19745,  19815,
      1280,   0,      -12887, 19954,  20020,  2240,   1,      20069,  20148,
      20210,  -12493, 1984,   25,     20402,  20467,  20513,  20588,  20658,
      20713,  20788,  20897,  2624,   1,      20980,  1024,   0,      21102,
      21155,  21221,  3200,   0,      21300,  21363,  21420,  21541,  -11090,
      2112,   256,    3648,   0,      21742,  21806,  2048,   8,      21871,
      3456,   2,      21929,  -10778, -10708, 22128,  22190,  22254,  1472,
      0,      22312,  22452,  22565,  22638,  22693,  22767,  22830,  22900,
      22949,  -9748,  23086,  23140,  23284,  23348,  23476,  23598,  23726,
      -8983,  23858,  23916,  3392,   1,      24039,  24168,  24301,  24421,
      24499,  1728,   0,      1728,   0,      24609,  24692,  24756,  24876,
      24995,  25129,  25193,  25266,  25313,  25395,  3520,   1,      2368,
      0,      25458,  25588,  25633,  25714,  25908,  26021,  26081,  26159,
      26223,  2304,   9,      26277,  3584,   0,      1088,   0,      1024,
      1,      26341,  26478,  26543,  1152,   0,      2176,   137,    1920,
      268,    2688,   0,      26596,  1664,   3,      26669,  26725,  0,
      2,      1344,   0,      2688,   0,      26796,  26867,  26927,  26988,
      27113,  1984,   105,    27173,  27244,  -5389,  1152,   0,      3264,
      1,      27448,  27500,  27630,  27698,  27762,  2560,   6,      27892,
      27957,  28016,  28069,  28199,  28261,  28404,  28519,  2432,   0,
      28579,  28711,  1984,   41,     28788,  28852,  1984,   57,     28967,
      29101,  1856,   121,    29157,  29236,  29298,  2240,   -255,   29349,
      3776,   0,      1280,   0,      29426,  2048,   0,      29477,  29551,
      1216,   0,      1408,   32,     29601,  29671,  29737,  29807,  29874,
      29985,  30066,  30192,  30316,  30437,  30510,  30567,  1984,   73,
      30637,  1984,   121,    1024,   0,      1408,   0,      30770,  30885,
      31026,  3776,   1,      1984,   89,     1280,   0,      31073,  31149,
      1280,   0};
  const short Phrase[127 /*0:126*/] = {
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      0,   0,   0,   0,   257, 249, 368, 430, 264, 269, 286, 298, 335, 345, 0,
      452, 237, 374, 381, 0,   420, 437};
  const int Initbase = 472;
  static unsigned short Gram[532 /*0:531*/] = {
      66,    4084,  4511,  4898,  5028,  6440,  64,    7071,  7330,  5028,
      64,    11553, 1955,  11685, 11945, 12273, 12321, 2467,  6439,  5617,
      12429, 2996,  64,    5786,  5557,  5620,  2157,  12575, 12834, 6440,
      64,    12954, 12955, 6961,  64,    13089, 6439,  5489,  4589,  13345,
      1955,  12273, 7433,  12429, 64,    6005,  7602,  5557,  64,    7925,
      13569, 13737, 64,    12429, 5630,  13089, 5489,  7149,  8257,  5557,
      14068, 3250,  5558,  64,    8442,  8538,  4746,  12429, 64,    9042,
      9200,  8963,  14217, 14350, 14479, 14617, 9927,  12429, 14763, 66,
      14970, 15098, 15489, 64,    15729, 16129, 64,    8062,  16378, 5576,
      12274, 16769, 64,    16897, 64,    5614,  5618,  69,    6439,  64,
      12653, 5621,  17281, 64,    17409, 64,    17612, 13569, 64,    3124,
      64,    18154, 18287, 9976,  9956,  116,   5599,  15199, 10378, 18319,
      64,    18636, 15859, 10762, 12429, 64,    18897, 16479, 11274, 5557,
      64,    19021, 17105, 17155, 12239, 19276, 19788, 17736, 19851, 19981,
      64,    20218, 9964,  20225, 64,    20363, 64,    17616, 20619, 64,
      19443, 22409, 12429, 64,    12275, 22905, 89,    9963,  23126, 23554,
      64,    20806, 21279, 22306, 21796, 64,    23809, 24609, 24867, 64,
      25089, 25889, 24867, 64,    21357, 22593, 26125, 26362, 26881, 64,
      23242, 10378, 12429, 64,    5516,  64,    24014, 24330, 5516,  64,
      23809, 20806, 27649, 64,    23809, 64,    25294, 28682, 25582, 20618,
      5516,  64,    28929, 64,    22724, 26458, 22538, 29067, 29197, 64,
      27084, 27402, 17804, 22905, 26881, 22905, 27854, 24586, 28147, 28426,
      5516,  64,    27649, 20806, 25089, 64,    29390, 29562, 91,    25459,
      29663, 29836, 64,    30046, 22538, 29197, 64,    30534, 31135, 31522,
      31652, 40,    31691, 35,    39,    66,    31213, 35,    64,    32139,
      64,    32385, 64,    32597, 32780, 64,    88,    33163, 66,    33402,
      33503, 33676, 64,    98,    34049, 64,    34252, 33802, 66,    34597,
      34801, 34955, 64,    35194, 35296, 35481, 64,    35677, 35834, 35936,
      34954, 36236, 64,    36444, 34570, 66,    36875, 64,    37114, 37215,
      37401, 64,    37608, 37754, 37855, 38028, 64,    99,    39937, 40847,
      41104, 39569, 39058, 41363, 64,    41602, 12429, 14763, 66,    41737,
      41870, 64,    40147, 40304, 40067, 14217, 14350, 14479, 9927,  41985,
      64,    12429, 66,    42114, 64,    41184, 42346, 42479, 42582, 9953,
      42746, 41196, 42864, 41195, 41162, 43126, 43520, 43691, 43820, 66,
      67,    44022, 43382, 43691, 66,    44939, 44538, 45448, 45577, 45711,
      67,    45173, 45824, 12,    64,    46202, 45544, 120,   46604, 64,
      46313, 46728, 46857, 66,    44539, 47098, 46824, 105,   47361, 64,
      47569, 47728, 47491, 66,    49281, 48770, 50182, 50311, 50443, 50607,
      64,    50308, 50693, 51078, 66,    49492, 49648, 49411, 50308, 50693,
      51078, 66,    51302, 51453, 51578, 51834, 50941, 51972, 49001, 52200,
      52733, 48873, 48780, 64,    48816, 64,    52861, 52349, 52868, 52997,
      49129, 52327, 50921, 53501, 53245, 53508, 52457, 52329, 53757, 53225,
      54401, 2,     54539, 54703, 64,    47572, 45306, 54906, 48,    64,
      55307, 66,    55546, 55615, 55306, 12,    64,    56175, 56288, 56457,
      64,    56641, 56826, 56928, 57098, 64,    57338, 57440, 57610, 64,
      57850, 96,    58057, 58251, 58479, 58618, 58721, 58977, 59142, 64,
      59276, 64,    59621, 59782, 64,    58251, 64,    60005, 60143, 60257,
      59142, 66,    0,     8833,  0,     0,     0,     0,     0,     0,
      0,     0,     0,     0,     0,     0,     0,     40847, 41104, 39569,
      39058, 41363, 5524,  10261, 5526,  10391, 0,     0,     5786,  6299,
      0,     10525, 10782, 2079,  928,   0,     3362,  0,     1444,  0,
      294,   0,     6440,  10921, 3498,  0,     0,     0,     0,     0,
      0,     11185, 0,     11315, 0,     0,     6838,  2615,  5560,  11449,
      5562,  59};
  static unsigned char Perm[519 /*0:518*/] = {
      0,
      'A',  'D',  'D',  'R',  ':',  0x0B, 0x62,
      'A',  'R',  'C',  'C',  'O',  'S',  ':',  0x07, 0x22,
      'A',  'R',  'C',  'S',  'I',  'N',  ':',  0x07, 0x22,
      'A',  'R',  'R',  'A',  'Y',  ':',  0xFC, 0xF8,
      'A',  'R',  'C',  'T',  'A',  'N',  ':',  0x0D, 0x22,
      'B',  'Y',  'T',  'E',  'I',  'N',  'T',  'E',  'G',  'E',  'R',  ':',  0x01, 0x4A,
      'C',  'H',  'A',  'R',  'N',  'O',  ':',  0x0E, 0x4A,
      'C',  'L',  'O',  'S',  'E',  'S',  'T',  'R',  'E',  'A',  'M',  ':',  0x01, 0x06,
      'C',  'O',  'S',  ':',  0x07, 0x22,
      'E',  'X',  'P',  ':',  0x07, 0x22,
      'F',  'R',  'A',  'C',  'P',  'T',  ':',  0x07, 0x22,
      'F',  'R',  'O',  'M',  'S',  'T',  'R',  'I',  'N',  'G',  ':',  0x0F, 0x82,
      'I',  'M',  'O',  'D',  ':',  0x01, 0x62,
      'I',  'N',  'T',  ':',  0x07, 0x62,
      'I',  'N',  'T',  'P',  'T',  ':',  0x07, 0x62,
      'I',  'N',  'T',  'E',  'G',  'E',  'R',  ':',  0x01, 0x6A,
      'L',  'E',  'N',  'G',  'T',  'H',  ':',  0x0A, 0x4A,
      'L',  'O',  'G',  ':',  0x07, 0x22,
      'L',  'O',  'N',  'G',  'R',  'E',  'A',  'L',  ':',  0x01, 0x1A,
      'M',  'O',  'D',  ':',  0x07, 0x22,
      'N',  'E',  'W',  'L',  'I',  'N',  'E',  ':',  0x00, 0x06,
      'N',  'E',  'W',  'L',  'I',  'N',  'E',  'S',  ':',  0x01, 0x06,
      'N',  'E',  'W',  'P',  'A',  'G',  'E',  ':',  0x00, 0x06,
      'N',  'E',  'X',  'T',  'I',  'T',  'E',  'M',  ':',  0x00, 0x82,
      'N',  'E',  'X',  'T',  'C',  'H',  ':',  0x00, 0x62,
      'N',  'E',  'X',  'T',  'S',  'Y',  'M',  'B',  'O',  'L',  ':',  0x00, 0x62,
      'N',  'L',  ':',  0x00, 0x62,
      'P',  'I',  ':',  0x00, 0x22,
      'P',  'R',  'I',  'N',  'T',  ':',  0x0C, 0x06,
      'P',  'R',  'I',  'N',  'T',  'C',  'H',  ':',  0x01, 0x06,
      'P',  'R',  'I',  'N',  'T',  'F',  'L',  ':',  0x08, 0x06,
      'P',  'R',  'I',  'N',  'T',  'S',  'T',  'R',  'I',  'N',  'G',  ':',  0x09, 0x06,
      'P',  'R',  'I',  'N',  'T',  'S',  'Y',  'M',  'B',  'O',  'L',  ':',  0x01, 0x06,
      'R',  'A',  'D',  'I',  'U',  'S',  ':',  0x0D, 0x22,
      'R',  'E',  'A',  'D',  ':',  0x0B, 0x06,
      'R',  'E',  'A',  'D',  'C',  'H',  ':',  0x0B, 0x06,
      'R',  'E',  'A',  'D',  'I',  'T',  'E',  'M',  ':',  0x0A, 0x06,
      'R',  'E',  'A',  'D',  'S',
      'T',  'R',  'I',  'N',  'G',  ':',  0x0A, 0x06,
      'R',  'E',  'A',  'D',  'S',  'Y',  'M',  'B',  'O',  'L',  ':',  0x0B, 0x06,
      'R',  'E',  'A',  'L',  ':',  0x01, 0x1A,
      'R',  'E',  'C',  'O',  'R',  'D',  ':',  0x01, 0x0A,
      'S',  'E',  'L',  'E',  'C',  'T',  'I',  'N',  'P',  'U',  'T',  ':',  0x01, 0x06,
      'S',  'E',  'L',  'E',  'C',  'T',  'O',  'U',  'T',  'P',  'U',  'T',  ':',  0x01, 0x06,
      'S',  'E',  'T',  'M',  'A',  'R',  'G',  'I',  'N',  'S',  ':',  0x03, 0x06,
      'S',  'H',  'O',  'R',  'T',
      'I',  'N',  'T',  'E',  'G',  'E',  'R',  ':',  0x01, 0x5A,
      'S',  'I',  'N',  ':',  0x07, 0x22,
      'S',  'K',  'I',  'P',  'S',  'Y',  'M',  'B',  'O',  'L',  ':',  0x00, 0x06,
      'S',  'P',  'A',  'C',  'E',  ':',  0x00, 0x06,
      'S',  'P',  'A',  'C',  'E',  'S',  ':',  0x01, 0x06,
      'S',  'Q',  'R',  'T',  ':',  0x07, 0x22,
      'S',  'T',  'R',  'I',  'N',  'G',  ':',  0x01, 0x8A,
      'T',  'A',  'N',  ':',  0x07, 0x22,
      'T',  'O',  'S',  'T',  'R',  'I',  'N',  'G',  ':',  0x01, 0x82,
      'W',  'R',  'I',  'T',  'E',  ':',  0x02, 0x06};
  auto void Printss(void);
  auto void Report(int N);
  auto void Codeatom(void);
  auto void Popcontext(void);
  auto void Define(int Disp, int Val);
  void Fault(int N) {
    if (Faultnum < 0) {
      Faultnum = N;
      Faultpos = Fpos1;
    }
  }
  static int A_sw;
  static void *A[128 /*0:127*/] = {
      &&A_0,       &&A_1,       &&A_2,       &&A_3,       &&A_4,       &&A_5,
      &&A_6,       &&A_7,       &&A_8,       &&A_9,       &&A_10,      &&A_11,
      &&A_12,      &&A_13,      &&A_14,      &&A_15,      &&A_16,      &&A_17,
      &&A_18,      &&A_19,      &&A_20,      &&A_21,      &&A_22,      &&A_23,
      &&A_default, &&A_25,      &&A_26,      &&A_27,      &&A_default, &&A_29,
      &&A_30,      &&A_31,      &&A_32,      &&A_33,      &&A_34,      &&A_35,
      &&A_36,      &&A_37,      &&A_38,      &&A_39,      &&A_40,      &&A_41,
      &&A_42,      &&A_43,      &&A_44,      &&A_45,      &&A_default, &&A_47,
      &&A_48,      &&A_default, &&A_50,      &&A_51,      &&A_52,      &&A_53,
      &&A_54,      &&A_55,      &&A_56,      &&A_57,      &&A_58,      &&A_59,
      &&A_60,      &&A_default, &&A_default, &&A_63,      &&A_64,      &&A_65,
      &&A_66,      &&A_67,      &&A_68,      &&A_69,      &&A_70,      &&A_71,
      &&A_72,      &&A_73,      &&A_74,      &&A_75,      &&A_76,      &&A_77,
      &&A_78,      &&A_79,      &&A_80,      &&A_81,      &&A_82,      &&A_83,
      &&A_84,      &&A_85,      &&A_86,      &&A_default, &&A_88,      &&A_89,
      &&A_90,      &&A_91,      &&A_92,      &&A_93,      &&A_94,      &&A_95,
      &&A_96,      &&A_97,      &&A_98,      &&A_99,      &&A_100,     &&A_101,
      &&A_102,     &&A_103,     &&A_104,     &&A_105,     &&A_106,     &&A_107,
      &&A_108,     &&A_109,     &&A_110,     &&A_111,     &&A_112,     &&A_113,
      &&A_114,     &&A_115,     &&A_116,     &&A_117,     &&A_118,     &&A_119,
      &&A_120,     &&A_121,     &&A_122,     &&A_123,     &&A_124,     &&A_125,
      &&A_126,     &&A_default,
  };
  static int X_sw;
  static void *X[5 /*0:4*/] = {
      &&X_0, &&X_1, &&X_2, &&X_3, &&X_4,
  };
  Time1 = Cputime();
  for (I = 0; I <= 255; I++)
    Index[I] = 0;
  C = (Blockinf){0};
  Idents = 0;
  Printpos = 0;
  Precision = 0;
  Level = 0;
  Nextline = 1;
  Faultnum = -1;
  Parmax = 15;
  Adgram0 = Addr(Gram[0]);
  Link1 = (Gram[1] >> 6 & 1022) + Adgram0;
  Appcont = (Gram[Gram[Phrase[112]] >> 7 & 511] >> 6 & 1022) + Adgram0;
  Dlim = Addr(Dict[1]);
  Dbound = Addr(Dict[4000]);
  Fpos = Addr(Perm[1]) - 1;
  Fmax = Addr(Perm[518]);
  for (I = 1; I <= 54; I++) {
    Symcode = 0;
    Codeatom();
    if (Atom != Ident) {
      _imp_monitor(0);
      exit(0);
    }
    *Integer(Dlim) = (*Byteinteger(Fpos + 1) << 8) + *Byteinteger(Fpos + 2);
    Fpos += 2;
    *Integer(Dlim + 4) = 0;
    *Integer(Dlim + 8) = *Head;
    *Head = Dlim;
    Dlim = Newdlim;
  }
  C.Local = Dlim;
  Fpos = Fstart - 1;
  Fmax = Fpos + Fsize;
  Symcode = 0;
L1:
  if (Fpos >= Fmax)
    goto Ended;
  Linebase = Fpos;
  Line = Nextline;
L3:
  Atom = Jump;
  Skipmin = Skip1min;
  Codeatom();
  Skipmin = Nlcode;
  Stats++;
  Extind = 0;
  Decltype = 0;
  Constcount = 0;
  Dimcount = 0;
  Np = 51;
  Linkmax = 1;
  Link[1] = Link1;
  I = Gram[Initbase + Atom];
  if (!I)
    goto Err;
  G = (I >> 6 & 1022) + Adgram0;
  goto *A[A_sw = Atom];
A_1:;
A_6:;
A_9:;
A_13:;
A_25:;
  I = *Shortinteger(G);
  G = (I >> 6 & 1022) + Adgram0;
  goto *A[A_sw = I & 127];
A_10:
A_11:
A_12:
A_15:
A_18:
A_19:
A_20:;
A_21:
A_23:
A_27:
A_37:;
A_43:
A_44:
A_45:;
A_47:
A_48:
A_50:
A_57:
A_65:;
Code:;
  Codeatom();
On:;
Rep:
  for (;;) {
    Class = *Shortinteger(G) & 127;
    if (Class >= 60 || Class == Atom)
      break;
    G += 2;
  }
 G = (*Shortinteger(G) >> 6 & 1022) + Adgram0;
  goto *A[A_sw = Class];
A_109:
A_110:
A_111:
A_113:
A_114:;
A_115:
A_116:
A_117:
A_118:
A_119:;
A_120:
A_121:
A_122:
A_123:
A_124:;
A_125:
A_126:;
Enter:;
  Linkmax++;
  if (Linkmax > 20)
    goto Err;
  Link[Linkmax] = G;
  G = (Phrase[Class] << 1) + Adgram0;
  goto Rep;
A_66:;
Exit:;
  G = Link[Linkmax];
  Linkmax--;
  goto Rep;
A_67:;
  I = *Shortinteger(Link[Linkmax]);
  Linkmax--;
  if (I & 127)
    goto Err;
  G = (I >> 6 & 1022) + Adgram0;
  goto On;
A_68:;
  if (Faultnum >= 0)
    Report(Faultnum);
  if (!Atomtype) {
    Linebase = Fpos;
    Line = Nextline;
  }
  goto Code;
Unknown:;
  while (Dpos < 0) {
    //if (*String(-Dpos + 4) == *String(Dlim + 12))
    //if (_imp_strcmp(*(_imp_string *)(-Dpos + 4), *(_imp_string *)(Dlim + 12)) == 0)
    if (imp_string_compare(-Dpos + 4, Dlim + 12) == 0)
      goto Ignore;
    Dpos = *Integer(-Dpos);
  }
  Fault(2);
  for (;;) {
    Dbound -= 4;
    Newdlim -= 4;
    if (Newdlim == Dlim + 8)
      break;
    *Integer(Dbound) = *Integer(Newdlim);
  }
  while (*Head > 0)
    Head = Integer(*Head + 8);
  *Integer(Dbound) = *Head;
  *Head = -Dbound;
  goto Ignore;
Moderr:;
  Fault(3);
  goto Ignore;
A_0:
A_64:;
Err:
  Faultnum = 0;
  if (!Atom)
    Faultnum = Atomtype;
  if (Faultnum == 99)
    goto Disaster;
  Faultpos = Fpos1;
Ignore:;
  while (Atom != Terminator) {
    I = Atom;
    Codeatom();
  }
  if (I == Start)
    C.Stack = (C.Stack << 2) + 3;
  if (I == Cycle)
    C.Stack = (C.Stack << 2) + 2;
  if (Faultnum >= 0)
    Report(Faultnum);
  while (I == Comma && Atomtype == 0)
    do {
      I = Atom;
      Codeatom();
    } while (Atom != Terminator);
A_69:;
Fin:
  if (Faultnum >= 0)
    Report(Faultnum);
  if (C.Btype & 1) {
    Dlim = C.Local;
    C = Hold[Level];
    Level--;
  }
  if (Atomtype)
    goto L3;
  goto L1;
Disaster:;
  printf("** SPACE EXHAUSTED AT LINE ");
  Write(Nextline, 0);
  Newline();
  return;
A_74:;
Napp:;
  if (!(Type & Appmask))
    goto On;
  goto Err;
Er20:;
  Fault(20);
  goto Napp;
Er22:;
  Fault(22);
  goto Napp;
A_22:;
  Precision = Atomtype;
  goto Code;
A_38:;
A_42:;
  Extind = 1;
  goto Code;
A_70:;
  Decltype = 0;
  goto On;
A_36:;
  Recidents = Dlim;
A_29:;
A_30:;
A_31:;
A_32:;
A_33:;
A_34:;
A_35:;
A_39:;
A_40:;
A_41:;
  Decltype = Decltype ^ Atomtype;
  if ((Decltype & 0xF0) == 0x10)
    Decltype = Decltype | Precision;
  Idents = Dlim;
  Modes = ~0;
  goto Code;
A_75:;
  Decltype = 0xF9;
  goto On;
A_78:;
  Head = Integer(Fidentpos + 4);
  Dpos = *Head;
A_76:;
D1:
  if (C.Btype & 1)
    goto Add;
D2:
  for (;;) {
    if (Dpos < C.Local)
      goto New;
    // if (*String(Dpos + 12) == *String(Dlim + 12))
    //if (_imp_strcmp(*(_imp_string *)(Dpos + 12), *(_imp_string *)(Dlim + 12)) == 0)
    if (imp_string_compare(Dpos + 12, Dlim + 12) == 0)
      break;
    Dpos = *Integer(Dpos + 8);
  }
  if ((*Integer(Dpos) & 0xFF) - 1 == Decltype && (Decltype & 6) != 0 &&
      (Decltype & 1) == 0)
    goto D5;
  Fault(5);
New:
  *Integer(Dlim + 8) = *Head;
  *Head = Dlim;
Add:
  *Integer(Dlim) = Decltype;
  *Integer(Dlim + 4) = 0;
  Dlim = Newdlim;
  goto Code;
D5:
  if (Decltype == Lab)
    *Integer(Dpos) = Decltype;
  Idents = Dpos;
  goto Code;
A_77:;
  Decltype = Recformat;
  Fidentpos = Dlim;
  goto D1;
A_2:;
  Type = Atomtype;
  Val = Atomval;
  goto Code;
A_3:;
  if ((Type & 0xFFF4) != 0 && Type != Recformat)
    goto Err;
  Codeatom();
  if (Atom != Ident)
    goto Err;
  if (!Val)
    goto Ignore;
  Dpos = Val;
  Head = &Val;
A_81:;
Look:;
  Looks++;
  for (;;) {
    Times++;
    if (Dpos <= 0)
      goto Unknown;
    // if (*String(Dpos + 12) == *String(Dlim + 12))
    //if (_imp_strcmp(*(_imp_string *)(Dpos + 12), *(_imp_string *)(Dlim + 12)) == 0)
    if (imp_string_compare(Dpos + 12, Dlim + 12) == 0)
      break;
    Dpos = *Integer(Dpos + 8);
  }
  Type = *Integer(Dpos);
  Val = *Integer(Dpos + 4);
  if (Modes << (Type & 15) < 0)
    goto Code;
  goto Moderr;
A_82:;
  Modes = Imp1modes;
  if (*Byteinteger(Fpos) != ':')
    goto Look;
  Decltype = Lab;
  goto D2;
A_83:;
  Modes = Impmodes;
  goto Look;
A_84:;
  Modes = Expmodes;
  goto Look;
A_85:;
  Modes = Fmatmodes;
  goto Look;
A_86:;
  while (Dpos >= C.Local) {
    // if (*String(Dpos + 12) == *String(Dlim + 12))
    //if (_imp_strcmp(*(_imp_string *)(Dpos + 12), *(_imp_string *)(Dlim + 12)) == 0)
    if (imp_string_compare(Dpos + 12, Dlim + 12) == 0)
      goto Jl1;
    Dpos = *Integer(Dpos + 8);
  }
  *Integer(Dlim + 8) = *Head;
  *Head = Dlim;
  *Integer(Dlim) = Jumplab;
  *Integer(Dlim + 4) = 0;
  Dpos = Dlim;
  Dlim = Newdlim;
Jl1:
  Type = *Integer(Dpos);
  if ((Type & 14) == Lab)
    goto Code;
  goto Moderr;
A_79:;
  if ((Type & 0xF4) != 0 || Val != 0 || Dpos < C.Local)
    goto Moderr;
  Recidents = -Dpos;
  goto On;
A_88:;
  Idents = Recidents;
  if (Idents >= 0)
    Define(4, *Integer(Dpos + 4));
  else
    *Integer(-Idents + 4) = *Integer(Dpos + 4);
  goto On;
A_80:;
  if ((Type & 0xFF03) != Fn || Dpos < C.Local)
    goto Moderr;
  Idents = Dpos;
  goto On;
A_72:;
  Pidentpos = Idents;
  Level++;
  if (Level > 12)
    goto Disaster;
  Hold[Level] = C;
  C.Btype = Decltype;
  C.Stack = 0;
  C.Local = Dlim;
  goto On;
A_89:;
  Idents = C.Local;
  Np = 51;
  while (Idents != Dlim) {
    Np--;
    Ntype[Np] = *Integer(Idents);
    Idents = (*Byteinteger(Idents + 12) & (~3)) + Idents + 16;
  }
  I = 0;
  while (Np != 51) {
    J = (I << 24) + Ntype[Np];
    Np++;
    do
      I++;
    while (I <= Parmax && Partype[I] != J);
    if (I > Parmax) {
      if (I == 252)
        goto Disaster;
      Parmax = I;
      Partype[I] = J;
    }
  }
  if ((C.Btype & 1) == 0 && (*Integer(Pidentpos) & 1) != 0) {
    if (*Byteinteger(Pidentpos + 2) != I)
      Fault(18);
    *Integer(Pidentpos) = C.Btype;
  }
  *Byteinteger(Pidentpos + 2) = I;
  *Integer(Pidentpos) = *Integer(Pidentpos) & (~Extind);
  goto Fin;
A_90:;
  Constcount--;
  if (Type & 15)
    goto Er20;
  if (!(Type & Decltype))
    goto Er22;
  if (!(Decltype & 15))
    Define(4, Val);
  goto On;
A_91:;
  if (Constcount != 0 && Constcount < 1000000)
    Fault(21);
  goto Fin;
A_92:;
  Define(0, Dimcount);
  Dimcount = 0;
  goto On;
A_93:;
  if (Dimcount == 6)
    Fault(23);
  else
    Dimcount++;
  goto Code;
A_94:;
  Constcount = Constcount - Val + 1;
  goto On;
A_95:;
  if (Type & 15)
    goto Er20;
A_96:;
  if (!(Type & Intbit))
    goto Er22;
  goto Napp;
A_97:;
  if (!(Type & Stringbit))
    goto Er22;
  goto Napp;
A_98:;
  Stringsize = Val;
  if (0 < Val && Val <= 255)
    goto On;
  Fault(19);
  Stringsize = 255;
  goto On;
A_99:;
  Lastval = Nval[Np];
  Np++;
  if (-32768 > Lastval || Lastval > 32767)
    goto Cberr;
  Constcount = Val - Lastval + 1;
  if (0 >= Constcount || Constcount > 32767)
    goto Cberr;
  if (Decltype == Switch)
    do {
      J = Dbound;
      Dbound = J - ((Constcount + 63) >> 5 << 2);
      if (Dbound <= Dlim)
        goto Disaster;
      *Integer(Idents + 4) = Dbound;
      *Integer(Dbound) = (Lastval << 16) + Constcount;
      for (;;) {
        J -= 4;
        if (J == Dbound)
          break;
        *Integer(J) = 0;
      }
      Idents = (*Byteinteger(Idents + 12) & (~3)) + Idents + 16;
    } while (Idents != Dlim);
Cb1:
  Idents = Dlim;
  goto On;
Cberr:;
  Fault(23);
  Constcount = 2000000;
  goto Cb1;
A_100:;
  if (Decltype)
    goto Fin;
  if (Type != Jumplab)
    goto Err;
  if (Lasttype & 15) {
    Fault(20);
    goto Fin;
  }
  if (!Val)
    goto Fin;
  J = Lastval - *Shortinteger(Val);
  if (0 > J || J >= *Shortinteger(Val)) {
    Fault(19);
    goto Fin;
  }
  I = Val + (J >> 5 << 2);
  J = 0x80000000 >> (J & 31);
  if (*Integer(I + 4) & J)
    Fault(16);
  *Integer(I + 4) = *Integer(I + 4) | J;
  goto Fin;
A_101:;
  if (Atomtype != Stringbit)
    goto Err;
A_60:;
  Modes = Destmodes;
  goto Code;
A_73:;
  if (!(Type & Stringbit))
    goto Er22;
  Modes = Destmodes;
  goto On;
A_102:;
  if (!(Atomtype & 3))
    goto Err;
  Type = Atomtype;
  Val = 0;
  goto Op1;
A_7:;
  Type = Atomtype;
  Val = -1;
  goto Op1;
A_8:;
A_4:;
A_5:;
A_104:;
  if (Type & Appmask)
    goto Err;
  if ((Type & 0xFF4F) == Intbit)
    Type = Type | 15;
  else
    Type = Type & (~15);
  if (Type & Numbits)
    Type = Type | Realbits;
Op1:
  Np--;
  Ntype[Np] = Type & Atomtype;
  Nval[Np] = Val;
  goto Code;
A_105:;
  if (Type & Appmask)
    goto Err;
  if (Type & Numbits)
    Type = Type | Realbits;
  I = Ntype[Np];
  Np++;
  J = I & Type & 0xF0;
  if (!J)
    goto Er22;
  if ((Type & 0xFF4F) == Intbit)
    goto *X[X_sw = I & 15];
X_0:;
  Type = J + Exp;
  goto On;
X_1:
  Val += Nval[Np - 1];
X1:
  Type = Numbits;
  goto On;
X_2:
  Val -= Nval[Np - 1];
  goto X1;
X_3:
  Val = Nval[Np - 1] | Val;
  goto X1;
X_4:
  Val = Nval[Np - 1] ^ Val;
  goto X1;
A_103:;
  if (Ntype[Np] != 0x43)
    goto On;
  if (Atom != Op3 || Atomtype != 0x43)
    goto Err;
  Np++;
  Codeatom();
  goto Exit;
A_106:;
  if ((Type & 0xFF0C) != 8)
    goto Err;
Save:;
  Np--;
  Ntype[Np] = Type;
  Nval[Np] = Val;
  goto Code;
A_14:;
  Modes = Adrmodes;
  if ((Type & 15) == Ref)
    goto Save;
  goto Err;
A_107:;
  I = Ntype[Np];
  Np++;
As1:
  if (!(I & Type & 0xC0)) {
    I = I & 0xF0;
    if (!I) {
      if ((Type & 0xF0) != 0 && ((Type & 0xFF4F) != Intbit || Val != 0)) {
        goto Er22;
      } else if (I > 0x30 || (Type & Numbits) == 0) {
        goto Er22;
      }
    }
  }
  goto Napp;
A_108:;
  I = Ntype[Np];
  Np++;
Ra1:
  if (((I ^ Type) & 0xF0) != 0 && (I & 0xF0) != 0xF0 && (Type & 0xF0) != 0xF0)
    Fault(22);
  if (!(I & Appmask))
    goto Napp;
  if ((Type & Appmask) == 0 || (Type & 14) == Map)
    Fault(22);
  goto On;
A_17:;
  if ((C.Btype & 7) != Fn)
    Fault(25);
  Type = C.Btype & 0xF8;
  if (!(Type & 8))
    Type += Var;
  Val = 0;
  goto Code;
A_71:;
  if ((Type & 0xFFFC) == 4)
    goto On;
  goto Err;
A_112:;
  if (Atom != Lb)
    goto On;
  Linkmax++;
  if (Linkmax > 20)
    goto Err;
  Link[Linkmax] = G;
  Np--;
  Nval[Np] = Val;
Ap:
  if (!(Type & Appmask))
    goto Err;
  Ntype[Np] = Type;
  G = Appcont;
  Codeatom();
  J = Partype[Type >> 8] & 15;
  Class = 122;
  if (J == Var)
    goto Enter;
  Class = 111;
  Modes = Adrmodes;
  if (J == Ref)
    goto Enter;
  Modes = 0xC0000000 >> J;
  goto Enter;
A_63:;
  J = Ntype[Np];
  I = Partype[J >> 8];
  Lasttype = Type;
  Lastval = Val;
  Type = (I >> 16) + (J & 0xFF);
  if (Atom == Comma)
    goto Ap;
  if (Atom != Rb)
    goto Err;
  Val = Nval[Np];
  Np++;
  if (Type & Appmask) {
    Type = Type ^ Appmask;
    if (Type & 0xFE00)
      goto Err;
  }
  Type = (Type & 0xFFFC) | 1;
  Codeatom();
  goto Exit;
A_16:;
  if ((Atomtype == 1 && (C.Btype & 15) != Routine) ||
      (Atomtype == 2 && ((C.Stack ^ 0x55555555) << 1 & C.Stack) == 0))
    Fault(25);
  goto Code;
A_54:;
  Condind = 2;
A_53:;
  C.Stack = (C.Stack << 2) + Condind;
  goto Code;
A_55:;
A_56:;
  Condind = C.Stack & 3;
  if (Condind == 0 || ((Condind ^ Atomtype) & 1) != 0)
    Fault(12 + Atomtype);
  else
    C.Stack = C.Stack >> 2;
  goto Code;
A_52:;
  if (Condind == 1)
    Fault(25);
A_26:;
A_51:;
  Condind = Atomtype;
  goto Code;
A_58:;
  if (Level == 0 || (Level == 1 && C.Btype == 0))
    Fault(11);
  else
    Popcontext();
  goto Code;
A_59:;
  Fpos1 = Fpos;
  if (Level > Atomtype)
    Report(8);
  if (Level < Atomtype)
    Report(11);
  while (Level > 0)
    Popcontext();
  Time2 = Cputime();
  goto Endok;
Ended:;
  Time2 = Cputime();
  printf("** END OF FILE AT LINE ");
  Write(Nextline, 0);
  Newline();
Endok:;
  if (*Parm & 4) {
    Write(Line, 4);
    Printsymbol('L'); Space();
    Write(Stats, 4);
    Printsymbol('S'); Space();
    if (Stats == 0)
      Stats = 1;
    Print(Atoms / Stats, 2, 1);
    Printsymbol('A'); Space();
    Print(Numbers / Stats, 2, 1);
    Printsymbol('N'); Space();
    Print(Identifiers / Stats, 2, 1);
    Printsymbol('I'); Space();
    Print(Loops / Stats, 2, 1);
    Printsymbol('C'); Space();
    Print(Times / Looks, 2, 1);
    Printsymbol('H'); Space();
    Print((Time2 - Time1) * 1000 / Stats, 3, 3);
    Printsymbol('M');
    Newline();
  }
  if (*Parm & 8)
    for (I = 0; I <= 255; I++) {
      J = Index[I];
      if (J > 0) {
        Write(I, 3);
        Printsymbol(':');
        while (J > 0) {
          Space();
          {int I;
            for (I = 1; I <= *Byteinteger(J + 12); I++) {
              Printsymbol(*Byteinteger(J + 12 + I));
            }
            // Printstring(*String(J + 12));
          }
          J = *Integer(J + 8);
        }
        Newline();
      }
    }
  return;
  void Printss(void) {
    int K;
    void Write(int V, int P) {
      if (V >= 10) {
        Write(V / 10, P - 1);
        V -= 10 * (V / 10);
      } else
        Spaces(P - 1);
      Printsymbol(V + '0');
    }
    Write(Line, 4);
    Space();
    Printpos = Linebase;
    do {
      Printpos++;
      if (Printpos == Faultpos)
        Printsymbol(Marker);
      K = *Byteinteger(Printpos);
      if (K == Nl || (32 <= K && K <= 126))
        Printsymbol(K);
      else {
        Printsymbol('[');
        Write(K, 0);
        Printsymbol(']');
      }
    } while (Printpos != Fpos1);
    if (K != Nl)
      Newline();
  }
  void Report(int N) {
    static int S_sw;
    static void *S[26 /*0:25*/] = {
        &&S_0,       &&S_1,  &&S_2,  &&S_3,       &&S_4,  &&S_5,  &&S_default,
        &&S_default, &&S_8,  &&S_9,  &&S_10,      &&S_11, &&S_12, &&S_13,
        &&S_default, &&S_15, &&S_16, &&S_17,      &&S_18, &&S_19, &&S_20,
        &&S_21,      &&S_22, &&S_23, &&S_default, &&S_25,
    };
    if (N > 7)
      Faultpos = 0;
    if (Printpos != Fpos1)
      Printss();
    Printsymbol('*');
    goto *S[S_sw = N];
  S_0:
    printf("FORM?");
    goto F;
  S_1:
    printf("ATOM?");
    goto F;
  S_2:
    printf("NAME?");
    goto F;
  S_3:
    printf("MODE?");
    goto F;
  S_4:
    printf("SIZE?");
    goto F;
  S_11:
    printf("%%BEGIN");
    goto M;
  S_12:
    printf("%%CYCLE");
    goto M;
  S_13:
    printf("%%START");
    goto M;
  S_8:
    printf("%%END");
    goto M;
  S_9:
    printf("%%REPEAT");
    goto M;
  S_10:
    printf("%%FINISH");
    goto M;
  S_15:
    Printsymbol('\'');
    //Printstring(*(_imp_string *)(Dpos + 12));
    {int I;
      for (I = 1; I <= *Byteinteger(Dpos + 12); I++) {
        Printsymbol(*Byteinteger(Dpos + 12 + I));
      }
    }
    Printsymbol('\'');
  M:
    printf(" MISSING");
    goto F;
  S_23:
    printf("BOUNDS?");
    goto F;
  S_25:
    printf("CONTEXT?");
    goto F;
  S_5:;
  S_16:
    printf("DUPLICATE");
    goto F;
  S_17:
    printf("ORDER?");
    goto F;
  S_18:
    printf("MATCH?");
    goto F;
  S_19:
    printf("RANGE?");
    goto F;
  S_20:
    printf("LITERAL?");
    goto F;
  S_21:
    if (Constcount < 0) {
      Write(-Constcount, 1);
      printf(" EXTRA");
    } else {
      Write(Constcount, 1);
      printf(" MISSING");
    }
    printf(" VALUE(S)");
    goto F;
  S_22:
    printf("TYPE?");
    goto F;
  F:
    Newline();
    Faultnum = -1;
    *Parm = *Parm | 0x80000000;
    goto S_skip;
  S_default:
    fprintf(stderr, "Switch label 'S(%d):' not set in %s", S_sw,
            __PRETTY_FUNCTION__);
    exit(1) /* or %signal ... */;
  S_skip:;
  }
  void Codeatom(void) {
    register int Fp; // R5
    register int Sc; // R6
    int I;
    int J;
    int K;
    int L;
    int Hash;
    Atoms++;
    Fp = Fpos;
    Sc = Symcode;
    if (Sc)
      goto C2;
  C1:
    do {
      Fp++;
      Sc = *Byteinteger(Fp);
    } while (Sc == ' ');
    Sc = Syminit[Sc];
  C2:
    Fpos1 = Fp;
    if (Sc < 127)
      goto Namenum;
    Sc -= 128;
    if (Sc > 0)
      goto Keyword;
    if (Sc)
      goto Quotemark;
    Fp++;
    Sc = Syminit[*Byteinteger(Fp) | 128];
    if (Sc)
      goto C2;
    goto C1;
  Keyword:;
    if (Sc >= Skipmin)
      goto Nlq;
    I = Sc;
    L = 0;
    if (Sc < Punctmin)
      L = 128;
    for (;;) {
      for (;;) {
        Fp++;
        K = *Byteinteger(Fp);
        Sc = Syminit[K | L];
        if (Sc & 127)
          break;
        L = Sc;
      }
      if (Sc & 128)
        K -= 32;
      for (;;) {
        J = Keydict[I];
        if (J >= 0 || (J & 63) == K)
          break;
        I++;
      }
      if ((J & 63) != K)
        break;
      I = J >> 6 & 511;
    }
    if (J & 63)
      goto Err;
    Atomtype = Keydict[I + 1] & 0xFFFF;
    Atom = J >> 6;
    if (!Atom)
      goto Key5;
  Fin:
    Fpos = Fp;
    Symcode = Sc;
    return;
  Key5:;
    if (Atomtype) {
      if (Skipmin != Skip1min)
        goto Fin;
      goto Skp;
    }
    if (*Byteinteger(Fp) != Nl)
      goto Err;
    Nextline++;
    if (Fp >= Fmax)
      goto Term;
    goto C1;
  Nlq:;
    if (Skipmin != Skip1min)
      goto Term;
  Skp:;
    Fp--;
    do {
      Fp++;
      Sc = *Byteinteger(Fp);
    } while (Sc != Nl && Sc != ';');
    if (Sc == Nl) {
      if (Fp >= Fmax)
        goto Term;
      Linebase = Fp;
      Nextline++;
      Line = Nextline;
    }
    goto C1;
  Term:;
    Atom = Terminator;
    Atomtype = 0;
    Nextline++;
    Sc = 0;
    if (Fp >= Fmax)
      Sc = 255;
    goto Fin;
  Disaster:;
    Atomtype = 99;
    goto Er1;
  Stringerr:;
    Atomtype = 4;
    Nextline = L;
  Er1:
    Fp = Fpos1;
    Sc = 0;
    goto Er2;
  Err:
    Atomtype = 1;
  Er2:
    Atom = 0;
    goto Fin;
  Namenum:;
    if (Sc <= '9' && Atom != Jump)
      goto Number;
    if (*Byteinteger(Fp + 1) == '\'') {
      if (Sc == 'X')
        goto Hex;
      if (Sc == 'K')
        goto Oct;
      if (Sc == 'B')
        goto Bin;
      if (Sc == 'M')
        goto Multi;
    }
    J = Dlim;
    if (J + 84 >= Dbound)
      goto Disaster;
    Hash = 0;
    do {
      if (Sc) {
        J++;
        *Byteinteger(J + 12) = Sc;
        Hash = Hash << 1 ^ Sc;
      }
      Fp++;
      Sc = Syminit[*Byteinteger(Fp)];
    } while (Sc <= 'Z');
    *Byteinteger(Dlim + 12) = J - Dlim;
    Newdlim = (J & (~3)) + 16;
    Head = &Index[Hash & 255];
    Dpos = *Head;
    Atom = Ident;
    Identifiers++;
    goto Fin;
  Number:;
    Atomtype = Numbits;
    Atomval = Sc - '0';
    for (;;) {
      Fp++;
      Sc = Syminit[*Byteinteger(Fp)];
      if (Sc > '9')
        break;
      if (Sc != 0 && Atomval < 1000000)
        Atomval = (((Atomval << 2) + Atomval) << 1) + Sc - '0';
    }
    if (*Byteinteger(Fp) == '.') {
      do {
        Fp++;
        Sc = Syminit[*Byteinteger(Fp)];
      } while (Sc <= '9');
      Atomtype = Realbits;
    }
    if (*Byteinteger(Fp) == '@') {
      do {
        Fp++;
        Sc = *Byteinteger(Fp);
      } while (Sc == ' ');
      if (Sc == '-')
        do {
          Fp++;
          Sc = *Byteinteger(Fp);
        } while (Sc == ' ');
      Sc = Syminit[Sc];
      if (Sc > '9')
        goto Err;
      do {
        Fp++;
        Sc = Syminit[*Byteinteger(Fp)];
      } while (Sc <= '9');
      Atomtype = Realbits;
    }
  Nn:
    Atom = Const;
    Numbers++;
    goto Fin;
  Multi:;
    Fp++;
    Atomtype = Numbits;
    goto Q1;
  Quotemark:;
    Atomtype = Stringbit;
  Q1:
    K = *Byteinteger(Fp);
    J = -1;
    L = Nextline;
    Atomval = 0;
    for (;;) {
      Fp++;
      Sc = *Byteinteger(Fp);
      if (Sc == Nl) {
        Nextline++;
        if (Fp >= Fmax)
          goto Term;
      }
      if (Sc == K) {
        if (Sc != *Byteinteger(Fp + 1))
          break;
        Fp++;
      }
      Atomval = (Atomval << 8) + Sc;
      J++;
      if (J == 255)
        goto Stringerr;
    }
    if (Atomtype == Stringbit) {
      Atomval = (J << 8) + (Atomval & 255);
      if (!J)
        Atomtype = Stringbit + Numbits;
    }
    Sc = 0;
    goto Nn;
  Hex:
    J = 4;
    goto Rad;
  Oct:
    J = 3;
    goto Rad;
  Bin:
    J = 1;
  Rad:
    Fp++;
    Atomtype = Numbits;
    Atomval = 0;
    for (;;) {
      Fp++;
      Sc = *Byteinteger(Fp);
      if (Sc == '\'')
        break;
      K = Sc - '0';
      if (K >= 'A' - '0')
        K += '0' - 'A' + 10;
      if (K >> J)
        goto Err;
      Atomval = (Atomval << J) + K;
    }
    Sc = 0;
    goto Nn;
  }
  void Popcontext(void) {
    int I;
    Dpos = C.Local;
    Fpos1 = Fpos;
    while (Dpos != Dlim) {
      I = *Integer(Dpos);
      if (I != Recformat) {
        if ((I & 1) != 0 && (I & 6) != 0) {
          Report(15);
        } else if (*Integer(Dpos + 4)) {
          Dpos = *Integer(Dpos + 4);
        }
      }
      Dpos = (*Byteinteger(Dpos + 12) & (~3)) + Dpos + 16;
    }
    while (C.Stack) {
      Report((C.Stack & 1) + 9);
      C.Stack = C.Stack >> 2;
    }
    Dlim = C.Local;
    C = Hold[Level];
    Level--;
    for (I = Addr(Index[0]); I <= Addr(Index[255]); I += 4)
      while (*Integer(I) >= Dlim)
        *Integer(I) = *Integer(*Integer(I) + 8);
  }
  void Define(int Disp, int Val) {
    while (Idents != Dlim) {
      if (Disp)
        *Integer(Idents + 4) = Val;
      else
        *Byteinteger(Idents + 2) = Val;
      Idents = (*Byteinteger(Idents + 12) & (~3)) + Idents + 16;
    }
  }
  goto A_skip;
A_default:
  fprintf(stderr, "Switch label 'A(%d):' not set in %s", A_sw,
          __PRETTY_FUNCTION__);
  exit(1) /* or %signal ... */;
A_skip:;
}


#include <error.h>
#include <errno.h>

int Check(char *Param) {
  static unsigned char Text[1024*1024];
  //static char Text[200]; // static ensures address is positive.  Comes in useful later. Use small test files for now.
  FILE *source = fopen(Param, "r");
  int Length = 0, Flag = 0;
  if (source == NULL) {
    fprintf(stderr, "check: cannot open %s - %s\n", Param, strerror(errno));
    exit(1);
  }
  for (;;) {
    int c = fgetc(source);
    if (c == EOF) break;
    Text[Length++] = c;
  }
  fclose(source);
  //fprintf(stderr, "Checkinner(%p %d, %d, %p)\n", Text, (int)Text, Length, &Flag);
  // Flag = 8|4;
  Checkinner((int)&Text, Length, &Flag);
  if (Flag == 0) {
    fprintf(stderr, "Compiled OK\n");
    return 0;
  } else {
    fprintf(stderr, "Syntax errors\n");
    return 1;
  }
}

int _imp_mainep(int _imp_argc, char **_imp_argv) {
  if (_imp_argc != 2) {
    fprintf(stderr, "syntax: check file.imp\n");
    exit(1);
  }
  exit(Check(_imp_argv[1]));
  return (1);
}