expression Subroutine

public recursive subroutine expression(inlin0, outval, outlin0, ierr, ilen)

NAME

 expression(3f) - [M_calculator] return value from a string expression processing messages to simplify call to CALCULATOR(3f)
 (LICENSE:PD)

SYNOPSIS

subroutine expression(inlin0,outval,outlin0,ierr,ilen)

 character(len=*), intent=(in)  :: inlin0
 doubleprecision, intent=(out)  :: outval
 character(len=*), intent=(out) :: outlin0
 integer, intent=(out)          :: ierr
 integer, intent=(out)          :: ilen

DESCRIPTION

 expression() takes a string containing a FORTRAN-like expression and evaluates
 it and returns a numeric or string value as appropriate.
 The main purpose of expression() is to assume the burden of displaying the
 calculator messages for codes that make multiple calls to CALCULATOR(3f).
 CALCULATOR(3f) does not display error messages directly.

   o EXPRESSION(3f) calls the calculator routine CALCULATOR(3f) to evaluate the
     expressions.
   o Messages beginning with a # are considered comments and are not passed
     on to the calculator.

 inlin0  INLIN0 is a string containing a numeric expression. The expression can
         be up to (iclen_calc=512) characters long. The syntax of an expression
         is as described in the main document of the Calc library. For example:

           'A=sin(3.1416/5)'
           '# this is a comment'
           '$STR("The value is ",40/3)'

 outval  OUTVAL is a numeric value calculated from the expression in INLIN0
         (when IERR returns 0).
         When a string value is returned (IERR=2) then OUTVAL is the length of
         the output string.
 outlin0  OUTLIN0 contains a string representation of the number returned in
          OUTVAL up to 23 characters long when INLIN0 is a numeric expression. It
          contains a string up to (iclen_calc=512) characters long when INLIN0 is
          a string expression.
 ierr    IERR returns

         o -1 if an error occurred
         o 0 if a numeric value is returned (value is in OUTVAL, string
           representation of the value is in OUTLIN2).
         o 1 if no value was returned but a message was displayed (If a 'dump'
           or 'funcs' command was passed to the calculator).
         o 2 if the expression evaluated to a string value instead of a
           numeric value (value is in OUTLIN0).
 ilen    ILEN returns the length of the input string minus trailing blanks.

DEPENDENCIES

   o User-supplied routines:
     All programs that call the calculator routine can supply their
     own substitute_subroutine(3f) and substitute_C(3f) procedures. See
     the example program for samples.

EXAMPLES

Sample program:

 program demo_expression
 use M_calculator, only : iclen_calc
 use M_calculator, only : expression
 implicit none
 character(len=iclen_calc) ::  outlin0
 doubleprecision :: outval
 integer :: ierr, ilen
    call expression('A=3.4**5    ',outval,outlin0,ierr,ilen)
    write(*,*)'value of expression is ',outval
    write(*,*)'string representation of value is ',trim(outlin0)
    write(*,*)'error flag value is ',ierr
    write(*,*)'length of expression is ',ilen
 end program demo_expression

Results:

 value of expression is    454.35424000000000
 string representation of value is 454.35424
 error flag value is            0
 length of expression is            8

SEE ALSO

 See also: RNUM0(),CALCULATOR(),INUM0(),SNUM0()

AUTHOR

John S. Urban

LICENSE

Public Domain

AUTHOR John S. Urban

VERSION V1.0, 19971123

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: inlin0
doubleprecision :: outval
character(len=*) :: outlin0
integer, intent(out) :: ierr
integer, intent(out) :: ilen

Source Code

recursive subroutine expression(inlin0,outval,outlin0,ierr,ilen)

! ident_20="@(#) M_calculator expression(3f) call CALCULATOR(3f) calculator and display messages"

! evaluate a FORTRAN-like string expression and return a numeric
! value and its character equivalent or a string value as appropriate
character(len=*),intent(in) :: inlin0
doubleprecision             :: outval
character(len=*)            :: outlin0
integer,intent(out)         :: ierr
integer,intent(out)         :: ilen

character(len=iclen_calc)   :: line
character(len=iclen_calc)   :: outlin
doubleprecision,save        :: rvalue=0.0d0
intrinsic                   :: len
integer                     :: imaxi
character(len=iclen_calc)   :: event
!#----------------------------------------------------------------------------------------------------------------------------------
   ! copy INLIN0 to working copy LINE and find position of last non-blank character
   ! in the string
   line=''
   line=inlin0
   ! if the line is blank set imaxi to 1, else set it to the least of the length of the input string or (iclen_calc)
   ! NOTE: not checking if input expression is longer than (iclen_calc) characters!!
   imaxi=max(min(len(line),len(inlin0)),1)
   ilen=len_trim(line(1:imaxi))
!-----------------------------------------------------------------------------------------------------------------------------------
   if(ilen.eq.0)then                                            ! command was totally blank
      ierr=-1
      write(*,g)'*expression* warning===> blank expression'
!-----------------------------------------------------------------------------------------------------------------------------------
   elseif(line(:1).eq.'#')then                                  ! line was a comment
!-----------------------------------------------------------------------------------------------------------------------------------
   else
      ierr=0
      call calculator(line(:ilen),outlin,event,rvalue,ierr)         ! evaluate the expression
!-----------------------------------------------------------------------------------------------------------------------------------
      select case(ierr)
      case(-1)                                    ! trapped error, display error message
        write(*,g)'*expression* error===>',event
        !call pdec(line(:ilen))                   ! echo input string as is and in ASCII decimal
      case(1)                                     ! general message, display message
        write(*,g)'*expression* message===>',event
      case(0)                                     ! numeric output
         outlin0=outlin
      case(2)                                     ! string output
         outlin0=event                            ! assumes outlin is long enough to return the string into
         ilen=int(rvalue)                         ! in special mode where a string is returned, rvalue is the length of the string
      case default
        write(*,g)'*expression* warning===> unexpected ierr value=',ierr
      end select
!-----------------------------------------------------------------------------------------------------------------------------------
   endif
!-----------------------------------------------------------------------------------------------------------------------------------
   outval=rvalue                            ! return normal sized real value
end subroutine expression