@@ -35,6 +35,7 @@ module function_parser
35
35
! parameters:
36
36
real (wp), parameter :: zero = 0.0_wp
37
37
real (wp), parameter :: one = 1.0_wp
38
+ real (wp), parameter :: pi = acos (- one)
38
39
39
40
! Note: these should be continuous, unique integers:
40
41
! [they must have the values that correspond to the array indices below]
@@ -60,8 +61,8 @@ module function_parser
60
61
cAcos = 20 , &
61
62
cAtan2 = 21 , & ! atan2 must precede atan to prevent aliasing.
62
63
cAtan = 22 , &
63
- cTest0 = 23 , & ! Test function with 0 arguments (returns 15.0).
64
- cTest3 = 24 ! Test function with 3 arguments (returns sum of arguments).
64
+ cPi = 23 , & ! Pi ( function with zero arguments)
65
+ cIf = 24 ! Test function with 3 arguments (returns sum of arguments).
65
66
integer , parameter :: VarBegin = 25
66
67
67
68
character (len= 1 ), dimension (cAdd:cPow), parameter :: operators = [ ' +' , & ! plus
@@ -70,7 +71,7 @@ module function_parser
70
71
' /' , & ! divide
71
72
' ^' ] ! power
72
73
73
- character (len= 5 ), dimension (cAbs:cTest3 ), parameter :: functions = [ ' abs ' , &
74
+ character (len= 5 ), dimension (cAbs:cIf ), parameter :: functions = [ ' abs ' , &
74
75
' exp ' , &
75
76
' log10' , &
76
77
' log ' , &
@@ -85,11 +86,11 @@ module function_parser
85
86
' acos ' , &
86
87
' atan2' , &
87
88
' atan ' , &
88
- ' test0 ' , &
89
- ' test3 ' ]
89
+ ' pi ' , &
90
+ ' if ' ]
90
91
91
92
! Specify the number of required arguments each `functions` element must have.
92
- integer , dimension (cAbs:cTest3 ), parameter :: required_args = [ 1 , & ! abs
93
+ integer , dimension (cAbs:cIf ), parameter :: required_args = [ 1 , & ! abs
93
94
1 , & ! exp
94
95
1 , & ! log10
95
96
1 , & ! log
@@ -104,11 +105,11 @@ module function_parser
104
105
1 , & ! acos
105
106
2 , & ! atan2
106
107
1 , & ! atan
107
- 0 , & ! test0
108
- 3 ] ! test3
108
+ 0 , & ! pi
109
+ 3 ] ! if
109
110
110
111
! Specify the number of optional arguments each `functions` element might have.
111
- integer , dimension (cAbs:cTest3 ), parameter :: optional_args = [ 0 , & ! abs
112
+ integer , dimension (cAbs:cIf ), parameter :: optional_args = [ 0 , & ! abs
112
113
0 , & ! exp
113
114
0 , & ! log10
114
115
0 , & ! log
@@ -123,8 +124,8 @@ module function_parser
123
124
0 , & ! acos
124
125
0 , & ! atan2
125
126
1 , & ! atan
126
- 0 , & ! test0
127
- 0 ] ! test3
127
+ 0 , & ! pi
128
+ 0 ] ! if
128
129
129
130
! The maximum number of arguments any `functions` element might have.
130
131
integer , parameter :: max_func_args = maxval (required_args + optional_args)
@@ -1042,9 +1043,9 @@ end subroutine catan2_func
1042
1043
1043
1044
! ******************************************************************
1044
1045
! >
1045
- ! Test function with zero arguments.
1046
+ ! Pi. A function with zero arguments.
1046
1047
1047
- subroutine ctest0_func (me ,ip ,dp ,sp ,val ,ierr )
1048
+ subroutine cPi_func (me ,ip ,dp ,sp ,val ,ierr )
1048
1049
1049
1050
implicit none
1050
1051
@@ -1056,17 +1057,21 @@ subroutine ctest0_func(me,ip,dp,sp,val,ierr)
1056
1057
integer ,intent (out ) :: ierr ! ! error flag
1057
1058
1058
1059
sp = sp + 1
1059
- me% stack(sp) = 15.0_wp
1060
+ me% stack(sp) = pi
1060
1061
ierr = 0
1061
1062
1062
- end subroutine ctest0_func
1063
+ end subroutine cPi_func
1063
1064
! ******************************************************************
1064
1065
1065
1066
! ******************************************************************
1066
1067
! >
1067
- ! Test function with three arguments.
1068
+ ! If function with three arguments.
1069
+ !
1070
+ ! `If(expression, value is true, value if false)`
1071
+ !
1072
+ ! Where: 0 is false and /=0 is true.
1068
1073
1069
- subroutine ctest3_func (me ,ip ,dp ,sp ,val ,ierr )
1074
+ subroutine cif_func (me ,ip ,dp ,sp ,val ,ierr )
1070
1075
1071
1076
implicit none
1072
1077
@@ -1077,11 +1082,16 @@ subroutine ctest3_func(me,ip,dp,sp,val,ierr)
1077
1082
real (wp),dimension (:),intent (in ) :: val ! ! variable values
1078
1083
integer ,intent (out ) :: ierr ! ! error flag
1079
1084
1080
- me% stack(sp-2 ) = me% stack(sp-2 ) + me% stack(sp-1 ) + me% stack(sp)
1085
+ if (me% stack(sp-2 ) /= zero) then ! true
1086
+ me% stack(sp-2 ) = me% stack(sp-1 )
1087
+ else ! false
1088
+ me% stack(sp-2 ) = me% stack(sp)
1089
+ end if
1090
+
1081
1091
sp = sp - 2
1082
1092
ierr = 0
1083
1093
1084
- end subroutine ctest3_func
1094
+ end subroutine cif_func
1085
1095
! ******************************************************************
1086
1096
1087
1097
! ******************************************************************
@@ -1136,9 +1146,9 @@ subroutine find_arg_positions(paren_start, func, num_args, arg_pos, ierr, err_po
1136
1146
integer :: cur_pos, & ! ! The current position in `func` being processed.
1137
1147
func_len, & ! ! The length of `func`.
1138
1148
open_parens, & ! ! The number of open parentheses.
1139
- arg_len, & ! ! The length of an argument.
1149
+ arg_len, & ! ! The length of an argument.
1140
1150
iarg ! ! Argument index.
1141
-
1151
+
1142
1152
! Initialize outputs.
1143
1153
num_args = 1
1144
1154
arg_pos = 0
@@ -1147,14 +1157,14 @@ subroutine find_arg_positions(paren_start, func, num_args, arg_pos, ierr, err_po
1147
1157
1148
1158
func_len = len_trim (func)
1149
1159
open_parens = 1
1150
-
1160
+
1151
1161
cur_pos = paren_start + 1
1152
1162
func_len = len_trim (func)
1153
1163
1154
1164
! Step through the function string until we find the function's closing parenthesis.
1155
1165
! Every time we find a comma character at the same parentheses level as the function's
1156
- ! opening parenthesis, increment the number of arguments and record the previous
1157
- ! argument's last character.
1166
+ ! opening parenthesis, increment the number of arguments and record the previous
1167
+ ! argument's last character.
1158
1168
do while (open_parens > 0 )
1159
1169
if (cur_pos > func_len) then
1160
1170
! The function did not have a closing parenthesis.
@@ -1176,7 +1186,7 @@ subroutine find_arg_positions(paren_start, func, num_args, arg_pos, ierr, err_po
1176
1186
end if
1177
1187
1178
1188
open_parens = open_parens - 1
1179
-
1189
+
1180
1190
! We have arrived at the function's closing parenthesis.
1181
1191
if (open_parens == 0 ) arg_pos(num_args) = cur_pos - 1
1182
1192
@@ -1203,9 +1213,9 @@ subroutine find_arg_positions(paren_start, func, num_args, arg_pos, ierr, err_po
1203
1213
do iarg = 1 , num_args
1204
1214
if (iarg == 1 ) then
1205
1215
arg_len = arg_pos(iarg) - paren_start
1206
- else
1216
+ else
1207
1217
arg_len = arg_pos(iarg) - arg_pos(iarg - 1 ) - 1
1208
- endif
1218
+ endif
1209
1219
1210
1220
if (arg_len == 0 ) then
1211
1221
if (present (ierr)) ierr = empty_arg
@@ -1215,7 +1225,7 @@ subroutine find_arg_positions(paren_start, func, num_args, arg_pos, ierr, err_po
1215
1225
end do
1216
1226
1217
1227
end subroutine find_arg_positions
1218
-
1228
+ ! *******************************************************************************
1219
1229
1220
1230
! *******************************************************************************
1221
1231
! >
@@ -1254,7 +1264,7 @@ recursive subroutine check_syntax (me,func,funcstr,var,ipos)
1254
1264
if (c == ' (' ) then
1255
1265
parcnt = parcnt + 1
1256
1266
elseif (c == ' )' ) then
1257
- parcnt = parcnt - 1
1267
+ parcnt = parcnt - 1
1258
1268
end if
1259
1269
1260
1270
if (parcnt < 0 ) then
@@ -1306,25 +1316,25 @@ recursive subroutine check_syntax (me,func,funcstr,var,ipos)
1306
1316
call me% add_error(j, ipos, funcstr, ' Missing opening parenthesis' )
1307
1317
return
1308
1318
end if
1309
-
1319
+
1310
1320
! Find the number of function arguments and argument substring positions
1311
1321
! in `func`.
1312
1322
call find_arg_positions(j, func, num_args, arg_pos, ierr, err_pos)
1313
1323
if (ierr /= 0 ) then
1314
1324
select case (ierr)
1315
- case (1 ); call me% add_error(err_pos, ipos, funcstr, ' Missing function closing parenthesis' )
1325
+ case (1 ); call me% add_error(err_pos, ipos, funcstr, ' Missing function closing parenthesis' )
1316
1326
case (2 ); call me% add_error(err_pos, ipos, funcstr, ' Function has too many arguments' )
1317
1327
case (3 ); call me% add_error(err_pos, ipos, funcstr, ' Function has an empty argument' )
1318
1328
case default ; call me% add_error(err_pos, ipos, funcstr, ' Unknown find argument position error' )
1319
1329
end select
1320
1330
return
1321
1331
end if
1322
1332
1323
- ! Verify that the number of function arguments present is consistent
1333
+ ! Verify that the number of function arguments present is consistent
1324
1334
! with the specified function.
1325
1335
if (num_args < required_args(n)) then
1326
1336
call me% add_error(j, ipos, funcstr, ' Missing required function argument' )
1327
- return
1337
+ return
1328
1338
elseif (num_args > required_args(n) + optional_args(n)) then
1329
1339
call me% add_error(j, ipos, funcstr, ' Too many function arguments' )
1330
1340
return
@@ -1336,7 +1346,7 @@ recursive subroutine check_syntax (me,func,funcstr,var,ipos)
1336
1346
else
1337
1347
do iarg = 1 , num_args
1338
1348
if (iarg == 1 ) then
1339
- arg_start = j + 1
1349
+ arg_start = j + 1
1340
1350
else
1341
1351
arg_start = arg_pos(iarg-1 ) + 2
1342
1352
endif
@@ -1346,7 +1356,7 @@ recursive subroutine check_syntax (me,func,funcstr,var,ipos)
1346
1356
1347
1357
call me% check_syntax(func(arg_start:arg_end), funcstr, var, func_arg_ipos)
1348
1358
if (me% error()) return
1349
- end do
1359
+ end do
1350
1360
1351
1361
j = arg_pos(num_args) + 2
1352
1362
endif
@@ -1518,7 +1528,7 @@ function mathfunction_index (str) result (n)
1518
1528
character (len= len (functions)) :: fun
1519
1529
1520
1530
n = 0
1521
- do j= cAbs,cTest3 ! check all math functions
1531
+ do j= cAbs,cIf ! check all math functions
1522
1532
k = min (len_trim (functions(j)), len (str))
1523
1533
call to_lowercase (str(1 :k), fun)
1524
1534
if (fun == functions(j)) then ! compare lower case letters
@@ -1724,8 +1734,8 @@ subroutine add_compiled_byte (me, b, num_args)
1724
1734
case (1 ); me% bytecode_ops(me% bytecodesize)% f = > catan_func
1725
1735
case (2 ); me% bytecode_ops(me% bytecodesize)% f = > catan2_func
1726
1736
end select
1727
- case (cTest0 ); me% bytecode_ops(me% bytecodesize)% f = > ctest0_func
1728
- case (cTest3 ); me% bytecode_ops(me% bytecodesize)% f = > ctest3_func
1737
+ case (cPi ); me% bytecode_ops(me% bytecodesize)% f = > cPi_func
1738
+ case (cIf ); me% bytecode_ops(me% bytecodesize)% f = > cif_func
1729
1739
case default ; me% bytecode_ops(me% bytecodesize)% f = > cdefault_func
1730
1740
end select
1731
1741
@@ -1749,7 +1759,7 @@ function mathitem_index (me, f, var) result (n)
1749
1759
integer :: n ! ! byte value of math item
1750
1760
1751
1761
n = 0
1752
- if (len (f)==0 ) return ! error condition
1762
+ if (len (f)==0 ) return ! error condition
1753
1763
1754
1764
if (scan (f(1 :1 ),' 0123456789.' ) > 0 ) then ! check for begin of a number
1755
1765
me% immedsize = me% immedsize + 1
@@ -1845,7 +1855,7 @@ recursive subroutine compile_substr (me, f, b, e, var)
1845
1855
end do
1846
1856
else
1847
1857
me% stackptr = me% stackptr + 1
1848
- if (me% stackptr > me% stacksize) me% stacksize = me% stacksize + 1
1858
+ if (me% stackptr > me% stacksize) me% stacksize = me% stacksize + 1
1849
1859
end if
1850
1860
1851
1861
call add_compiled_byte (me, n, num_args)
@@ -1877,7 +1887,7 @@ recursive subroutine compile_substr (me, f, b, e, var)
1877
1887
end do
1878
1888
else
1879
1889
me% stackptr = me% stackptr + 1
1880
- if (me% stackptr > me% stacksize) me% stacksize = me% stacksize + 1
1890
+ if (me% stackptr > me% stacksize) me% stacksize = me% stacksize + 1
1881
1891
end if
1882
1892
1883
1893
call add_compiled_byte (me, n, num_args)
0 commit comments