#include <perms.h>

//          Edinburgh IMP77 Compiler - Version 8.4
//
//     1  %external %real %function S To R (%string (255) Input)

float STOR(_imp_string255 INPUT) {
  //     2    %integer Sign = 0,

  int SIGN;
  SIGN = 0;
  int SYM;
  int POS;
  POS = 1;

  //     3+            Sym,
  //     4+            Pos = 1
  //     5    %long %real Value,

  double VALUE;
  double EXP;

  //     6+               Exp
  //     7
  //     8     %routine Next

  void NEXT(void) {
    //     9        Pos = Pos + 1

    POS = POS + 1;

    //    10        %if Pos > Length (Input) %start

    if (POS <= *_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &INPUT)) goto L_0001;

      //    11           Sym = 0

    SYM = 0;

    //    12        %else

    goto L_0002;
  L_0001:;

  //    13           Sym = Char No (Input, Pos)

    SYM = *_imp_CHARNO((_imp_string255 *)/*p*/ /*?*/ &INPUT, POS);

    //    14        %finish

  L_0002:;

  //    15     %end

    return;
  } /* end of NEXT */

  //    16
  //    17     Sym = Char No (Input, Pos)

  SYM = *_imp_CHARNO((_imp_string255 *)/*p*/ /*?*/ &INPUT, POS);

  //    18     %if Sym = '-' %start

  if (SYM != 45) goto L_0003;

    //    19        Sign = 1

  SIGN = 1;

  //    20        Next

  NEXT();

  //    21     %finish

L_0003:;

//    22     Value = 0

  VALUE = 0;

  //    23     %if Sym # '.' %start

  if (SYM == 46) goto L_0004;

    //    24        %signal 6, 5, Pos %unless '0' <= Sym <= '9'           {Char No out of range}

  {
// Double-sided test on SYM (Part I)
    int tmp;
    if (48 > (tmp = SYM)) goto L_0005;
// Double-sided test on SYM (Part II)
    if (tmp <= 57) goto L_0006;
  }
L_0005:;
  _imp_signal(6, 5, POS, "");
L_0006:;

//    25        %cycle

L_0007:;

//    26           Value = Value*10.0 + (Sym - '0')

  VALUE = VALUE * 10.0 + (SYM - 48);

  //    27           Next

  NEXT();

  //    28        %repeat %until %not '0' <= Sym <= '9'

  {
// Double-sided test on SYM (Part I)
    int tmp;
    if (48 > (tmp = SYM)) goto L_0008;
// Double-sided test on SYM (Part II)
    if (tmp > 57) goto L_0008;
  }
  goto L_0007;
L_0008:;

//    29     %finish

L_0004:;

//    30     %if Sym = '.' %start

  if (SYM != 46) goto L_0009;

    //    31        Exp = 10.0

  EXP = 10.0;

  //    32        %cycle

L_000A:;

//    33           Next

  NEXT();

  //    34           %exit %unless '0' <= Sym <= '9'

  {
// Double-sided test on SYM (Part I)
    int tmp;
    if (48 > (tmp = SYM)) goto L_000B;
// Double-sided test on SYM (Part II)
    if (tmp <= 57) goto L_000C;
  }
L_000B:;
  goto L_000D;
L_000C:;

//    35           Value = Value + (Sym - '0')/Exp

  VALUE = VALUE + (double)((SYM - 48) / EXP);

  //    36           Exp = Exp * 10.0

  EXP = EXP * 10.0;

  //    37        %repeat

  goto L_000A;
L_000D:;

//    38     %finish

L_0009:;

//    39     %if Sym = '@' %start

  if (SYM != 64) goto L_000E;

    //    40        Sym = S To I (Sub String (Input, Pos + 1, Length (Input)))

  SYM = _imp_STOI(
      *({
        __typeof__(_imp_string255) tmp = _imp_SUBSTRING((_imp_string255 *)/*p*/ /*?*/ &INPUT, POS + 1,
                                                        *_imp_LENGTH((_imp_string255 *)/*p*/ /*?*/ &INPUT)) /*q*/;
        (_imp_string255 *)&tmp;
      })
  );

  //    41        Value = Value * 10.0\Sym

  VALUE = VALUE * (_imp_REXP(10.0, SYM));

  //    42     %finish

L_000E:;

//    43     Value = -Value %if Sign # 0

  if (SIGN == 0) goto L_000F;
  VALUE = -VALUE;
L_000F:;

//    44     %result = Value

  return VALUE;

  //    45  %end {S To R}

} /* end of STOR */

//    46
//    47  %endoffile