diff --git a/CHANGELOG.md b/CHANGELOG.md index dbcfce80..088dd70c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ Modifications by (in alphabetical order): * P. Vitt, University of Siegen, Germany * A. Voysey, UK Met Office +26/08/2026 PR #518. Adds support for the remaining F2008 intrinsics. + 26/08/2026 PR #526 for #484. Adds a 'format-missing-comma' extension which permits commas to be omitted between character-string edit descriptors and neighbouring format items. diff --git a/src/fparser/two/Fortran2008/intrinsics_f08.py b/src/fparser/two/Fortran2008/intrinsics_f08.py index d80096c4..28e94508 100644 --- a/src/fparser/two/Fortran2008/intrinsics_f08.py +++ b/src/fparser/two/Fortran2008/intrinsics_f08.py @@ -61,20 +61,82 @@ class Intrinsic_Name(F2003_Intrinsic_Name): f08_math_intrinsics = { "ERF": {"min": 1, "max": 1}, + "ERFC": {"min": 1, "max": 1}, + "ERFC_SCALED": {"min": 1, "max": 1}, "GAMMA": {"min": 1, "max": 1}, + "HYPOT": {"min": 2, "max": 2}, + "LOG_GAMMA": {"min": 1, "max": 1}, + "NORM2": {"min": 1, "max": 2}, + } + + f08_bitsequence_comparison_intrinsics = { + "BGE": {"min": 2, "max": 2}, + "BGT": {"min": 2, "max": 2}, + "BLE": {"min": 2, "max": 2}, + "BLT": {"min": 2, "max": 2}, } f08_bitshift_intrinsics = { + "DSHIFTL": {"min": 3, "max": 3}, + "DSHIFTR": {"min": 3, "max": 3}, "SHIFTL": {"min": 2, "max": 2}, "SHIFTR": {"min": 2, "max": 2}, "SHIFTA": {"min": 2, "max": 2}, + "MERGE_BITS": {"min": 3, "max": 3}, + } + + f08_counting_bit_intrinsics = { + "LEADZ": {"min": 1, "max": 1}, + "POPCNT": {"min": 1, "max": 1}, + "POPPAR": {"min": 1, "max": 1}, + "TRAILZ": {"min": 1, "max": 1}, + } + + f08_masking_bit_intrinsics = { + "MASKL": {"min": 1, "max": 2}, + "MASKR": {"min": 1, "max": 2}, + } + + f08_bit_transformation_intrinsics = { + "IALL": {"min": 1, "max": 3}, + "IANY": {"min": 1, "max": 3}, + "IPARITY": {"min": 1, "max": 3}, + } + + f08_other_intrinsics = { + "STORAGE_SIZE": {"min": 1, "max": 2}, + "PARITY": {"min": 1, "max": 2}, + "EXECUTE_COMMAND_LINE": {"min": 1, "max": 5}, + "FINDLOC": {"min": 2, "max": 6}, + } + + f08_trig_and_hyper_functions = { + "ACOSH": {"min": 1, "max": 1}, + "ASINH": {"min": 1, "max": 1}, + "ATANH": {"min": 1, "max": 1}, + } + + f08_bessel_functions = { + "BESSEL_J0": {"min": 1, "max": 1}, + "BESSEL_J1": {"min": 1, "max": 1}, + "BESSEL_JN": {"min": 2, "max": 3}, + "BESSEL_Y0": {"min": 1, "max": 1}, + "BESSEL_Y1": {"min": 1, "max": 1}, + "BESSEL_YN": {"min": 2, "max": 3}, } # Create the dicts (not inherited from F2003_Intrinsic_Name) generic_function_names = {} generic_function_names.update(F2003_Intrinsic_Name.generic_function_names) generic_function_names.update(f08_math_intrinsics) + generic_function_names.update(f08_bitsequence_comparison_intrinsics) generic_function_names.update(f08_bitshift_intrinsics) + generic_function_names.update(f08_counting_bit_intrinsics) + generic_function_names.update(f08_masking_bit_intrinsics) + generic_function_names.update(f08_bit_transformation_intrinsics) + generic_function_names.update(f08_other_intrinsics) + generic_function_names.update(f08_trig_and_hyper_functions) + generic_function_names.update(f08_bessel_functions) specific_function_names = F2003_Intrinsic_Name.specific_function_names diff --git a/src/fparser/two/tests/fortran2008/test_intrinsics_2008.py b/src/fparser/two/tests/fortran2008/test_intrinsics_2008.py index ff54ee60..3ab3bd07 100644 --- a/src/fparser/two/tests/fortran2008/test_intrinsics_2008.py +++ b/src/fparser/two/tests/fortran2008/test_intrinsics_2008.py @@ -96,3 +96,32 @@ def test_f2008_intrinsic_f2003_parse(f2003_parser): partref = walk(tree, Fortran2003.Part_Ref) assert len(partref) == 1 assert str(partref[0]) == "erf(i)" + + +@pytest.mark.parametrize( + "dtype, intrinsic, output", + [ + ("integer", "erf(i)", "ERF"), + ("integer", "min(i, i)", "MIN"), + ("integer", "dshiftl(i, j, 1)", "DSHIFTL"), + ("integer", "popcnt(i)", "POPCNT"), + ("integer", "maskl(i, kind=8)", "MASKL"), + ("integer, dimension(100)", "iparity(i, 1)", "IPARITY"), + ("logical, dimension(100)", "parity(i)", "PARITY"), + ("real", "acosh(i)", "ACOSH"), + ("real", "bessel_j0(i)", "BESSEL_J0"), + ], +) +def test_f2008_intrinsic_types(dtype, intrinsic, output, f2008_parser): + """Test each subtype of f2008 intrinsics are correctly parsed.""" + reader = FortranStringReader(f"""subroutine test + + {dtype} :: i, j + + i = {intrinsic} + end subroutine test""") + + tree = f2008_parser(reader) + intrinsic = walk(tree, Fortran2008.Intrinsic_Name) + assert len(intrinsic) == 1 + assert str(intrinsic[0]) == output