Fortran std support
- Dominant language
- Python
- Stars
- 9
- Forks
- 9
- Avg merge
- 12d 12h
- Merged PRs (30d)
- 2
Description
While the analyse step supports specifying the Fortran standard to be used by fparser. But `parse/fortran.py` does hard-code some classes Fortran 2008, and so de-facto the standard does not work (admittedly in rather rare circumstances like mixing C and Fortran).
Test:
```
git diff CFortranInterop/test_CFortranInterop.py
diff --git a/tests/system_tests/CFortranInterop/test_CFortranInterop.py b/tests/system_tests/CFortranInterop/test_CFortranInterop.py
index 1231c37..ccff586 100644
--- a/tests/system_tests/CFortranInterop/test_CFortranInterop.py
+++ b/tests/system_tests/CFortranInterop/test_CFortranInterop.py
@@ -35,7 +35,8 @@ def test_CFortranInterop(tmp_path):
c_pragma_injector(config)
preprocess_c(config)
preprocess_fortran(config)
- analyse(config, root_symbol='main')
+ analyse(config, root_symbol='main',
+ std="f2003")
compile_c(config, common_flags=['-c', '-std=c99'])
with warns(UserWarning, match="Removing managed flag"):
compile_fortran(config, common_flags=['-c'])
```
Results in linking errors due to missing symbols.
Most cases can be fixed by e.g.:
```
< elif obj_type == Type_Declaration_Stmt:
---
> elif isinstance(obj, Type_Declaration_Stmt):
```
and importing Type_Declaration_Stmt from `fparser.two.fortran2003`, NOT `fparser.two.fortran2008` (since f2008's class is derived from the 2003 class).
Main issue is that the above inheritance does NOT apply for `*_List`, esp. `Attr_Spec_List` (all `*_List` classes are programmatically created in fparser), meaning:
```
specs = _typed_child(obj, Attr_Spec_List)
```
does not work (since Attr_Spec_list is either F2003 or 2008).
Possible solutions: either import both types and check for a tuple:
```
...
from f2008 Type_Declaration_Stmt as Type_Declaration_Stmt_2008...
...
specs = _typed_child(obj, (Attr_Spec_List, Type_Declaration_Stmt_2008))
```
Or, using knowledge about fparser's implementation (which avoids importing anything from Fortran2008)
```
if isinstance(child, SequenceBase) and child.subclass_names == ["Attr_Spec"]:
specs = child
break
else:
specs = None
```
Ideally, fparser would provide an API to use this (or maybe the implementation can be changed that `F2008.*_List` inherits from `F2003.*_List`.
Contributor guide
Research direction
Inspect parse/fortran.py and the fparser standard handling, then reproduce the issue by applying the shown std="f2003" change in tests/system_tests/CFortranInterop/test_CFortranInterop.py. Compare the F2003 and F2008 type and list classes, and use the test to verify that the C/Fortran interoperability case links successfully without missing symbols.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100