]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
runtime(fortran): update fortran syntax (#13870)
authorAjit-Thakkar <142174202+Ajit-Thakkar@users.noreply.github.com>
Mon, 15 Jan 2024 21:42:03 +0000 (17:42 -0400)
committerGitHub <noreply@github.com>
Mon, 15 Jan 2024 21:42:03 +0000 (22:42 +0100)
Support most remaining features of Fortran 2018/2023
Small improvements to folding etc,
Code cleanup: use \? instead of mix of \= and \?

Signed-off-by: Ajit-Thakkar <142174202+Ajit-Thakkar@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/syntax/fortran.vim

index 1fb8a1c424b8e529f0039332c4468b01568e0434..306fa11cf12f2586e09e23d09db64220d94801f4 100644 (file)
@@ -1,6 +1,6 @@
 " Vim syntax file
 " Language:    Fortran 2023 (and Fortran 2018, 2008, 2003, 95, 90, and 77)
-" Version:     (v110) 2024 January 03
+" Version:     (v111) 2024 January 15
 " Maintainers: Ajit J. Thakkar <ajit@unb.ca>; <https://ajit.ext.unb.ca/>
 "              Joshua Hollett <j.hollett@uwinnipeg.ca>
 " Usage:       For instructions, do :help fortran-syntax from Vim
@@ -78,13 +78,13 @@ syn match fortranConstructName          "\%(\<end\s*forall\s\+\)\@15<=\a\w*\>"
 syn match fortranConstructName          "\%(\<end\s*critical\s\+\)\@17<=\a\w*\>"
 syn match fortranConstructName          "\%(\<end\s*associate\s\+\)\@18<=\a\w*\>"
 
-syn match fortranUnitName               "\%(\<\%(end\s*\)\?\%(subroutine\|function\|module\|program\|submodule\)\s\+\)\@12<=\a\w\+"
+syn match fortranUnitName               "\%(\<\%(end\s*\)\?\%(subroutine\|function\|module\|program\|submodule\)\s\+\)\@12<=\a\w*"
 syn match fortranUnitHeader             "\<end\>\ze\s*\%(!.*\)\?$"
 
 syn keyword fortranIntrinsic   abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh
 syn keyword fortranIntrinsicR  achar iachar transfer dble dprod dim lge lgt lle llt mod
 syn keyword fortranIntrinsic    command_argument_count get_command get_command_argument get_environment_variable is_iostat_end is_iostat_eor move_alloc new_line same_type_as extends_type_of
-syn keyword fortranIntrinsic    selected_real_kind selected_int_kind selected_logical_kind selected_char_kind
+syn keyword fortranIntrinsic    selected_real_kind selected_int_kind selected_logical_kind selected_char_kind next previous
 syn keyword fortranIntrinsic    acosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2
 syn keyword fortranIntrinsic    adjustl adjustr all allocated any associated bit_size btest ceiling cshift date_and_time digits
 syn keyword fortranIntrinsic    dot_product eoshift exponent floor fraction iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc merge minexponent minloc
@@ -92,19 +92,27 @@ syn keyword fortranIntrinsic    modulo mvbits nearest pack precision present rad
 "syn keyword fortranIntrinsic    count epsilon maxval minval product sum huge tiny
 " intrinsic names often used for variables in older Fortran code
 syn match fortranIntrinsic      '\<\%(count\|epsilon\|maxval\|minval\|product\|sum\|huge\|tiny\)\>\ze\s*('
-syn keyword fortranIntrinsic    spread system_clock transpose trim ubound unpack verify
+syn keyword fortranIntrinsic    spread system_clock transpose trim ubound unpack verify is_contiguous event_query
 syn keyword fortranIntrinsic    atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits
 syn keyword fortranIntrinsic    bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image
 syn keyword fortranIntrinsic    null cpu_time failed_images stopped_images image_status co_broadcast co_max co_min co_sum co_reduce
 syn keyword fortranIntrinsic    atomic_add atomic_and atomic_or atomic_xor atomic_fetch_add atomic_fetch_and atomic_fetch_or atomic_fetch_xor atomic_cas
-syn keyword fortranIntrinsic    ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode
-syn keyword fortranIntrinsic    ieee_max ieee_max_mag ieee_min ieee_min_mag split tokenize ieee_support_subnormal ieee_get_modes ieee_set_modes
-syn keyword fortranIntrinsic    ieee_set_status ieee_get_rounding_mode ieee_set_rounding_mode
-syn keyword fortranIntrinsic    iso_c_binding c_loc c_funloc c_sizeof c_associated c_f_pointer c_f_procpointer
-syn keyword fortranIntrinsic   out_of_range reduce random_init coshape
+syn keyword fortranIntrinsic    ieee_arithmetic ieee_features ieee_exceptions
+syn keyword fortranIntrinsic   ieee_class ieee_copy_sign ieee_fma ieee_get_rounding_mode ieee_get_underflow_mode ieee_int ieee_is_finite
+syn keyword fortranIntrinsic   ieee_is_nan ieee_is_negative ieee_is_normal ieee_logb ieee_max ieee_max_mag ieee_max_num ieee_max_num_mag
+syn keyword fortranIntrinsic   ieee_min ieee_min_mag ieee_min_num ieee_min_num_mag ieee_next_after ieee_next_down ieee_next_up ieee_quiet_eq
+syn keyword fortranIntrinsic   ieee_quiet_ge ieee_quiet_gt ieee_quiet_le ieee_quiet_lt ieee_quiet_ne ieee_real ieee_rem ieee_rint ieee_scalb
+syn keyword fortranIntrinsic   ieee_selected_real_kind ieee_set_rounding_mode ieee_set_underflow_mode ieee_signaling_eq ieee_signaling_ge
+syn keyword fortranIntrinsic   ieee_signaling_gt ieee_signaling_le ieee_signaling_lt ieee_signaling_ne ieee_signbit ieee_support_datatype
+syn keyword fortranIntrinsic   ieee_support_denormal ieee_support_divide ieee_support_inf ieee_support_io ieee_support_nan ieee_support_rounding
+syn keyword fortranIntrinsic   ieee_support_sqrt ieee_support_subnormal ieee_support_standard ieee_support_underflow_control
+syn keyword fortranIntrinsic   ieee_unordered ieee_value ieee_get_flag ieee_get_halting_mode ieee_get_modes ieee_get_status
+syn keyword fortranIntrinsic   ieee_set_flag ieee_set_halting_mode ieee_set_modes ieee_set_status ieee_support_flag ieee_support_halting
+syn keyword fortranIntrinsic    iso_c_binding c_loc c_funloc c_sizeof c_associated c_f_pointer c_f_procpointer c_f_strpointer f_c_string
+syn keyword fortranIntrinsic    iso_fortran_env compiler_options compiler_version
+syn keyword fortranIntrinsic   out_of_range reduce random_init coshape get_team team_number split tokenize
 syn keyword fortranIntrinsic    acosd asind atand atan2d cosd sind tand acospi asinpi atanpi atan2pi cospi sinpi tanpi
-syn keyword fortranIntrinsic    compiler_options compiler_version get_team team_number
-syn match fortranIntrinsic     "\<real\s*("me=s+4
+syn match fortranIntrinsic      "\%(^\s*\|type *is *(\s*\)\@12<!\<real\s*("me=s+4
 syn match fortranIntrinsic     "\<logical\s*("me=s+7
 syn match fortranIntrinsic      "\<not\s*("me=s+3
 syn match fortranIntrinsic     "\<len\s*("me=s+3
@@ -114,17 +122,19 @@ syn keyword fortranIntrinsicOb    alog alog10 amax0 amax1 amin0 amin1 amod cabs cco
 " Extra intrinsics provided by some vendors
 syn keyword fortranExtraIntrinsic      algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh
 
-syn keyword fortranType         generic final enumerator import
-syn keyword fortranType         c_ptr c_funptr elemental pure impure recursive non_recursive
+syn keyword fortranType         generic final enumerator import classof typeof
+syn keyword fortranType         c_ptr c_funptr elemental pure impure recursive non_recursive simple
 syn match fortranTypeOb         "^\s*\zs\%(character\s*\)\@15<=\*"
 syn match fortranType           "^\s*\zs\%(implicit\s\+\)\?\%(real\|integer\|logical\|complex\|character\|type\)\>"
 syn match fortranType           "^\s*\zsimplicit\s\+none\>"
-syn match fortranType           "\<\%(class\|type\)\%(of\)\?\>"
+syn match fortranType           "\<class\>"
+syn match fortranType           "\%(\<type\s\+is\s\+[(]\s*\)\@15<=\%(real\|double precision\|integer\|logical\|complex\|character\)\>"
 syn match fortranType           "\<\%(end\s*\)\?interface\>"
 syn match fortranType           "\<enum\s*,\s*bind\s*(\s*c\s*)"
 syn match fortranType           "\<end\s*\%(enum\|type\)\>"
-syn match fortranType           "\<\%(end\s*\)\?enumeration\s\+type"
+syn match fortranType           "\<\%(end\s*\)\?enumeration\s\+type\>"
 syn match fortranType           "\<\%(end\s*\)\?\%(module\s\+\)\?procedure\>"
+syn match fortranType           "\%(simple \|pure \|impure \|recursive \|non-recursive \|elemental \|module \)\@17<=\%(real\|double precision\|integer\|logical\|complex\|character\)"
 syn match fortranTypeR         display "\<double\s*precision\>"
 syn match fortranTypeR         display "\<double\s\+complex\>"
 syn keyword fortranAttribute    value bind deferred contiguous intrinsic non_intrinsic
@@ -149,10 +159,10 @@ syn keyword fortranTodo           contained bug note debug todo fixme
 syn region fortranParen transparent start="(" end=")" contains=ALLBUT,fortranParenError,@fortranCommentGroup,cIncluded,@spell
 syn match  fortranParenError   ")"
 
-syn match fortranOperator      "\.\s*n\=eqv\s*\."
+syn match fortranOperator      "\.\s*n\?eqv\s*\."
 syn match fortranOperator      "\.\s*\%(and\|or\|not\)\s*\."
 syn match fortranOperator      "\%(+\|-\|/\|\*\)"
-syn match fortranOperator      "\%(\%(>\|<\)=\=\|==\|/=\|=\)"
+syn match fortranOperator      "\%(\%(>\|<\)=\?\|==\|/=\|=\)"
 syn match fortranOperator      "\%(%\|?\|=>\)"
 syn match fortranOperator       "\%([\|]\)"
 syn match fortranOperatorR     "\.\s*[gl][et]\s*\."
@@ -170,17 +180,17 @@ endif
 
 "Numbers of various sorts
 " Integers
-syn match fortranNumber        display "\<\d\+\%(_\a\w*\)\=\>"
+syn match fortranNumber        display "\<\d\+\%(_\a\w*\)\?\>"
 " floating point number, without a decimal point
-syn match fortranFloatIll      display "\<\d\+[deq][-+]\=\d\+\%(_\a\w*\)\=\>"
+syn match fortranFloatIll      display "\<\d\+[deq][-+]\?\d\+\%(_\a\w*\)\?\>"
 " floating point number, starting with a decimal point
-syn match fortranFloatIll      display "\.\d\+\%([deq][-+]\=\d\+\)\=\%(_\a\w*\)\=\>"
+syn match fortranFloatIll      display "\.\d\+\%([deq][-+]\?\d\+\)\?\%(_\a\w*\)\?\>"
 " floating point number, no digits after decimal
-syn match fortranFloatIll      display "\<\d\+\.\%([deq][-+]\=\d\+\)\=\%(_\a\w*\)\=\>"
+syn match fortranFloatIll      display "\<\d\+\.\%([deq][-+]\?\d\+\)\?\%(_\a\w*\)\?\>"
 " floating point number, D or Q exponents
-syn match fortranFloatIll      display "\<\d\+\.\d\+\%([dq][-+]\=\d\+\)\=\%(_\a\w*\)\=\>"
+syn match fortranFloatIll      display "\<\d\+\.\d\+\%([dq][-+]\?\d\+\)\?\%(_\a\w*\)\?\>"
 " floating point number
-syn match fortranFloat display "\<\d\+\.\d\+\%(e[-+]\=\d\+\)\=\%(_\a\w*\)\=\>"
+syn match fortranFloat display "\<\d\+\.\d\+\%(e[-+]\?\d\+\)\?\%(_\a\w*\)\?\>"
 " binary number
 syn match fortranBinary        display "b["'][01]\+["']"
 " octal number
@@ -189,8 +199,8 @@ syn match fortranOctal      display "o["'][0-7]\+["']"
 syn match fortranHex   display "z["'][0-9A-F]\+["']"
 " Numbers in formats
 syn match fortranFormatSpec    display "\d*f\d\+\.\d\+"
-syn match fortranFormatSpec    display "\d*e[sn]\=\d\+\.\d\+\%(e\d+\>\)\="
-syn match fortranFormatSpec    display "\d*\%(d\|q\|g\)\d\+\.\d\+\%(e\d+\)\="
+syn match fortranFormatSpec    display "\d*e[sn]\?\d\+\.\d\+\%(e\d+\>\)\?"
+syn match fortranFormatSpec    display "\d*\%(d\|q\|g\)\d\+\.\d\+\%(e\d+\)\?"
 syn match fortranFormatSpec    display "\d\+x\>"
 " The next match cannot be used because it would pick up identifiers as well
 " syn match fortranFormatSpec  display "\<\%(a\|i\)\d\+"
@@ -198,34 +208,29 @@ syn match fortranFormatSpec       display "\d\+x\>"
 syn match fortranLabelNumber   display "^\zs\d\{1,5}\ze\s"
 syn match fortranLabelNumber   display "^ \zs\d\{1,4}\ze\s"
 syn match fortranLabelNumber   display "^  \zs\d\{1,3}\ze\s"
-syn match fortranLabelNumber   display "^   \zs\d\d\=\ze\s"
+syn match fortranLabelNumber   display "^   \zs\d\d\?\ze\s"
 syn match fortranLabelNumber   display "^    \zs\d\ze\s"
 " Numbers as targets
 syn match fortranTarget        display "\%(\<if\s*(.\+)\s*\)\@<=\%(\d\+\s*,\s*\)\{2}\d\+\>"
 syn match fortranTarget        display "\%(\<do\s\+\)\@11<=\d\+\>"
-syn match fortranTarget        display "\%(\<go\s*to\s*(\=\)\@11<=\%(\d\+\s*,\s*\)*\d\+\>"
+syn match fortranTarget        display "\%(\<go\s*to\s*(\?\)\@11<=\%(\d\+\s*,\s*\)*\d\+\>"
 
 syn match fortranBoolean       "\.\s*\%(true\|false\)\s*\."
 
-syn keyword fortranKeyword     call
-syn keyword fortranKeyword     use only contains
+syn keyword fortranKeyword      call use only continue allocate deallocate nullify return cycle exit contains
 syn match fortranKeyword        "\<fail\s\+image\>"
-syn match fortranKeyword       "\<\%(error\s\+\)\=stop\>"
-syn keyword fortranKeyword     continue
+syn match fortranKeyword       "\<\%(error\s\+\)\?stop\>"
 syn match fortranKeyword       "\<go\s*to\>"
 syn match fortranKeywordDel    "\<go\s*to\ze\s\+.*,\s*(.*$"
 syn match fortranKeywordOb     "\<go\s*to\ze\s*(\d\+.*$"
 syn keyword fortranKeywordDel  assign pause
-syn keyword fortranKeyword     allocate deallocate nullify return cycle exit
 
 syn region fortranString       start=+'+ end=+'+       contains=fortranLeftMargin,fortranContinueMark,fortranSerialNumber
 syn region fortranString       start=+"+ end=+"+       contains=fortranLeftMargin,fortranContinueMark,fortranSerialNumber
 
 syn match fortranIO            '\%(\%((\|,\|, *&\n\)\s*\)\@<=\%(access\|blank\|direct\|exist\|file\|fmt\|form\|formatted\|iostat\|name\|named\|nextrec\|number\|opened\|rec\|recl\|sequential\|status\|unformatted\|unit\)\ze\s*='
 syn keyword fortranIOR         format namelist
-syn keyword fortranIO          pad position action delim readwrite
-syn keyword fortranIO          eor advance nml
-syn keyword fortranIO           newunit decimal round iomsg
+syn keyword fortranIO          pad position action delim readwrite eor advance nml newunit decimal round iomsg
 syn match   fortranIO          contains=fortranOperator "\<e\%(nd\|rr\)\s*=\s*\d\+"
 
 syn keyword fortranConditional else then where elsewhere
@@ -233,8 +238,9 @@ syn match fortranConditional    "\<if\>"
 syn match fortranConditional    "\<else\s*if\>"
 syn match fortranConditional    "\<\%(end\s*\)\?\%(if\|where\|select\)\>"
 syn match fortranConditional    "\<select\s\+\%(case\|rank\|type\)\>"
-syn match fortranConditional    "\<\%(class\|type\)\s\+is\>"
 syn match fortranConditional    "\<\%(case\|rank\)\%(\s\+default\)\?\>"
+syn match fortranConditional    "\<class\s\+default\>"
+syn match fortranConditional    "\<\%(class\|type\)\s\+is\>"
 syn match fortranConditionalDel        "\<if\s*(.*)\s*\d\+\s*,\s*\d\+\s*,\s*\d\+\s*$"
 
 syn keyword fortranInclude             include
@@ -248,8 +254,7 @@ syn match fortranImageControl   "\<notify\s\+wait\ze\s*("
 syn keyword fortranUnitHeaderOb        entry
 syn match fortranUnitHeaderOb  display "\<block\s*data\>"
 
-syn keyword fortranStorageClass                in out
-syn match  fortranStorageClass          "\<in\s*out\>"
+syn keyword fortranStorageClass                in out inout
 syn match fortranStorageClass           "\<kind\s*="me=s+4
 syn match fortranStorageClass           "\<len\s*="me=s+3
 syn match fortranStorageClass           "^\s*\zsdata\>\%(\s\+\a\w*\s*/\)\@="
@@ -257,11 +262,17 @@ syn match fortranStorageClassOb         "^\s*\zscommon\>"
 syn match fortranStorageClassOb         "^\s*\zscommon\>\%(\s*/\)\@="
 syn keyword fortranStorageClassOb      equivalence
 
-syn keyword fortranConstant         c_null_char c_alert c_backspace c_form_feed c_new_line c_carriage_return c_horizontal_tab c_vertical_tab
-syn keyword fortranConstant         c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr
-syn keyword fortranConstant         iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit stat_failed_image stat_unlocked_failed_image
-syn keyword fortranConstant         int8 int16 int32 int64 real16 real32 real64 real128 character_kinds integer_kinds logical_kinds real_kinds iostat_inquire_internal_unit
-syn keyword fortranConstant         ieee_negative_subnormal ieee_positive_subnormal
+syn keyword fortranConstant             c_null_char c_alert c_backspace c_form_feed c_new_line c_carriage_return c_horizontal_tab c_vertical_tab
+syn keyword fortranConstant             c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr
+syn keyword fortranConstant             character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit stat_failed_image stat_unlocked_failed_image
+syn keyword fortranConstant             int8 int16 int32 int64 real16 real32 real64 real128 character_kinds integer_kinds logical_kinds real_kinds iostat_inquire_internal_unit
+syn keyword fortranConstant             ieee_invalid ieee_overflow ieee_divide_by_zero ieee_underflow ieee_inexact ieee_usual ieee_all
+syn keyword fortranConstant             ieee_signaling_nan ieee_quiet_nan ieee_negative_inf ieee_negative_normal ieee_negative_subnormal
+syn keyword fortranConstant             ieee_negative_zero ieee_positive_zero ieee_positive_subnormal ieee_positive_normal ieee_positive_inf
+syn keyword fortranConstant             ieee_other_value ieee_negative_denormal ieee_positive_denormal ieee_negative_subnormal
+syn keyword fortranConstant             ieee_positive_subnormal ieee_nearest ieee_to_zero ieee_up ieee_down ieee_away ieee_other ieee_datatype
+syn keyword fortranConstant             ieee_denormal ieee_divide ieee_halting ieee_inexact_flag ieee_inf ieee_invalid_flag ieee_nan
+syn keyword fortranConstant             ieee_rounding ieee_sqrt ieee_subnormal ieee_underflow_flag
 
 " CUDA fortran
 if exists("fortran_CUDA")
@@ -324,7 +335,7 @@ else
 endif
 
 syn match fortranComment       excludenl "!.*$" contains=@fortranCommentGroup,@spell
-syn match fortranOpenMP                excludenl               "^\s*\zs!\$\%(OMP\)\=&\=\s.*$"
+syn match fortranOpenMP                excludenl               "^\s*\zs!\$\%(OMP\)\?&\?\s.*$"
 syn match fortranEndStatement   display ";"
 
 "cpp is often used with Fortran
@@ -352,43 +363,43 @@ if exists("fortran_fold")
     setlocal foldmethod=syntax
   endif
   if (b:fortran_fixed_source == 1)
-    syn region fortranProgram transparent fold keepend start="^\s*program\s\+\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%(program\%(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranModule
-    syn region fortranModule transparent fold keepend start="^\s*submodule\s\+(\a\w*\s*\%(:\a\w*\s*\)*)\s*\z\(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%(submodule\%(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranProgram,fortranModule
-    syn region fortranModule transparent fold keepend start="^\s*module\s\+\%(procedure\)\@!\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%(module\%(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranProgram
-    syn region fortranFunction transparent fold keepend extend start="^\s*\%(elemental \|pure \|impure \|module \|recursive \)\=\s*\%(\%(\%(real \|integer \|logical \|complex \|double \s*precision \)\s*\%((\%(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\|type\s\+(\s*\w\+\s*) \|character \%((\%(\s*len\s*=\)\=\s*\d\+\s*)\|(\%(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\=\s*function\s\+\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%($\|function\%(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
-    syn region fortranSubroutine transparent fold keepend extend start="^\s*\%(elemental \|pure \|impure \|module \|recursive \)\=\s*subroutine\s\+\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%($\|subroutine\%(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
-    syn region fortranBlockData transparent fold keepend start="\<block\>" skip="^\s*[!#].*$" excludenl end="\<end\s*block\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
-    syn region fortranAssociate transparent fold keepend start="^\s*\<associate\s\+" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*associate" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
-    syn region fortranCritical transparent fold keepend start="^\s*\<critical\s\+" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*critical" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
-    syn region fortranTeam transparent fold keepend start="^\s*\<change\s\+team\>" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*team\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
-    syn region fortranInterface transparent fold keepend extend start="^\s*\%(abstract \)\=\s*interface\>" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
-    syn region fortranTypeDef transparent fold keepend extend start="^\s*type\s*\%(,\s*\%(public\|private\|abstract\)\)\=\s*::" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*type\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock,fortranInterface
+    syn region fortranProgram transparent fold keepend start="^\s*program\s\+\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%(program\%(\s\+\z1\>\)\?\|$\)" contains=ALLBUT,fortranModule
+    syn region fortranModule transparent fold keepend start="^\s*submodule\s\+(\a\w*\s*\%(:\a\w*\s*\)*)\s*\z\(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%(submodule\%(\s\+\z1\>\)\?\|$\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranModule transparent fold keepend start="^\s*module\s\+\%(procedure\)\@9!\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%(module\%(\s\+\z1\>\)\?\|$\)" contains=ALLBUT,fortranProgram
+    syn region fortranFunction transparent fold keepend extend start="\<function\s\+\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%($\|function\%(\s\+\z1\>\)\?\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranSubroutine transparent fold keepend extend start="\<subroutine\s\+\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*\%($\|subroutine\%(\s\+\z1\>\)\?\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranBlockData transparent fold keepend start="\<block\>" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*block\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranAssociate transparent fold keepend start="\<associate\s\+" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*associate" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
+    syn region fortranCritical transparent fold keepend start="\<critical\s\+" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*critical" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
+    syn region fortranTeam transparent fold keepend start="\<change\s\+team\>" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*team\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
+    syn region fortranInterface transparent fold keepend extend start="^\s*\%(abstract \)\?\s*interface\>" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranTypeDef transparent fold keepend extend start="^\s*type\s*\%(,\s*\%(abstract\|private\|public\|bind(c)\|extends(\a\w*)\)\)\{0,4}\s*::\s*\z(\a\w*\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*type\>\%(\s\+\z1\>\)\?" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
     syn region fortranMultiComments fold  start="^\zs[!c*].*\_s*[!c*]" skip="^[!c*]"   end='^\ze\s*[^!c*]'
   else
-    syn region fortranProgram transparent fold keepend start="^\s*program\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%(program\%(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranModule
-    syn region fortranModule transparent fold keepend start="^\s*submodule\s\+(\a\w*\s*\%(:\a\w*\s*\)*)\s*\z\(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%(submodule\%(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranProgram,fortranModule
-    syn region fortranModule transparent fold keepend start="^\s*module\s\+\%(procedure\)\@!\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%(module\%(\s\+\z1\>\)\=\|$\)" contains=ALLBUT,fortranProgram
-    syn region fortranFunction transparent fold keepend extend start="^\s*\%(elemental \|pure \|impure \|module \|recursive \)\=\s*\%(\%(\%(real \|integer \|logical \|complex \|double \s*precision \)\s*\%((\%(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\|type\s\+(\s*\w\+\s*) \|character \%((\%(\s*len\s*=\)\=\s*\d\+\s*)\|(\%(\s*kind\s*=\)\=\s*\w\+\s*)\)\=\)\=\s*function\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%($\|function\%(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
-    syn region fortranSubroutine transparent fold keepend extend start="^\s*\%(elemental \|pure \|impure \|module \|recursive \)\=\s*subroutine\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%($\|subroutine\%(\s\+\z1\>\)\=\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranProgram transparent fold keepend start="^\s*program\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%(program\%(\s\+\z1\>\)\?\|$\)" contains=ALLBUT,fortranModule
+    syn region fortranModule transparent fold keepend start="^\s*submodule\s\+(\a\w*\s*\%(:\a\w*\s*\)*)\s*\z\(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%(submodule\%(\s\+\z1\>\)\?\|$\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranModule transparent fold keepend start="^\s*module\s\+\%(procedure\)\@9!\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%(module\%(\s\+\z1\>\)\?\|$\)" contains=ALLBUT,fortranProgram
+    syn region fortranFunction transparent fold keepend extend start="\<function\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%($\|function\%(\s\+\z1\>\)\?\)" contains=ALLBUT,fortranProgram,fortranModule
+    syn region fortranSubroutine transparent fold keepend extend start="\<subroutine\s\+\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*\%($\|subroutine\%(\s\+\z1\>\)\?\)" contains=ALLBUT,fortranProgram,fortranModule
     syn region fortranBlockData transparent fold keepend start="\<block\>" skip="^\s*[!#].*$" excludenl end="\<end\s*block\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
     syn region fortranAssociate transparent fold keepend start="\<associate\>" skip="^\s*[!#].*$" excludenl end="\<end\s*associate\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
     syn region fortranCritical transparent fold keepend start="\<critical\>" skip="^\s*[!#].*$" excludenl end="\<end\s*critical\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
     syn region fortranTeam transparent fold keepend start="\<change\s\+team\>" skip="^\s*[!#].*$" excludenl end="\<end\s*team\>" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
-    syn region fortranInterface transparent fold keepend extend start="^\s*\%(abstract \)\=\s*interface\>" skip="^\s*[!#].*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
-    syn region fortranTypeDef transparent fold keepend extend start="^\s*type\s*\%(,\s*\%(public\|private\|abstract\)\)\=\s*::" skip="^\s*[!#].*$" excludenl end="\<end\s*type\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock,fortranInterface
+    syn region fortranInterface transparent fold keepend extend start="^\s*\%(abstract \)\?\s*interface\>" skip="^\s*[!#].*$" excludenl end="\<end\s*interface\>" contains=ALLBUT,fortranProgram,fortranModule,fortran77Loop,fortranCase,fortran90Loop,fortranIfBlock
+    syn region fortranTypeDef transparent fold keepend extend start="^\s*type\s*\%(,\s*\%(abstract\|private\|public\|bind(c)\|extends(\a\w*)\)\)\{0,4}\s*::\s*\z(\a\w*\)" skip="^\s*[!#].*$" excludenl end="\<end\s*type\>\%(\s\+\z1\>\)\?" contains=ALLBUT,fortranProgram,fortranModule,fortranSubroutine,fortranFunction
     syn region fortranMultiComments fold  start="^\zs\s*!.*\_s*!"      skip="^\s*!"    end='^\ze\s*[^!]'
   endif
 
   if exists("fortran_fold_conditionals")
     if (b:fortran_fixed_source == 1)
       syn region fortran77Loop transparent fold keepend start="\<do\s\+\z(\d\+\)" end="^\s*\z1\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
-      syn region fortran90Loop transparent fold keepend extend start="\%(\<end\s\+\)\@<!\<do\%(\s\+\a\|\s*$\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
-      syn region fortranIfBlock transparent fold keepend extend start="\%(\<e\%(nd\|lse\)\s\+\)\@<!\<if\s*(.\+)\s*then\>" skip="^\%([!c*]\|\s*#\).*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortran90Loop transparent fold keepend extend start="\%(\<end\s\+\)\@5<!\<do\%(\s\+\a\|\s*$\)" skip="^\%([!c*]\|\s*#\).*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranIfBlock transparent fold keepend extend start="\%(\<e\%(nd\|lse\)\s\+\)\@6<!\<if\s*(.\+)\s*then\>" skip="^\%([!c*]\|\s*#\).*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
       syn region fortranCase transparent fold keepend extend start="\<select\s*\%(case\|type\|rank\)\>" skip="^\%([!c*]\|\s*#\).*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
     else
       syn region fortran77Loop transparent fold keepend start="\<do\s\+\z(\d\+\)" end="^\s*\z1\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
-      syn region fortran90Loop transparent fold keepend extend start="\%(\<end\s\+\)\@<!\<do\%(\s\+\a\|\s*$\)" skip="^\s*[!#].*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
-      syn region fortranIfBlock transparent fold keepend extend start="\%(\<e\%(nd\|lse\)\s\+\)\@<!\<if\s*(\%(.\|&\s*\n\)\+)\%(\s\|&\s*\n\)*then\>" skip="^\s*[!#].*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortran90Loop transparent fold keepend extend start="\%(\<end\s\+\)\@5<!\<do\%(\s\+\a\|\s*$\)" skip="^\s*[!#].*$" excludenl end="\<end\s*do\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
+      syn region fortranIfBlock transparent fold keepend extend start="\%(\<e\%(nd\|lse\)\s\+\)\@6<!\<if\s*(\%(.\|&\s*\n\)\+)\%(\s\|&\s*\n\)*then\>" skip="^\s*[!#].*$" end="\<end\s*if\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
       syn region fortranCase transparent fold keepend extend start="\<select\s*\%(case\|type\|rank\)\>" skip="^\s*[!#].*$" end="\<end\s*select\>" contains=ALLBUT,fortranUnitHeader,fortranAttribute,fortranStorageClass,fortranType,fortranProgram,fortranModule,fortranSubroutine,fortranFunction,fortranBlockData
     endif
   endif
@@ -414,13 +425,13 @@ hi def link fortranLabelError             Error
 hi def link fortranObsolescent         Todo
 hi def link fortranType                        Type
 hi def link fortranAttribute           Type
-hi def link fortranBlock                fortranConditional
+hi def link fortranBlock                Conditional
 hi def link fortranImageControl         Keyword
 hi def link fortranStorageClass         StorageClass
 hi def link fortranIntrinsic            Function
 hi def link fortranCalled               Function
 hi def link fortranUnitName            Function
-hi def link fortranUnitHeader           fortranPreCondit
+hi def link fortranUnitHeader           PreCondit
 hi def link fortranReadWrite            Keyword
 hi def link fortranIO                   Keyword
 hi def link fortranConstant            Constant
@@ -428,7 +439,22 @@ hi def link fortranConstant        Constant
 hi def link fortranInclude              Include
 hi def link fortranLabelNumber          Special
 hi def link fortranTarget               Special
-hi def link fortranFloatIll             fortranFloat
+hi def link fortranFloatIll             Float
+
+hi def link fortranFormatSpec                  Identifier
+hi def link fortranFloat                       Float
+hi def link fortranPreCondit                   PreCondit
+hi def link fortranOpenMP                      PreProc
+hi def link fortranParenError                  Error
+hi def link fortranComment                     Comment
+hi def link fortranMultiComments        Comment
+hi def link fortranSerialNumber                Todo
+hi def link fortranTab                 Error
+
+hi def link cIncluded                  String
+hi def link cInclude                   Include
+hi def link cPreProc                   PreProc
+hi def link cPreCondit                 PreCondit
 
 " Redundant features which may one day become obsolescent
 hi def link fortranIntrinsicR          fortranIntrinsic
@@ -440,39 +466,25 @@ hi def link fortranRepeatR                fortranRepeat
 
 " features deleted or declared obsolescent in Fortran 2023
 if (b:fortran_fixed_source == 1)
-  hi def link fortranUnitHeaderOb    fortranUnitHeader
-  hi def link fortranKeywordOb       fortranKeyword
-  hi def link fortranKeywordDel      fortranKeyword
-  hi def link fortranConditionalDel  fortranConditional
-  hi def link fortranTypeOb          fortranType
-  hi def link fortranStorageClassOb  fortranStorageClass
-  hi def link fortranRepeatOb        fortranRepeat
-  hi def link fortranIntrinsicOb     fortranIntrinsic
+  hi def link fortranUnitHeaderOb      fortranUnitHeader
+  hi def link fortranKeywordOb         fortranKeyword
+  hi def link fortranKeywordDel        fortranKeyword
+  hi def link fortranConditionalDel    fortranConditional
+  hi def link fortranTypeOb            fortranType
+  hi def link fortranStorageClassOb    fortranStorageClass
+  hi def link fortranRepeatOb          fortranRepeat
+  hi def link fortranIntrinsicOb       fortranIntrinsic
 else
-  hi def link fortranUnitHeaderOb    fortranObsolescent
-  hi def link fortranKeywordOb       fortranObsolescent
-  hi def link fortranKeywordDel      fortranObsolescent
-  hi def link fortranConditionalDel  fortranObsolescent
-  hi def link fortranTypeOb          fortranObsolescent
-  hi def link fortranStorageClassOb  fortranObsolescent
-  hi def link fortranRepeatOb        fortranObsolescent
-  hi def link fortranIntrinsicOb     fortranObsolescent
+  hi def link fortranUnitHeaderOb      fortranObsolescent
+  hi def link fortranKeywordOb         fortranObsolescent
+  hi def link fortranKeywordDel        fortranObsolescent
+  hi def link fortranConditionalDel    fortranObsolescent
+  hi def link fortranTypeOb            fortranObsolescent
+  hi def link fortranStorageClassOb    fortranObsolescent
+  hi def link fortranRepeatOb          fortranObsolescent
+  hi def link fortranIntrinsicOb       fortranObsolescent
 endif
 
-hi def link fortranFormatSpec  Identifier
-hi def link fortranFloat       Float
-hi def link fortranPreCondit   PreCondit
-hi def link cIncluded          fortranString
-hi def link cInclude           Include
-hi def link cPreProc           PreProc
-hi def link cPreCondit         PreCondit
-hi def link fortranOpenMP       PreProc
-hi def link fortranParenError  Error
-hi def link fortranComment     Comment
-hi def link fortranMultiComments  Comment
-hi def link fortranSerialNumber        Todo
-hi def link fortranTab         Error
-
 if exists("fortran_CUDA")
   hi def link fortranIntrinsicCUDA        fortranIntrinsic
   hi def link fortranTypeCUDA             fortranType