-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Yet another edge case, which is most likely not possible to resolve without having procedures in the symbol table. However, I felt it might be useful to document it:
Function calls in expressions and derived type member references are represented inconsistently. One distinction seems to be made based on whether named arguments are used or not.
A little example:
fcode = """
module inline_call_mod
implicit none
type mytype
integer :: val
integer :: arr(3)
contains
procedure :: some_func
end type mytype
contains
function check(val, thr) result(is_bad)
integer, intent(in) :: val
integer, intent(in), optional :: thr
integer :: eff_thr
logical :: is_bad
if (present(thr)) then
eff_thr = thr
else
eff_thr = 10
end if
is_bad = val > thr
end function check
function some_func(this) result(is_bad)
class(mytype), intent(in) :: this
logical :: is_bad
is_bad = check(this%val, thr=10) &
& .or. check(this%arr(1)) .or. check(val=this%arr(2)) .or. check(this%arr(3))
end function some_func
end module inline_call_mod
""".strip()
from fparser.common.readfortran import FortranStringReader
from fparser.two.parser import ParserFactory
reader = FortranStringReader(fcode)
parser = ParserFactory().create(std='f2003')
ast = parser(reader)
ast
The four calls to check
in the is_bad = ...
expression are represented as:
check(this%val, thr=10)
:
Structure_Constructor(Type_Name('check'), Component_Spec_List(',', (Proc_Component_Ref(Name('this'), '%', Name('val')), Component_Spec(Name('thr'), Int_Literal_Constant('10', None))))
check(this%arr(1))
:
Part_Ref(Name('check'), Section_Subscript_List(',', (Data_Ref('%', (Name('this'), Part_Ref(Name('arr'), Section_Subscript_List(',', (Int_Literal_Constant('1', None),))))),)))
check(val=this%arr(2))
:
Structure_Constructor(Type_Name('check'), Component_Spec_List(',', (Component_Spec(Name('val'), Data_Ref('%', (Name('this'), Part_Ref(Name('arr'), Section_Subscript_List(',', (Int_Literal_Constant('2', None),)))))),)))
check(this%arr(3))
:
Part_Ref(Name('check'), Section_Subscript_List(',', (Data_Ref('%', (Name('this'), Part_Ref(Name('arr'), Section_Subscript_List(',', (Int_Literal_Constant('3', None),))))),)))
What should, to my understanding, be a Function_Reference
, is either represented as Structure_Constructor
(named argument present) or Part_Ref
(no named argument present).
Additionally, the reference to this%val
is represented as a Proc_Component_Ref
in the first case, but (correctly?) identified as a Data_Ref
in all others.