#include <perms.h>
static const int Addresssize = 4;
static const int Integertype = 1;
static const int Realtype = 2;
static const int Stringtype = 3;
static const int Recordtype = 4;
static const int Bytetype = 5;
static const int Shorttype = 6;
static const int Longtype = 7;
static const int Longrealtype = 8;
static const int Arraytype = 9;
static const int Labeltype = 10;
int Arrayentrysize(int Dvp, int Address) {
  int Dim;
  int St;
  int Staddress;
  if ((Dvp & 1) == 1)
    St = Dvp;
  else {
    Dim = *Integer(Dvp);
    Staddress = Dvp + (2 * Dim + 1) * Addresssize;
    St = *Integer(Staddress);
  }
  return (((unsigned)St >> 5));
}
int Arrayentrytype(int Dvp, int Address) {
  int Dim;
  int St;
  int Staddress;
  if ((Dvp & 1) == 1)
    St = Dvp;
  else {
    Dim = *Integer(Dvp);
    Staddress = Dvp + (2 * Dim + 1) * Addresssize;
    St = *Integer(Staddress);
  }
  return (((unsigned)St >> 1) & 15);
}
int Arraydimensions(int Dvp, int Address) {
  int Dim;
  if ((Dvp & 1) == 1)
    Dim = 0;
  else
    Dim = *Integer(Dvp);
  return (Dim);
}
int Arraylowerbound(int Dvp, int Address, int Index) {
  int Dim;
  int Lb;
  int Lbaddress;
  int Ub;
  int Ubaddress;
  int Thebound;
  int I;
  if ((Dvp & 1) == 1)
    Thebound = 0;
  else {
    Dim = *Integer(Dvp);
    Lbaddress = Dvp + Addresssize;
    Ubaddress = Lbaddress + Addresssize;
    Thebound = 0;
    for (I = 1; I <= Dim; I++) {
      Lb = *Integer(Lbaddress);
      Ub = *Integer(Ubaddress);
      if (I == Index) Thebound = Lb;
      Lbaddress = Ubaddress + Addresssize;
      Ubaddress = Lbaddress + Addresssize;
    }
  }
  return (Thebound);
}
int Arrayupperbound(int Dvp, int Address, int Index) {
  int Dim;
  int Lb;
  int Lbaddress;
  int Ub;
  int Ubaddress;
  int Thebound;
  int I;
  if ((Dvp & 1) == 1)
    Thebound = 0;
  else {
    Dim = *Integer(Dvp);
    Lbaddress = Dvp + Addresssize;
    Ubaddress = Lbaddress + Addresssize;
    Thebound = 0;
    for (I = 1; I <= Dim; I++) {
      Lb = *Integer(Lbaddress);
      Ub = *Integer(Ubaddress);
      if (I == Index) Thebound = Ub;
      Lbaddress = Ubaddress + Addresssize;
      Ubaddress = Lbaddress + Addresssize;
    }
  }
  return (Thebound);
}
void Impadef(int *Dvp) {
  int Lb;
  int Lbaddress;
  int Ub;
  int Ubaddress;
  int Sz;
  int Szaddress;
  int I;
  int Dim;
  int Base;
  int Limit;
  int Row;
  Dim = *Dvp;
  Szaddress = Addr(*Dvp) + Addresssize * (2 * Dim + 1);
  Base = 0;
  Limit = 0;
  Ubaddress = Szaddress - Addresssize;
  Lbaddress = Ubaddress - Addresssize;
  for (I = 1; I <= Dim; I++) {
    Lb = *Integer(Lbaddress);
    Ub = *Integer(Ubaddress);
    if (Lb > Ub) _imp_signal(5, 3, 0, _imp_str_literal(""));
    Row = (Ub - Lb) + 1;
    Base = Base * Row + Lb;
    Limit = Limit * Row + Ub;
    Ubaddress = Lbaddress - Addresssize;
    Lbaddress = Ubaddress - Addresssize;
  }
  Sz = *Integer(Szaddress);
  Sz = ((unsigned)Sz >> 5);
  Base = Base * Sz;
  Limit = (Limit + 1) * Sz;
  asm("mov  edx,limit");
  asm("mov  eax,base");
  return;
}
int Imparef(void) {
  int Framep;
  int *Dvp;
  int Dvpaddress;
  int Indexaddress;
  int Szaddress;
  int Lbaddress;
  int Ubaddress;
  int Dim;
  int Sz;
  int Lb;
  int Ub;
  int Index;
  int Row;
  int Result;
  int I;
  asm("mov  framep,ebp");
  Dvpaddress = Framep + 2 * Addresssize;
  Dvp = Integer(*Integer(Dvpaddress));
  Indexaddress = Dvpaddress + Addresssize;
  Dim = *Dvp;
  Szaddress = Addr(*Dvp) + Addresssize * (2 * Dim + 1);
  Ubaddress = Szaddress - Addresssize;
  Lbaddress = Ubaddress - Addresssize;
  Result = 0;
  for (I = 1; I <= Dim; I++) {
    Lb = *Integer(Lbaddress);
    Ub = *Integer(Ubaddress);
    Index = *Integer(Indexaddress);
    if ((Lb > Index || Index > Ub))
      _imp_signal(6, 2, Index, _imp_str_literal(""));
    Row = (Ub - Lb) + 1;
    Result = (Result * Row) + Index;
    Ubaddress = Lbaddress - Addresssize;
    Lbaddress = Ubaddress - Addresssize;
    Indexaddress += Addresssize;
  }
  Sz = *Integer(Szaddress);
  Sz = ((unsigned)Sz >> 5);
  return (Result * Sz);
}
_imp_string Typename(int T) {
  _imp_string S;
  static int Sw_sw;
  static void *Sw[16 /*0:15*/] = {
      &&Sw_0,       &&Sw_1,       &&Sw_2,       &&Sw_3,
      &&Sw_4,       &&Sw_5,       &&Sw_6,       &&Sw_7,
      &&Sw_8,       &&Sw_9,       &&Sw_10,      &&Sw_default,
      &&Sw_default, &&Sw_default, &&Sw_default, &&Sw_default,
  };
  S = _imp_str_literal("");
  goto *Sw[Sw_sw = T & 15];
Sw_0:
  S = _imp_str_literal("unknown");
  goto Esac;
Sw_1:
  S = _imp_str_literal("integer");
  goto Esac;
Sw_2:
  S = _imp_str_literal("real");
  goto Esac;
Sw_3:
  S = _imp_str_literal("string");
  goto Esac;
Sw_4:
  S = _imp_str_literal("record");
  goto Esac;
Sw_5:
  S = _imp_str_literal("byte");
  goto Esac;
Sw_6:
  S = _imp_str_literal("shortinteger");
  goto Esac;
Sw_7:
  S = _imp_str_literal("longinteger");
  goto Esac;
Sw_8:
  S = _imp_str_literal("longreal");
  goto Esac;
Sw_9:
  S = _imp_str_literal("array");
  goto Esac;
Sw_10:
  S = _imp_str_literal("label");
  goto Esac;
Sw_default:
  S = _imp_join(_imp_str_literal("illegal("),
                _imp_join(Itos(T & 15, 0), _imp_str_literal(")")));
  goto Esac;
Esac:;
  return (S);
}
int Typeof(int Dvp, int Address) {
  if ((Dvp & 1) == 1)
    return (((unsigned)Dvp >> 1) & 15);
  else
    return (9);
}
int Sizeof(int Dvp, int Address) {
  int Dim;
  int Sz;
  int Entries;
  int Lb;
  int Lbaddress;
  int Ub;
  int Ubaddress;
  int I;
  if ((Dvp & 1) == 1)
    return (((unsigned)Dvp >> 5));
  else {
    Dim = *Integer(Dvp);
    Lbaddress = Dvp + Addresssize;
    Ubaddress = Lbaddress + Addresssize;
    Entries = 1;
    for (I = 1; I <= Dim; I++) {
      Lb = *Integer(Lbaddress);
      Ub = *Integer(Ubaddress);
      if (Lb > Ub) _imp_signal(5, 3, I, _imp_str_literal(""));
      Entries = Entries * ((Ub - Lb) + 1);
      Lbaddress = Ubaddress + Addresssize;
      Ubaddress = Lbaddress + Addresssize;
    }
    Sz = *Integer(Lbaddress);
    Sz = ((unsigned)Sz >> 5);
    return (Entries * Sz);
  }
}
