expression(3f) - [M_calculator] return value from a string expression processing messages to simplify call to CALCULATOR(3f)
(LICENSE:PD)
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
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.
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.
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: RNUM0(),CALCULATOR(),INUM0(),SNUM0()
John S. Urban
Public Domain
AUTHOR John S. Urban
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | inlin0 | |||
doubleprecision | :: | outval | ||||
character(len=*) | :: | outlin0 | ||||
integer, | intent(out) | :: | ierr | |||
integer, | intent(out) | :: | ilen |
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