#include <perms.h>
int _imp_mainep(int _imp_argc, char **_imp_argv) {
  float Eval(void) {
    auto void Pushopd(float Val);
    auto void Pushop(int Op);
    auto float Popopd(void);
    auto int Popop(void);
    auto float Nextopd(void);
    auto int Nextop(void);
    auto void Operate(void);
    static const int Plus = 1;
    static const int Minus = 2;
    static const int Times = 3;
    static const int Divide = 4;
    static const int Exp = 5;
    static const int Assign = 6;
    static const int End = 7;
    static const int Space = ' ';
    static const int Prec[6 /*1:6*/] = {1, 1, 2, 2, 3, 0};
    float Opds[5 /*0:4*/];
    int Ops[4 /*0:3*/];
    static float Vars[26 /*97:122*/] = {[0 ... 25] = 0};
    static int Vara[26 /*97:122*/] = {[0 ... 25] = 0};
    int Op;
    int Opdsp;
    int Opsp;
    int Var;
    Opdsp = 0;
    Opsp = 0;
    Pushopd(Nextopd());
    for (;;) {
      Op = Nextop();
      if (Op == End) break;
      while (Opsp > 0 && Prec[Ops[Opsp]] >= Prec[Op]) Operate();
      if (Op == Assign) {
        Readsymbol(Var);
        if (('a' > Var || Var > 'z') && ('A' > Var || Var > 'Z')) {
          Printsymbol(Var);
          Printstring(_imp_str_literal(" variable"));
          _imp_signal(15, 0, 0, _imp_str_literal(""));
        }
        if ('A' <= Var && Var <= 'Z') Var = Var - 'A' + 'a';
        Vars[Var] = Opds[Opdsp];
        Vara[Var] = 1;
        continue;
      }
      Pushop(Op);
      Pushopd(Nextopd());
    }
    while (Opsp > 0) Operate();
    return (Popopd());
    void Pushopd(float Val) {
      Opdsp++;
      Opds[Opdsp] = Val;
    }
    void Pushop(int Op) {
      Opsp++;
      Ops[Opsp] = Op;
    }
    float Popopd(void) {
      float Val;
      Val = Opds[Opdsp];
      Opdsp--;
      return (Val);
    }
    int Popop(void) {
      int Op;
      Op = Ops[Opsp];
      Opsp--;
      return (Op);
    }
    float Nextopd(void) {
      int Var;
      float Opd;
      while (Nextsymbol() == Space || Nextsymbol() == Nl) Skipsymbol();
      if ('0' <= Nextsymbol() && Nextsymbol() <= '9' || Nextsymbol() == '-' || Nextsymbol() == '.') {
        Read(Opd);
        return (Opd);
      }
      if (Nextsymbol() == '(') {
        Skipsymbol();
        return (Eval());
      }
      if ('a' <= Nextsymbol() && Nextsymbol() <= 'z' || 'A' <= Nextsymbol() && Nextsymbol() <= 'Z') {
        Readsymbol(Var);
        if ('A' <= Var && Var <= 'Z') Var = Var - 'A' + 'a';
        if (!Vara[Var]) {
          Printsymbol(Var);
          Printstring(_imp_str_literal(" unassigned"));
          _imp_signal(15, 0, 0, _imp_str_literal(""));
        }
        return (Vars[Var]);
      }
      Readsymbol(Var);
      Printsymbol(Var);
      Printstring(_imp_str_literal(" operand"));
      _imp_signal(15, 0, 0, _imp_str_literal(""));
    }
    int Nextop(void) {
      int Sym;
      while (Nextsymbol() == Space) Skipsymbol();
      Readsymbol(Sym);
      if (Sym == '+') return (Plus);
      if (Sym == '-') return (Minus);
      if (Sym == '*') return (Times);
      if (Sym == '/') return (Divide);
      if (Sym == '^') return (Exp);
      if (Sym == ':') return (Assign);
      if (Sym == ')' || Sym == Nl) return (End);
      Printsymbol(Sym);
      Printstring(_imp_str_literal(" operator"));
      _imp_signal(15, 0, 0, _imp_str_literal(""));
    }
    void Operate(void) {
      float Opd1;
      float Opd2;
      static int Opn_sw;
      static void *Opn[5 /*1:5*/] = {
          &&Opn_1, &&Opn_2, &&Opn_3, &&Opn_4, &&Opn_5,
      };
      Opd2 = Popopd();
      Opd1 = Popopd();
      goto *Opn[Opn_sw = (Popop()) - 1];
    Opn_1:
      Pushopd(Opd1 + Opd2);
      return;
    Opn_2:
      Pushopd(Opd1 - Opd2);
      return;
    Opn_3:
      Pushopd(Opd1 * Opd2);
      return;
    Opn_4:
      if (!Opd2) {
        Printstring(_imp_str_literal("divide by zero"));
        _imp_signal(15, 0, 0, _imp_str_literal(""));
      }
      Pushopd(Opd1 / Opd2);
      return;
    Opn_5:
      Pushopd(REXP(Opd1, Int(Opd2)));
    }
  }
  float Val;
  if (_imp_on_event(9, 15)) {
    if (Event.Event() == 9) exit(0);
    Printstring(_imp_str_literal("?\n"));
    goto Again;
  }
  Selectinput(0);
  Selectoutput(0);
  Prompt(_imp_str_literal("eval:"));
Again:
  Val = Eval();
  if (Val == Int(Val)) Write(Int(Val), 0);
  Newline();
  goto Again;
  exit(0);
  return (1);
}
