3 * Description: Fortran90 programming language.
4 * Author: David Bowler <david.bowler@ucl.ac.uk>
6 * Copyright (C) 2009 Free Software Foundation, Inc.
10 * Deal with strings enclosed with '...'
12 state f90_string_single extends Highlight
24 * Deal with strings enclosed with "..."
26 state f90_string_double extends Highlight
38 * Deal function/subroutine declarations and subroutine calls: end with ) at end of line or then comment
40 state f90_func extends Highlight
46 /(\)[ \t]*)(![a-zA-Z_0-9\,\.\(\)\*\%\: \t]*)/ {
60 * Highlight variable declarations
62 state f90_new_var_list extends Highlight
64 /* Catch variable names followed by a comment: 1. Continuation marker present */
65 /([ \t]*::|[ \t]+)([a-zA-Z_0-9\,\.\(\)\*\%\: \t]+[^\&][ \t]*)(\&[ \t]*)(![a-zA-Z_0-9\,\.\(\)\*\%\: \t]*)/ {
67 variable_name_face(true);
70 variable_name_face(false);
76 /* Catch variable names followed by a comment: 2. No continuation marker (so return)*/
77 /([ \t]*::|[ \t]+)([a-zA-Z_0-9\,\.\(\)\*\%\: \t]+[^\&][ \t]*)(![a-zA-Z_0-9\,\.\(\)\*\%\: \t]*)/ {
79 variable_name_face(true);
81 variable_name_face(false);
88 /* Is this a specifier ? 1. real(var) ? */
89 /(\([ \t]*)([a-zA-Z0-9_]+)([ \t]*\))/{
92 /* Is this a specifier ? 2. real(kind=var) */
93 /(\([ \t]*)(len|kind)([a-zA-Z0-9_ =]+)(\))/{
101 /* Is this a specifier ? 3. real(kind=selected_real_kind(6,90)) */
102 /(\([ \t]*)(len|kind)([ \t]*=[ \t]*)(selected_(int_kind|real_kind))([ \t]*\([ \t]*[0-9\,]+[ \t]*\)[ \t]*)(\))/{
114 /* Highlight modifiers
115 (build-re '(allocatable Allocatable ALLOCATABLE external External EXTERNAL
116 intent Intent INTENT optional Optional OPTIONAL parameter Parameter PARAMETER pointer Pointer POINTER
117 private Private PRIVATE public Public PUBLIC save SAVE Save target TARGET Target))
119 /(\,[ \t]*)(A(LLOCATABLE|llocatable)|E(XTERNAL|xternal)|I(NTENT|ntent)\
121 |P(ARAMETER|OINTER|RIVATE|UBLIC|arameter|ointer|rivate|ublic)\
122 |S(AVE|ave)|T(ARGET|arget)|allocatable|external|intent|optional\
123 |p(arameter|ointer|rivate|ublic)|save|target)/ {
129 /(\,[ \t]*)(D(IMENSION|imension)|dimension)([ \t]*\([ \:\,\-+*a-zA-Z_0-9]+[ \t]*\))/ {
136 /* Highlight variable names up to continuation marker */
137 /([ \t]*::|[^\,\(][ \t]*)([a-zA-Z_0-9]+[a-zA-Z_0-9\,\.\(\)\*\%\:\+\- \t]+[\&][ \t]*)$/ {
139 variable_name_face(true);
141 variable_name_face(false);
143 /* Highlight variable names up to end of line (no continuation marker: return) */
144 /([ \t]*::|[^\,\(][ \t]*)([a-zA-Z_0-9]+[a-zA-Z_0-9\,\.\(\)\*\%\:\+\- \t]*[^\&][ \t]*)$/ {
146 variable_name_face(true);
148 variable_name_face(false);
151 /* Highlight variable names up to equals sign (return after equals)*/
152 /([ \t]*::|[^\,\(][ \t]*)([a-zA-Z_0-9]+[a-zA-Z_0-9\,\.\(\)\*\%\:\+\- \t]*[^\&])([ \t]*=)/ {
154 variable_name_face(true);
156 variable_name_face(false);
166 * Highlight F90 io statements
168 state f90_io extends Highlight
175 comment_face (false);
177 /* String constants. */
181 call (f90_string_single);
187 call (f90_string_double);
191 /* This terminates an io statement */
197 /* IO Keywords. (build-re '(FMT UNIT REC END ERR FILE STATUS
198 ACCESS FORM RECL BLANK IOSTAT EXIST OPENED NUMBER NAME
199 SEQUENTIAL DIRECT FORMATTED UNFORMATTED NEXTREC)) */
200 /\b(ACCESS|BLANK|DIRECT|E(ND|RR|XIST)|F(ILE|MT|ORM(|ATTED))|IOSTAT\
201 |N(AME|EXTREC|UMBER)|OPENED|REC(|L)|S(EQUENTIAL|TATUS)\
202 |UN(FORMATTED|IT))\b/ {
205 keyword_face (false);
208 /* IO Keywords. (build-re '(fmt unit rec end err file
209 status access form recl blank iostat exist
210 opened number name sequential direct
211 formatted unformatted nextrec)) */
212 /\b((a|A)ccess|(b|B)lank|(d|D)irect|(e|E)(nd|rr|xist)|(f|F)(ile|mt|orm(|atted))|(i|I)ostat\
213 |(n|N)(ame|extrec|umber)|(o|O)pened|(r|R)ec(|l)|(s|S)(equential|tatus)\
214 |(u|U)n(formatted|it))\b/ {
217 keyword_face (false);
224 state f90 extends HighlightEntry
233 /* String constants. */
237 call (f90_string_single);
243 call (f90_string_double);
246 /* Labels - whitespace followed by number at start of line */
252 /* Comments. We'll only have free-form, modern f90 statements - ! to end of line*/
257 comment_face (false);
259 /* builtins - maths, matrices etc */
261 (build-re '(abs achar acos adjustl adjustr aimag aint all allocated
262 anint any asin associated atan atan2 bit_size btest
263 ceiling char cmplx conjg cos cosh count cshift
264 date_and_time dble digits dim dot_product dprod eoshift
265 epsilon exp exponent floor fraction huge iachar iand
266 ibclr ibits ibset ichar ieor index int ior ishft
267 ishftc kind lbound len len_trim lge lgt lle llt log
268 logical log10 matmul max maxexponent maxloc maxval merge
269 min minexponent minloc minval mod modulo mvbits nearest
270 nint not pack precision present product radix
271 random_number random_seed range real repeat reshape
272 rrspacing scale scan selected_int_kind selected_real_kind
273 set_exponent shape sign sin sinh size spacing spread
274 sqrt sum system_clock tan tanh tiny transfer transpose
275 trim ubound unpack verify))
277 /\b((a|A)(bs|c(har|os)|djust(l|r)|i(mag|nt)|ll(|ocated)|n(int|y)|s(in|sociated)\
279 |(b|B)(it_size|test)|(c|C)(eiling|har|mplx|o(njg|s(|h)|unt)|shift)\
280 |(d|D)(ate_and_time|ble|i(gits|m)|ot_product|prod)\
281 |(e|E)(oshift|psilon|xp(|onent))|(f|F)(loor|raction)|(h|H)uge\
282 |(i|I)(a(char|nd)|b(clr|its|set)|char|eor|n(dex|t)|or|shft(|c))|(k|K)ind\
283 |(l|L)(bound|en(|_trim)|g(e|t)|l(e|t)|og(|10|ical))\
284 |(m|M)(a(tmul|x(|exponent|loc|val))|erge|in(|exponent|loc|val)|od(|ulo)\
286 |(n|N)(earest|int|ot)|(p|P)(ack|r(e(cision|sent)|oduct))\
287 |(r|R)(a(dix|n(dom_(number|seed)|ge))|e(al|peat|shape)|rspacing)\
288 |(s|S)(ca(le|n)|e(lected_(int_kind|real_kind)|t_exponent)|hape\
289 |i(gn|n(|h)|ze)|p(acing|read)|qrt|um|ystem_clock)\
290 |(t|T)(an(|h)|iny|r(ans(fer|pose)|im))|(u|U)(bound|npack)|(v|V)erify)\b/ {
293 builtin_face (false);
296 (build-re '(ABS ACHAR ACOS ADJUSTL ADJUSTR AIMAG AINT ALL ALLOCATED
297 ANINT ANY ASIN ASSOCIATED ATAN ATAN2 BIT_SIZE BTEST
298 CEILING CHAR CMPLX CONJG COS COSH COUNT CSHIFT
299 DATE_AND_TIME DBLE DIGITS DIM DOT_PRODUCT DPROD EOSHIFT
300 EPSILON EXP EXPONENT FLOOR FRACTION HUGE IACHAR IAND
301 IBCLR IBITS IBSET ICHAR IEOR INDEX INT IOR ISHFT
302 ISHFTC KIND LBOUND LEN LEN_TRIM LGE LGT LLE LLT LOG
303 LOGICAL LOG10 MATMUL MAX MAXEXPONENT MAXLOC MAXVAL MERGE
304 MIN MINEXPONENT MINLOC MINVAL MOD MODULO MVBITS NEAREST
305 NINT NOT PACK PRECISION PRESENT PRODUCT RADIX
306 RANDOM_NUMBER RANDOM_SEED RANGE REAL REPEAT RESHAPE
307 RRSPACING SCALE SCAN SELECTED_INT_KIND SELECTED_REAL_KIND
308 SET_EXPONENT SHAPE SIGN SIN SINH SIZE SPACING SPREAD
309 SQRT SUM SYSTEM_CLOCK TAN TANH TINY TRANSFER TRANSPOSE
310 TRIM UBOUND UNPACK VERIFY))
312 /\b(A(BS|C(HAR|OS)|DJUST(L|R)|I(MAG|NT)|LL(|OCATED)|N(INT|Y)|S(IN|SOCIATED)\
314 |B(IT_SIZE|TEST)|C(EILING|HAR|MPLX|O(NJG|S(|H)|UNT)|SHIFT)\
315 |D(ATE_AND_TIME|BLE|I(GITS|M)|OT_PRODUCT|PROD)\
316 |E(OSHIFT|PSILON|XP(|ONENT))|F(LOOR|RACTION)|HUGE\
317 |I(A(CHAR|ND)|B(CLR|ITS|SET)|CHAR|EOR|N(DEX|T)|OR|SHFT(|C))|KIND\
318 |L(BOUND|EN(|_TRIM)|G(E|T)|L(E|T)|OG(|10|ICAL))\
319 |M(A(TMUL|X(|EXPONENT|LOC|VAL))|ERGE|IN(|EXPONENT|LOC|VAL)|OD(|ULO)\
321 |N(EAREST|INT|OT)|P(ACK|R(E(CISION|SENT)|ODUCT))\
322 |R(A(DIX|N(DOM_(NUMBER|SEED)|GE))|E(AL|PEAT|SHAPE)|RSPACING)\
323 |S(CA(LE|N)|E(LECTED_(INT_KIND|REAL_KIND)|T_EXPONENT)|HAPE\
324 |I(GN|N(|H)|ZE)|P(ACING|READ)|QRT|UM|YSTEM_CLOCK)\
325 |T(AN(|H)|INY|R(ANS(FER|POSE)|IM))|U(BOUND|NPACK)|VERIFY)\b/ {
328 builtin_face (false);
334 /* Comparators. We have to roll by hand because of the
335 dots - "\b" doesn't delimit here. */
336 /\.((a|A)nd|(e|E)qv?|(g|G)(e|t)|(l|L)(e|t)|(n|N)e(qv)?|(n|N)ot|(o|O)r|(t|T)rue|(f|F)alse)\./ {
339 keyword_face (false);
342 /* Comparators. We have to roll by hand because of the
343 dots - "\b" doesn't delimit here. */
344 /\.(AND|EQV?|G(E|T)|L(E|T)|NE(QV)?|NOT|OR|TRUE|FALSE)\./ {
347 keyword_face (false);
349 /* function, subroutine declaration or subroutine call: 1. with arguments*/
350 /(^[ \t]*((c|C)all|(f|F)unction|(s|S)ubroutine)[ \t]+)([a-zA-Z_0-9]+)([ \t]*\()/ {
354 function_name_face(true);
356 function_name_face(false);
360 /* function, subroutine declaration or subroutine call: 1. without arguments*/
361 /(^[ \t]*((c|C)all|(f|F)unction|(s|S)ubroutine)[ \t]+)([a-zA-Z_0-9]+[ \t]*)$/ {
365 function_name_face(true);
367 function_name_face(false);
370 /* function, subroutine declaration or subroutine call*/
371 /((CALL|FUNCTION|SUBROUTINE)[ \t]+)([a-zA-Z_0-9]+)([ \t]*\()/ {
375 function_name_face(true);
377 function_name_face(false);
381 /* end function, subroutine declaration or subroutine call*/
382 /(((e|E)nd)[ \t]*)(((c|C)all|(f|F)unction|(s|S)ubroutine)[ \t]+)([a-zA-Z_0-9]+)/ {
387 function_name_face(true);
389 function_name_face(false);
391 /* end function, subroutine declaration or subroutine call*/
392 /((END)[ \t]*)((CALL|FUNCTION|SUBROUTINE)[ \t]+)([a-zA-Z_0-9]+)/ {
397 function_name_face(true);
399 function_name_face(false);
401 /* Module, program, use declaration */
402 /(((e|E)nd)?[ \t]*)(((m|M)odule|(p|P)rogram|(u|U)se)[ \t]+)([a-zA-Z_0-9]+)/ {
407 function_name_face(true);
409 function_name_face(false);
411 /* Module, program, use declaration */
412 /((END)?[ \t]*)((MODULE|PROGRAM|USE)[ \t]+)([a-zA-Z_0-9]+)/ {
413 debug(concat("Strings: ",$0));
414 debug(concat($1,"|"));
415 debug(concat($2,"|"));
416 debug(concat($3,"|"));
417 debug(concat($4,"|"));
418 debug(concat($5,"|"));
419 debug(concat($6,"|"));
424 function_name_face(true);
426 function_name_face(false);
429 /* Unfortunately, as F90 uses round brackets for function calls and arrays, this breaks */
430 /* /(=[ \t]*)([a-zA-Z_0-9]+)([ \t]*\()/{
432 function_name_face(true);
434 function_name_face(false);
437 /* Variable declaration */
438 /^([ \t]*)((i|I)nteger|(r|R)eal|(c|C)omplex|(c|C)haracter|(l|L)ogical|([ \t]*(e|E)nd[ \t]*)?(t|T)ype)/ {
442 call (f90_new_var_list);
444 /^([ \t]*)(INTEGER|REAL|COMPLEX|CHARACTER|LOGICAL|([ \t]*END[ \t]*)?TYPE)/ {
448 call (f90_new_var_list);
456 /* IO Statement (build-re '(open close read
457 write inquire backspace endfile rewind )) */
458 /\b((b|B)ackspace|(c|C)lose|(e|E)ndfile|(i|I)nquire|(o|O)pen|(r|R)e(ad|wind)|(w|W)rite)\b/ {
462 keyword_face (false);
466 /* IO Statement (build-re '(OPEN CLOSE READ
467 WRITE INQUIRE BACKSPACE ENDFILE REWIND )) */
468 /\b(BACKSPACE|CLOSE|ENDFILE|INQUIRE|OPEN|RE(AD|WIND)|WRITE)\b/ {
472 keyword_face (false);
477 /* (build-re '(allocate allocatable assign assignment block
479 continue cycle data deallocate dimension do double else
480 elseif elsewhere end enddo endif entry equivalence
481 exit external forall format goto if implicit
482 include intent interface intrinsic module
483 namelist none nullify only operator optional parameter
484 pause pointer precision print private procedure program
485 public recursive result return save select
486 sequence stop subroutine target then use where
489 /\b((a|A)(llocat(able|e)|ssign(|ment))|(b|B)lock\
490 |(c|C)(ase|o(mmon|nt(ains|inue))|ycle)|(d|D)(ata|eallocate|imension|o(|uble))\
491 |(e|E)(lse(|if|where)|n(d(|do|if)|try)|quivalence|x(it|ternal))\
492 |(f|F)or(all|mat)|(g|G)oto|(i|I)(f|mplicit|n(clude|t(e(nt|rface)|rinsic)))\
494 |(n|N)(amelist|ullify)|(o|O)(nly|p(erator|tional))\
495 |(p|P)(a(rameter|use)|ointer|r(ecision|i(nt|vate)|o(cedure|gram))|ublic)\
496 |(r|R)e(cursive|sult|turn)|(s|S)(ave|e(lect|quence)|top|ubroutine)\
497 |(t|T)(arget|hen)|(u|U)se|(w|W)h(ere|ile))\b/ {
500 keyword_face (false);
502 /* (build-re '(ALLOCATE ALLOCATABLE ASSIGN ASSIGNMENT BLOCK
504 CONTINUE CYCLE DATA DEALLOCATE DIMENSION DO DOUBLE ELSE
505 ELSEIF ELSEWHERE END ENDDO ENDIF ENTRY EQUIVALENCE
506 EXIT EXTERNAL FORALL FORMAT GOTO IF IMPLICIT
507 INCLUDE INTENT INTERFACE INTRINSIC MODULE
508 NAMELIST NULLIFY ONLY OPERATOR OPTIONAL PARAMETER
509 PAUSE POINTER PRECISION PRINT PRIVATE PROCEDURE PROGRAM
510 PUBLIC RECURSIVE RESULT RETURN SAVE SELECT
511 SEQUENCE STOP SUBROUTINE TARGET THEN USE WHERE
514 /\b(A(LLOCAT(ABLE|E)|SSIGN(|MENT))|BLOCK\
515 |C(ASE|O(MMON|NT(AINS|INUE))|YCLE)|D(ATA|EALLOCATE|IMENSION|O(|UBLE))\
516 |E(LSE(|IF|WHERE)|N(D(|DO|IF)|TRY)|QUIVALENCE|X(IT|TERNAL))\
517 |FOR(ALL|MAT)|GOTO|I(F|MPLICIT|N(CLUDE|T(E(NT|RFACE)|RINSIC)))\
519 |N(AMELIST|ULLIFY)|O(NLY|P(ERATOR|TIONAL))\
520 |P(A(RAMETER|USE)|OINTER|R(ECISION|I(NT|VATE)|O(CEDURE|GRAM))|UBLIC)\
521 |RE(CURSIVE|SULT|TURN)|S(AVE|E(LECT|QUENCE)|TOP|UBROUTINE)\
522 |T(ARGET|HEN)|USE|WH(ERE|ILE))\b/ {
525 keyword_face (false);