Skip to content

Commit 84af6c2

Browse files
committed
Fixed a bug with multiple function args
fixed case with minus sign after a comma [e.g, atan(1,-2)]. Fixes #14
1 parent 343fdf2 commit 84af6c2

File tree

2 files changed

+67
-62
lines changed

2 files changed

+67
-62
lines changed

src/function_parser.f90

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ subroutine parse_function (me, funcstr, var, case_sensitive)
435435
logical,intent(in),optional :: case_sensitive !! are the variables case sensitive?
436436
!! [default is false]
437437

438-
character (len=len(funcstr)) :: func !! function string, local use
438+
character (len=:),allocatable :: func !! function string, local use
439439
character(len=len(var)),dimension(size(var)) :: tmp_var !! variable list, local use
440440
integer,dimension(:),allocatable :: ipos
441441

@@ -452,11 +452,11 @@ subroutine parse_function (me, funcstr, var, case_sensitive)
452452
call me%destroy()
453453

454454
!if is case insensitive, then convert both to lowercase:
455+
func = trim(adjustl(funcstr)) ! local copy of function string
455456
if (is_case_sensitive) then
456-
func = funcstr ! local copy of function string
457457
tmp_var = var
458458
else
459-
call to_lowercase (funcstr, func) ! local copy of function string
459+
call to_lowercase (func, func) ! local copy of function string
460460
call to_lowercase (var, tmp_var) !
461461
end if
462462

@@ -1541,9 +1541,6 @@ recursive subroutine check_syntax (me,func,funcstr,var,ipos)
15411541
end if
15421542
c = func(j:j)
15431543
if (c /= '(') then
1544-
! write(*,*) 'here', funcstr
1545-
! write(*,*) 'j = ', j
1546-
! write(*,*) 'c = ', c
15471544
call me%add_error(j, ipos, funcstr, 'Missing opening parenthesis')
15481545
return
15491546
end if
@@ -2164,7 +2161,7 @@ recursive subroutine compile_substr (me, f, b, e, var)
21642161
elseif (f(j:j) == '(') then
21652162
k = k-1
21662163
end if
2167-
if (k == 0 .and. f(j:j) == operators(io) .and. is_binary_operator (j, f)) then
2164+
if (k == 0 .and. f(j:j) == operators(io) .and. is_binary_operator (j, f)) then
21682165
if (any(f(j:j) == operators(cmul:cpow)) .and. f(b:b) == '-') then ! case 6: f(b:e) = '-...op...' with op > -
21692166
call compile_substr (me, f, b+1, e, var)
21702167
call add_compiled_byte (me, cneg)
@@ -2214,7 +2211,7 @@ function is_binary_operator (j, f) result (res)
22142211
if (f(j:j) == '+' .or. f(j:j) == '-') then ! plus or minus sign:
22152212
if (j == 1) then ! - leading unary operator ?
22162213
res = .false.
2217-
elseif (scan(f(j-1:j-1),'+-*/^(') > 0) then ! - other unary operator ?
2214+
elseif (scan(f(j-1:j-1),',+-*/^(') > 0) then ! - other unary operator ? (or comma from multi-arg functions)
22182215
res = .false.
22192216
elseif (scan(f(j+1:j+1),'0123456789') > 0 .and. & ! - in exponent of real number ?
22202217
scan(f(j-1:j-1),'eEdD') > 0) then
@@ -2235,7 +2232,7 @@ function is_binary_operator (j, f) result (res)
22352232
exit ! * all other characters
22362233
end if
22372234
end do
2238-
if (dflag .and. (k == 1 .or. scan(f(k:k),'+-*/^(') > 0)) res = .false.
2235+
if (dflag .and. (k == 1 .or. scan(f(k:k),',+-*/^(') > 0)) res = .false. ! need the comma here too ??
22392236
end if
22402237
end if
22412238

test/tests.f90

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -261,33 +261,37 @@ subroutine fptest6()
261261

262262
implicit none
263263

264-
integer, parameter :: nfunc = 26
265-
character (len=*), dimension(nfunc), parameter :: func = [ '-1.0*x ', &
266-
'-sqrt(x) ', &
267-
'a*COS(b*x)+5 ', &
268-
'a*COS(b*x)+5.0 ', &
269-
'exp(x)-abs(x)+log(1.0)+log10(1.0) ', &
270-
'sinh(x) ', &
271-
'cosh(x) ', &
272-
'tanh(x) ', &
273-
'tan(x) ', &
274-
'asin(y) ', &
275-
'acos(y) ', &
276-
'atan(y) ', &
277-
'-x**2 ', &
278-
'-x^2 ', &
279-
'sin(x) ', &
280-
'sin*2 ', &
281-
'2*(sin)*sin+1-sin(x) ', &
282-
'ceiling(1.1) + ceiling(1.1) ', &
283-
'floor(1.1) + floor(1.1) ', &
284-
'gamma(2.0) ', &
285-
'hypot(1.0, 2.0) ', &
286-
'max(1.0, 2.0) ', &
287-
'min(1.0, 2.0) ', &
288-
'modulo(180.0, -23.0)+mod(180.0, 23.0)', &
289-
'mod(180.0, 23.0)+modulo(180.0, 23.0) ', &
290-
'sign(1.0, -2.0) ' ]
264+
integer, parameter :: nfunc = 30
265+
character (len=*), dimension(nfunc), parameter :: func = [ '-1.0*x ', &
266+
'-sqrt(x) ', &
267+
'a*COS(b*x)+5 ', &
268+
'a*COS(b*x)+5.0 ', &
269+
'exp(x)-abs(x)+log(1.0)+log10(1.0) ', &
270+
'sinh(x) ', &
271+
'cosh(x) ', &
272+
'tanh(x) ', &
273+
'tan(x) ', &
274+
'asin(y) ', &
275+
'acos(y) ', &
276+
'atan(y) ', &
277+
'-x**2 ', &
278+
'-x^2 ', &
279+
'sin(x) ', &
280+
'sin*2 ', &
281+
'2*(sin)*sin+1-sin(x) ', &
282+
'ceiling(1.1) + ceiling(1.1) ', &
283+
'floor(1.1) + floor(1.1) ', &
284+
'gamma(2.0) ', &
285+
'hypot(1.0, 2.0) ', &
286+
'max(1.0, 2.0) ', &
287+
'min(1.0, 2.0) ', &
288+
'atan2(180.0, 23.0) ', &
289+
'atan2(1.0, -2.0) ', &
290+
'atan2(180.0, -23.0)+atan2(180.0, 23.0) ', &
291+
'mod(180.0, 23.0) ', &
292+
'modulo(180.0, 23.0) ', &
293+
'mod(-180.0, 23.0)+modulo(180.0, -23.0) ', &
294+
'sign(1.0, -2.0) ' ]
291295

292296
integer, parameter :: nvar = 5
293297
character (len=*), dimension(nvar), parameter :: var = [ 'x ', &
@@ -321,32 +325,36 @@ subroutine fptest6()
321325
b = val(3)
322326
y = val(4)
323327
s = val(5)
324-
call compare(func(1), -1.0_wp*x, res(1))
325-
call compare(func(2), -sqrt(x), res(2))
326-
call compare(func(3), a*cos(b*x)+5, res(3))
327-
call compare(func(4), a*cos(b*x)+5.0, res(4))
328-
call compare(func(5), exp(x)-abs(x)+log(1.0)+log10(1.0), res(5))
329-
call compare(func(6), sinh(x), res(6))
330-
call compare(func(7), cosh(x), res(7))
331-
call compare(func(8), tanh(x), res(8))
332-
call compare(func(9), tan(x), res(9))
333-
call compare(func(10), asin(y), res(10))
334-
call compare(func(11), acos(y), res(11))
335-
call compare(func(12), atan(y), res(12))
336-
call compare(func(13), -x**2, res(13))
337-
call compare(func(14), -x**2, res(14))
338-
call compare(func(15), sin(x), res(15))
339-
call compare(func(16), 2.0_wp, res(16))
340-
call compare(func(17), 2*(s)*s+1-sin(x), res(17))
341-
call compare(func(18), real(ceiling(1.1_wp) + ceiling(1.1_wp), wp) , res(18))
342-
call compare(func(19), real(floor(1.1_wp) + floor(1.1_wp), wp) , res(19))
343-
call compare(func(20), gamma(2.0_wp) , res(20))
344-
call compare(func(21), hypot(1.0_wp, 2.0_wp) , res(21))
345-
call compare(func(22), max(1.0_wp, 2.0_wp) , res(22))
346-
call compare(func(23), min(1.0_wp, 2.0_wp) , res(23))
347-
call compare(func(24), modulo(180.0_wp, -23.0_wp)+mod(180.0_wp, 23.0_wp) , res(24))
348-
call compare(func(25), mod(180.0_wp, 23.0_wp)+modulo(180.0_wp, 23.0_wp) , res(25))
349-
call compare(func(26), sign(1.0_wp, -2.0_wp) , res(26))
328+
call compare(func(1), -1.0_wp*x, res(1))
329+
call compare(func(2), -sqrt(x), res(2))
330+
call compare(func(3), a*cos(b*x)+5, res(3))
331+
call compare(func(4), a*cos(b*x)+5.0, res(4))
332+
call compare(func(5), exp(x)-abs(x)+log(1.0)+log10(1.0), res(5))
333+
call compare(func(6), sinh(x), res(6))
334+
call compare(func(7), cosh(x), res(7))
335+
call compare(func(8), tanh(x), res(8))
336+
call compare(func(9), tan(x), res(9))
337+
call compare(func(10), asin(y), res(10))
338+
call compare(func(11), acos(y), res(11))
339+
call compare(func(12), atan(y), res(12))
340+
call compare(func(13), -x**2, res(13))
341+
call compare(func(14), -x**2, res(14))
342+
call compare(func(15), sin(x), res(15))
343+
call compare(func(16), 2.0_wp, res(16))
344+
call compare(func(17), 2*(s)*s+1-sin(x), res(17))
345+
call compare(func(18), real(ceiling(1.1_wp) + ceiling(1.1_wp), wp) , res(18))
346+
call compare(func(19), real(floor(1.1_wp) + floor(1.1_wp), wp) , res(19))
347+
call compare(func(20), gamma(2.0_wp) , res(20))
348+
call compare(func(21), hypot(1.0_wp, 2.0_wp) , res(21))
349+
call compare(func(22), max(1.0_wp, 2.0_wp) , res(22))
350+
call compare(func(23), min(1.0_wp, 2.0_wp) , res(23))
351+
call compare(func(24), atan2(180.0_wp, 23.0_wp) , res(24))
352+
call compare(func(25), atan2(1.0_wp, -2.0_wp) , res(25))
353+
call compare(func(26), atan2(180.0_wp, -23.0_wp)+atan2(180.0_wp, 23.0_wp) , res(26))
354+
call compare(func(27), mod(180.0_wp, 23.0_wp) , res(27))
355+
call compare(func(28), modulo(180.0_wp, 23.0_wp) , res(28))
356+
call compare(func(29), mod(-180.0_wp, 23.0_wp)+modulo(180.0_wp, -23.0_wp) , res(29))
357+
call compare(func(30), sign(1.0_wp, -2.0_wp) , res(30))
350358

351359
end if
352360

0 commit comments

Comments
 (0)