calc.f90 Source File


This file depends on

sourcefile~~calc.f90~~EfferentGraph sourcefile~calc.f90 calc.f90 sourcefile~funcs.f90 funcs.f90 sourcefile~calc.f90->sourcefile~funcs.f90 sourcefile~ui.f90 ui.f90 sourcefile~calc.f90->sourcefile~ui.f90 sourcefile~eval.f90 eval.f90 sourcefile~calc.f90->sourcefile~eval.f90 sourcefile~reg.f90 reg.f90 sourcefile~calc.f90->sourcefile~reg.f90 sourcefile~gamma.f90 gamma.f90 sourcefile~funcs.f90->sourcefile~gamma.f90 sourcefile~trig.f90 trig.f90 sourcefile~funcs.f90->sourcefile~trig.f90 sourcefile~rat.f90 rat.f90 sourcefile~funcs.f90->sourcefile~rat.f90 sourcefile~hyper.f90 hyper.F90 sourcefile~funcs.f90->sourcefile~hyper.f90 sourcefile~stats.f90 stats.f90 sourcefile~funcs.f90->sourcefile~stats.f90 sourcefile~bessel.f90 bessel.f90 sourcefile~funcs.f90->sourcefile~bessel.f90 sourcefile~ui.f90->sourcefile~funcs.f90 sourcefile~ui.f90->sourcefile~reg.f90 sourcefile~eval.f90->sourcefile~funcs.f90 sourcefile~eval.f90->sourcefile~ui.f90 sourcefile~eval.f90->sourcefile~reg.f90 sourcefile~help.f90 help.f90 sourcefile~eval.f90->sourcefile~help.f90 sourcefile~gamma.f90->sourcefile~rat.f90 sourcefile~gamma.f90->sourcefile~hyper.f90 sourcefile~rat.f90->sourcefile~reg.f90 sourcefile~hyper.f90->sourcefile~reg.f90 sourcefile~hyper.f90->sourcefile~rat.f90 sourcefile~stats.f90->sourcefile~reg.f90 sourcefile~stats.f90->sourcefile~rat.f90 sourcefile~k1.f k1.f sourcefile~bessel.f90->sourcefile~k1.f sourcefile~ribesl.f ribesl.f sourcefile~bessel.f90->sourcefile~ribesl.f sourcefile~rybesl.f rybesl.f sourcefile~bessel.f90->sourcefile~rybesl.f sourcefile~k0.f k0.f sourcefile~bessel.f90->sourcefile~k0.f sourcefile~rkbesl.f rkbesl.f sourcefile~bessel.f90->sourcefile~rkbesl.f sourcefile~i0.f i0.f sourcefile~bessel.f90->sourcefile~i0.f sourcefile~i1.f i1.f sourcefile~bessel.f90->sourcefile~i1.f sourcefile~rjbesl.f rjbesl.f sourcefile~bessel.f90->sourcefile~rjbesl.f

Contents

Source Code


Source Code

! main program for Fortran 2018 RPN calculator

!---- (historical notes) -----------
!  Programmer:   David G. Simpson
!                NASA Goddard Space Flight Center
!                Greenbelt, Maryland  20771
!  Date:         December 28, 2005
!-----------------------------------


PROGRAM RPN
use, intrinsic:: iso_fortran_env, only: stdout=>output_unit, stdin=>input_unit
USE GLOBAL
use funcs, only:  isrational, isreal, iscomplex, toUpper
use stackops, only: printx, push_stack
use evals, only: eval
IMPLICIT NONE

real(wp), PARAMETER :: PI = 4._wp * atan(1._wp)
real(wp), PARAMETER :: TWOPI = 2*pi
INTEGER :: IDX, IERR, DEL, PTR, RN, RD
real(wp) :: X
COMPLEX(wp) :: CX
CHARACTER(300) :: LINE, SUBSTR
CHARACTER(100) :: NUMSTR
LOGICAL :: NUM_FLAG = .false.


print *, 'Fortran 2018  RPN Calculator, Version '//VERSION

!     Initialize data.

call init_stack()

DEL = IACHAR('a') - IACHAR('A')                                               ! find ASCII position diff between 'A' and 'a'

STACK = 0._wp                                                                 ! clear the REAL stack
REG = 0._wp                                                                   ! clear the REAL registers
LASTX = 0._wp                                                                 ! clear the REAL LAST X register

NN = 0._wp                                                                    ! clear the REAL summation registers
SUMX = 0._wp
SUMX2 = 0._wp
SUMY = 0._wp
SUMY2 = 0._wp
SUMXY = 0._wp

CSTACK = (0._wp,0._wp)                                                        ! clear the COMPLEX stack
CREG = (0._wp,0._wp)                                                          ! clear the COMPLEX registers
CLASTX = (0._wp,0._wp)                                                        ! clear the COMPLEX LAST X register

CNN = (0._wp,0._wp)                                                           ! clear the COMPLEX summation registers
CSUMX = (0._wp,0._wp)
CSUMX2 = (0._wp,0._wp)
CSUMY = (0._wp,0._wp)
CSUMY2 = (0._wp,0._wp)
CSUMXY = (0._wp,0._wp)

RNSTACK = 0; RDSTACK = 1                                                      ! clear the RATIONAL stack
RNREG = 0; RDREG = 1                                                          ! clear the RATIONAL registers
RNLASTX = 0; RDLASTX = 1                                                      ! clear the RATIONAL LAST X register

RNNN = 0; RDNN = 1                                                            ! clear the RATIONAL summation registers
RNSUMX = 0; RDSUMX = 1
RNSUMX2 = 0; RDSUMX2 = 1
RNSUMY = 0; RDSUMY = 1
RNSUMY2 = 0; RDSUMY2 = 1
RNSUMXY = 0; RDSUMXY = 1

ANGLE_MODE = INITIAL_ANGLE_MODE

SELECT CASE (ANGLE_MODE)
   CASE (1)                                                                   ! deg
      ANGLE_FACTOR = PI/180._wp
   CASE (2)                                                                   ! rad
      ANGLE_FACTOR = 1._wp
   CASE (3)                                                                   ! grad
      ANGLE_FACTOR = PI/200._wp
   CASE (4)                                                                   ! rev
      ANGLE_FACTOR = TWOPI
END SELECT

DISP_MODE = INITIAL_DISP_MODE                                                 ! set modes
DISP_DIGITS = INITIAL_DISP_DIGITS
DOMAIN_MODE = INITIAL_DOMAIN_MODE
BASE_MODE = INITIAL_BASE_MODE
FRACTION_MODE = INITIAL_FRACTION_MODE

FRACTOL = INITIAL_FRACTOL                                                     ! set decimal-to-fraction tolerance

!     call random_init()   ! Fortran 2018 + the following line
CALL RANDOM_SEED()                                                           ! init random number generator

! -----  Main loop.

DO                                                                            ! loop once for each input line
   WRITE(stdout,'(A)', ADVANCE='NO') '  ? '
   READ (stdin,'(A132)', iostat=ierr) LINE
   if (ierr<0) exit  ! Ctrl D was pressed

!     Convert the input line to all uppercase, removing leftmost blanks

   LINE = toUpper(ADJUSTL(LINE))
   
!     Search for QUIT 'Q'

   IF (TRIM(LINE) == 'Q') exit

   PTR = 1

!     Loop for each element in the input line.

   DO
      IDX = INDEX(LINE(PTR:), ' ') + PTR - 1                                  ! look for the next space..
      IF (IDX .EQ. 0) IDX = LEN(LINE(PTR:))                                   ! ..or end of line
      SUBSTR = LINE(PTR:IDX-1)                                                ! get the current substring

      SELECT CASE (DOMAIN_MODE)
         CASE (1)
            NUM_FLAG = ISREAL(SUBSTR, X)                                     ! convert to a real number, if possible
         CASE (2)
            NUM_FLAG = ISCOMPLEX (SUBSTR, CX)                                 ! convert to a complex number, if possible
         CASE (3)
            NUM_FLAG = ISRATIONAL (SUBSTR, RN, RD)                            ! convert to a rational number, if possible
      END SELECT

      IF (NUM_FLAG) THEN                                                      ! if a number, then put it on the stack
         SELECT CASE (DOMAIN_MODE)
            CASE (1)
               CALL PUSH_STACK (X)                                            ! push real number onto real stack
            CASE (2)
               CALL push_stack(CX)                                          ! push complex number onto complex stack
            CASE (3)
               CALL push_stack(RN, RD)                                      ! push rational number onto rational stack
         END SELECT
      ELSE                                                                    ! else it's an operator
         CALL EVAL (SUBSTR)                                                   ! evaluate operator
      END IF

      PTR = IDX + 1                                                           ! update line pointer
      IF (LEN_TRIM(LINE(PTR:)) .EQ. 0) EXIT                                   ! exit if at end of line
   END DO


!     Print X register.

   SELECT CASE (DOMAIN_MODE)
      CASE (1)
         CALL PRINTX(STACK(1), NUMSTR)                                        ! format REAL X
      CASE (2)
         CALL PRINTX(CSTACK(1), NUMSTR)                                      ! format COMPLEX X
      CASE (3)
         CALL PRINTX(RNSTACK(1), RDSTACK(1), NUMSTR)                         ! format RATIONAL X
   END SELECT

   print '(3X,A)', TRIM(NUMSTR)                                  ! print X

END DO

! -- end program by printing last value (helping automatic self test cases)
print *,new_line('')
SELECT CASE (DOMAIN_MODE)
CASE (1)
  CALL PRINTX(STACK(1), NUMSTR) 
CASE (2)
  CALL PRINTX(CSTACK(1), NUMSTR) 
CASE (3)
  CALL PRINTX(RNSTACK(1), RDSTACK(1), NUMSTR) 
END SELECT

print '(3X,A)', TRIM(NUMSTR)

END PROGRAM RPN