#define USE_IMP_TRACING 3
#include <perms.h>
#undef Snl
#undef SNL
#ifndef return
#define return(x) do {_imp_leave();return(x);} while (0)
#endif

//void Exit(int Rc);
static void Do(_imp_string Text);
static int /* boolean */ Find(int Flag, int *Ty, int *La);
static const _imp_string Snl = _imp_str_literal("\n");
static int Instream = 0;
static int Outstream = 0;
static unsigned char Named[1024 /*1:1024*/] = {
$define Named[X] Named[(X)-1]
    10,  'R', 'E', 'A', 'D',
    'S', 'Y', 'M', 'B', 'O',
    'L', 10,  'N', 'E', 'X',
    'T', 'S', 'Y', 'M', 'B',
    'O', 'L', 10,  'S', 'K',
    'I', 'P', 'S', 'Y', 'M',
    'B', 'O', 'L', 11,  'P',
    'R', 'I', 'N', 'T', 'S',
    'Y', 'M', 'B', 'O', 'L',
    5,   'S', 'P', 'A', 'C',
    'E', 6,   'S', 'P', 'A',
    'C', 'E', 'S', 7,   'N',
    'E', 'W', 'L', 'I', 'N',
    'E', 8,   'N', 'E', 'W',
    'L', 'I', 'N', 'E', 'S',
    7,   'N', 'E', 'W', 'P',
    'A', 'G', 'E', 4,   'R',
    'E', 'A', 'D', 5,   'W',
    'R', 'I', 'T', 'E', [94 ... 1023] = 0};
static int Namedlink[256 /*0:255*/] = {0,
                                       76,
                                       [2 ... 13] = 0,
                                       89,
                                       [15 ... 68] = 0,
                                       84,
                                       [70 ... 187] = 0,
                                       52,
                                       [189 ... 199] = 0,
                                       1,
                                       12,
                                       23,
                                       34,
                                       [204 ... 207] = 0,
                                       67,
                                       [209 ... 231] = 0,
                                       46,
                                       [233 ... 237] = 0,
                                       59,
                                       [239 ... 255] = 0};
static int Taglink[256 /*0:255*/] = {0,
                                     13,
                                     [2 ... 13] = 0,
                                     16,
                                     [15 ... 68] = 0,
                                     14,
                                     [70 ... 187] = 0,
                                     8,
                                     [189 ... 199] = 0,
                                     1,
                                     3,
                                     4,
                                     5,
                                     [204 ... 207] = 0,
                                     11,
                                     [209 ... 231] = 0,
                                     7,
                                     [233 ... 237] = 0,
                                     10,
                                     [239 ... 255] = 0};
static int Tag[512 /*1:512*/] = {
$define Tag[X] Tag[(X)-1]
    0x40100001, 0x11010002, 0x41000002, 0x40000003,      0x40100004,
    0x01010002, 0x40000005, 0x40100006, 0x01010002,      0x40000007,
    0x40100008, 0x01010002, 0x40000009, 0x4010000A,      0x11010002,
    0x4020000B, 0x01010002, 0x01010003, [18 ... 511] = 0};
static int Link[512 /*1:512*/] = {
$define Link[X] Link[(X)-1]
    2, 0, 0, 0, 6, 0, 0, 9, 0, 0, 12, 0, 0, 15, 0, 17, 18, 0, [18 ... 511] = 0};
static int Namedp = 95;
static int Tagasl = 19;
static int Expropt = 0;
static int Condopt = 0;
static int Tagsopt = 0;
static int Traceopt = 0;
static int Checkopt = 0;
static int Infoopt = 0;
static int Level = 0;
static void Statement(int Statementp);
static void Fault(_imp_string Mess);
static void Dump(_imp_string Lab, _imp_string Op, _imp_string Reg,
                 _imp_string Addr);
static _imp_string Strint(int N, int P);
static _imp_string Strhex(int N);
static _imp_string Name(int Ident);
static void Proc(int Ap);
static void Array(int Ap);
//static int Getcoti(int Const);
static int A[500 /*1:500*/];
$define A[X] A[(X)-1]
static int Intstr(_imp_string Val);
static void Expr(int Exprp);
static void Filllabel(int Label);
//static int Fillbranch(int Label);
static int Nextplabel(void);
static _imp_string S(int I);
static int Cond(int Condp, int Tlabel, int Flabel);
static int Getwork(void);
static void Returnwork(int Work);
static void Clearwork(void);
static int Newtag(void);
static void Pushtag(int Ident, int Form, int Type, int Dim, int Level, int Rad);
static void Poptags(void);
static int Getlabel(int Constp);
static void Poplabels(void);
static void Pushstart(int Flag, int Plab);
static void Popstart(int *Flag, int *Plab);
static void Findcontinue(int *Type, int *Flag);
static void Findexit(int *Type, int *Flag);
static void Popcycle(int *Type, int *Lab);
static void Clearstart(void);
static int Enter(void);
static void Dumpreturn(void);
static void Endofprog(void);
static int Nextrad[16 /*0:15*/];
static _imp_string Display[16 /*0:15*/] = {
    _imp_str_literal("Bug"),   _imp_str_literal("-2,X"),
    _imp_str_literal("-4,X"),  _imp_str_literal("-6,X"),
    _imp_str_literal("-8,X"),  _imp_str_literal("-10,X"),
    _imp_str_literal("-12,X"), _imp_str_literal("-14,X"),
    _imp_str_literal("-16,X"), _imp_str_literal("-18,X"),
    _imp_str_literal("-20,X"), _imp_str_literal("-22,X"),
    _imp_str_literal("-24,X"), _imp_str_literal("-26,X"),
    _imp_str_literal("-28,X"), _imp_str_literal("-30,X")};
static int Nextcad = 1;
static int Pstr = 0;
static int Proctype[16 /*0:15*/];
static int Staticalloc[16 /*0:15*/];
static _imp_string Regs[2 /*1:2*/] = {_imp_str_literal("A"),
$define Regs[X] Regs[(X)-1]
                                      _imp_str_literal("A,B")};
static int Rt[16 /*0:15*/];
static int Parms[16 /*0:15*/];
static int Aopt = 0;
static void Statement(int Statementp) {
  _imp_enter();
  static int Access = 1;
  auto void Doloop(int Loopsp);
  auto void Instr(int Instrp);
  _imp_string Base;
  _imp_string B1;
  _imp_string B2;
  static int Sttype_sw;
  static void *Sttype[13 /*1:13*/] = {
      &&Sttype_1,  &&Sttype_2,  &&Sttype_3,  &&Sttype_4, &&Sttype_5,
      &&Sttype_6,  &&Sttype_7,  &&Sttype_8,  &&Sttype_9, &&Sttype_10,
      &&Sttype_11, &&Sttype_12, &&Sttype_13,
  };
  int Condp;
  int Instrp;
  int Elsep;
  int Constp;
  int Arrayp;
  int Namep;
  int Namesp;
  int Expr1p;
  int Expr2p;
  int Instr2p;
  int Tlabel;
  int Flabel;
  int Label;
  int Fplabel;
  int Tplabel;
  int Work1;
  int Work2;
  int Flag;
  int Plabel;
  int Procp;
  int Formalp;
  int Formp;
  int Params;
  int Procid;
  int Ident;
  int Form;
  int Paramt;
  int Paraml;
  int Dim;
  int Basep;
  int Type;
  int Cyclab;
  int Cntlab;
  int Extlab;
  goto *Sttype[Sttype_sw = (A[Statementp]) - 1];
Sttype_1:; // <INSTR><CYCLAUSE>,
  if (!Access) {
    Fault(_imp_str_literal("ACCESS?"));
    Access = 1;
  }
  if (Traceopt == 1)
    Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
         _imp_str_literal(""));
  if (A[A[A[Statementp + 2] + 1]] != 2) Doloop(A[Statementp + 2]);  // <CYCLAUSE>=<FORLOOP>,<WHILE>,<UNTIL>;
  Instr(A[Statementp + 1]); // <INSTR>
  if (A[A[A[Statementp + 2] + 1]] == 2) {
    _imp_leave();
    return;
  }
  if (!Access) {
    Fault(_imp_str_literal("DUBIOUS STATEMENT"));
    Access = 1;
  }
  Condp = A[A[A[Statementp + 2] + 1] + 1];
  A[1] = 1;
  A[2] = 3;
  if (A[A[Statementp + 2]] <= 2)
    A[3] = 2;
  else
    A[3] = 1;
  Statementp = 1;
  goto Untilst;
Sttype_2:; // "IF"<COND>"THEN"<INSTR><ELSE>,
  Condp = A[Statementp + 1];
  Instrp = A[Statementp + 2];
  Elsep = A[Statementp + 3];
  if (!Access) {
    Fault(_imp_str_literal("ACCESS?"));
    Access = 1;
  }
  if (Traceopt == 1)
    Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
         _imp_str_literal(""));
  if ((7 <= A[Instrp] && A[Instrp] <= 8) || A[Instrp] == 2) {
    if (A[Instrp] == 7)                  // "CONTINUE",
      Findcontinue(&Type, &Tlabel);
    else if (A[Instrp] == 8)             // "EXIT",
      Findexit(&Type, &Tlabel);
    else {                               // '->'<CONST>,
      Constp = A[Instrp + 1];
      Tlabel = Getlabel(Constp);
    }
    if (A[Elsep] == 2)      // <ELSE>="ELSE"<INSTR>,;
      Filllabel(Cond(Condp, Tlabel, -1));
    else {                  // <ELSE>="ELSE"<INSTR>,;
      Instrp = A[Elsep + 1];
      if ((7 <= A[Instrp] && A[Instrp] <= 8) || A[Instrp] == 2) {
        if (A[Instrp] == 7)              // "CONTINUE",
          Findcontinue(&Type, &Flabel);
        else if (A[Instrp] == 8)         // "EXIT",
          Findexit(&Type, &Flabel);
        else {                           // '->'<CONST>,
          Constp = A[Instrp + 1];
          Flabel = Getlabel(Constp);
        }
        Access = 0;
        Filllabel(Cond(Condp, Tlabel, Flabel));
        Dump(_imp_str_literal(""), _imp_str_literal("LBRA"),
             _imp_str_literal(""), _imp_join(_imp_str_literal("L"), S(Flabel)));
        _imp_leave();
        return;
      } else {
        Filllabel(Cond(Condp, Tlabel, -1));
        if (A[Instrp] == 3)              // "START",
          Pushstart(1, -1);
        else
          Instr(Instrp);
      }
    }
  } else if (A[Elsep] == 2) {            // <ELSE>="ELSE"<INSTR>,;
    Fplabel = Cond(Condp, -1, -1);
    if (A[Instrp] == 3)                  // "START",
      Pushstart(0, Fplabel);
    else {
      Instr(Instrp);
      Filllabel(Fplabel);
    }
  } else {
    Instr2p = A[Elsep + 1];
    if ((7 <= A[Instr2p] && A[Instr2p] <= 8) || A[Instr2p] == 2) {
      if (A[Instr2p] == 7)               // "CONTINUE",
        Findcontinue(&Type, &Flabel);
      else if (A[Instr2p] == 8)          // "EXIT",
        Findexit(&Type, &Flabel);
      else {                             // '->'<CONST>,
        Constp = A[Instr2p + 1];
        Flabel = Getlabel(Constp);
      }
      Fplabel = Cond(Condp, -1, Flabel);
      Instr(Instrp);
    } else {
      Fplabel = Cond(Condp, -1, -1);
      Instr(Instrp);
      Tplabel = Nextplabel();
      Dump(_imp_str_literal(""), _imp_str_literal("LBRA"), _imp_str_literal(""),
           _imp_join(_imp_str_literal("L"), S(Tplabel)));
      Filllabel(Fplabel);
      if (A[Instr2p] == 3)               // "START",
        Pushstart(1, Tplabel);
      else {
        Instr(Instr2p);
        Filllabel(Tplabel);
      }
    }
  }
  Access = 1;
  _imp_leave();
  return;
Sttype_3:; // <CONST>':'<STATEMENT>,
  Access = 1;
  Constp = A[Statementp + 1];
  Statementp = A[Statementp + 2];
  Label = Getlabel(Constp);
  Filllabel(Label);
  Statement(Statementp);
  _imp_leave();
  return;
Sttype_4:; // "FINISH"<ELSE>,
  Access = 1;
  Elsep = A[Statementp + 1];
  Popstart(&Flag, &Plabel);
  if (!Flag)
    if (A[Elsep] == 1) {                 // <ELSE>="ELSE"<INSTR>,;
      Instrp = A[Elsep + 1];
      Tplabel = Nextplabel();
      Dump(_imp_str_literal(""), _imp_str_literal("LBRA"), _imp_str_literal(""),
           _imp_join(_imp_str_literal("L"), S(Tplabel)));
      Filllabel(Plabel);
      if (A[Instrp] == 3)                // "START",
        Pushstart(1, Tplabel);
      else {
        Instr(Instrp);
        Filllabel(Tplabel);
      }
    } else
      Filllabel(Plabel);
  else if (A[Elsep] == 1)
    Fault(_imp_str_literal("SPURIOUS %ELSE"));
  else
    Filllabel(Plabel);
  _imp_leave();
  return;
Sttype_5:; // "BYTE"<ARRAY>,
  Arrayp = A[Statementp + 1];
  Namep = A[Arrayp + 1];
  Namesp = A[Arrayp + 2];
  if (A[Arrayp] == 1) { // "ARRAY"<NAME><NAMES>'('<EXPR>':'<EXPR>')'<RARRAY>,<name><names>;
    if (Traceopt == 1)
      Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
           _imp_str_literal(""));
    if (!Access) {
      Fault(_imp_str_literal("ACCESS?"));
      Access = 1;
    }
    if (Find(2, &Cyclab, &Type)) Fault(_imp_str_literal("ORDER?"));
    if (Level == 1)
      Base = _imp_str_literal(",X");
    else
      Base = _imp_str_literal(",Y");
    for (;;) {
      Expr1p = A[Arrayp + 3];
      Expr2p = A[Arrayp + 4];
      Expr(Expr1p);
      Dump(_imp_str_literal(""), _imp_str_literal("SEX"), _imp_str_literal(""),
           _imp_str_literal(""));
      Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
           _imp_str_literal("A,B"));
      Work1 = Getwork();
      Expr(Expr2p);
      Dump(_imp_str_literal(""), _imp_str_literal("SEX"), _imp_str_literal(""),
           _imp_str_literal(""));
      Dump(_imp_str_literal(""), _imp_str_literal("ADD"), _imp_str_literal("D"),
           _imp_str_literal("#1"));
      Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
           _imp_str_literal("A,B"));
      Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""),
           _imp_str_literal("S,D"));
      Work2 = Getwork();
      for (;;) {
        Staticalloc[Level] = Staticalloc[Level] + 2;
        Nextrad[Level] = Nextrad[Level] + 2;
        Pushtag(A[Namep + 1], 2, 1, 2, Level, Nextrad[Level]);
        Dump(_imp_str_literal(""), _imp_str_literal("SUB"),
             _imp_str_literal("D"), _imp_str_literal("0,U"));
        Dump(_imp_str_literal(""), _imp_str_literal("ST"),
             _imp_str_literal("D"),
             _imp_join(_imp_str_literal("-"),
                       _imp_join(S(Nextrad[Level]), Base)));
        Dump(_imp_str_literal(""), _imp_str_literal("ADD"),
             _imp_str_literal("D"), _imp_str_literal("2,U"));
        if (A[Namesp] == 2) break;
        Namep = A[Namesp + 1];
        Namesp = A[Namesp + 2];
      }
      Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""),
           _imp_str_literal("D,S"));
      Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("U"),
           _imp_str_literal("4,U"));
      Returnwork(Work1);
      Returnwork(Work2);
      if (A[A[Arrayp + 5]] == 1) { // <RARRAY>=','<NAME><NAMES>'('<EXPR>':'<EXPR>')'<RARRAY>,;
        Arrayp = A[Arrayp + 5];
        Namep = A[Arrayp + 1];
        Namesp = A[Arrayp + 2];
        continue;
      } else {
        _imp_leave();
        return;
      }
    }
  } else { // "array"<name><names>'('<expr>':'<expr>')'<rarray>,<NAME><NAMES>;
    for (;;) {
      Staticalloc[Level] = Staticalloc[Level] + 1;
      Nextrad[Level] = Nextrad[Level] + 1;
      Pushtag(A[Namep + 1], 0, 1, 1, Level, Nextrad[Level]);
      if (A[Namesp] == 2) break;
      Namep = A[Namesp + 1];
      Namesp = A[Namesp + 2];
    }
  }
  _imp_leave();
  return;
Sttype_6:; // <PROC><NAME><FORMAL>,
  if (!Level) Fault(_imp_str_literal("PROCEDURE BEFORE %BEGIN"));
  if (Level == 15) Fault(_imp_str_literal("PROCEDURE NESTING TOO DEEP"));
  Access = 1;
  Procp = A[Statementp + 1];            // "ROUTINE","BYTEFN";
  Namep = A[Statementp + 2];            // 
  Formalp = A[Statementp + 3];          // '('"BYTE"<FORM><NAME><NAMES><FORMALS>')',;
  Procid = A[Namep + 1];
  Pushtag(Procid, 4, A[Procp] - 1, 0, Level, Nextcad);
  Level++;
  Rt[Level] = Tag[Taglink[Procid]] & 0xFFFF;
  Dump(_imp_str_literal(""), _imp_str_literal("LBRA"), _imp_str_literal(""),
       _imp_join(_imp_str_literal("S"), S(Rt[Level])));
  Dump(_imp_join(_imp_str_literal("E"), S(Rt[Level])), _imp_str_literal("EQU"),
       _imp_str_literal(""), _imp_str_literal("*"));
  Proctype[Level] = A[Procp];
  Staticalloc[Level] = Enter();
  Parms[Level] = 0;
  if (A[Formalp] == 2) goto Retn;
  Params = 0;
  Paraml = Taglink[Procid];
  do {
    Formp = A[Formalp + 1];             // "ARRAYNAME","NAME",;
    Namep = A[Formalp + 2];             // 
    Namesp = A[Formalp + 3];            // ','<NAME><NAMES>,;
    Formalp = A[Formalp + 4];           // ','"BYTE"<FORM><NAME><NAMES><FORMALS>,;
    if (A[Formp] == 1) {                // "ARRAYNAME","name",;
      Form = 3;
      Dim = 2;
    } else if (A[Formp] == 2) {         // "arrayname","NAME",;
      Form = 1;
      Dim = 2;
    } else {
      Form = 0;
      Dim = 1;
    }
    for (;;) {
      Ident = A[Namep + 1];
      Nextrad[Level] = Nextrad[Level] + Dim;
      Staticalloc[Level] = Staticalloc[Level] + Dim;
      Pushtag(Ident, Form, 1, Dim, Level, Nextrad[Level]);
      Paramt = Newtag();
      Tag[Paramt] = Tag[Taglink[Ident]];
      Link[Paramt] = Link[Paraml];
      Link[Paraml] = Paramt;
      Paraml = Paramt;
      Parms[Level] = Parms[Level] + Dim;
      Params++;
      if (Params > 15) {
        Fault(_imp_join(Name(Procid),
                        _imp_str_literal(" HAS TOO MANY PARAMETERS")));
        _imp_leave();
        exit(0);
      }
      if (A[Namesp] == 2) break;
      Namep = A[Namesp + 1];
      Namesp = A[Namesp + 2];
    }
  } while (A[Formalp] != 2);
  Tag[Taglink[Procid]] = Tag[Taglink[Procid]] | Params << 20;
Retn:;
  Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
       _imp_join(_imp_str_literal("-A"),
                 _imp_join(S(Rt[Level]), _imp_str_literal(",S"))));
  _imp_leave();
  return;
Sttype_7:; // "END"<OFPROG>,
  if (Level > 1) {
    if (Proctype[Level] != 1 && Checkopt == 1)
      Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal(""),
           _imp_str_literal(""));
  }
  Poptags();
  Poplabels();
  Clearstart();
  Clearwork();
  Dump(_imp_join(_imp_str_literal("A"), S(Rt[Level])), _imp_str_literal("EQU"),
       _imp_str_literal(""), S(Staticalloc[Level]));
  if (Proctype[Level] >= 1 && Access == 1) Dumpreturn();
  Access = 1;
  Level--;
  if (A[A[Statementp + 1]] == 2) {
    if (Level <= 0) {
      Fault(_imp_str_literal("SPURIOUS %END"));
      Endofprog();
    }
    Dump(_imp_join(_imp_str_literal("S"), S(Rt[Level + 1])),
         _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("*"));
  } else {
    if (Level) Fault(_imp_str_literal("TOO FEW %ENDS"));
    Endofprog();
  }
  _imp_leave();
  return;
Sttype_8:; // "BEGIN",
  if (Level)
    Fault(_imp_str_literal("SPURIOUS %BEGIN"));
  else {
    Rt[1] = 0;
    Level = 1;
    Proctype[1] = 0;
    Staticalloc[1] = Enter();
    Nextrad[1] = Staticalloc[1];
  }
  _imp_leave();
  return;
Sttype_9:; // <LOOPS>"CYCLE",
  if (!Access) {
    Fault(_imp_str_literal("WARNING - ACCESS???"));
    Access = 1;
  }
  if (Traceopt == 1)
    Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
         _imp_str_literal(""));
  Doloop(A[Statementp + 1]);
  _imp_leave();
  return;
Sttype_10:; // "REPEAT"<UNTIL>,
  Condp = A[A[Statementp + 1] + 1];
  if (Traceopt == 1)
    Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
         _imp_str_literal(""));
Untilst:;
  Access = 1;
  Popcycle(&Type, &Cyclab);
  Cntlab = Cyclab + 1;
  Extlab = Cntlab + 1;
  if (A[A[Statementp + 1]] != 2) {
    Dump(_imp_join(_imp_str_literal("L"), S(Cntlab)), _imp_str_literal("EQU"),
         _imp_str_literal(""), _imp_str_literal("*"));
    Tplabel = Cond(Condp, -1, Cyclab);
    if (Type == 2)
      Dump(_imp_join(_imp_str_literal("L"), S(Extlab)), _imp_str_literal("LEA"),
           _imp_str_literal("U"), _imp_str_literal("4,U"));
    else
      Dump(_imp_join(_imp_str_literal("L"), S(Extlab)), _imp_str_literal("EQU"),
           _imp_str_literal(""), _imp_str_literal("*"));
  } else {
    Dump(_imp_join(_imp_str_literal("L"), S(Cntlab)), _imp_str_literal("LBRA"),
         _imp_str_literal(""), _imp_join(_imp_str_literal("L"), S(Cyclab)));
    if (Type == 2)
      Dump(_imp_join(_imp_str_literal("L"), S(Extlab)), _imp_str_literal("LEA"),
           _imp_str_literal("U"), _imp_str_literal("4,U"));
    else
      Dump(_imp_join(_imp_str_literal("L"), S(Extlab)), _imp_str_literal("EQU"),
           _imp_str_literal(""), _imp_str_literal("*"));
  }
  _imp_leave();
  return;
Sttype_13:; // "PRINTTEXT"<STRING>;
  Pstr = 1;
  if (!Access) {
    Fault(_imp_str_literal("ACCESS?"));
    Access = 1;
  }
  if (Traceopt == 1)
    Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
         _imp_str_literal(""));
  Dump(_imp_str_literal(""), _imp_str_literal("LBSR"), _imp_str_literal(""),
       _imp_str_literal("PSTR"));
  Printstring(_imp_str_literal("          FCB       "));
  Work1 = 4;
  for (;;) {
    Work2 = A[Work1];
    if (Work2 != 0x80)
      Write(Work2, 0);
    else {
      Printstring(_imp_str_literal("$80"));
      break;
    }
    Printsymbol(',');
    Work1++;
  }
  Newline();
  _imp_leave();
  return;
Sttype_11:; // "VECTOR" <NAME> '==' <CONST>,
  Dump(Name(A[A[Statementp + 1] + 1]), _imp_str_literal("EQU"),
       _imp_str_literal(""), S(A[A[Statementp + 2] + 1]));
  _imp_leave();
  return;
Sttype_12:; // "LABEL" <NAME>,
  Dump(Name(A[A[Statementp + 1] + 1]), _imp_str_literal("EQU"),
       _imp_str_literal(""), _imp_str_literal("*"));
  _imp_leave();
  return;
  void Instr(int Instrp) {
    _imp_enter();
    static int Instype_sw;
    static void *Instype[14 /*1:14*/] = {
        &&Instype_1,  &&Instype_2,  &&Instype_3,  &&Instype_4,  &&Instype_5,
        &&Instype_6,  &&Instype_7,  &&Instype_8,  &&Instype_9,  &&Instype_10,
        &&Instype_11, &&Instype_12, &&Instype_13, &&Instype_14,
    };
    _imp_string Base;
    int Namep;
    int Assignp;
    int Constp;
    int Ident;
    int Actualp;
    int Exprp;
    int Nametag;
    int Disp;
    int Work;
    int Rinstrp;
    int Type;
    int Lab;
    goto *Instype[Instype_sw = (A[Instrp]) - 1];
  Instype_1:; // <NAME><ACTUAL><ASSIGN><RINSTR>,
    Namep = A[Instrp + 1];
    Actualp = A[Instrp + 2];
    Assignp = A[Instrp + 3];
    Rinstrp = A[Instrp + 4]; // "AND"<INSTR>,;
    Ident = A[Namep + 1];
    if (!Taglink[Ident])
      if (A[Assignp] != 1)
        Dump(_imp_str_literal(""), _imp_str_literal("FDB"),
             _imp_str_literal(""), Name(Ident));
      else {
        Expr(A[Assignp + 1]);
        Dump(_imp_str_literal(""), _imp_str_literal("ST"),
             _imp_str_literal("B"), Name(Ident));
      }
    else {
      Nametag = Tag[Taglink[Ident]];
      if (A[Assignp] == 1) {  // <ASSIGN>='='<EXPR>,;
        if ((unsigned)Nametag >> 28 == 4) {  // rt/fn
          Fault(_imp_join(Name(Ident), _imp_str_literal(" NOT A DESTINATION")));
          _imp_leave();
          return;
        }
        Exprp = A[Assignp + 1];
        if ((unsigned)Nametag >> 28 >= 2) {
          Expr(Exprp);
          Work = Getwork();
          Dump(_imp_str_literal(""), _imp_str_literal("PSH"),
               _imp_str_literal("U"), _imp_str_literal("B"));
          Array(Instrp);
          Dump(_imp_str_literal(""), _imp_str_literal("PUL"),
               _imp_str_literal("U"), _imp_str_literal("B"));
          Dump(_imp_str_literal(""), _imp_str_literal("ST"),
               _imp_str_literal("B"), _imp_str_literal("[0,X]"));
          Returnwork(Work);
        } else {
          Expr(Exprp);
          Basep = (unsigned)Nametag >> 16 & 0xF;
          Disp = Nametag & 0xFFFF;
          Base = Display[Basep];
          if (Basep == Level) Base = _imp_str_literal(",Y");
          if (Basep == 1) Base = _imp_str_literal(",X");
          if (Basep == Level || Basep == 1) {
            if ((unsigned)Nametag >> 28 == 1) {
              B1 = _imp_str_literal("[");
              B2 = _imp_str_literal("]");
            } else {
              B1 = _imp_str_literal("");
              B2 = _imp_str_literal("");
            }
            Dump(_imp_str_literal(""), _imp_str_literal("ST"),
                 _imp_str_literal("B"),
                 _imp_join(B1,
                           _imp_join(_imp_str_literal("-"),
                                     _imp_join(S(Disp), _imp_join(Base, B2)))));
          } else {
            Dump(_imp_str_literal(""), _imp_str_literal("PSH"),
                 _imp_str_literal("U"), _imp_str_literal("A,B"));
            Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                 _imp_str_literal("D"), Base);
            Dump(_imp_str_literal(""), _imp_str_literal("SUB"),
                 _imp_str_literal("D"),
                 _imp_join(_imp_str_literal("#"), S(Disp)));
            Dump(_imp_str_literal(""), _imp_str_literal("ST"),
                 _imp_str_literal("D"), _imp_str_literal("0,X"));
            if ((unsigned)Nametag >> 28 == 1) {
              Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                   _imp_str_literal("D"), _imp_str_literal("[0,X]"));
              Dump(_imp_str_literal(""), _imp_str_literal("ST"),
                   _imp_str_literal("D"), _imp_str_literal("0,X"));
            }
            Dump(_imp_str_literal(""), _imp_str_literal("PUL"),
                 _imp_str_literal("U"), _imp_str_literal("A,B"));
            Dump(_imp_str_literal(""), _imp_str_literal("ST"),
                 _imp_str_literal("B"), _imp_str_literal("[0,X]"));
          }
          if (A[Actualp] == 1)
            Fault(_imp_join(Name(Ident),
                            _imp_str_literal(" DECLARED AS SCALAR")));
        }
      } else if ((unsigned)Nametag >> 28 == 4 &&
                 ((unsigned)Nametag >> 24 & 0xF) == 0)
        Proc(Instrp);
      else
        Fault(_imp_join(Name(Ident), _imp_str_literal(" NOT A ROUTINE NAME")));
    }
    if (A[Rinstrp] == 1) {
      Instrp = A[Rinstrp + 1];
      goto *Instype[Instype_sw = (A[Instrp]) - 1];
    }
    _imp_leave();
    return;
  Instype_2:; // '->'<CONST>,
    Access = 0;
    Constp = A[Instrp + 1];
    Label = Getlabel(Constp);
    Dump(_imp_str_literal(""), _imp_str_literal("LBRA"), _imp_str_literal(""),
         _imp_join(_imp_str_literal("L"), S(Label)));
    _imp_leave();
    return;
  Instype_3:; // "START",
    Fault(_imp_str_literal("ILLEGAL %START"));
    _imp_leave();
    return;
  Instype_4:; // "RETURN",
    if (Proctype[Level] != 1) Fault(_imp_str_literal("%RETURN OUT OF CONTEXT"));
    Access = 0;
    Dumpreturn();
    _imp_leave();
    return;
  Instype_5:; // "RESULT"'='<EXPR>,
    if (Proctype[Level] != 2) Fault(_imp_str_literal("%RESULT OUT OF CONTEXT"));
    Access = 0;
    Expr(A[Instrp + 1]); // <UNARY><OPERAND><EXPRREST>;
    Dumpreturn();
    _imp_leave();
    return;
  Instype_6:; // "STOP",
    Access = 0;
    Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("2"),
         _imp_str_literal(""));
    _imp_leave();
    return;
  Instype_7:; // "CONTINUE",
    Access = 0;
    Findcontinue(&Type, &Lab);
    Dump(_imp_str_literal(""), _imp_str_literal("LBRA"), _imp_str_literal(""),
         _imp_join(_imp_str_literal("L"), S(Lab)));
    _imp_leave();
    return;
  Instype_8:; // "EXIT",
    Access = 0;
    Findexit(&Type, &Lab);
    Dump(_imp_str_literal(""), _imp_str_literal("LBRA"), _imp_str_literal(""),
         _imp_join(_imp_str_literal("L"), S(Lab)));
    _imp_leave();
    return;
  Instype_9:; // '*' <NAME> '_#'<CONST>,
    Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]), _imp_str_literal(""),
         _imp_join(_imp_str_literal("#"), S(A[A[Instrp + 2] + 1])));
    _imp_leave();
    return;
  Instype_10:; // '*' <NAME> '_'<CONST>,
    Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]), _imp_str_literal(""),
         S(A[A[Instrp + 2] + 1]));
    _imp_leave();
    return;
  Instype_11:; // '*' <NAME> '_#'<NAME>,
    Namep = A[Instrp + 2];
    Ident = A[Namep + 1];
    Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]), _imp_str_literal(""),
         _imp_join(_imp_str_literal("#"), Name(Ident)));
    _imp_leave();
    return;
  Instype_12:; // '*' <NAME> '_'<NAME>,
    Namep = A[Instrp + 2];
    Ident = A[Namep + 1];
    if (Taglink[Ident]) Nametag = Tag[Taglink[Ident]];
    if (Taglink[Ident] == 0 || (unsigned)Nametag >> 28 == 4)
      Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]),
           _imp_str_literal(""), Name(Ident));
    else {
      Basep = (unsigned)Nametag >> 16 & 15;
      Disp = Nametag & 0xFFFF;
      Base = Display[Basep];
      if (Basep == Level) Base = _imp_str_literal(",Y");
      if (Basep == 1) Base = _imp_str_literal(",X");
      B1 = _imp_str_literal("");
      B2 = _imp_str_literal("");
      if ((unsigned)Nametag >> 28 == 1) {
        B1 = _imp_str_literal("[");
        B2 = _imp_str_literal("]");
      }
      Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]),
           _imp_str_literal(""),
           _imp_join(B1, _imp_join(_imp_str_literal("-"),
                                   _imp_join(S(Disp), _imp_join(Base, B2)))));
    }
    _imp_leave();
    return;
  Instype_13:; // '*' <NAME> '_' <STRING>,
    {
      _imp_string Addr = _imp_str_literal("");
      int I;
      int Sym;
      I = 10;
      for (;;) {
        Sym = A[I];
        I++;
        if (Sym == 128) break;
        Addr = _imp_join(Addr, Tostring(Sym));
      }
      Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]),
           _imp_str_literal(""), Addr);
    }
    _imp_leave();
    return;
  Instype_14:; // '*' <NAME>;
    Dump(_imp_str_literal(""), Name(A[A[Instrp + 1] + 1]), _imp_str_literal(""),
         _imp_str_literal(""));
    _imp_leave();
    return;
    _imp_leave();
  }
  void Doloop(int Loopsp) {
    _imp_enter();
    int Type;
    int Cyclab;
    int Cntlab;
    int Extlab;
    int Namep;
    int Actualp;
    int Forp;
    int Initp;
    int Incrp;
    int Finalp;
    int Tplabel;
    int Condp;
    int Whilep;
    int Disp;
    int Nametag;
    _imp_string Base;
    _imp_string Reg;
    static int Cycle_sw;
    static void *Cycle[3 /*1:3*/] = {
        &&Cycle_1,
        &&Cycle_default,
        &&Cycle_default,
    };
    // <LOOPS>=<FORLOOP>,<WHILE>,;
    if (A[Loopsp] == 1)
      Type = 2;
    else
      Type = 3;
    Cyclab = Nextplabel();
    Cntlab = Nextplabel();
    Extlab = Nextplabel();
    Pushstart(Type, Cyclab);
    goto *Cycle[Cycle_sw = (A[Loopsp]) - 1];
  Cycle_1:;          // <FORLOOP>="FOR"<NAME><ACTUAL>'='<EXPR>','<EXPR>','<EXPR>;
    Forp = A[Loopsp + 1];
    Namep = A[Forp + 1];
    Actualp = A[Forp + 2];
    Initp = A[Forp + 3];
    Incrp = A[Forp + 4];
    Finalp = A[Forp + 5];
    Ident = A[Namep + 1];
    Reg = _imp_str_literal("D");
    if (!Taglink[Ident])
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("D"),
           _imp_join(_imp_str_literal("#"), Name(Ident)));
    else {
      Nametag = Tag[Taglink[Ident]];
      if ((unsigned)Nametag >> 28 == 4) {
        Fault(_imp_str_literal("NOT A DESTINATION"));
        _imp_leave();
        return;
      }
      if ((unsigned)Nametag >> 28 == 2) {
        Aopt = 1;
        Array(Forp);
      } else {
        Basep = (unsigned)Nametag >> 16 & 0xF;
        Base = Display[Basep];
        Disp = Nametag & 0xFFFF;
        if (Basep == Level) Base = _imp_str_literal("Y");
        if (Basep == 1) Base = _imp_str_literal("X");
        if ((unsigned)Nametag >> 28 == 1)
          if (1 < Basep && Basep < Level) {
            Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                 _imp_str_literal("D"), Base);
            Dump(_imp_str_literal(""), _imp_str_literal("SUB"),
                 _imp_str_literal("D"),
                 _imp_join(_imp_str_literal("#"), S(Disp)));
            Dump(_imp_str_literal(""), _imp_str_literal("ST"),
                 _imp_str_literal("D"), _imp_str_literal("0,X"));
            Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                 _imp_str_literal("D"), _imp_str_literal("[0,X]"));
          } else
            Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                 _imp_str_literal("D"),
                 _imp_join(_imp_str_literal("-"),
                           _imp_join(S(Disp),
                                     _imp_join(_imp_str_literal(","), Base))));
        else {
          if (1 < Basep && Basep < Level) {
            Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                 _imp_str_literal("D"), Base);
            Dump(_imp_str_literal(""), _imp_str_literal("SUB"),
                 _imp_str_literal("D"),
                 _imp_join(_imp_str_literal("#"), S(Disp)));
          } else if (Basep == 1 && 1 == Level) {
            Dump(_imp_str_literal(""), _imp_str_literal("LEA"),
                 _imp_str_literal("Y"),
                 _imp_join(_imp_str_literal("-"),
                           _imp_join(S(Disp), _imp_str_literal(",X"))));
            Reg = _imp_str_literal("Y");
          } else {
            Dump(_imp_str_literal(""), _imp_str_literal("TFR"),
                 _imp_str_literal(""), _imp_join(Base, _imp_str_literal(",D")));
            Dump(_imp_str_literal(""), _imp_str_literal("SUB"),
                 _imp_str_literal("D"),
                 _imp_join(_imp_str_literal("#"), S(Disp)));
          }
          if (A[Actualp] == 1)
            Fault(_imp_join(Name(Ident),
                            _imp_str_literal(" DECLARED AS SCALAR")));
        }
      }
    }
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
         Reg);
    Expr(Finalp);
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
         _imp_str_literal("B"));
    Expr(Incrp);
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
         _imp_str_literal("B"));
    Expr(Initp);
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("B"),
         _imp_str_literal(",U"));
    Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("B"),
         _imp_str_literal("[2,U]"));
    Dump(_imp_join(_imp_str_literal("L"), S(Cyclab)), _imp_str_literal("EQU"),
         _imp_str_literal(""), _imp_str_literal("*"));
    Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("B"),
         _imp_str_literal("[2,U]"));
    Dump(_imp_str_literal(""), _imp_str_literal("CMP"), _imp_str_literal("B"),
         _imp_str_literal("1,U"));
    Dump(_imp_str_literal(""), _imp_str_literal("LBEQ"), _imp_str_literal(""),
         _imp_join(_imp_str_literal("L"), S(Extlab)));
    Dump(_imp_str_literal(""), _imp_str_literal("ADD"), _imp_str_literal("B"),
         _imp_str_literal(",U"));
    Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("B"),
         _imp_str_literal("[2,U]"));
    _imp_leave();
    return;
  Cycle_default:;
    Dump(_imp_join(_imp_str_literal("L"), S(Cyclab)), _imp_str_literal("EQU"),
         _imp_str_literal(""), _imp_str_literal("*"));
    if (A[Loopsp] != 2) {
      _imp_leave();
      return;
    }
    Whilep = A[Loopsp + 1];       // <WHILE>="WHILE"<COND>;
    Condp = A[Whilep + 1];
    Tplabel = Cond(Condp, -1, Extlab);
    _imp_leave();
  }

  _imp_leave();
}
static int Condflag = 0;
static int Cond(int Condp, int Tlabel, int Flabel) {
  _imp_enter();
  auto void Processcond(int Condp);
  auto void Test(int Ltestp);
  auto void Condrest(int Condrestp);
  auto void Store(int Testp, int Level, int Andor);
  auto void Show(const _imp_string An, const int *A, int P);
  // <COMP>='=','#','<=','<','>=','>';
  static const _imp_string True[6 /*1:6*/] = {
$define True[X] True[(X)-1]
      _imp_str_literal("LBEQ"), _imp_str_literal("LBNE"),
      _imp_str_literal("LBLE"), _imp_str_literal("LBLT"),
      _imp_str_literal("LBGE"), _imp_str_literal("LBGT")};
  static const _imp_string False[6 /*1:6*/] = {
$define False[X] False[(X)-1]
      _imp_str_literal("LBNE"), _imp_str_literal("LBEQ"),
      _imp_str_literal("LBGT"), _imp_str_literal("LBGE"),
      _imp_str_literal("LBLT"), _imp_str_literal("LBLE")};
  _imp_string Opn;                                                                            // SEE NOTE IN Proc() RE Opn/Base/Reg
  static const int Index[17 /*1:17*/] = {1,  2,  3,  4,  5,  6,  7,  8, 9,
$define Index[X] Index[(X)-1]
                                         10, 11, 12, 13, 14, 15, 16, 17};
  int Testpa[16 /*1:16*/];
$define Testpa[X] Testpa[(X)-1]
  int Levela[16 /*1:16*/];
$define Levela[X] Levela[(X)-1]
  int Andora[16 /*1:16*/];
$define Andora[X] Andora[(X)-1]
  int Brancha[16 /*1:16*/];
$define Brancha[X] Brancha[(X)-1]
  int Labela[17 /*1:17*/];
$define Labela[X] Labela[(X)-1]
  int P;
  int Pp;
  int Ppp;
  int Testp;
  int Level;
  int Andor;
  int Comp;
  Level = 0;
  P = 1;
  Processcond(Condp); // <COND>=<TEST><CONDREST>;
  Store(Testp, -1, 1);
  Store(0, -2, 2);
  P -= 2;
  for (Pp = 1; Pp <= P; Pp++) {
    Level = Levela[Pp];
    Andor = Andora[Pp];
    for (Ppp = Pp + 1; Ppp <= P + 1; Ppp++)
      if (Levela[Ppp] < Level) {
        Level = Levela[Ppp];
        if (Andora[Ppp] != Andor) break;
      }
    Brancha[Pp] = Ppp + 1;
  }
  if (Tlabel >= 0) {
    Andora[P] = 2;
    Brancha[P] = P + 1;
    Labela[P + 1] = Tlabel;
  }
  Labela[P + 2] = Flabel;
  for (Pp = 1; Pp <= P; Pp++)
    if (Labela[Brancha[Pp]] < 0) Labela[Brancha[Pp]] = Nextplabel();
  if (Condopt == 1) {
    Newline();
    Show(_imp_str_literal("      "), Index, P + 2);
    Show(_imp_str_literal("TESTP "), Testpa, P);
    Show(_imp_str_literal("LEVEL "), Levela, P + 1);
    Show(_imp_str_literal("ANDOR "), Andora, P + 1);
    Show(_imp_str_literal("BRANCH"), Brancha, P);
    Show(_imp_str_literal("LABEL "), Labela, P + 2);
    Newline();
  }
  for (Pp = 1; Pp <= P; Pp++) {
    if (Labela[Pp] >= 0) Filllabel(Labela[Pp]);
    Condflag = 1;
    Expr(Testpa[Pp]);
    Comp = A[A[Testpa[Pp] + 2]];
    if (Andora[Pp] == 1)
      Opn = False[Comp];
    else
      Opn = True[Comp];
    Dump(_imp_str_literal(""), Opn, _imp_str_literal(""),
         _imp_join(_imp_str_literal("L"), S(Labela[Brancha[Pp]])));
  }
  if (Labela[P + 1] >= 0 && Tlabel < 0) Filllabel(Labela[P + 1]);
  if (Flabel >= 0)
    return (-1);
  else
    return (Labela[P + 2]);
  void Processcond(int Condp) {
    _imp_enter();
    Test(A[Condp + 1]);      // <COND>=<TEST><CONDREST>;
    Condrest(A[Condp + 2]);
    _imp_leave();
  }
  void Test(int Ltestp) {
    _imp_enter();
    if (A[Ltestp] == 1)     // <TEST>=<EXPR><COMP><EXPR>,'('<COND>')';
      Testp = Ltestp;
    else {
      Level++;
      Processcond(A[Ltestp + 1]);
      Level--;
    }
    _imp_leave();
  }
  void Condrest(int Condrestp) {
    _imp_enter();
    int Andor;
    Andor = A[Condrestp];   // <CONDREST>="AND"<TEST><ANDCOND>,"OR"<TEST><ORCOND>,;
    if (Andor != 3) do {
        Store(Testp, Level, Andor);
        Test(A[Condrestp + 1]);
        Condrestp = A[Condrestp + 2];
      } while (A[Condrestp] != 2);

    _imp_leave();
  }
  void Store(int Testp, int Level, int Andor) {
    _imp_enter();
    if (P > 16) {
      Fault(_imp_str_literal("CONDITION TOO LONG"));
      _imp_leave();
      exit(0);
    }
    Testpa[P] = Testp;
    Levela[P] = Level;
    Andora[P] = Andor;
    Labela[P] = -1;
    P++;
    _imp_leave();
  }
  void Show(const _imp_string An, const int *A, int P) {
    _imp_enter();
    int Pp;
    Printstring(_imp_join(An, _imp_str_literal("  ")));
    for (Pp = 1; Pp <= P; Pp++) Write(A[Pp], 5);
    Newline();
    _imp_leave();
  }

  _imp_leave();
  fault("Reached end of %s without a %%result", __PRETTY_FUNCTION__);
}
static int Faults = 0;
static void Popitem(int *F, int *L);
static int Used[16 /*0:15*/] = {[0 ... 15] = 0};
static int Worklist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Namelist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Branchlist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Startlist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Cot[128 /*0:127*/];
static int Cotp;
static int Params;
static _imp_string Strint(int N, int P) {
  _imp_enter();
  _imp_string R;
  _imp_string S;
  if (N < 0) {
    S = _imp_str_literal("-");
    N = -N;
  } else
    S = _imp_str_literal("");
  R = _imp_str_literal("");
  do {
    R = _imp_join(Tostring(N - N / 10 * 10 + '0'), R);
    N = N / 10;
  } while (N);
  R = _imp_join(S, R);
  while (*Length(R) < P) R = _imp_join(_imp_str_literal(" "), R);
  return (R);
}
static _imp_string S(int I) {
  _imp_enter();
  return (Strint(I, 0));
}
static _imp_string Strhex(int N) {
  _imp_enter();
  static const _imp_string H[16 /*0:15*/] = {
      _imp_str_literal("0"), _imp_str_literal("1"), _imp_str_literal("2"),
      _imp_str_literal("3"), _imp_str_literal("4"), _imp_str_literal("5"),
      _imp_str_literal("6"), _imp_str_literal("7"), _imp_str_literal("8"),
      _imp_str_literal("9"), _imp_str_literal("A"), _imp_str_literal("B"),
      _imp_str_literal("C"), _imp_str_literal("D"), _imp_str_literal("E"),
      _imp_str_literal("F")};
  int I;
  _imp_string Sh;
  Sh = _imp_str_literal("");
  for (I = 1; I <= 8; I++) {
    Sh = _imp_join(H[N & 0xF], Sh);
    N = (unsigned)N >> 4;
  }
  return (Sh);
}
static void Fault(_imp_string Mess) {
  _imp_enter();
  int St;
  Printstring(_imp_join(_imp_str_literal("?  "),
                        _imp_join(Mess, _imp_str_literal("\n\n"))));
  St = Outstream();
  Selectoutput(0);
  Printstring(_imp_join(_imp_str_literal("*"), _imp_join(Mess, Snl)));
  Selectoutput(St);
  Faults++;
  _imp_leave();
}
static void Dump(_imp_string Lab, _imp_string Op, _imp_string Reg,
                 _imp_string Addr) {
  _imp_enter();
  static _imp_string Label = _imp_str_literal("");
  auto void Codeout(_imp_string L, _imp_string O, _imp_string R, _imp_string A);
  if (*Length(Label) != 0) {
    if (*Length(Lab) == 0)
      Lab = Label;
    else {
      Codeout(Label, _imp_str_literal("EQU"), _imp_str_literal(""),
              _imp_str_literal("*"));
      Label = _imp_str_literal("");
    }
  }
  // Some peepholing first:
  if ((_imp_strcmp(Op, _imp_str_literal("ADD")) == 0 ||
       _imp_strcmp(Op, _imp_str_literal("SUB")) == 0 ||
       _imp_strcmp(Op, _imp_str_literal("EOR")) == 0 ||
       _imp_strcmp(Op, _imp_str_literal("OR")) == 0) &&
      _imp_strcmp(Addr, _imp_str_literal("#0")) == 0) {
    _imp_leave();
    return;
  }
  if ((_imp_strcmp(Op, _imp_str_literal("AND")) == 0 ||
       _imp_strcmp(Op, _imp_str_literal("LD")) == 0) &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0 &&
      _imp_strcmp(Addr, _imp_str_literal("#0")) == 0) {
    Op = _imp_str_literal("CLR");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("ADD")) == 0 &&
      _imp_strcmp(Addr, _imp_str_literal("#1")) == 0 &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0) {
    Op = _imp_str_literal("INC");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("SUB")) == 0 &&
      _imp_strcmp(Addr, _imp_str_literal("#1")) == 0 &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0) {
    Op = _imp_str_literal("DEC");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("CMP")) == 0 &&
      _imp_strcmp(Addr, _imp_str_literal("#0")) == 0 &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0) {
    Op = _imp_str_literal("TST");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("EQU")) == 0 &&
      _imp_strcmp(Addr, _imp_str_literal("*")) == 0)
    Label = Lab;
  else {
    Label = _imp_str_literal("");
    Codeout(Lab, Op, Reg, Addr);
  }
  void Codeout(_imp_string Lab, _imp_string Op, _imp_string Reg,
               _imp_string Addr) {
    _imp_enter();
    _imp_string Nums;
    _imp_string NULLX;
    int I;
    void Dump2(_imp_string Lab, _imp_string Op, _imp_string Reg,
               _imp_string Addr) {
      _imp_enter();
      static _imp_string Lastop = _imp_str_literal("silly");
      static int Inhibit = 0;
      if (_imp_strcmp(Reg, _imp_str_literal("B")) == 0 &&
          _imp_strcmp(Op, _imp_str_literal("LD")) == 0 &&
          _imp_resolve(Addr, &NULLX, _imp_str_literal("#"), &Nums) && *Length(NULLX)==0 &&
          (!(_imp_resolve(Nums, &NULLX, _imp_str_literal("-"), &Nums) && *Length(NULLX)!=0)) &&
          Intstr(Nums) > 255)
        Reg = _imp_str_literal("D");
      if (*Length(Lab) != 0) {
        if (_imp_strcmp(Op, _imp_str_literal("EQU")) == 0 &&
            _imp_strcmp(Addr, _imp_str_literal("*")) == 0)
          Inhibit = 0;
        if (_imp_strcmp(Op, _imp_str_literal("EQU")) != 0) Inhibit = 0;
      }
      if (Inhibit == 0 || _imp_strcmp(Op, _imp_str_literal("EQU")) == 0) {
        Lastop = Op;
        if (_imp_strcmp(Op, _imp_str_literal("TST")) == 0 &&
            _imp_strcmp(Reg, _imp_str_literal("B")) == 0 &&
            *Length(Lab) == 0) {
          _imp_leave();
          return;
        }
        if (_imp_strcmp(Op, _imp_str_literal("CMP")) == 0 &&
            _imp_strcmp(Addr, _imp_str_literal("#1")) == 0) {
          Addr = _imp_str_literal("");
          Op = _imp_str_literal("DEC");
        }
        Printstring(Lab);
        Spaces(10 - *Length(Lab));
        Op = _imp_join(Op, Reg);
        Printstring(Op);
        Spaces(10 - *Length(Op));
        Printstring(Addr);
        Newline();
        Nextcad++;
      }
      if (_imp_strcmp(Op, _imp_str_literal("LBRA")) == 0 ||
          _imp_strcmp(Op, _imp_str_literal("SWI2")) == 0 ||
          (_imp_strcmp(Op, _imp_str_literal("SWI")) == 0 &&
           _imp_strcmp(Reg, _imp_str_literal("2")) == 0))
        Inhibit = 1;
      if (_imp_strcmp(Op, _imp_str_literal("LBSR")) != 0) {
        _imp_leave();
        return;
      }
      // Do we need to include some %prim routine code?
      if (_imp_strcmp(Addr, _imp_str_literal("SHL")) == 0) Used[12] = 1;
      if (_imp_strcmp(Addr, _imp_str_literal("SHR")) == 0) Used[13] = 1;
      if (_imp_strcmp(Addr, _imp_str_literal("EXP")) == 0) Used[14] = 1;
      if (_imp_strcmp(Addr, _imp_str_literal("DIV")) == 0) Used[15] = 1;
      _imp_leave();
    }
    static _imp_string L[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
$define L[X] L[(X)-1]
    static _imp_string O[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
$define O[X] O[(X)-1]
    static _imp_string R[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
$define R[X] R[(X)-1]
$undef A
    static _imp_string A[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
$define A[X] A[(X)-1]
    static int Buffptr = 0;
    static int Load_sw;
    static void *Load[3 /*0:2*/] = {
        &&Load_0,
        &&Load_1,
        &&Load_2,
    };
    static int Store_sw;
    static void *Store[3 /*0:2*/] = {
        &&Store_0,
        &&Store_1,
        &&Store_2,
    };
    void Flushbuffer(void) {
      _imp_enter();
      int I;
      for (I = 1; I <= Buffptr; I++) Dump2(L[I], O[I], R[I], A[I]);
      Buffptr = 0;
      _imp_leave();
    }
    void Checklabel(int Buff) {
      _imp_enter();
      if (Buff == 3) {
        if (*Length(Lab) != 0)
          Dump2(Lab, _imp_str_literal("EQU"), _imp_str_literal(""),
                _imp_str_literal("*"));
        _imp_leave();
        return;
      }
      if (*Length(L[Buff]) != 0)
        Dump2(L[Buff], _imp_str_literal("EQU"), _imp_str_literal(""),
              _imp_str_literal("*"));
      _imp_leave();
    }
    void Savethisinstr(void) {
      _imp_enter();
      _imp_string NULLX;
      Buffptr++;
      if (Buffptr > 2) {
        Printstring(_imp_join(_imp_str_literal("*?????Buffer full..."), Snl));
        Flushbuffer();
      }
      L[Buffptr] = Lab;
      O[Buffptr] = Op;
      R[Buffptr] = Reg;
      A[Buffptr] = Addr;
      _imp_leave();
    }
    if (_imp_strcmp(Op, _imp_str_literal("SEX")) == 0 && Buffptr != 0 &&
        _imp_strcmp(O[Buffptr], _imp_str_literal("LD")) == 0 &&
        _imp_resolve(A[Buffptr], &NULLX, _imp_str_literal("#"), &Nums) && *Length(NULLX)==0 &&
        (!(_imp_resolve(Nums, NULL, _imp_str_literal("-"), &Nums) && *Length(NULLX)!=0)) &&
        Intstr(Nums) > 255) {
      _imp_leave();
      return;
    }
    if (_imp_strcmp(Reg, _imp_str_literal("B")) != 0) {
      Flushbuffer();
      Dump2(Lab, Op, Reg, Addr);
      _imp_leave();
      return;
    }
    if (_imp_strcmp(Op, _imp_str_literal("LD")) == 0) {
      goto *Load[Load_sw = Buffptr];
    Load_0:;
      Savethisinstr();
      _imp_leave();
      return;
    Load_1:;
      if (_imp_strcmp(O[1], _imp_str_literal("LD")) == 0) {
        Checklabel(1);
        Buffptr = 0;
      } else if (_imp_strcmp(O[1], _imp_str_literal("ST")) == 0 && _imp_strcmp(A[1], Addr)==0) {
        if (*Length(Lab) != 0) {
          Flushbuffer();
          Savethisinstr();
          _imp_leave();
          return;
        } else {
          _imp_leave();
          return;
        }
      }
      Savethisinstr();
      _imp_leave();
      return;
    Load_2:;
      Dump2(L[1], O[1], R[1], A[1]);
      L[1] = L[2];
      R[1] = R[2];
      O[1] = O[2];
      A[1] = A[2];
      Buffptr = 1;
      Printstring(_imp_join(
          _imp_str_literal("?***** Unexpected third el = load"), Snl));
      goto *Load[Load_sw = 1];
    }
    if (_imp_strcmp(Op, _imp_str_literal("ST")) == 0) {
      goto *Store[Store_sw = Buffptr];
    Store_0:;
      Savethisinstr();
      _imp_leave();
      return;
    Store_1:;
      if (_imp_strcmp(O[1], _imp_str_literal("LD")) == 0 ||
          _imp_strcmp(O[1], _imp_str_literal("ST")) == 0)  {
        if (_imp_strcmp(A[1], Addr)==0) {
          if (*Length(Lab) != 0) {
            Flushbuffer();
            Savethisinstr();
            _imp_leave();
            return;
          } else {
            _imp_leave();
            return;
          }
        } else {
          Flushbuffer();
          Savethisinstr();
          _imp_leave();
          return;
        }
      }
      if (_imp_strcmp(O[1], _imp_str_literal("CLR")) == 0) {
        Checklabel(1);
        Buffptr = 0;
        Dump2(Lab, _imp_str_literal("CLR"), _imp_str_literal(""), Addr);
        _imp_leave();
        return;
      }
      Flushbuffer();
      Savethisinstr();
      _imp_leave();
      return;
    Store_2:;
      if (_imp_strcmp(O[1], _imp_str_literal("LD")) == 0 && _imp_strcmp(A[1], Addr)==0 &&
          (_imp_strcmp(O[2], _imp_str_literal("INC")) == 0 ||
           _imp_strcmp(O[2], _imp_str_literal("DEC")) == 0 ||
           _imp_strcmp(O[2], _imp_str_literal("NEG")) == 0 ||
           _imp_strcmp(O[2], _imp_str_literal("COM")) == 0)) {
        Checklabel(2);
        Checklabel(3);
        Dump2(L[1], O[2], _imp_str_literal(""), Addr);
        Buffptr = 0;
        _imp_leave();
        return;
      }
      Dump2(L[1], O[1], R[1], A[1]);
      L[1] = L[2];
      O[1] = O[2];
      R[1] = R[2];
      A[1] = A[2];
      Buffptr = 1;
      goto *Store[Store_sw = 1];
    }
    if (_imp_strcmp(Op, _imp_str_literal("TST")) == 0) {
      if (Buffptr)
        if (_imp_strcmp(O[Buffptr], _imp_str_literal("LD")) == 0) {
          Dump2(L[Buffptr], Op, _imp_str_literal(""), A[Buffptr]);
          Checklabel(3);
          Buffptr--;
          _imp_leave();
          return;
        }
      Flushbuffer();
      Dump2(Lab, Op, Reg, Addr);
      _imp_leave();
      return;
    }
    if (_imp_strcmp(Op, _imp_str_literal("INC")) == 0 ||
        _imp_strcmp(Op, _imp_str_literal("DEC")) == 0 ||
        _imp_strcmp(Op, _imp_str_literal("CLR")) == 0 ||
        _imp_strcmp(Op, _imp_str_literal("NEG")) == 0 ||
        _imp_strcmp(Op, _imp_str_literal("COM")) == 0) {
      if (Buffptr == 2) {
        Dump2(L[1], O[1], R[1], A[1]);
        L[1] = L[2];
        O[1] = O[2];
        R[1] = R[2];
        A[1] = A[2];
        L[2] = Lab;
        O[2] = Op;
        R[2] = Reg;
        A[2] = Addr;
        Buffptr = 2;
        _imp_leave();
        return;
      }
      Savethisinstr();
      _imp_leave();
      return;
    }
    Flushbuffer();
    Dump2(Lab, Op, Reg, Addr);
    _imp_leave();
  }

  _imp_leave();
}
static _imp_string Name(int Ident) {
  _imp_enter();
  if (0 > Ident || Ident > 255 || Namedlink[Ident] == 0) {
    return (_imp_str_literal(""));
  }
  return (*String(Addr(Named[Namedlink[Ident]])));      // CHEK THAT THIS WORKS.  MAPPING AN IMP STRING.
}
static int Newtag(void) {
  _imp_enter();
  int I;
  if (!Tagasl) {
    Fault(_imp_str_literal("TAG SPACE FULL"));
    _imp_leave();
    exit(0);
  }
  I = Tagasl;
  Tagasl = Link[Tagasl];
  return (I);
}
static int Returntag(int Tagi) {
  _imp_enter();
  int L;
  L = Link[Tagi];
  Link[Tagi] = Tagasl;
  Tagasl = Tagi;
  return (L);
}
static int Getwork(void) {
  _imp_enter();
  return (0);
}
static void Returnwork(int Work) {
  _imp_enter();

  _imp_leave();
}
static void Clearwork(void) {
  _imp_enter();
  int Cell;
  Cell = Worklist[Level];
  while (Cell) Cell = Returntag(Cell);
  Worklist[Level] = 0;
  _imp_leave();
}
#ifdef NEVER
static int Getcoti(int Const) {
  _imp_enter();
  int Coti;
  if (Cotp > 0)
    for (Coti = 0; Coti <= Cotp - 1; Coti++)
      if (Cot[Coti] == Const) return (Coti);
  if (Cotp == 128) {
    Fault(_imp_str_literal("CONSTANT TABLE FULL"));
    _imp_leave();
    exit(0);
  }
  Cot[Cotp] = Const;
  Cotp++;
  return (Cotp - 1);
}
#endif
static void Pushtag(int Ident, int Form, int Type, int Dim, int Level,
                    int Rad) {
  _imp_enter();
  int Tagi;
  if (Taglink[Ident] != 0 &&
      ((unsigned)Tag[Taglink[Ident]] >> 16 & 0xF) == Level)
    Fault(
        _imp_join(_imp_str_literal("NAME "),
                  _imp_join(Name(Ident), _imp_str_literal(" DECLARED TWICE"))));
  Tagi = Newtag();
  Tag[Tagi] = Form << 28 | Type << 24 | Dim << 20 | Level << 16 | Rad;
  Link[Tagi] = Taglink[Ident];
  Taglink[Ident] = Tagi;
  Tagi = Newtag();
  Tag[Tagi] = Ident;
  Link[Tagi] = Namelist[Level];
  Namelist[Level] = Tagi;
  _imp_leave();
}
static void Poptags(void) {
  _imp_enter();
  int Cell;
  int Ident;
  int Nametag;
  int Params;
  _imp_string S;
  if (Tagsopt == 1) Newline();
  Cell = Namelist[Level];
  while (Cell) {
    Ident = Tag[Cell];
    Cell = Returntag(Cell);
    Nametag = Tag[Taglink[Ident]];
    Taglink[Ident] = Returntag(Taglink[Ident]);
    if (Tagsopt == 1) {
      S = Name(Ident);
      Printstring(
          _imp_join(Strint(Ident, 3), _imp_join(_imp_str_literal("   "), S)));
      Spaces(10 - *Length(S));
      Printstring(Strhex(Nametag));
    }
    if ((unsigned)Nametag >> 28 == 4) {
      Params = (unsigned)Nametag >> 20 & 0xF;
      while (Params) {
        if (Tagsopt == 1)
          Printstring(_imp_join(_imp_str_literal("\n                    "),
                                Strhex(Tag[Taglink[Ident]])));
        Taglink[Ident] = Returntag(Taglink[Ident]);
        Params--;
      }
    }
    if (Tagsopt == 1) Newline();
    if (!Taglink[Ident]) {
      Namedp = Namedlink[Ident];
      Namedlink[Ident] = 0;
    }
  }
  if (Tagsopt == 1) Newline();
  Namelist[Level] = 0;
  _imp_leave();
}
static int Getlabel(int Constp) {
  _imp_enter();
  int Label;
  Label = A[Constp + 1];
  if (Label > 9999) {
    Fault(
        _imp_join(_imp_str_literal("LABEL "),
                  _imp_join(Strint(Label, 1), _imp_str_literal(" TOO LARGE"))));
    return (-1);
  } else
    return (Label);
}
static void Filllabel(int Label) {
  _imp_enter();
  if (Label < 0) {
    _imp_leave();
    return;
  }
  Dump(_imp_join(_imp_str_literal("L"), S(Label)), _imp_str_literal("EQU"),
       _imp_str_literal(""), _imp_str_literal("*"));
  _imp_leave();
}
#ifdef NEVER
static int Fillbranch(int Label) {
  _imp_enter();
  int Cell;
  int Cad;
  if (Label < 0) return (0);
  Cell = Branchlist[Level];
  while (Cell) {
    if ((unsigned)Tag[Cell] >> 16 == Label) {
      Cad = Tag[Cell] & 0x7FFF;
      if (Tag[Cell] & 0x8000) Tag[Cell] = Label << 16 | 0x8000 | Nextcad;
      return (Cad);
    }
    Cell = Link[Cell];
  }
  Cell = Newtag();
  Link[Cell] = Branchlist[Level];
  Branchlist[Level] = Cell;
  Tag[Cell] = Label << 16 | 0x8000 | Nextcad;
  return (0);
}
#endif
static void Poplabels(void) {
  _imp_enter();
  int Cell;
  Cell = Branchlist[Level];
  while (Cell) {
    if (Tag[Cell] & 0x8000)
      Fault(_imp_join(
          _imp_str_literal("LABEL "),
          _imp_join(Strint((unsigned)Tag[Cell] >> 16, 1),
                    _imp_join(_imp_str_literal(" NOT SET (BRANCH LIST "),
                              _imp_join(Strint(Tag[Cell] & 0x7FFF, 1),
                                        _imp_str_literal(")"))))));
    Cell = Returntag(Cell);
  }
  Branchlist[Level] = 0;
  _imp_leave();
}
static int Nextplabel(void) {
  _imp_enter();
  static int Plabel = 9999;
  Plabel++;
  return (Plabel);
}
static void Pushstart(int Flag, int Plab) {
  _imp_enter();
  int Cell;
  Cell = Newtag();
  Tag[Cell] = (Flag << 16) | (Plab & 0xFFFF);
  Link[Cell] = Startlist[Level];
  Startlist[Level] = Cell;
  _imp_leave();
}
static int /* boolean */ Find(int Type, int *T, int *Lab) {
  _imp_enter();
  int Cell;
  Cell = Startlist[Level];
  while (Cell) {
    *T = (unsigned)Tag[Cell] >> 16;
    if ((*T & 2) == Type) {
      *Lab = Tag[Cell] & 0xFFFF;
      return (1);
    }
    Cell = Link[Cell];
  }
  *T = 0;
  *Lab = 0;
  return (0);
}
static void Findcontinue(int *Type, int *Lab) {
  _imp_enter();
  if (Find(2, Type, Lab))
    *Lab = *Lab + 1;
  else {
    *Type = 0;
    *Lab = 0;
    Fault(_imp_str_literal("%CYCLE MISSING"));
  }
  _imp_leave();
}
static void Findexit(int *Type, int *Lab) {
  _imp_enter();
  if (Find(2, Type, Lab))
    *Lab = *Lab + 2;
  else {
    *Type = 0;
    *Lab = 0;
    Fault(_imp_str_literal("%CYCLE MISSING"));
  }
  _imp_leave();
}
static int /* boolean */ Findcycle(void) {
  _imp_enter();
  int T;
  int L;
  if (Find(2, &T, &L)) return (1);
  return (0);
}
static int /* boolean */ Findstart(void) {
  _imp_enter();
  int T;
  int L;
  if (Find(0, &T, &L)) return (1);
  return (0);
}
static void Popcycle(int *Type, int *Lab) {
  _imp_enter();
  Popitem(Type, Lab);
  if (!(*Type & 2)) {
    if (Findcycle())
      Fault(_imp_str_literal("%FINISH MISSING {Or spurious %REPEAT??}"));
    else {
      Fault(_imp_str_literal("SPURIOUS %REPEAT"));
      if (*Lab) Pushstart(*Type, *Lab);
    }
    *Lab = 0;
    *Type = 3;
  }
  _imp_leave();
}
static void Popstart(int *Type, int *Lab) {
  _imp_enter();
  Popitem(Type, Lab);
  if ((*Type & 2) == 2 || *Lab == 0) {
    if (Findstart())
      Fault(_imp_str_literal("%REPEAT MISSING {Or spurious %FINISH??}"));
    else {
      Fault(_imp_str_literal("SPURIOUS %FINISH"));
      if (*Lab) Pushstart(*Type, *Lab);
    }
    *Lab = 0;
    *Type = 0;
  }
  _imp_leave();
}
static void Popitem(int *Flag, int *Plab) {
  _imp_enter();
  int Cell;
  Cell = Startlist[Level];
  if (!Cell) {
    *Flag = 0;
    *Plab = 0;
  } else {
    *Flag = (unsigned)Tag[Cell] >> 16;
    *Plab = Tag[Cell] & 0xFFFF;
    if (*Plab == 0xFFFF) *Plab = -1;
    Startlist[Level] = Returntag(Cell);
  }
  _imp_leave();
}
static void Clearstart(void) {
  _imp_enter();
  int Cell;
  static const _imp_string What[2 /*0:1*/] = {_imp_str_literal("%FINISH"),
                                              _imp_str_literal("%REPEAT")};
  Cell = Startlist[Level];
  while (Cell) {
    Fault(_imp_join(What[(unsigned)Tag[Cell] >> 17],
                    _imp_str_literal(" MISSING")));
    Cell = Returntag(Cell);
  }
  Startlist[Level] = 0;
  _imp_leave();
}
static int Enter(void) {
  _imp_enter();
$undef Regs
  static _imp_string Regs[2 /*1:2*/] = {_imp_str_literal("A"),
                                        _imp_str_literal("A,B")};
$define Regs[X] Regs[(X)-1]
  _imp_string Base;
  int Alloc;
  int Dim;
  if (Level == 1) {
    if (Nextcad != 1) Fault(_imp_str_literal("%BEGIN NOT FIRST STATEMENT"));
    Dump(_imp_str_literal(""), _imp_str_literal("ORG"), _imp_str_literal(""),
         _imp_str_literal("$F800"));
    Dump(_imp_str_literal("START"), _imp_str_literal("EQU"),
         _imp_str_literal(""), _imp_str_literal("*"));
    if (Traceopt == 1)
      Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"),
           _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("U"),
         _imp_str_literal("#STACK"));
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("X"),
         _imp_str_literal("-USTK,U"));
    Base = _imp_str_literal(",X");
    Alloc = 34;
  } else {
    if (Level > 2)
      Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("Y"),
           Display[Level - 1]);
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("S"),
         _imp_str_literal("Y"));
    Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""),
         _imp_str_literal("S,Y"));
    Alloc = 0;
    Base = _imp_str_literal(",Y");
  }
  if (Level != 1)
    ;
  else
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_join(_imp_str_literal("-A"),
                   _imp_join(S(Rt[Level]), _imp_str_literal(",X"))));
  Nextrad[Level] = Alloc;
  return (Alloc);
}
static void Dumpreturn(void) {
  _imp_enter();
  Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""),
       _imp_str_literal("Y,S"));
  Dump(_imp_str_literal(""), _imp_str_literal("PUL"), _imp_str_literal("S"),
       _imp_str_literal("Y,PC"));
  _imp_leave();
}
static void Array(int Arrayp) {
  _imp_enter();
  int Namep;
  int Actualp;
  int Exprp;
  int Exprsp;
  int Ident;
  int Nametag;
  int Basep;
  int Disp;
  _imp_string Base;
  Namep = A[Arrayp + 1];
  Actualp = A[Arrayp + 2];
  Ident = A[Namep + 1];
  if (A[Actualp] == 1) {
    Dump(_imp_str_literal("  "), _imp_str_literal("CLR"), _imp_str_literal("A"),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("ANDCC"), _imp_str_literal(""),
         _imp_str_literal("0"));
    Exprp = A[Actualp + 1];
    Exprsp = A[Actualp + 2];
    Expr(Exprp);
    Nametag = Tag[Taglink[Ident]];
    Basep = (unsigned)Nametag >> 16 & 0xF;
    Base = Display[Basep];
    if (Basep == Level) Base = _imp_str_literal(",Y");
    if (Basep == 1) Base = _imp_str_literal(",X");
    Disp = Nametag & 0xFFFF;
    Dump(_imp_str_literal(""), _imp_str_literal("BCC"), _imp_str_literal(""),
         _imp_str_literal("*+3"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal("A"),
         _imp_str_literal(""));
    if (Basep == 1 || Basep == Level)
      Dump(_imp_str_literal(""), _imp_str_literal("ADD"), _imp_str_literal("D"),
           _imp_join(_imp_str_literal("-"), _imp_join(S(Disp), Base)));
    else {
      Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
           _imp_str_literal("A,B"));
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("D"),
           Display[Basep]);
      Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("D"),
           _imp_join(_imp_str_literal("#"), S(Disp)));
      Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("D"),
           _imp_str_literal("0,X"));
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("D"),
           _imp_str_literal("[0,X]"));
      Dump(_imp_str_literal(""), _imp_str_literal("ADD"), _imp_str_literal("D"),
           _imp_str_literal(",U++"));
    }
    if (!Aopt)
      Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("D"),
           _imp_str_literal("0,X"));
    Aopt = 0;
    if (A[Exprsp] == 1)
      Fault(_imp_join(
          _imp_str_literal("ARRAY "),
          _imp_join(Name(Ident), _imp_str_literal(" HAS EXTRA INDEX"))));
  } else
    Fault(_imp_join(_imp_str_literal("ARRAY "),
                    _imp_join(Name(Ident), _imp_str_literal(" HAS NO INDEX"))));
  _imp_leave();
}
static void Proc(int Procp) {
  _imp_enter();
  _imp_string Opn;                    // CHECK THE IMP SOURCE.  %string or %string(*)%name????   ALSO SIMILAR IN Cond()
  _imp_string Base;
  _imp_string Reg;
  int Namep;
  int Ident;
  int Nametag;
  int Ptagl;
  int L;
  int Actualp;
  int Exprp;
  int Unaryp;
  int Operandp;
  int Npars;
  int Ptag;
  int Pnamep;
  int Pident;
  int Pnametag;
  int Pactualp;
  int Disp;
  int Exprrestp;
  int Exprsp;
  int Oldparams;
  int Basep;
  int Size;
  if (Params >= 2)
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_join(_imp_str_literal("-"),
                   _imp_join(S(Params + 1), _imp_str_literal(",S"))));
  Oldparams = Params;
  Params = 4;
  Namep = A[Procp + 1];
  Actualp = A[Procp + 2];
  Ident = A[Namep + 1];
  L = Taglink[Ident];
  Nametag = Tag[L];
  Ptagl = Link[L];
  Npars = (unsigned)Nametag >> 20 & 0xF;
  if (!Npars) {
    if (A[Actualp] == 1) {
      Fault(_imp_join(Name(Ident), _imp_str_literal(" HAS PARAMETERS")));
      _imp_leave();
      return;
    }
  } else {
    if (A[Actualp] == 2) {
      Fault(_imp_join(Name(Ident), _imp_str_literal(" MISSING PARAMETERS")));
      _imp_leave();
      return;
    }
    Exprp = A[Actualp + 1];
    Exprsp = A[Actualp + 2];
    for (;;) {
      Ptag = Tag[Ptagl];
      if (!((unsigned)Ptag >> 28)) {
        Expr(Exprp);
        Reg = _imp_str_literal("B");
      } else {
        Reg = _imp_str_literal("D");
        Unaryp = A[Exprp + 1];
        Operandp = A[Exprp + 2];
        Exprrestp = A[Exprp + 3];
        if (A[Unaryp] != 4 || A[Operandp] != 1 || A[Exprrestp] != 2)
          Fault(_imp_str_literal("NOT A %NAME PARAMETER"));
        else {
          Pnamep = A[Operandp + 1];
          Pactualp = A[Operandp + 2];
          Pident = A[Pnamep + 1];
          if (!Taglink[Pident])
            Dump(_imp_str_literal(""), _imp_str_literal("LD"),
                 _imp_str_literal("B"), Name(Pident));
          else {
            Pnametag = Tag[Taglink[Pident]];
            if ((unsigned)Pnametag >> 28 == 4)
              Fault(_imp_join(Name(Pident), _imp_str_literal(" NOT A %NAME")));
            else {
              Basep = (unsigned)Pnametag >> 16 & 0xF;
              Base = Display[Basep];
              Disp = Pnametag & 0xFFFF;
              if (Basep == Level) Base = _imp_str_literal("Y");
              if (Basep == 1) Base = _imp_str_literal("X");
              if ((unsigned)Ptag >> 28 == 1)
                if ((unsigned)Pnametag >> 28 >= 2) {
                  Aopt = 1;
                  Array(Operandp);
                } else {
                  if ((unsigned)Pnametag >> 28 == 1)
                    if (1 < Basep && Basep < Level) {
                      Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                           Base);
                      Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg,
                           _imp_join(_imp_str_literal("#"), S(Disp)));
                      Dump(_imp_str_literal(""), _imp_str_literal("ST"), Reg,
                           _imp_str_literal("0,X"));
                      Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                           _imp_str_literal("[0,X]"));
                    } else
                      Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                           _imp_join(_imp_str_literal("-"),
                                     _imp_join(S(Disp),
                                               _imp_join(_imp_str_literal(","),
                                                         Base))));
                  else if (1 < Basep && Basep < Level) {
                    Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                         Base);
                    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg,
                         _imp_join(_imp_str_literal("#"), S(Disp)));
                  } else {
                    if (Basep == 1 && 1 == Level) {
                      Dump(_imp_str_literal(""), _imp_str_literal("LEA"),
                           _imp_str_literal("Y"),
                           _imp_join(
                               _imp_str_literal("-"),
                               _imp_join(S(Disp), _imp_str_literal(",X"))));
                      Reg = _imp_str_literal("Y");
                    } else {
                      Dump(_imp_str_literal(""), _imp_str_literal("TFR"),
                           _imp_str_literal(""),
                           _imp_join(Base, _imp_str_literal(",D")));
                      Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg,
                           _imp_join(_imp_str_literal("#"), S(Disp)));
                    }
                  }
                  if (A[Pactualp] == 1)
                    Fault(_imp_join(Name(Pident),
                                    _imp_str_literal(" DECLARED AS SCALAR")));
                }
              else {
                if (_imp_strcmp(Base, _imp_str_literal("Y")) == 0 ||
                    _imp_strcmp(Base, _imp_str_literal("X")) == 0)
                  Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                       _imp_join(
                           _imp_str_literal("-"),
                           _imp_join(S(Disp),
                                     _imp_join(_imp_str_literal(","), Base))));
                else {
                  Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg, Base);
                  Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg,
                       _imp_join(_imp_str_literal("#"), S(Disp)));
                  Dump(_imp_str_literal(""), _imp_str_literal("ST"), Reg,
                       _imp_str_literal("0,X"));
                  Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                       _imp_str_literal("[0,X]"));
                }
                if (A[Pactualp] == 1)
                  Fault(_imp_join(
                      _imp_str_literal("%ARRAYNAME "),
                      _imp_join(Name(Pident), _imp_str_literal(" HAS INDEX"))));
              }
            }
          }
        }
      }
      if (_imp_strcmp(Reg, _imp_str_literal("D")) == 0 ||
          _imp_strcmp(Reg, _imp_str_literal("Y")) == 0)
        Size = 2;
      else
        Size = 1;
      Params += Size;
      Dump(_imp_str_literal(""), _imp_str_literal("ST"), Reg,
           _imp_join(_imp_str_literal("-"),
                     _imp_join(S(Params), _imp_str_literal(",S"))));
      Npars--;
      if (!Npars) {
        if (A[Exprsp] == 1)
          Fault(_imp_join(Name(Ident),
                          _imp_str_literal(" HAS EXTRA PARAMETERS")));
        break;
      }
      Ptagl = Link[Ptagl];
      if (A[Exprsp] == 2) {
        Fault(
            _imp_join(Name(Ident), _imp_str_literal(" IS MISSING PARAMETERS")));
        break;
      }
      Exprp = A[Exprsp + 1];
      Exprsp = A[Exprsp + 2];
    }
  }
  if (!((unsigned)Nametag >> 16 & 0xF))
    Base = _imp_str_literal("EXT");
  else
    Base = _imp_str_literal("E");
  if (!((unsigned)Nametag >> 16 & 0xF)) Used[Nametag & 0xF] = 1;
  Dump(_imp_str_literal(""), _imp_str_literal("LBSR"), _imp_str_literal(""),
       _imp_join(Base, S(Nametag & 0xFFFF)));
  Params = Oldparams;
  if (Params >= 2)
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_join(S(Params + 1), _imp_str_literal(",S")));
  _imp_leave();
}
static void Endofprog(void) {
  _imp_enter();
  int I;
  Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("2"),
       _imp_str_literal(""));
  Dump(_imp_str_literal("STACK"), _imp_str_literal("EQU"), _imp_str_literal(""),
       _imp_str_literal("$0800-1"));
  Dump(_imp_str_literal("USTK"), _imp_str_literal("EQU"), _imp_str_literal(""),
       _imp_str_literal("$20"));
  if (Used[12] == 1) {
    Dump(_imp_str_literal("DOSHL"), _imp_str_literal("LSL"),
         _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("A"),
         _imp_str_literal("#1"));
    Dump(_imp_str_literal("SHL"), _imp_str_literal("CMP"),
         _imp_str_literal("A"), _imp_str_literal("#0"));
    Dump(_imp_str_literal(""), _imp_str_literal("BGT"), _imp_str_literal(""),
         _imp_str_literal("DOSHL"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""),
         _imp_str_literal(""));
  }
  if (Used[13] == 1) {
    Dump(_imp_str_literal("DOSHR"), _imp_str_literal("LSR"),
         _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("A"),
         _imp_str_literal("#1"));
    Dump(_imp_str_literal("SHR"), _imp_str_literal("CMP"),
         _imp_str_literal("A"), _imp_str_literal("#0"));
    Dump(_imp_str_literal(""), _imp_str_literal("BGT"), _imp_str_literal(""),
         _imp_str_literal("DOSHR"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""),
         _imp_str_literal(""));
  }
  if (Used[14] == 1) {
    Dump(_imp_str_literal("EXP"), _imp_str_literal("PSH"),
         _imp_str_literal("S"), _imp_str_literal("B"));
    Dump(_imp_str_literal("EXP2"), _imp_str_literal("CMP"),
         _imp_str_literal("A"), _imp_str_literal("#1"));
    Dump(_imp_str_literal(""), _imp_str_literal("BGT"), _imp_str_literal(""),
         _imp_str_literal("DOEXP"));
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_str_literal("1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""),
         _imp_str_literal(""));
    Dump(_imp_str_literal("DOEXP"), _imp_str_literal("PSH"),
         _imp_str_literal("U"), _imp_str_literal("A"));
    Dump(_imp_str_literal(""), _imp_str_literal("LDA"), _imp_str_literal(""),
         _imp_str_literal("0,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("MUL"), _imp_str_literal(""),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("PUL"), _imp_str_literal("U"),
         _imp_str_literal("A"));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("A"),
         _imp_str_literal("#1"));
    Dump(_imp_str_literal(""), _imp_str_literal("BRA"), _imp_str_literal(""),
         _imp_str_literal("EXP2"));
  }
  if (Used[15] == 1) {
    Dump(_imp_str_literal("DIV"), _imp_str_literal("EQU"), _imp_str_literal(""),
         _imp_str_literal("*"));
    Dump(_imp_str_literal(""), _imp_str_literal("CLR"), _imp_str_literal(""),
         _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("CLR"), _imp_str_literal(""),
         _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""),
         _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("TST"), _imp_str_literal("B"),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BGE"), _imp_str_literal(""),
         _imp_str_literal("TRYA"));
    Dump(_imp_str_literal(""), _imp_str_literal("NEG"), _imp_str_literal("B"),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("CLR"), _imp_str_literal(""),
         _imp_str_literal("-2,S"));
    Dump(_imp_str_literal("TRYA"), _imp_str_literal("TST"),
         _imp_str_literal("A"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BGE"), _imp_str_literal(""),
         _imp_str_literal("OK"));
    Dump(_imp_str_literal(""), _imp_str_literal("NEG"), _imp_str_literal("A"),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("TST"), _imp_str_literal(""),
         _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""),
         _imp_str_literal("OK"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""),
         _imp_str_literal("-2,S"));
    Dump(_imp_str_literal("OK"), _imp_str_literal("TST"), _imp_str_literal("B"),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BLT"), _imp_str_literal(""),
         _imp_str_literal("DONE"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""),
         _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"),
         _imp_str_literal("A"));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("B"),
         _imp_str_literal(",U+"));
    Dump(_imp_str_literal(""), _imp_str_literal("BRA"), _imp_str_literal(""),
         _imp_str_literal("OK"));
    Dump(_imp_str_literal("DONE"), _imp_str_literal("DEC"),
         _imp_str_literal(""), _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("TST"), _imp_str_literal(""),
         _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""),
         _imp_str_literal("RET"));
    Dump(_imp_str_literal(""), _imp_str_literal("NEG"), _imp_str_literal(""),
         _imp_str_literal("-1,S"));
    Dump(_imp_str_literal("RET"), _imp_str_literal("LD"), _imp_str_literal("B"),
         _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""),
         _imp_str_literal(""));
  } else
    Dump(_imp_str_literal("DIV"), _imp_str_literal("EQU"), _imp_str_literal(""),
         _imp_str_literal("0"));
  if (Pstr) {
    Dump(_imp_str_literal("OUTCH"), _imp_str_literal("LD"),
         _imp_str_literal("A"), _imp_str_literal("ACIAS"));
    Dump(_imp_str_literal(""), _imp_str_literal("AND"), _imp_str_literal("A"),
         _imp_str_literal("#2"));
    Dump(_imp_str_literal(""), _imp_str_literal("BEQ"), _imp_str_literal(""),
         _imp_str_literal("OUTCH"));
    Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("B"),
         _imp_str_literal("ACIAD"));
    Dump(_imp_str_literal("WAITX"), _imp_str_literal("LD"),
         _imp_str_literal("B"), _imp_str_literal("#$FF"));
    Dump(_imp_str_literal(""), _imp_str_literal("DEC"), _imp_str_literal("B"),
         _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""),
         _imp_str_literal("WAITX"));
    Dump(_imp_str_literal("PSTR"), _imp_str_literal("LD"),
         _imp_str_literal("B"), _imp_str_literal("[0,S]"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""),
         _imp_str_literal("1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""),
         _imp_str_literal("NOCAR"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""),
         _imp_str_literal("0,S"));
    Dump(_imp_str_literal("NOCAR"), _imp_str_literal("CMP"),
         _imp_str_literal("B"), _imp_str_literal("#$80"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""),
         _imp_str_literal("OUTCH"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""),
         _imp_str_literal(""));
  }
  if (Faults > 0) {
    int St;
    St = Outstream();
    Printstring(_imp_join(_imp_str_literal("Program contains "),
                          _imp_join(S(Faults), _imp_str_literal(" fault"))));
    if (Faults > 1) Printsymbol('s');
    Newline();
    Selectoutput(St);
  }
  Newline();
  if (Faults > 0)
    Printstring(_imp_join(_imp_str_literal("?"), Strint(Faults, 4)));
  else
    Printstring(_imp_str_literal("*NO"));
  Printstring(_imp_str_literal(" FAULT"));
  if (Faults != 1) Printsymbol('S');
  Printstring(_imp_str_literal(" IN THIS PROGRAM\n"));
  {
    _imp_string Param = _imp_str_literal("");
    //if (Instream()) Closeinput();
    //Selectinput(0);
    //if (Outstream()) Closeoutput();
    //Selectoutput(0);
    _imp_leave();
    _imp_signal(13,0,0,_imp_str_literal("compilation complete"));
  }

  _imp_leave();
}
static const int Proceedure = -1;
static const int Arrayelement = -2;
static const int Scalar = -3;
static const int Unary = 11;
static const int Complex = -2;
static const int Terminal = 0;
static const int True = 1;
static const int Load = 0;
static const int Exp = 6;
static const int Sub = 10;
static const int Mult = 8;
static const int Div = 7;
static const int Shr = 2;
static const int Shl = 1;
static const int Cmp = 13;
static int Intstr(_imp_string Val) {
  _imp_enter();
  int I;
  int Total;
  Total = 0;
  for (I = 1; I <= *Length(Val); I++)
    Total = Total * 10 + *Charno(Val, I) - '0';
  return (Total);
}
static void Expr(int Exprp) {
  _imp_enter();
  auto int Totree(int Exprp);
  auto void Evaluate(int Exprp);
  auto void Opn(int Op, int Ptr);
  int Tree[64 /*1:64*/];
$define Tree[X] Tree[(X)-1]
  int Treep;
  int Treenode;
  int Treenode1;
  int Treenode2;
  int Testp;
  int Expr1p;
  int Expr2p;
  int Compp;
  int I;
  int J;
  int L;
  // <COMP>='=','#','<=','<','>=','>';  (possibly \= for # ?)
  static const int Reversecomp[6 /*1:6*/] = {1, 2, 5, 6, 3, 4};
$define Reversecomp[X] Reversecomp[(X)-1]
  Treep = 1;
  if (!Condflag)
    Treenode = Totree(Exprp);  // <EXPR><COMP><EXPR>,'('<COND>')';
  else {
    Condflag = 0;
    Testp = Exprp;             // <EXPR><COMP><EXPR>,'('<COND>')';
    Expr1p = A[Testp + 1];
    Compp = A[Testp + 2];
    Expr2p = A[Testp + 3];
    Treenode1 = Totree(Expr1p);
    Treenode2 = Totree(Expr2p);
    Tree[Treep] = 13;
    if (Tree[Treenode1] == -4) {
      A[Compp] = Reversecomp[A[Compp]];
      Tree[Treep + 1] = Treenode2;
      Tree[Treep + 2] = Treenode1;
    } else {
      Tree[Treep + 1] = Treenode1;
      Tree[Treep + 2] = Treenode2;
    }
    Treenode = Treep;
  }
  if (Expropt == 1) {
    Newline();
    if (0 < Tree[Treenode] && Tree[Treenode] <= 10)
      L = Treenode + 2;
    else
      L = Treenode + 1;
    J = 0;
    for (I = 1; I <= L; I++) {
      Write(Tree[I], 4);
      J += 5;
      if (I == Treenode) {
        Printstring(_imp_str_literal("*"));
        J++;
      }
      if (Tree[I] == -3) {
        I++;
        Printstring(_imp_join(_imp_str_literal("  "), Strhex(Tree[I])));
        J += 10;
      }
      if (J > 70) {
        Newline();
        J = 0;
      }
    }
    Newlines(2);
  }
  Evaluate(Treenode);
  _imp_leave();
  return;
  int Totree(int Exprp) {
    _imp_enter();
    auto void Pseval(int Type, int Datum);
    int Os[4 /*1:4*/];
$define Os[X] Os[(X)-1]
    int Ps[5 /*1:5*/];
$define Ps[X] Ps[(X)-1]
    int Osp;
    int Psp;
    int Unaryp;
    int Operandp;
    int Exprrestp;
    int Opp;
    int Namep;
    int Actualp;
    int Ident;
    int Nametag;
    static const int Prec[12 /*1:12*/] = {3, 3, 2, 1, 1, 3, 2, 2, 1, 1, 1, 4};
$define Prec[X] Prec[(X)-1]
    int Constop(int Op, int Val1) {
      _imp_enter();
      static int Exec_sw;
      static void *Exec[10 /*1:10*/] = {
          &&Exec_1, &&Exec_2, &&Exec_3, &&Exec_4, &&Exec_5,
          &&Exec_6, &&Exec_7, &&Exec_8, &&Exec_9, &&Exec_10,
      };
      int Res;
      goto *Exec[Exec_sw = (Op)-1];
    Exec_1:;
      Res = Tree[Val1 + 1] << Tree[Val1 + 3];
      goto Cont;
    Exec_2:;
      Res = (unsigned)Tree[Val1 + 1] >> Tree[Val1 + 3];
      goto Cont;
    Exec_3:;
      Res = Tree[Val1 + 1] & Tree[Val1 + 3];
      goto Cont;
    Exec_4:;
      Res = Tree[Val1 + 1] ^ Tree[Val1 + 3];
      goto Cont;
    Exec_5:;
      Res = Tree[Val1 + 1] | Tree[Val1 + 3];
      goto Cont;
    Exec_6:;
      Res = IEXP(Tree[Val1 + 1], Tree[Val1 + 3]);
      goto Cont;
    Exec_7:;
      if (!Tree[Val1 + 3]) {
        Fault(_imp_str_literal("DIVISION BY ZERO"));
        Res = 0;
        goto Cont;
      }
      Res = Tree[Val1 + 1] / Tree[Val1 + 3];
      goto Cont;
    Exec_8:;
      Res = Tree[Val1 + 1] * Tree[Val1 + 3];
      goto Cont;
    Exec_9:;
      Res = Tree[Val1 + 1] + Tree[Val1 + 3];
      goto Cont;
    Exec_10:;
      Res = Tree[Val1 + 1] - Tree[Val1 + 3];
    Cont:;
      return (Res);
    }
    Unaryp = A[Exprp + 1];
    Operandp = A[Exprp + 2];
    Exprrestp = A[Exprp + 3];
    if (A[Unaryp] <= 2) {
      Os[1] = A[Unaryp] + 10;
      Osp = 1;
    } else
      Osp = 0;
    Psp = 0;
    for (;;) {
      if (A[Operandp] == 1) {
        Namep = A[Operandp + 1];
        Actualp = A[Operandp + 2];
        Ident = A[Namep + 1];
        if (!Taglink[Ident]) {
          Pseval(-3, -Ident);
        } else {
          Nametag = Tag[Taglink[Ident]];
          if ((unsigned)Nametag >> 28 <= 1)
            if (A[Actualp] == 1) {
              Fault(_imp_join(
                  _imp_str_literal("SCALAR "),
                  _imp_join(Name(Ident), _imp_str_literal(" HAS PARAMETER"))));
              Pseval(-3, 0);
            } else
              Pseval(-3, Nametag);
          else if ((unsigned)Nametag >> 28 <= 3)
            Pseval(-2, Operandp);
          else if (!((unsigned)Nametag >> 24 & 0xF)) {
            Fault(_imp_join(
                _imp_str_literal("ROUTINE NAME "),
                _imp_join(Name(Ident), _imp_str_literal(" IN EXPRESSION"))));
            Pseval(-3, 0);
          } else
            Pseval(-1, Operandp);
        }
      } else if (A[Operandp] == 2)
        Pseval(-4, A[A[Operandp + 1] + 1]);
      else {
        Psp++;
        Ps[Psp] = Totree(A[Operandp + 1]);
      }
      if (A[Exprrestp] == 2) break;
      Opp = A[Exprrestp + 1];
      Operandp = A[Exprrestp + 2];
      Exprrestp = A[Exprrestp + 3];
      while (Osp > 0 && Prec[A[Opp]] <= Prec[Os[Osp]]) {
        Pseval(Os[Osp], 0);
        Osp--;
      }
      Osp++;
      Os[Osp] = A[Opp];
    }
    while (Osp > 0) {
      Pseval(Os[Osp], 0);
      Osp--;
    }
    return (Ps[1]);
    void Pseval(int Type, int Datum) {
      _imp_enter();
      auto void Store(int T);
      int Nodep;
      int Temp;
      Nodep = Treep;
      Store(Type);
      if (Type > 0)
        if (Type > 10)
          Store(Ps[Psp]);
        else if (Tree[Ps[Psp - 1]] == -4 && Tree[Ps[Psp]] == -4 &&
                 Ps[Psp - 1] == Treep - 5 && Ps[Psp] == Treep - 3) {
          Temp = Constop(Type, Treep - 5);
          if (Temp >= 0) {
            Treep = Ps[Psp - 1] + 2;
            Tree[Ps[Psp - 1] + 1] = Temp;
            Psp--;
            Ps[Psp] = Treep - 2;
            _imp_leave();
            return;
          } else
            goto Over;
        } else {
        Over:;
          Store(Ps[Psp - 1]);
          Store(Ps[Psp]);
          Psp--;
        }
      else {
        Store(Datum);
        Psp++;
      }
      Ps[Psp] = Nodep;
      void Store(int T) {
        _imp_enter();
        if (Treep > 64) {
          Fault(_imp_str_literal("EXPRESSION TOO LONG"));
          _imp_leave();
          exit(0);
        }
        Tree[Treep] = T;
        Treep++;
        _imp_leave();
      }

      _imp_leave();
    }

    _imp_leave();
    fault("Reached end of %s without a %%result", __PRETTY_FUNCTION__);
  }
  static const _imp_string Strop[14 /*0:13*/] = {
      _imp_str_literal("LD"),  _imp_str_literal("SHL"), _imp_str_literal("SHR"),
      _imp_str_literal("AND"), _imp_str_literal("EOR"), _imp_str_literal("OR"),
      _imp_str_literal("EXP"), _imp_str_literal("DIV"), _imp_str_literal("MUL"),
      _imp_str_literal("ADD"), _imp_str_literal("SUB"), _imp_str_literal("NEG"),
      _imp_str_literal("COM"), _imp_str_literal("CMP")};
  static const int Args[14 /*0:13*/] = {1, 0,  0, 1, 1, 1, 0,
                                        0, -1, 1, 1, 1, 1, 1};
  static const int Commut[14 /*0:13*/] = {0, 0, 0, 1, 1, 1, 0,
                                          0, 1, 1, 0, 0, 0, 1};
  void Doop(int Op, _imp_string Val) {                                                    // Val: STRING OR STRINGNAME?
    _imp_enter();
    _imp_string Const;
    _imp_string NULLX;
    int Value;
    static int Clever_sw;
    static void *Clever[14 /*0:13*/] = {
        &&Clever_default, &&Clever_1,       &&Clever_2,       &&Clever_default,
        &&Clever_default, &&Clever_default, &&Clever_6,       &&Clever_7,
        &&Clever_8,       &&Clever_default, &&Clever_default, &&Clever_default,
        &&Clever_default, &&Clever_default,
    };
    if (Args[Op] != 1) {
      if (_imp_resolve(Val, &NULLX, _imp_str_literal("#"), &Const) && *Length(NULLX)==0) {
        Value = Intstr(Const);
        goto *Clever[Clever_sw = Op];
      Clever_8:;
        if (Value == 2 || Value == 4)
          while (Value != 1) {
            Dump(_imp_str_literal(""), _imp_str_literal("ASL"),
                 _imp_str_literal("B"), _imp_str_literal(""));
            Value = (unsigned)Value >> 1;
          }
        if (Value == 1) {
          _imp_leave();
          return;
        }
        goto Eval;
      Clever_7:;
        if (Value == 2 || Value == 4)
          while (Value != 1) {
            Dump(_imp_str_literal(""), _imp_str_literal("ASR"),
                 _imp_str_literal("B"), _imp_str_literal(""));
            Value = (unsigned)Value >> 1;
          }
        if (Value == 1) {
          _imp_leave();
          return;
        }
        goto Eval;
      Clever_6:;
        if (Value == 2) {
          Dump(_imp_str_literal(""), _imp_str_literal("TFR"),
               _imp_str_literal(""), _imp_str_literal("B,A"));
          Dump(_imp_str_literal(""), _imp_str_literal("MUL"),
               _imp_str_literal(""), _imp_str_literal(""));
          _imp_leave();
          return;
        } else
          goto Eval;
      Clever_1:;
        if (1 <= Value && Value <= 2) do {
            Dump(_imp_str_literal(""), _imp_str_literal("LSL"),
                 _imp_str_literal("B"), _imp_str_literal(""));
            Value--;
          } while (Value);
        if (3 > Value || Value > 7) {
          _imp_leave();
          return;
        }
        goto Eval;
      Clever_2:;
        if (1 <= Value && Value <= 2) do {
            Dump(_imp_str_literal(""), _imp_str_literal("LSR"),
                 _imp_str_literal("B"), _imp_str_literal(""));
            Value--;
          } while (Value);
        if (3 > Value || Value > 7) {
          _imp_leave();
          return;
        }
        goto Eval;
      Clever_default:;
      Eval:;
      }
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("A"),
           Val);
      if (Args[Op] < 0)
        Dump(_imp_str_literal(""), _imp_str_literal("MUL"),
             _imp_str_literal(""), _imp_str_literal(""));
      else
        Dump(_imp_str_literal(""), _imp_str_literal("LBSR"),
             _imp_str_literal(""), Strop[Op]);
    } else
      Dump(_imp_str_literal(""), Strop[Op], _imp_str_literal("B"), Val);
    _imp_leave();
  }
  void Opn(int Op, int Nodep) {
    _imp_enter();
    int Type;
    int Basep;
    int Varp;
    int Disp;
    _imp_string Base;
    Type = Tree[Nodep];
    if (Type > Scalar) Fault(_imp_str_literal("*BUG"));
    Varp = Tree[Nodep + 1];
    if (Varp < 0)
      Doop(Op, Name(-Varp));
    else if (Type == Scalar) {
      Basep = (unsigned)Varp >> 16 & 0xF;
      Base = Display[Basep];
      if (Basep == Level) Base = _imp_str_literal(",Y");
      if (Basep == 1) Base = _imp_str_literal(",X");
      Disp = Varp & 0xFFFF;
      if ((unsigned)Varp >> 28 == 1) {
        if (Basep == Level && Level != 1)
          Doop(Op, _imp_join(
                       _imp_str_literal("["),
                       _imp_join(
                           _imp_str_literal("-"),
                           _imp_join(S(Disp),
                                     _imp_join(Base, _imp_str_literal("]"))))));
        else if (Basep != Level && Level != 1) {
          Dump(_imp_str_literal(""), _imp_str_literal("PSH"),
               _imp_str_literal("U"), _imp_str_literal("A,B"));
          Dump(_imp_str_literal(""), _imp_str_literal("LD"),
               _imp_str_literal("D"), Base);
          Dump(_imp_str_literal(""), _imp_str_literal("ADD"),
               _imp_str_literal("D"),
               _imp_join(_imp_str_literal("#"), S(Disp)));
          Dump(_imp_str_literal(""), _imp_str_literal("ST"),
               _imp_str_literal("D"), _imp_str_literal("0,X"));
          Dump(_imp_str_literal(""), _imp_str_literal("PUL"),
               _imp_str_literal("U"), _imp_str_literal("A,B"));
          Doop(Op, _imp_str_literal("[0,X]"));
        }
        _imp_leave();
        return;
      }
      if (Basep == Level || Basep == 1)
        Doop(Op, _imp_join(_imp_str_literal("-"), _imp_join(S(Disp), Base)));
      else {
        Dump(_imp_str_literal(""), _imp_str_literal("PSH"),
             _imp_str_literal("U"), _imp_str_literal("A,B"));
        Dump(_imp_str_literal(""), _imp_str_literal("LD"),
             _imp_str_literal("D"), Base);
        Dump(_imp_str_literal(""), _imp_str_literal("ADD"),
             _imp_str_literal("D"), _imp_join(_imp_str_literal("#"), S(Disp)));
        Dump(_imp_str_literal(""), _imp_str_literal("ST"),
             _imp_str_literal("D"), _imp_str_literal("0,X"));
        Dump(_imp_str_literal(""), _imp_str_literal("PUL"),
             _imp_str_literal("U"), _imp_str_literal("A,B"));
        Doop(Op, _imp_str_literal("[0,X]"));
      }
    } else
      Doop(Op, _imp_join(_imp_str_literal("#"), S(Varp)));
    _imp_leave();
  }
  void Regop(int Op, _imp_string R1, _imp_string R2) {
    _imp_enter();
    if (Args[Op] != 1)
      if (Args[Op] < 0)
        Dump(_imp_str_literal(""), _imp_str_literal("MUL"),
             _imp_str_literal(""), _imp_str_literal(""));
      else
        Dump(_imp_str_literal(""), _imp_str_literal("LBSR"),
             _imp_str_literal(""), Strop[Op]);
    else
      Dump(_imp_str_literal(""), Strop[Op], R1, R2);
    _imp_leave();
  }
  void Loadb(int Nodep) {
    _imp_enter();
    int Type;
    int Datum;
    Type = Tree[Nodep];
    Datum = Tree[Nodep + 1];
    if (Type == Proceedure) {
      Proc(Datum);
      _imp_leave();
      return;
    }
    if (Type == Arrayelement) {
      Array(Datum);
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("B"),
           _imp_str_literal("[0,X]"));
      _imp_leave();
      return;
    }
    Opn(Load, Nodep);
    _imp_leave();
  }
  void Evaluate(int Nodep) {
    _imp_enter();
    int Op;
    int Opd1p;
    int Opd2p;
    if (Tree[Nodep] <= Terminal) {
      Loadb(Nodep);
      _imp_leave();
      return;
    }
    Op = Tree[Nodep];
    Opd1p = Tree[Nodep + 1];
    if (Cmp > Op && Op >= Unary) {
      Evaluate(Opd1p);
      Dump(_imp_str_literal(""), Strop[Op], _imp_str_literal("B"),
           _imp_str_literal(""));
      _imp_leave();
      return;
    }
    Opd2p = Tree[Nodep + 2];
    if (Tree[Opd1p] >= Complex)
      if (Tree[Opd2p] >= Complex) {
        Evaluate(Opd2p);
        Dump(_imp_str_literal(""), _imp_str_literal("PSH"),
             _imp_str_literal("U"), _imp_str_literal("B"));
        Evaluate(Opd1p);
        Doop(Op, _imp_str_literal(",U+"));
      } else {
        Evaluate(Opd1p);
        Opn(Op, Opd2p);
      }
    else if (Tree[Opd2p] >= Complex) {
      Evaluate(Opd2p);
      if (Commut[Op] == True) {
        Opn(Op, Opd1p);
        _imp_leave();
        return;
      }
      if (Args[Op] <= 0) {
        Dump(_imp_str_literal(""), _imp_str_literal("TFR"),
             _imp_str_literal(""), _imp_str_literal("B,A"));
        Opn(Load, Opd1p);
        Regop(Op, _imp_str_literal("B"), _imp_str_literal("A"));
      } else {
        Dump(_imp_str_literal(""), _imp_str_literal("PSH"),
             _imp_str_literal("U"), _imp_str_literal("B"));
        Opn(Load, Opd1p);
        Doop(Op, _imp_str_literal(",U+"));
      }
    } else {
      Opn(Load, Opd1p);
      Opn(Op, Opd2p);
    }
    _imp_leave();
  }

  _imp_leave();
}
static void Do(_imp_string Text) {
  _imp_enter();
  Printstring(Text);
  Newline();
  system(Text.cstr.s);
  _imp_leave();
}
static void Skimp(_imp_string Cliparam) {
  _imp_enter();
  _imp_string S;
  _imp_string Param;
  auto void Readps(void);
  auto void Readstatement(void);
  auto void Rpsym(int *L);
  auto int Findk(_imp_string * K);
  auto int Compare(int P);
  typedef struct Kdf {
    unsigned char L;
    unsigned char N;
    unsigned char A;
    unsigned char B;
  } Kdf;
  Kdf Kd[255 /*1:255*/];
$define Kd[X] Kd[(X)-1]
  _imp_string Pn[64 /*256:319*/];
$define Pn[X] Pn[(X)-256]
  int Pp[64 /*256:319*/];
$define Pp[X] Pp[(X)-256]
  int Ps[512 /*1:512*/];
$define Ps[X] Ps[(X)-1]
  int T[256 /*1:256*/];
$define T[X] T[(X)-1]
  int Tt[256 /*1:256*/];
$define Tt[X] Tt[(X)-1]
  int Tp;
  int Ap;
  int Ttp;
  int I;
  int J;
  int Psflag;

                                                                                      // STRINGS OR STRINGNAMES????
  _imp_string File;
  _imp_string Options;
  _imp_string Option;
  _imp_string As;
  
  _imp_string NULLX;
  static int Lexopt = 0;
  static int Analopt = 0;
  static int Codeopt = 1;
  static int Listopt = 1;
  static int Assmopt = 0;
  static int Shift = 32;
  static _imp_string Assopt = _imp_str_literal("");
  S = Cliparam;
  if (_imp_resolve(S, &NULLX, _imp_str_literal("/"), &Options) && *Length(NULLX)==0) {
    if (!_imp_resolve(Options, &Options, _imp_str_literal(" "), &File))
      File = _imp_str_literal("");
    do {
      if (!_imp_resolve(Options, &Option, _imp_str_literal("/"), &Options)) {
        Option = Options;
        Options = _imp_str_literal("");
      }
      if (_imp_resolve(Option, &NULLX, _imp_str_literal("NO"), &Option) && *Length(NULLX)==0)
        I = 0;
      else
        I = 1;
      if (_imp_strcmp(Option, _imp_str_literal("LEX")) == 0) {
        Lexopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("ANAL")) == 0) {
        Analopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("EXPR")) == 0) {
        Expropt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("COND")) == 0) {
        Condopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("TAGS")) == 0) {
        Tagsopt = I;
        continue;
      } else if (_imp_resolve(Option, &NULLX, _imp_str_literal("OPT="), &Assopt) && *Length(NULLX)==0) {
        Assmopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("TRACE")) == 0) {
        Traceopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("CHECK")) == 0) {
        Checkopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("LIST")) == 0) {
        Listopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("CODE")) == 0) {
        Codeopt = I;
        continue;
      } else if (_imp_strcmp(Option, _imp_str_literal("INFO")) == 0) {
        Infoopt = I;
        continue;
      }
      Printstring(_imp_join(Option, _imp_str_literal(" OPTION ?\n")));
      _imp_leave();
      exit(0);
    } while (_imp_strcmp(Options, _imp_str_literal("")) != 0);
  } else
    File = S;
  if (_imp_on_event(9, 13)) {
    if (Instream()) Closeinput();
    Selectinput(0);
    if (Outstream()) Closeoutput();
    Selectoutput(0);
    //Printstring(_imp_join(
    //    _imp_str_literal("FILE NOT FOUND - OR SOME OTHER ERROR!"), Snl));
    if (*Length(File) == 0 || (Codeopt == Listopt && Listopt == 0) || Faults > 0) {
      _imp_leave();
      exit(0);
    }
    
    Param = _imp_str_literal("");
    if (!Codeopt) Param = _imp_join(Param, _imp_str_literal("/NOOBJECT"));
    if (Listopt == 1) Param = _imp_join(Param, _imp_str_literal("/LIST"));
    Selectoutput(0);
    // https://www.6809.org.uk/asm6809/doc/asm6809.shtml
    // The NAM directive appears to be different from Fred's assembler.
    Do( _imp_join(
        _imp_join(_imp_str_literal("asm6809 "), File),
        _imp_join(
        _imp_join(_imp_str_literal(".asm --listing="), File),
        _imp_join(_imp_str_literal(".lst --define=ACIAS=\\$F000 --define=ACIAD=\\$F001 --define="), File)
       )));
    _imp_leave();
    exit(0);
  }
  Readps();
  if (*Length(File) == 0)
    Openoutput(1, _imp_str_literal("/dev/stdout"));
  else
    Openoutput(1, _imp_join(File, _imp_str_literal(".asm")));
  Selectoutput(1);
  if (*Length(File) != 0)
    Printstring(
        _imp_join(_imp_str_literal("          NAM "), _imp_join(File, Snl)));
  if (Assmopt == 1)
    Printstring(
        _imp_join(_imp_str_literal("          OPT "), _imp_join(Assopt, Snl)));
  Printstring(_imp_join(
      _imp_str_literal("\n*                File: "),
      _imp_join(File, _imp_str_literal("\n*                Options: "))));
  if (Lexopt == 1) Printstring(_imp_str_literal("/LEX "));
  if (Analopt == 1) Printstring(_imp_str_literal("/ANAL "));
  if (Expropt == 1) Printstring(_imp_str_literal("/EXPR "));
  if (Condopt == 1) Printstring(_imp_str_literal("/COND "));
  if (Tagsopt == 1) Printstring(_imp_str_literal("/TAGS "));
  if (Infoopt == 1) Printstring(_imp_str_literal("/INFO "));
  if (Traceopt == 1) Printstring(_imp_str_literal("/TRACE "));
  if (Checkopt == 1) Printstring(_imp_str_literal("/CHECK "));
  if (!Listopt) Printstring(_imp_str_literal("/NOLIST "));
  if (!Codeopt) Printstring(_imp_str_literal("/NOCODE "));
  if (Assmopt == 1) Printstring(_imp_join(_imp_str_literal("/OPT="), Assopt));
  Newline();
  if (Psflag) {
    Fault(_imp_str_literal("PHRASE STRUCTURE FAULTY"));
    _imp_leave();
    exit(0);
  }
  if (*Length(File) == 0)
    Openinput(1, _imp_str_literal("/dev/stdin"));
  else
    Openinput(1, File);
  Selectinput(1);
  for (I = Tagasl; I <= 511; I++) Link[I] = I + 1;
  for (;;) {
    Readstatement();
    Ttp = Tp - 1;
    Tp = 1;
    Ap = 1;
    if (Compare(259) == 0 || Tp != Ttp)
      Fault(_imp_str_literal("SYNTAX ?"));
    else {
      if (Analopt == 1) {
        Newline();
        J = 0;
        for (I = 1; I <= Ap - 1; I++) {
          if (A[I] < 0) {
            As = _imp_join(
                _imp_str_literal("  ("),
                _imp_join(Strint(I, 1),
                          _imp_join(_imp_str_literal("/"),
                                    _imp_join(Pn[(unsigned)A[I] << 1 >> 17],
                                              _imp_str_literal(")")))));
            Printstring(As);
            J += *Length(As);
            A[I] = A[I] & 0xFFFF;
          }
          Write(A[I], 4);
          J += 5;
          if (J > 60) {
            Newline();
            J = 0;
          }
        }
        Newlines(2);
      } else
        for (I = 1; I <= Ap - 1; I++)
          if (A[I] < 0) A[I] = A[I] & 0xFFFF;
      Statement(1);
    }
  }
fprintf(stderr, "*** EXITED NORMALLY\n");exit(0);
  void Readps(void) {
    _imp_enter();
    _imp_string Ka[128 /*1:128*/];
$define Ka[X] Ka[(X)-1]
    int Kna[128 /*1:128*/];
$define Kna[X] Kna[(X)-1]
    _imp_string K;
    int Kap;
    int Kdasl;
    int Kn;
    int I;
    int L;
    int Psp;
    int Pnp;
    int Alt;
    int *Np;
    auto void Insert(_imp_string K);
    auto void Extract(int I, _imp_string K);
    auto void Assign(int I);
    auto int Newkd(void);
    auto void Returnkd(int I);
    auto void Returnlist(int I);
    auto int Phrase(void);
    auto void Literal(void);
    auto void Keyword(void);
    Openinput(2, _imp_str_literal("skimpps.new"));
    Selectinput(2);
    if (Infoopt == 1)
      Openoutput(2, _imp_str_literal("skimpps.lis"));
    else
      Openoutput(2, _imp_str_literal("/dev/null"));
    Selectoutput(2);
    Printstring(_imp_str_literal("\n\nPHRASE STRUCTURE\n\n"));
    Kap = 1;
    for (;;) {
      Rpsym(&L);
      if (L == '$') break;
      if (L == '"') {
        K = _imp_str_literal("");
        for (;;) {
          Rpsym(&L);
          if (L == '"') break;
          if ('A' <= L && L <= 'Z') K = _imp_join(K, Tostring(L));
        }
        Ka[Kap] = K;
        Kap++;
      }
    }
    for (I = 1; I <= 26; I++) Kd[I] = (Kdf){0};
    for (I = 27; I <= 254; I++) Kd[I].B = I + 1;
    Kdasl = 27;
    I = 1;
    do {
//      Write(I, 0);
//      Newline();
      Insert(Ka[I]);
      I++;
    } while (I != Kap);
    Kn = 128;
    for (I = 1; I <= 26; I++)
      if (Kd[I].L) Assign(I);
    Kap = 1;
    for (I = 1; I <= 26; I++)
      if (Kd[I].L) Extract(I, _imp_str_literal(""));
    Printstring(_imp_str_literal("\n\nKEYWORDS\n\n"));
    for (I = 1; I <= Kap - 1; I++)
      Printstring(
          _imp_join(Strint(Kna[I], 3),
                    _imp_join(_imp_str_literal("  "),
                              _imp_join(Ka[I], _imp_str_literal("\n")))));
    Closeinput();
    Printstring(_imp_join(_imp_str_literal("resetinput"), Snl));
    Openinput(2, _imp_str_literal("skimpps.new"));
    Selectinput(2);
    Pn[256] = _imp_str_literal("NAME");
    Pp[256] = 0;
    Pn[257] = _imp_str_literal("CONST");
    Pp[257] = 0;
    Pn[258] = _imp_str_literal("STRING");
    Pp[258] = 0;
    Pnp = 259;
    Psp = 1;
    for (;;) {
      Readsymbol(&L);
      if (L == '$') break;
      if (L == '<') {
        Pp[Phrase()] = Psp;
        for (;;) {
          Alt = Psp;
          Np = &Ps[Psp + 1];
          *Np = 0;
          Psp += 2;
          for (;;) {
            Readsymbol(&L);
            if (L == '<') {
              Ps[Psp] = Phrase();
              Psp++;
              *Np = *Np + 1;
            }
            if (L == '\'') Literal();
            if (L == '"') Keyword();
            if (L == ',' || L == ';') break;
          }
          Ps[Alt] = Psp;
          if (L == ';') break;
        }
        Ps[Psp] = 0;
        Psp++;
      }
    }
    Psflag = 0;
    for (I = 259; I <= Pnp - 1; I++)
      if (!Pp[I]) {
        Fault(_imp_join(_imp_str_literal("<"),
                        _imp_join(Pn[I], _imp_str_literal("> NOT DEFINED"))));
        Psflag = 1;
      }
    Printstring(_imp_str_literal("\n\nPHRASES\n\n"));
    for (I = 256; I <= Pnp - 1; I++)
      Printstring(_imp_join(
          Strint(I, 3),
          _imp_join(Strint(Pp[I], 6),
                    _imp_join(_imp_str_literal("   "),
                              _imp_join(Pn[I], _imp_str_literal("\n"))))));
    Printstring(_imp_str_literal("\n\nREDUCED PHRASE STRUCTURE\n\n"));
    for (I = 1; I <= Psp - 1; I++) {
      if (!((I - 1) & 15))
        Printstring(
            _imp_join(_imp_str_literal("\n"),
                      _imp_join(Strint(I, 3), _imp_str_literal("   "))));
      Write(Ps[I], 3);
    }
    Newlines(2);
    _imp_leave();
    return;
    void Insert(_imp_string K) {
      _imp_enter();
      int I;
      int J;
      int L;
      _imp_string NULLX;
      L = *Charno(K, 1);
//      if (!(_imp_resolve(K, &NULLX, Tostring(L), &K) && *Length(NULLX)!=0)) _imp_signal(7, 0, 0, _imp_str_literal("string resolution failed"));
      (void)_imp_resolve(K, NULL, Tostring(L), &K);
      I = L - 'A' + 1;
      if (Kd[I].L) {
      Search:;
        if (*Length(K) == 0) {
          if (Kd[I].A) {
            Extract(Kd[I].A, _imp_str_literal(""));
            Returnlist(Kd[I].A);
            Kd[I].A = 0;
          }
          _imp_leave();
          return;
        }
        if (!Kd[I].A) {
          Insert(K);
          _imp_leave();
          return;
        }
        L = *Charno(K, 1);
//        if (!(_imp_resolve(K, &NULLX, Tostring(L), &K) && *Length(NULLX)!=0)) _imp_signal(7, 0, 0, _imp_str_literal("string resolution failed"));
        (void)_imp_resolve(K, NULL, Tostring(L), &K);
        I = Kd[I].A;
        for (;;) {
          if (Kd[I].L == L) goto Search;
          if (!Kd[I].B) break;
          I = Kd[I].B;
        }
        J = I;
        I = Newkd();
        Kd[J].B = I;
      }
      for (;;) {
        Kd[I].L = L;
        if (*Length(K) == 0) {
          _imp_leave();
          return;
        }
        L = *Charno(K, 1);
//        if (!(_imp_resolve(K, &NULLX, Tostring(L), &K) && *Length(NULLX)!=0)) _imp_signal(7, 0, 0, _imp_str_literal("string resolution failed"));
        (void)_imp_resolve(K, NULL, Tostring(L), &K);
        J = I;
        I = Newkd();
        Kd[J].A = I;
      }
      _imp_leave();
    }
    void Extract(int I, _imp_string K) {
      _imp_enter();
      _imp_string Kk;
      if (!I) {
        _imp_leave();
        return;
      }
      Kk = _imp_join(K, Tostring(Kd[I].L));
      if (!Kd[I].A) {
        Ka[Kap] = Kk;
        Kna[Kap] = Kd[I].N;
        Kap++;
      } else
        Extract(Kd[I].A, Kk);
      Extract(Kd[I].B, K);
      _imp_leave();
    }
    void Assign(int I) {
      _imp_enter();
      if (!I) {
        _imp_leave();
        return;
      }
      if (!Kd[I].A) {
        Kd[I].N = Kn;
        Kn++;
      } else
        Assign(Kd[I].A);
      Assign(Kd[I].B);
      _imp_leave();
    }
    int Newkd(void) {
      _imp_enter();
      int I;
      if (!Kdasl) {
        Printstring(_imp_str_literal("KD ASL EMPTY"));
        _imp_leave();
        exit(0);
      }
      I = Kdasl;
if (Kd[I].B) {
      Kdasl = Kd[I].B;
}
      Kd[I] = (Kdf){0}; // GT: CHECK THIS IS A RECORD ASSIGNMENT NOT ASSIGNING NULL TO A POINTER.
      return (I);
    }
    void Returnkd(int I) {
      _imp_enter();
      Kd[I].B = Kdasl;
      Kdasl = I;
      _imp_leave();
    }
    void Returnlist(int I) {
      _imp_enter();
      if (!I) {
        _imp_leave();
        return;
      }
      Returnlist(Kd[I].A);
      Returnlist(Kd[I].B);
      Returnkd(I);
      _imp_leave();
    }
    int Phrase(void) {
      _imp_enter();
      _imp_string P;
      int I;
      int L;
      P = _imp_str_literal("");
      for (;;) {
        Readsymbol(&L);
        if (L == '>')
          break;
        else
          P = _imp_join(P, Tostring(L));
      }
      for (I = 256; I <= Pnp - 1; I++)
        if (_imp_strcmp(Pn[I], P)==0) {
          return (I);
        }
      Pn[Pnp] = P;
      Pp[Pnp] = 0;
      Pnp++;
      return (Pnp - 1);
    }
    void Literal(void) {
      _imp_enter();
      int L;
      for (;;) {
        Readsymbol(&L);
        if (L == '\'') {
          _imp_leave();
          return;
        } else {
          Ps[Psp] = L;
          Psp++;
        }
      }
      _imp_leave();
    }
    void Keyword(void) {
      _imp_enter();
      _imp_string K;
      int L;
      K = _imp_str_literal("");       // struct copy
      for (;;) {
        Readsymbol(&L);
        if (L == '"') break;
        if ('A' <= L && L <= 'Z') K = _imp_join(K, Tostring(L));
      }
      do {
        Ps[Psp] = Findk(&K);
        Psp++;
      } while (*Length(K) != 0);
      _imp_leave();
    }

    _imp_leave();
  }
  void Readstatement(void) {
    _imp_enter();
    auto void Store(int L);
    auto void Keyword(void);
    auto void Name(void);
    auto void Const(void);
    auto void Stringconst(void);
    int I;
    int L;
    int Ksh;
    int Ttp;
    int Ttpp;
    Newlines(2);
    Ttp = 1;
    Ksh = 0;
    for (;;) {
      Rpsym(&L);
      if (L == '%')
        Ksh = 128;
      else {
        if ('A' > L || L > 'Z') Ksh = 0;
        if (L != ' ') {
          if (L == '!' && Ttp == 1) {
            do
              Rpsym(&L);
            while (L != ';' && L != Nl);
          } else {
            Store(L);
            if (L == '"') {
              Shift = 0;
              do {
                Rpsym(&L);
                Store(L);
              } while (L != '"');
              Shift = 32;
            } else if (L == '\'') {
              Shift = 0;
              do {
                Rpsym(&L);
                Store(L);
              } while (L != '\'');
              Shift = 32;
            } else if (L == ';' || L == Nl) {
              if (Ttp == 2)
                Ttp = 1;
              else {
                if (L == ';') {
                  Newline();
                  break;
                }
                if (Tt[Ttp - 2] == 'C' + 128)
                  Ttp -= 2;
                else
                  break;
              }
            }
          }
        }
      }
    }
    Tp = 1;
    Ttpp = 1;
    do {
      I = Tt[Ttpp];
      if (I >= 128)
        Keyword();
      else if ('A' <= I && I <= 'Z')
        Name();
      else if (I == '"')
        Stringconst();
      else if (('0' <= I && I <= '9') || I == '\'' || I == '$')
        Const();
      else {
        T[Tp] = I;
        Tp++;
        Ttpp++;
      }
    } while (Ttpp != Ttp);
    if (Lexopt == 1) {
      Newline();
      for (Ttpp = 1; Ttpp <= Tp - 2; Ttpp++) {
        Write(T[Ttpp], 4);
        if (!(Ttpp & 0xF)) Newline();
      }
      Newline();
    }
    _imp_leave();
    return;
    void Store(int L) {
      _imp_enter();
      if (Ttp > 256) {
        Fault(_imp_str_literal("STATEMENT TOO LONG"));
        _imp_leave();
        exit(0);
      }
      Tt[Ttp] = L + Ksh;
      Ttp++;
      _imp_leave();
    }
    void Keyword(void) {
      _imp_enter();
      _imp_string K;
      int I;
      K = _imp_str_literal("");
      while (Tt[Ttpp] > 128) {
        K = _imp_join(K, Tostring(Tt[Ttpp] - 128));
        Ttpp++;
      }
      do {
        I = Findk(&K);
        T[Tp] = I;
        Tp++;
      } while (*Length(K) != 0 && I != 0);

      _imp_leave();
    }
    void Name(void) {
      _imp_enter();
      _imp_string *Sname;
      int I;
      int L;
      int Hash;
      Sname = String(Addr(Named[Namedp]));
      Hash = 0;
      *Sname = _imp_str_literal("");
      L = Tt[Ttpp];
      do {
        if (Namedp + *Length(*Sname) >= 1022) {
          Fault(_imp_str_literal("NAME DICTIONARY FULL"));
          _imp_leave();
          exit(0);
        }
        if (*Length(*Sname) == 255) {
          Fault(_imp_str_literal("NAME TOO LONG"));
          _imp_leave();
          exit(0);
        }
        *Sname = _imp_join(*Sname, Tostring(L));
        Hash = Hash << 8 | L;
        Ttpp++;
        L = Tt[Ttpp];
      } while (L >= '0' && ('9' >= L || L >= 'A') && L <= 'Z');
      Hash -= Hash / 251 * 251;
      I = Hash;
      for (;;) {
        if (!Namedlink[I]) {
          Namedlink[I] = Namedp;
          Namedp = Namedp + *Length(*Sname) + 1;
          break;
        }
        if (_imp_strcmp(*Sname, *String(Addr(Named[Namedlink[I]])))==0) break;
        I = (I + 1) & 255;
        if (I == Hash) {
          Fault(_imp_str_literal("NAME DICTIONARY FULL"));
          _imp_leave();
          exit(0);
        }
      }
      T[Tp] = 256;
      T[Tp + 1] = I;
      Tp += 2;
      _imp_leave();
    }
    void Const(void) {
      _imp_enter();
      int L;
      int Value;
      int Flag;
      int Count;
      int Maxby10;
      int Maxld;
      Value = 0;
      Flag = 0;
      if (Tt[Ttpp] == '$')
        for (;;) {
          Ttpp++;
          if (('0' > Tt[Ttpp] || Tt[Ttpp] > '9') &&
              ('A' > Tt[Ttpp] || Tt[Ttpp] > 'F'))
            break;
          if (Tt[Ttpp] < 'A')
            Value = Value << 4 | (Tt[Ttpp] - '0');
          else
            Value = Value << 4 | (Tt[Ttpp] - 'A' + 10);
          if (Value > 0xFFFF) {
            Flag = 1;
            break;
          }
        }
      else if (Tt[Ttpp] == '\'') {
        Count = 0;
        for (;;) {
          Ttpp++;
          if (Tt[Ttpp] == '\'') {
            Ttpp++;
            if (Tt[Ttpp] != '\'') break;
          }
          Value = Value << 8 | Tt[Ttpp];
          Count++;
        }
        if (Count > 2) Flag = 1;
      } else {
        Maxby10 = 0x7FFF / 10;
        Maxld = 0x7FFF - Maxby10 * 10 + '0';
        L = Tt[Ttpp];
        do {
          if (Value > Maxby10 || (Value == Maxby10 && L > Maxld))
            Flag = 1;
          else
            Value = Value * 10 + L - '0';
          Ttpp++;
          L = Tt[Ttpp];
        } while (L >= '0' && L <= '9');
      }
      T[Tp] = 257;
      if (Flag) {
        Fault(_imp_str_literal("CONSTANT INVALID"));
        Value = 0;
      }
      T[Tp + 1] = Value;
      Tp += 2;
      _imp_leave();
    }
    void Stringconst(void) {
      _imp_enter();
      T[Tp] = 258;
      if (Tt[Ttpp] != '"') {
        Fault(_imp_str_literal("INVALID STRING"));
        T[Tp + 1] = 0x80;
        _imp_leave();
        return;
      }
      for (;;) {
        Tp++;
        Ttpp++;
        if (Tt[Ttpp] == '"') {
          if (Tt[Ttpp + 1] == '"') {
            Ttpp++;
            T[Tp] = '"';
            continue;
          }
          T[Tp] = 0x80;
          Tp++;
          Ttpp++;
          _imp_leave();
          return;
        }
        T[Tp] = Tt[Ttpp];
      }
      _imp_leave();
    }

    _imp_leave();
  }
  void Rpsym(int *L) {
    _imp_enter();
    static int Flag = 1;
    Readsymbol(L);
    if (Flag == 1 && Outstream() == 1) {
      Printstring(_imp_str_literal("*     "));
      Flag = 0;
    }
    Printsymbol(*L);
    if (Outstream() == 1 && *L == ';' && Shift != 0) Newline();
    if (Outstream() == 1 && (*L == Nl || (*L == ';' && Shift != 0))) Flag = 1;
    if ('a' <= *L && *L <= 'z') *L = *L ^ Shift;
    _imp_leave();
  }
  int Findk(_imp_string * K) {
    _imp_enter();
    int I;
    int L;
    _imp_string NULLX;
    L = *Charno(*K, 1);             // THERE ARE BETTER WAYS TO IMPLEMENT THIS, WITHOUT STRING RESOLUTION
//    if (!(_imp_resolve(*K, &NULLX, Tostring(L), K) && *Length(NULLX)!=0)) _imp_signal(7, 0, 0, _imp_str_literal("string resolution failed"));
    (void)_imp_resolve(*K, NULL, Tostring(L), K);
    I = L - 'A' + 1;
    if (!Kd[I].L) return (0);
  Search:;
    if (*Length(*K) == 0 || Kd[I].A == 0)
      return (Kd[I].N);
    L = *Charno(*K, 1);
//    if (!(_imp_resolve(*K, &NULLX, Tostring(L), K) && *Length(NULLX)!=0)) _imp_signal(7, 0, 0, _imp_str_literal("string resolution failed"));
    (void)_imp_resolve(*K, NULL, Tostring(L), K);
    I = Kd[I].A;
    for (;;) {
      if (Kd[I].L == L) goto Search;
      if (!Kd[I].B) return (0);
      I = Kd[I].B;
    }
    _imp_leave();
    fault("Reached end of %s without a %%result", __PRETTY_FUNCTION__);
  }
  int Compare(int P) {
    _imp_enter();
    int App;
    int Tpp;
    int Alt;
    int Altend;
    int Psp;
    int Psi;
    A[Ap] = P << 16 | 0x80000001;
    if (P <= 257) {
      if (P == T[Tp]) {
        A[Ap + 1] = T[Tp + 1];
        Ap += 2;
        Tp += 2;
        return (1);
      } else
        return (0);
    }
    if (P == 258) {
      if (T[Tp] != P) return (0);
      Alt = 1;
      do {
        A[Ap + Alt] = T[Tp + Alt];
        Alt++;
      } while (T[Tp + Alt] != 0x80);
      A[Ap + Alt] = 0x80;
      Ap = Ap + Alt + 1;
      Tp = Tp + Alt + 1;
      return (1);
    }
    Tpp = Tp;
    App = Ap;
    Psp = Pp[P];
    for (;;) {
      Alt = Ap + 1;
      Altend = Ps[Psp];
      Ap = Alt + Ps[Psp + 1];
      if (Ap > 255) {
        Fault(_imp_str_literal("ANALYSIS RECORD TOO LONG"));
        _imp_leave();
        exit(0);
      }
      Psp += 2;
      for (;;) {
        if (Psp == Altend) {
          return (1);
        }
        Psi = Ps[Psp];
        if (Psi >= 256) {
          A[Alt] = Ap;
          if (!Compare(Psi)) break;
          Alt++;
        } else {
          if (Psi != T[Tp]) break;
          Tp++;
        }
        Psp++;
      }
      if (!Ps[Altend]) {
        return (0);
      }
      Psp = Altend;
      Tp = Tpp;
      Ap = App;
      A[Ap] = A[Ap] + 1;
    }
    _imp_leave();
    fault("Reached end of %s without a %%result", __PRETTY_FUNCTION__);
  }

  _imp_leave();
}
int _imp_mainep(int _imp_argc, char **_imp_argv) {
  _imp_enter();
  _imp_string *Blah;
  if (_imp_argc != 2) {
    fprintf(stderr, "syntax: skimp file.imp\n\n");
    exit(1);
  }
  Skimp(_imp_c2istr(_imp_argv[1]));
  _imp_leave();
  exit(0);
  return (1);
}
