!                                                              fcinnum1a
! 15/01/87 - insert %alias for amdahl system routines
!
      ! Modified    5/June/86   8.00








!***********************************************************************
!*********************************************************************%C
                                                                      %C
                                                                      %C
             A SET OF NUMBER CONVERSION ROUTINES   (version 6.0)      %C
                                                                      %C
                      FOR THE FORTRAN77                               %C
                                                                      %C
               (used either by the compiler or F77IOA and F77IOC)     %C
                                                                      %C
                                                                      %C
!*********************************************************************%C
!***********************************************************************



!---Modes of Operation:
    !
    !
   %constinteger Compile Time = 0
   %constinteger     Run Time1= 1  {     report CONSTANT OUT OF RANGE}
   %constinteger     Run Time2= 2  {dont report CONSTANT OUT OF RANGE}

   %constinteger         MODE = Compile Time

                 !change MODE if running with the compiler!










!---Conditional Compilation Variables:
    !
    !
    %constinteger       EMAS = 0
    %constinteger       PERQ = 1
    %constinteger       PNX  = 2
    %constinteger       IBM  = 3
    %constinteger       PERQ3= 4
    %constinteger Whitechapel= 5
    %constinteger       Gould= 6

    %constinteger       False= 0
    %constinteger       True = 1





                !---------------------------------------!
                !                                       !
                !                                       !
                !   CONDITIONAL COMPILATION CONSTANTS   !
                !                                       !
                !                                       !
                !---------------------------------------!

                       %CONSTINTEGER TARGET= GOULD
                       %CONSTINTEGER   HOST= IBM

                       %CONSTINTEGER  Relax Ansi= False



%IF TARGET=EMAS %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for EMAS
          !
          !
          %CONSTINTEGER k= 0                                               ;!%C
                        k is set to the shift count required to convert      %C
                          a byte displacement into an address displacement

          %CONSTINTEGER HALFs= True                                        ;!%C
                        HALFS= True implies that 16-bit entities are accessed%C
                                    via the HALFINTEGER map and are unsigned

          %CONSTINTEGER IEEE= False                                        ;!%C
                        IEEE= False implies that floating point constants    %C
                                    conform to the 'excess-64' notation as   %C
                                    used by IBM and ICL 2900s

          %CONSTINTEGER Byte Addressing= True                              ;!%C
                        Byte Addressing= True implies that {address}+1       %C
                             accesses the next byte and not the next word

          %CONSTINTEGER CR Delimiter= False                                ;!%C
                        CR Delimiter= False implies that the Carriage Return %C
                           character is not an alternative record delimiter  %C
                           to the Newline (NL) character in a formatted input%C
                           field

          %CONSTINTEGER Output Len= 120                                    ;!%C
                        Output Len= the record length of the diagnostic      %C
                                    stream. If the record length of          %C
                                    this stream changes then only            %C
                                    this variable need be altered

          %CONSTINTEGER UNIX IO= False                                     ;!%C
                        UNIX IO= False implies that the underlying target    %C
                             file system is not UNIX or UNIX based

          %CONSTINTEGER Unassigned Word= X'80808080'
          %CONSTINTEGER Unassigned Half= X'FFFF8080'
          %CONSTINTEGER Unassigned Char=   0

!   {!!!} %CONSTLONGINTEGER Unassigned Long= R'8080808080808080'
          %FINISH




%IF TARGET= IBM %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for Amdahl
          !
          !
          %CONSTINTEGER k= 0

          %CONSTINTEGER HALFs= False                                       ;!%C
                        HALFS= False if 16-bit entities are accessed via     %C
                                     the SHORTINTEGER map and they are signed
          %CONSTINTEGER IEEE= False

          %CONSTINTEGER Byte Addressing= True

          %CONSTINTEGER   CR Delimiter= False

          %CONSTINTEGER     Output Len= 120

          %CONSTINTEGER        UNIX IO= False

          %CONSTINTEGER Unassigned Word= X'81818181'
          %CONSTINTEGER Unassigned Half= X'FFFF8181'
          %CONSTINTEGER Unassigned Char=   0

!   {!!!} %CONSTLONGINTEGER Unassigned Long= R'8181818181818181'
          %FINISH



%IF TARGET=PERQ %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for ACCENT or WHITECHAPEL
          !
          !
          %CONSTINTEGER k= 1

          %CONSTINTEGER HALFs= False

          %CONSTINTEGER IEEE= True                                         ;!%C
                        IEEE= True implies that floating point constants     %C
                                   conform to the IEEE Standard

          %CONSTINTEGER Byte Addressing= False                             ;!%C
                        Byte Addressing= False implies that {address}+1      %C
                             accesses the next word and not the next byte

          %CONSTINTEGER CR Delimiter= True                                 ;!%C
                        CR Delimiter= True implies that the Carriage Return  %C
                           character within a formatted input field is to be %C
                           regarded as an alternative record delimiter to the%C
                           Newline (NL) character

          %CONSTINTEGER    Output Len= 84

          %CONSTINTEGER       UNIX IO= False

          %CONSTINTEGER Unassigned Word= X'80808080'
          %CONSTINTEGER Unassigned Half= X'FFFF8080'
          %CONSTINTEGER Unassigned Char= X'81'
          %FINISH



%IF TARGET= PNX %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for PNX
          !
          !
          %CONSTINTEGER k= 1

          %CONSTINTEGER HALFs= True

          %CONSTINTEGER IEEE= True

          %CONSTINTEGER Byte Addressing= False

          %CONSTINTEGER CR Delimiter= True

          %CONSTINTEGER    Output Len= 84

          %CONSTINTEGER UNIX IO= True                                      ;!%C
                        UNIX IO= True implies that the underlying target     %C
                                      file system is UNIX or UNIX-like

          %CONSTINTEGER Unassigned Word= X'80808080'
          %CONSTINTEGER Unassigned Half= X'FFFF8080'
          %CONSTINTEGER Unassigned Char= X'80'
          %FINISH




%IF TARGET= PERQ3 %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for PERQ3
          !
          !
          %CONSTINTEGER k= 0

          %CONSTINTEGER HALFs= False                                       ;!%C
                        HALFS= False if 16-bit entities are accessed via     %C
                                     the SHORTINTEGER map and they are signed
          %CONSTINTEGER IEEE= True

          %CONSTINTEGER Byte Addressing= True

          %CONSTINTEGER   CR Delimiter = True

          %CONSTINTEGER     Output Len = 84

          %CONSTINTEGER         UNIX IO= True

          %CONSTINTEGER Unassigned Word= X'81818181'
          %CONSTINTEGER Unassigned Half= X'FFFF8181'
          %CONSTINTEGER Unassigned Char= X'81'
          %FINISH




%IF TARGET= Whitechapel %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for WHITECHAPEL
          !
          !
          %CONSTINTEGER k= 0

          %CONSTINTEGER HALFs= False                                       ;!%C
                        HALFS= False if 16-bit entities are accessed via     %C
                                     the SHORTINTEGER map and they are signed
          %CONSTINTEGER IEEE= True

          %CONSTINTEGER Byte Addressing= False

          %CONSTINTEGER   CR Delimiter = True

          %CONSTINTEGER     Output Len = 84

          %CONSTINTEGER         UNIX IO= True

          %CONSTINTEGER Unassigned Word= X'81818181'
          %CONSTINTEGER Unassigned Half= X'FFFF8181'
          %CONSTINTEGER Unassigned Char= X'81'
          %FINISH




%IF TARGET= GOULD %THENSTART
          !
          !
          !   Define Conditional Compilation Constants for GOULD
          !
          !
          %CONSTINTEGER k= 0

          %CONSTINTEGER HALFs= False                                       ;!%C
                        HALFS= False if 16-bit entities are accessed via     %C
                                     the SHORTINTEGER map and they are signed
          %CONSTINTEGER IEEE= False

          %CONSTINTEGER Byte Addressing= True

          %CONSTINTEGER   CR Delimiter = True

          %CONSTINTEGER     Output Len = 80

          %CONSTINTEGER         UNIX IO= True

          %CONSTINTEGER Unassigned Word= X'81818181'
          %CONSTINTEGER Unassigned Half= X'FFFF8181'
          %CONSTINTEGER Unassigned Char= X'81'
          %FINISH


!NOTE: Other lines that might require changing are marked with the pattern {!!!}








%EXTERNALINTEGERFN IN NUMBER %ALIAS "S#INNUMBER"    %C
                             (%INTEGER     DATA AD, DATA LEN , FORMAT,BLANKS,
                              %INTEGER                   DECS,  SCALE FACTOR,
                              %INTEGERNAME          TEXT PTR ,   TEXT END   ,
                     %BYTEINTEGERARRAYNAME          IO BUFFER,   TEXT       )
!
!
!
!
!     This Procedure Analyses the Number in the Input Buffer
!
!          to determine  (A) if the Syntax is correct,
!
!                        (B) the scale of the number
!
!      and to remove all occurrences of signs, exponents, and decimal points.
!
!
!     This Procedure then Converts the Number into Binary.
!
!
!The following table represents values assigned to each
!    character in the ISO Character Set. The assignments
!    are made on the following basis:
               !
         %CONSTINTEGER   Syntax Fault     =  0    {for an invalid char},
                              A Blank     =  1    {for ' '            },
                              A Digit     =  2    {for '0' - '9' incl },
                              A Sign      =  3    {for '+' , '-'      },
                      A Decimal Point     =  4    {for '.'            },
                   A Lower Case Exp{onent}=  5    {for 'd' , 'e' , 'q'},
                             An Exponent  =  6    {for 'D' , 'E' , 'Q'},
                              A Comma     =  7    {for premature end  };    !%C
                     A Carriage Return    =  7   {           of field}

%CONSTBYTEINTEGERARRAY TYPE (0:127)= Syntax Fault (13),
                                          A Comma {for Carriage Return},
                                     Syntax Fault (18),   A Blank {   },
                                     Syntax Fault (10),
             A Sign     { + }      ,      A Comma     ,   A Sign  { - },
     A Decimal Point    { . }      , Syntax Fault     ,
             A Digit    {0-9} (10) , Syntax Fault (10),
            An Exponent {D,E} ( 2) , Syntax Fault (11),
            An Exponent { Q }      , Syntax Fault (18),
  A Lower Case Exp      {d,e} ( 2) , Syntax Fault (11),
  A Lower Case Exp      { q}       , Syntax Fault (14)
               !
               !
%SWITCH HANDLE (Syntax Fault:A Comma)


!NOTE that the parameter list makes no allowances for byte offsets
         ! from word addresses which is required for type BYTE
         ! when running on ACCENT, and hence it has been assumed
         ! that for type BYTE the calling routine will nominate an
         ! address of a four-byte work area which it will copy to
         ! the final destination after IN NUMBER returns.

!NOTE if running in compiler mode then IN NUMBER returns -1
       ! as a result if more digits are specified than can
       ! be represented in the requested precision
       !

       %IF MODE= Compile Time %THENSTART
               !
              !INTEGER RESULT

         %CONSTINTEGER No Comment=  0 ,
                Lost Significance= -1

         %FINISH



!
!***********************************************************************
!
!     CONSTANTS
!
!***********************************************************************
!
%CONSTINTEGER   CR    =13 {for Carriage Return}
%CONSTINTEGER Zero    = 0
%CONSTINTEGER Null    = 0
%CONSTINTEGER Not Set = 0
%CONSTINTEGER Off     = 0,  On  = 1
                      !Values taken by 'boolean' variables
                      !            (ie. Integers used as flags)

%CONSTINTEGER A Minus= 0 ; !values used internally
%CONSTINTEGER A Plus = 1 ; !    to indicate a positive or negative value is reqd


!Error Messages:
       !
       !
%CONSTINTEGER Invalid Integer      =  140
%CONSTINTEGER Invalid Real         =  141
%CONSTINTEGER Invalid Character    =  148
{CONSTINTEGER    Null Field        =  133}

%IF MODE= Compile Time %THENSTART
                       %CONSTINTEGER Constant Out Of Range=  20
     %FINISHELSESTART; %CONSTINTEGER Constant Out Of Range= 188
     %FINISH


%IF HOST=EMAS %OR HOST= IBM %OR HOST= GOULD %THENSTART

        %UNLESS TARGET= IBM %THENSTART
                      !
                      !   Double Precision Floating-Point Constants
                      !
                      %CONSTLONGREAL Largest Real= R'7FFFFFFFFFFFFFFF'

%FINISHELSESTART
       !
       !   'EXCESS 64' Notation Real Constants (for Amdahl)
       !
      !%CONSTLONGLONGREAL Largest Real= R'7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' {!!!}
       %FINISH

    %FINISHELSESTART

          %IF HOST=PNX %OR HOST=PERQ3 %OR HOST=Whitechapel %THENSTART
              !
              !   PNX/PERQ3/WHITECHAPEL Floating Point Constants
              !
              %CONSTLONGREAL Largest Real= R'7FEFFFFFFFFFFFFF'

              %FINISHELSESTART
                     !
                     !   PERQ (POS) Floating-Point Constants
                     !
                     %CONSTINTEGERARRAY PERQ LARGEST REAL (0:1)= X'FFFFFFFF',
                                                                 X'7FEFFFFF'
               %OWNLONGREALNAME LARGEST REAL                              ;!%C
                                LARGEST REAL is mapped onto PERQ LARGEST REAL
                                !
                                !
                               %FINISH; !if PERQ
%FINISH; !defining LARGEST REAL



%CONSTINTEGERARRAY Integer Power Of Ten (0:9)=                              %C
                                                                            %C
                                 1,
                                 10,         {by using this table    }
                                 100,        {we overcome any problem}
                                 1000,       {we may have if integer }
                                 10000,      {exponentiation has not }
                                 100000,     {yet been implemented   }
                                 1000000,
                                 10000000,
                                 100000000,
                                 1000000000




!
!*************************************************************************
!
!     SPECIFICATIONS FOR EXTERNAL PROCEDURES
!
!*************************************************************************
!

%EXTERNALLONGLONGREALFNSPEC POWER OF TEN %ALIAS "S#POWEROFTEN" (%INTEGER POWER) 





!
!************************************************************************
!
!     SPECIFICATIONS FOR LOCAL PROCEDURES
!
!************************************************************************
!

%INTEGERFNSPEC  TO INTEGER  (%INTEGER DATA AD, DATA LEN , INT LEN  , INT PTR)
%INTEGERFNSPEC  TO REAL     (%INTEGER DATA AD, DATA LEN , INT LEN  , INT PTR)

%INTEGERFNSPEC     COMPARE  (%INTEGER  LENGTH, THIS BASE, THIS DISP,
                             %INTEGER          THAT BASE, THAT DISP)





!
!   Local Variables
!
    %INTEGER  D PTR ; !ptr to decimal digits in local buffer
    %INTEGER  E PTR ; !ptr to exponent digits in local buffer
    %INTEGER  E LEN ; !number of digits in the exponent
    %INTEGER  E SIGN; !set zero of no exponent sign
                      !set  -ve if exponent sign='-'
                      !set  +ve if exponent sign='+'
    %INTEGER    SIGN; !set zero if no numeric sign
                      !set  -ve if numeric sign='-'
                      !set  +ve if numeric sign='+'
    %INTEGER  B FLAG; ! if zero then leading spaces are to be ignored
    %INTEGER  C     ; !the current character being analysed
    %INTEGER  I     ; !the scanning ptr through the local buffer
    %INTEGER  LENGTH; !the number of digits specified
    %INTEGER  FAULT
              !
    %INTEGER S1 PTR, S2 PTR, S PTR                                  ;!%C
             S1 PTR, S2 PTR are ptrs into the I/O buffer to positions %C
                            where significant digits for the numeric  %C
                            and exponent parts respectively are expected
               {and   S PTR points to the exponent character in the I/O buffer}
%INTEGER PTR, PTR MAX                                               ;!%C
         PTR, PTR MAX point to the start and end of the text          %C
                            in the I/O buffer respectively

%INTEGER INT PTR, INT LEN                                           ;!%C
         INT PTR, INT LEN describe the location and length of the     %C
                          analysed text which has been placed in TEXT

!
!   Exponent Related Variables
!
%INTEGER  EXP    ; !the exponent converted into binary
%INTEGER  MULT   ; !  a multiplier used while converting the exponent
%INTEGER  J      ; !--a utility variable


!
!   Initialise Variables
!
    D PTR = Not Set  ; !=> no decimal point found
    E PTR = Not Set  ; !=> no exponent found
    E SIGN= Not Set  ; !=> no exponent sign found
      SIGN= Not Set  ; !=> no numeric sign found
    B FLAG= Not Set  ; !=> leading spaces are not significant
      I   = Not Set  ; !=> no significant digits found
          !
      PTR = TEXT PTR
  PTR MAX = TEXT END
          !
  !S1 PTR = PTR; !used to determine a null numeric
  !S2 PTR = PTR; !                 or null exponent part

!
!
!   ANALYSE THE NUMBER
!
!
%WHILE PTR<PTR MAX %CYCLE
                 !
      {pick up}  C= IO BUFFER(PTR)
      {the next}              PTR= PTR+1
      {character}   -> HANDLE(TYPE(C))   {and go and process it}


HANDLE (Syntax Fault): ! Handle an ILLEGAL Character !
                       !                             !
                       !                             !
      INVALID CHAR   :  FAULT= Invalid Character; -> REPORT
      INVALID REAL   :  FAULT= Invalid Real     ; -> REPORT
      INVALID INTEGER:  FAULT= Invalid Integer

              REPORT :  TEXT PTR= PTR
                       %RESULT  = FAULT

!        NULL FIELD1 :  TEXT PTR= S1 PTR
!                      %RESULT  =    Null Field
!        NULL FIELD2 :  TEXT PTR= S2 PTR
!                      %RESULT  =    Null Field


HANDLE (A Blank): ! Handle a SPACE Character !
                  !                          !
                  !                          !
        %CONTINUE %IF B FLAG= 0 %OR BLANKS\=Zero {ignore insignificant blanks}
                            !
        {otherwise}     C   ='0' {and fall through}


HANDLE (A Digit): ! Handle a DIGIT !
                  !                !
                  !                !
           I=I+1;     TEXT(I)= C      {save the digit}
                    B FLAG   = ON
                  %CONTINUE


HANDLE (A Sign):  ! Handle a SIGN (it may signify an exponent) !
                  !                                            !
                  !                                            !
        %IF E PTR=Not Set %THENSTART
        %IF SIGN\=Not Set {ie we have already had a sign} %OR         %C
               I\=Not Set {ie we have at least one digit} %THEN       %C
                                 E SIGN= C  %AND -> AN EXPONENT
                    {otherwise}    SIGN= C {%AND S1 PTR= PTR}
        %FINISHELSESTART

        {IF E PTR \=Not Set %THENSTART}
        %IF E PTR \=    I+1 {ie sign is embedded in an exponent}    %ORC
            E SIGN\=Not Set {ie   we have an exponent sign already}   %C
                            %THEN -> INVALID REAL
            E SIGN =  C
           {S2 PTR = PTR}
           %FINISH
           %CONTINUE


HANDLE (A Decimal Point): ! Handle a DECIMAL part !
                          !                       !
                          !                       !
                          -> INVALID INTEGER %IF FORMAT='I'
                          -> INVALID REAL    %IF D PTR\= 0            %C
                                             %OR E PTR\= 0

                  B FLAG= ON  {save any embedded blank}
                  D PTR = I+1 {note the decimal point}
               %CONTINUE


HANDLE (A Lower Case Exp{onent}): ! Handle a Lower Case Exponent !
                                  !                              !
                                  !                              !
                                        C=C-' '
                                         {convert to upper case}


HANDLE (An Exponent): ! Handle an EXPONENT !
        AN EXPONENT : !                    !
                      !                    !
        -> INVALID CHAR    %IF      C='Q' %AND RELAX ANSI= False
        -> INVALID INTEGER %IF FORMAT='I'
        -> INVALID REAL    %IF E PTR\= Not Set

                               E PTR =  I+1
                               B FLAG=  Off
                              {S2 PTR=  PTR  %AND} S PTR= PTR
         %CONTINUE


HANDLE (A Comma): ! Handle Premature End !  HANDLE (A Carriage Return):
                  !     of Input Field   !
                  !                      !
                  %IF CR Delimiter=False %AND C=CR %THEN -> INVALID CHAR
                  %EXIT

%REPEAT; !for the next character


    LENGTH= I; TEXT PTR= PTR MAX - PTR
!
!   ANALYSE THE ANALYSIS
!
%IF E PTR\=Not Set %THENSTART
                   !
                   !   Analyse the given Exponent
                   !
                   %IF E PTR>LENGTH %THENSTART
!                    -> NULL FIELD2 %IF BLANKS\=Zero                  %C
                                    %OR S2 PTR = PTR
                                    %FINISH
                       E LEN=LENGTH - (E PTR-1)
                      LENGTH= E PTR -  1
                         PTR= S PTR -  1
    !
    !   Convert the given Exponent into Binary
    !
    %IF E LEN> 9 %THENSTART
                 !
                 !Use the Integer Conversion Routine for Large Exponents
                 !
                  J=TO INTEGER(ADDR(EXP),4,E LEN,E PTR)

       %FINISHELSESTART
             !
             EXP = 0
       %IF E LEN > 0 %THENSTART
                      !
                      MULT= Integer Power Of Ten (E LEN - 1)

      %WHILE MULT> 0 %CYCLE
             EXP = EXP + (MULT * ( TEXT(E PTR) - '0'))
           E PTR = E PTR+ 1
             MULT= MULT//10
      %REPEAT
      %FINISH; %FINISH
               !
               %IF EXP>32767  %THEN EXP=  32767
               %IF E SIGN='-' %THEN EXP= -EXP
                     !
                     SCALE FACTOR= -EXP
               %FINISH
                    !Handling an Exponent
    !
    !   Analyse the (rest of the) Number
    !
!   %IF LENGTH=Null %THENSTART
!              !
!          -> NULL FIELD1 %IF S1 PTR =   PTR - D PTR %OR              %C
!                            (S1 PTR\=S2 PTR - D PTR %AND BLANKS\=Zero)
!                   %FINISH
    %IF D PTR\=Null %THEN DECS=LENGTH - (D PTR-1)

!
!   Prepare to Call a Numeric Conversion Routine
!
%IF SIGN\= Not Set  %THENSTART
                     !
   {set parameters}  TEXT(0)= SIGN  ;  INT PTR= 0
   {for a call on }                    INT LEN= LENGTH+1
   {    TO REAL   } %FINISHELSESTART;  INT LEN= LENGTH
   { or on        }                    INT PTR= 1
   {    TO INTEGER}          %FINISH

!
!
!   NOW CONVERT TEXT INTO BINARY
!
!
%IF FORMAT= 'I' %THEN FAULT= TO INTEGER (DATA AD, DATA LEN, INT LEN, INT PTR) %C
                %ELSE FAULT= TO REAL    (DATA AD, DATA LEN, INT LEN, INT PTR)

%IF FAULT\= 0 %THEN TEXT PTR= PTR MAX
       !
%RESULT= FAULT







%INTEGERFN TO INTEGER (%INTEGER DATA AD , DATA LEN , TEXT LEN , TEXT INC)
!
!
!
!
!     THIS IS A PROCEDURE TO CONVERT A STRING OF CHARACTERS (which
!
!          have been analysed syntactically) INTO AN INTEGER VALUE.
!
!
!The character string is assumed to be in the area  TEXT, and is
!defined by the parameters TEXT LEN and TEXT INC which identify the
!length and start (relative to TEXT) of the string respectively. At
!exit the result is stored in the location defined by the parameters
!DATA AD and DATA LEN which identify the address and the length (in
!bytes) of the result location.
!
!
!NOTE1: It is assumed that there are no leading, embedded or trailing  blanks
!NOTE2: The string of digits is assumed to represent a valid integer
!
!
!       At Exit:  RESULT=  0 if the constant was within range
!                 RESULT= 20 if the constant was out of range and MODE= Compile Time
!                 RESULT=188 if the constant was out of range and MODE=     Run Time1
!
!
!
%IF TARGET= Gould %THENSTART
          !
          !
%CONSTINTEGERARRAY Maximum Of (0:2)= 0, -32768, X'80000000'
                           !
                           !the values above represent the largest
                           !    values that may be assigned to a
                           !    INTEGER*1 or INTEGER*2 or INTEGER*4 respectively
  %FINISHELSESTART
           !
           !
     %CONSTINTEGERARRAY Maximum Of (0:2)= -128, -32768, X'80000000'
                                !
                                !the values above represent the largest
                                !    values that may be assigned to a
                                !    BYTE or INTEGER*2 or INTEGER*4 respectively
     %FINISH


!Text of the Largest Negative Integer:
      !
     %CONSTBYTEINTEGERARRAY Largest Integer(0:9)= {-}'2','1','4','7','4',
                                                     '8','3','6','4','8'

!
!   Variables used to Address the Digits
!
    %INTEGER     PTR  {scanning ptr through TEXT  }
    %INTEGER MAX PTR  { maximum value PTR may have}
    %INTEGER LEN                                                    ;!%C
             LEN is the actual number                                 %C
                 of significant digits in the TEXT

!
!   Variables used to Convert the Digits to Binary
!
    %INTEGER  SIGN  ; !set +ve if value is positive, else set to zero
    %INTEGER  MULT  ; !scaling to be applied to the next digit
    %INTEGER  SUM   ; !the binary result
    %INTEGER  I
             {a utility variable}

!
!   Initialise Variables
!
     PTR=  TEXT INC      ; !initialise the scanning ptr
 MAX PTR=  TEXT LEN + PTR; !initialise its maximum value

!
!   Check for a Sign
!
    SIGN= TEXT (PTR)
%IF SIGN< '0' %THENSTART
              %IF SIGN='+' %THEN SIGN=A Plus                          %C
                           %ELSE SIGN=A Minus
                   PTR=PTR+1
              %FINISH      %ELSE SIGN=A Plus

!
!   Check Magnitude of the Value
!
    LEN= MAX PTR - PTR
%IF LEN> 9 %THENSTART  {chance of Integer Overflow later}

           !
           !   Skip any Leading Spaces or Zeros
           !
        A:     I=TEXT(PTR)
           %IF I='0' %THEN PTR=     PTR + 1   %AND -> A
                           LEN= MAX PTR - PTR
  -> INTEGER OVERFLOW  %IF LEN> 10
  ->  SIMPLE APPROACH  %IF LEN< 10

           !
           !   Now Test for Integer Overflow (when there are 10 digits)
           !
               I=COMPARE(10,ADDR(TEXT(0)),PTR,ADDR(Largest Integer(0)),0)
              -> INTEGER OVERFLOW                                     %C
                              %IF I+SIGN> 0
           %FINISH

SIMPLE APPROACH:      SUM=0;  %IF LEN>0 %THENSTART
       !
       !  Now Convert the Text into Binary
       !
              MULT=-Integer Power Of Ten (LEN-1)

       %WHILE MULT<  0 %CYCLE
                  !
              SUM =  SUM + (MULT * (TEXT(PTR) - '0'))
              PTR =  PTR + 1
              MULT=  MULT//10
       %REPEAT

              SUM = -SUM %UNLESS SIGN=A Minus
                         %FINISH

%IF DATA LEN= 4 {bytes} %THENSTART
    !
    !
    !   Assign the Value to an INTEGER*4
    !
    !
        INTEGER(DATA AD)= SUM
    %FINISHELSESTART

%IF DATA LEN= 2 {bytes} %THENSTART
    !
    !
    !   Assign the Value to an INTEGER*2
    !
    !
    %IF SIGN=A Minus %THENSTART
                            %IF SUM<-32768 %THEN -> INTEGER OVERFLOW
             %FINISH %ELSE  %IF SUM> 32767 %THEN -> INTEGER OVERFLOW
              !
              !
    {Perform the Assignment}    HALFINTEGER(DATA AD)= SUM %IF HALFs= True
                               SHORTINTEGER(DATA AD)= SUM %IF HALFs= False

%FINISHELSESTART
    !
    !
    !   Assign the Value to a BYTE or (INTEGER*1 if Gould)
    !
    !
    %IF SIGN=A Minus %THENSTART

       %IF TARGET = Gould %AND SUM<   0 %THEN -> INTEGER OVERFLOW
       %IF TARGET\= Gould %AND SUM<-128 %THEN -> INTEGER OVERFLOW
       %FINISHELSESTART

             %IF TARGET = Gould %AND SUM> 255 %THEN -> INTEGER OVERFLOW
             %IF TARGET\= Gould %AND SUM> 127 %THEN -> INTEGER OVERFLOW
             %FINISH
              !
              !
    {Perform the Assignment}        INTEGER(DATA AD)= SUM
        !                            Note that the calling routine is
    %FINISH; !                        expected to perform the actual
    %FINISH; !                        assignment

    %RESULT= 0 {return with no errors}


INTEGER OVERFLOW: !check if this is a fault
    !
    %IF MODE\= Run Time2 %THENRESULT= Constant Out Of Range

    !
    !   Set Data Item to Maximum Permitted Value
    !
        SUM= Maximum Of (DATA LEN >> 1)
        SUM=-(SUM+1) %IF SIGN=A Plus
        SUM=  SUM & X'FF' %IF TARGET= Gould
           !
    %IF DATA LEN= 2  %THENSTART
                     %IF Halfs= False %THEN SHORTINTEGER(DATA AD)= SUM        %C
                                      %ELSE  HALFINTEGER(DATA AD)= SUM
               %FINISHELSE                       INTEGER(DATA AD)= SUM

    %RESULT= 0

%END; !of TO INTEGER





%INTEGERFN TO REAL (%INTEGER DATA AD, DATA LEN,  INT LEN,  INT PTR)
!
!
!
!
!     THIS PROCEDURE CONVERTS A STRING OF CHARACTERS (which have been
!
!          analysed syntactically) INTO A FLOATING POINT NUMBER.
!
!
!The character string is assumed to be in an area TEXT and is defined
!by the parameters INT LEN, INT PTR, which identify the length and
!start (relative to TEXT) of the characters. The global integer DECS
!defines the implied positioning of the decimal point: while the global
!variable SCALE FACTOR defines the exponentiation to be applied to the
!result. The result is saved in the location defined by DATA AD and
!DATA LEN which specify its address and length (in bytes) respectively.
!
!
!NOTE1: There are no embedded or trailing blanks
!NOTE2: It is assumed that there are no leading spaces
!NOTE3: The character string is assumed to represent a
!           valid floating point number
!
!
!       At Exit:  RESULT=  0 if the constant was within range
!                 RESULT= 20 if the constant was out of range and MODE= Compile Time
!                 RESULT=188 if the constant was out of range and MODE=     Run Time1
!
!
!

!NOTE if running in compiler mode then TO REAL returns -1
       ! as a result if more digits are specified than can
       ! be represented in the requested precision
       !

       %IF MODE= Compile Time %THENSTART
               !
              %INTEGER RESULT

         !CONSTINTEGER No Comment=  0 ,
                Lost Significance= -1

         %FINISH


%IF IEEE= False %THENSTART; !-------------Define Excess-64 type Real Constants

%IF TARGET=EMAS %OR TARGET= IBM %THENSTART
          !
          !
          !   Declare IBM type specific Floating Point Constants
          !
          !
!%CONSTLONGLONGREAL  Maximum Single = R'7FFFFFFF000000000000000000000000' {!!!}
!%CONSTLONGLONGREAL  Maximum Double = R'7FFFFFFFFFFFFFFF0000000000000000' {!!!}

  %IF TARGET= EMAS %THENSTART
            !
 !%OWNLONGLONGREAL    Real4 Rounding= R'00000000800000000000000000000000' {!!!}
 !%OWNLONGLONGREAL    Real8 Rounding= R'00000000000000000080000000000000' {!!!}
                 !
                 !Note that on IBM style architectures, assignments to
                 !   a shorter precision is rounded up, but not on 2900
                 !   style architectures.
           %FINISH

 %FINISHELSESTART
            !
            !   Declare Gould specific Floating Point Constants
            !
            %CONSTLONGREAL Maximum Single= R'7FFFFFFF00000000'
            %CONSTLONGREAL Maximum Double= R'7FFFFFFFFFFFFFFF'
            %FINISH

%CONSTINTEGER     Max Power=  75
%CONSTINTEGER     Min Power= -78

  %OWNSTRING(40) LARGEST POSSIBLE= "7237005577332262213973186563043052414499"

                !LARGEST POSSIBLE is a representation, in characters, of
                !    the 40 most significant digits of the largest possible
                !    real in 'Excess 64' notation.

%FINISHELSESTART;           !-------------Define IEEE type Real Constants
       !
       !
       !   Declare IEEE specific Floating Point Constants
       !
       !
 %CONSTLONGREAL    Maximum Single= 3.40282356@+38
 %CONSTLONGREAL    Minimum Single= 1.17549440@-38

 %CONSTINTEGER         Min Power = -306
 %CONSTINTEGER         Max Power =  308

   %OWNSTRING(16) LARGEST POSSIBLE= "1797693134862315"

                 !LARGEST POSSIBLE is a representation, in characters, of
                 !    the 16 most significant digits of the largest possible
                 !    real defined in the IEEE Standard
 %FINISH

!
!   Variables used to Address the Digits
!
    %INTEGER     PTR  {scanning ptr through TEXT  }
    %INTEGER MAX PTR  { maximum value PTR may have}
    %INTEGER LEN                                                    ;!%C
             LEN is the actual number                                 %C
                 of significant digits in the TEXT

!
!   Variables associated with the Scale of the Number
!
    %INTEGER MAX DIGITS; !maximum significant digits associated with the required precision
    %INTEGER VAL SIZE  ; !scale of the  leftmost significant digit
    %INTEGER     EXP   ; !scale of the rightmost significant digit
    %INTEGER     SIGN  ; ! sign of the value, either=A MINUS,
                                                  or=A PLUS
!
!   Variables used in Numeric Conversion
!
    %INTEGER  MULT   ; !scaling to be applied to the next digit
    %INTEGER  SUM    ; ! binary integer value of the digits bar scaling
%LONGLONGREAL X      ; ! actual Real result
        %REAL Y


     EXP=-(SCALE FACTOR+DECS)
        !
        !Initialise the exponentiation to be applied

!
!
!   Examine the Number
!
!
    SIGN=A Plus {guess}
        !
%IF INT LEN>0 %THENSTART
    !
    !   Look for a Numeric Sign
    !
        SIGN= TEXT(INT PTR)
    %IF SIGN<'0' %THENSTART
                 %IF SIGN='-' %THEN SIGN=A Minus
                  INT LEN=INT LEN-1
                  INT PTR=INT PTR+1
                  !
                 %FINISH
    %FINISH

 PTR= 1; MAX PTR= INT LEN

!
!   Ignore Leading and Trailing Zeros
!
     PTR=    PTR+1 %WHILE MAX PTR>=PTR %AND TEXT(PTR)='0'
                          !ignore any leading zeros
 MAX PTR=MAX PTR-1 %AND                                               %C
     EXP=    EXP+1 %WHILE MAX PTR>=PTR %AND TEXT(MAX PTR)='0'
                          !ignore any trailing zeros

!
!   Determine the Magnitude of the Value
!
    LEN=MAX PTR - (PTR-1) %AND MAX DIGITS= DATA LEN << 1
%IF LEN>MAX DIGITS %THENSTART           {= 8 or 16 or 32}
            !
            !   Ignore any digits which have no bearing on the result
            !
                EXP= EXP + (LEN-MAX DIGITS)
                LEN= MAX DIGITS
             RESULT= Lost Significance %IF MODE= Compile Time
                   !
            %FINISHELSE %IF MODE= Compile Time %THEN RESULT= No Comment

    VAL SIZE=EXP + (LEN-1); !NOTE: LEN=number of significant digits
            !               !      EXP= scale of   rightmost digit
            !               ! VAL SIZE= scale of    leftmost digit
%IF VAL SIZE> Max Power %OR                                           %C
        EXP < Min Power %THEN -> FURTHER EXAMINATION
                        !Jump if
                        !     the value is around or beyond
                        !     the capabilities of the code below

FORM RESULT:      X=0.0
     !
     !   Test for a Zero
     !
     %IF LEN<= 0 %THENSTART
                  !
            -> ASSIGN A REAL4  %IF DATA LEN= 4
            -> ASSIGN A REAL8  %IF DATA LEN= 8 %OR TARGET\= IBM
            -> ASSIGN A REAL16 %IF TARGET= IBM
           %FINISH

!
!
!   Perform the Conversion
!
!
%IF LEN> 9 %THENSTART
           %CYCLE;   MULT= 100000000 {10 ** ** 8}
                      SUM= 0

                %CYCLE;   SUM =  SUM + (MULT * (TEXT(PTR) - '0'))
                          PTR =  PTR + 1
                          MULT= MULT// 10
                %REPEAT %UNTIL  MULT<= 0

            LEN= LEN - 9
              X=   X + (SUM * POWER OF TEN(EXP+LEN))

           %REPEAT %UNTIL LEN< 10
%FINISH
      !
      !The loop above is used when more than 9 digits are to be converted
      !    into a floating point number. Each set of nine digits (from
      !    left to right) are converted into an integer, then scaled as
      !    appropriate, and then added to the result of the previous
      !    loop (if any). Note if 10 or more digits were processed as a
      !    time then overflow would/could occur.

           !The code below operates similarly as above but uses the final
           !N digits (N<=9), and incorporates the result into the running
           !total if any:

                     MULT= Integer Power Of Ten (LEN-1)
                      SUM= 0

           %CYCLE;    SUM= SUM + (MULT * (TEXT(PTR) - '0'))
                      PTR= PTR + 1
                     MULT=MULT//10
           %REPEAT %UNTIL MULT<= 0

     X= X + (SUM * POWER OF TEN(EXP))


RETURN RESULT:
     !
     !
     !     Assign the Value to the I/O Item
     !
     !

%IF DATA LEN= 4 %THENSTART
                !
                !   Return a Single Precision Real
                !
                %IF X>= Maximum Single %THENSTART

%IF TARGET\=IBM %AND X> Maximum Single %AND MODE\=Run Time2 %THEN -> CHECK MODE
                     X= Maximum Single;%FINISHELSESTART

%IF TARGET\=IBM   %ANDC
    TARGET\=GOULD %AND X<=Minimum Single %THENSTART
                   %IF X< Minimum Single %AND MODE\=Run Time2 %THEN -> CHECK MODE
                       X= Minimum Single;%FINISH

%IF TARGET=EMAS %THEN BYTEINTEGER(ADDR(Real4 Rounding))=BYTEINTEGER(ADDR(X)) %C
                %AND            X= X + Real4 Rounding
                %FINISH

ASSIGN A REAL4:  Y= X
         !
         Y     =-Y %IF SIGN=A Minus
  REAL(DATA AD)= Y
              -> RETURN
       %FINISH

%IF TARGET= IBM %AND DATA LEN= 16 %THENSTART
                !
                !   Return an Extended Precision Real
                !
ASSIGN A REAL16:                    X =-X %IF SIGN=A Minus
                 LONGLONGREAL(DATA AD)= X
              -> RETURN
                %FINISH

    !
    !   Return a Double Precision Real
    !
    %IF TARGET = IBM %OR TARGET= EMAS %THENSTART
               !
         %IF X>= Maximum Double %THEN X= Maximum Double                               %ELSESTART

                %IF TARGET=EMAS %THEN BYTEINTEGER(ADDR(Real8 Rounding))= BYTEINTEGER(ADDR(X)) %C
                                %AND  X=X + Real8 Rounding
                                %FINISH
         %FINISH

ASSIGN A REAL8:                 X =-X %IF SIGN=A Minus
                 LONGREAL(DATA AD)= X

RETURN:         %RESULT= RESULT %IF MODE= Compile Time
                %RESULT= 0
                      != 0 if run time


FURTHER EXAMINATION: !required for very large or for very small
                     !         values before conversion can be
                     !         attempted
                     !
  %IF VAL SIZE<  Min Power %THEN -> VALUE TOO SMALL
  %IF VAL SIZE>= Max Power %THENSTART
  %IF VAL SIZE = Max Power %THENSTART
                         !
                         !   Compare Digits with the Largest Possible Real
                         !
                          -> VALUE TOO LARGE                          %C
                            %IF COMPARE (LEN,ADDR(TEXT(0)), PTR,
                                             ADDR(LARGEST POSSIBLE),1)>0
                         %FINISHELSE                                  %C
                                {!}                                   %C
                                 %IF LEN=0 %THEN -> VALUE TOO SMALL   %C
                                           %ELSE -> VALUE TOO LARGE
                     %FINISH

%IF EXP<  Min Power %THENSTART
                    !
                    !   Ignore digit which will have no effect on the Result
                    !
                        LEN = LEN + (EXP-Min Power)
                        EXP = Min Power
                    %FINISH

    -> FORM RESULT


!
!   HANDLE NUMBERS OUT OF THE PERMITTED RANGE
!
VALUE TOO SMALL:   X=    0.0     ;      -> CHECK MODE
VALUE TOO LARGE:   X=LARGEST REAL;
                   !
    CHECK MODE :   %IF MODE\= Run Time2 %THENRESULT= Constant Out Of Range
                          !\=> it is a fault

 -> RETURN RESULT
!
!
!
%END; !of TO REAL




!
!***********************************************************************
!
!     UTILITY PROCEDURES
!
!***********************************************************************
!

%INTEGERFN COMPARE (%INTEGER LENGTH, THIS BASE, THIS DISP,
                                     THAT BASE, THAT DISP)
!
!
!
!
!     A Utility Procedure to lexographically compare two texts
!
!            of equal length and to return a value which
!
!            represents the result of the comparision.
!
!
!     At Exit:  RESULT=  0 if Text(THIS BASE)=Text(THAT BASE) or LENGTH<=0
!               RESULT= -1 if Text(THIS BASE)<Text(THAT BASE)
!               RESULT=  1 if Text(THIS BASE)>Text(THAT BASE)
!
!
!
%IF TARGET= PERQ %OR TARGET= Whitechapel %THENSTART

   %BYTEINTEGERARRAYFORMAT Byte Format (0:30000)
   %BYTEINTEGERARRAYNAME   THIS
   %BYTEINTEGERARRAYNAME   THAT
                           THAT== ARRAY (THAT BASE, Byte Format)
                           THIS== ARRAY (THIS BASE, Byte Format)
   %WHILE LENGTH>0 %CYCLE
       !
      %RESULT= 1 {greater than} %IF THIS(THIS DISP)> THAT(THAT DISP)
      %RESULT=-1 {   less than} %IF THIS(THIS DISP)< THAT(THAT DISP)

                THIS DISP= THIS DISP + 1
                THAT DISP= THAT DISP + 1
                   LENGTH=    LENGTH - 1
      %REPEAT
      %RESULT= 0 {equal if we fall through the cycle}

%FINISHELSESTART
       !
%IF TARGET= PNX %THENSTART
                   !
                 THIS BASE= THIS BASE + THIS BASE + THIS DISP
                 THAT BASE= THAT BASE + THAT BASE + THAT DISP
%FINISHELSESTART
        !
      THAT BASE= THAT BASE +THAT DISP
      THIS BASE= THIS BASE +THIS DISP
   %FINISH

%WHILE LENGTH>0 %CYCLE
    !
    %RESULT= 1 {greater than}                                         %C
               %IF BYTEINTEGER(THIS BASE)>BYTEINTEGER(THAT BASE)

    %RESULT=-1 {   less than}                                         %C
               %IF BYTEINTEGER(THIS BASE)<BYTEINTEGER(THAT BASE)
                               !
                               THIS BASE = THIS BASE + 1
                               THAT BASE = THAT BASE + 1
                                  LENGTH =    LENGTH - 1
    %REPEAT
    !     !
    %RESULT= 0 {  equal to  }
    %FINISH
      !
%END; !of COMPARE



%END; !of IN NUMBER






%ENDOFFILE

!                                                                 fcinnum1
! 10/10/86 - copy of ftncinnum7