Small change to getopt stuff
[enscript.git] / states / hl / fortran.st
1 /**
2  * Name: fortran
3  * Description: Fortran77 programming language.
4  * Author: Keith Refson <Keith.Refson@earth.ox.ac.uk>
5  *    Markku Rossi <mtr@iki.fi>
6  *    edited by Joachim Kaiser <jhk@cmpnetmail.com>:
7  *       - relational/logical operators and io specifiers (named added) with
8  *         changed from keyword_face to builtin_face
9  *       - type statement keywords changed from keyword_face to type_face
10  *       - 'print' moved from keywords to io statements
11  *       - distinguish between 'real' type statement and 'real' type conversion
12  *         function
13  *       - 'endfile', 'enddo' and 'while' removed from keyword list (not
14  *         defined in FORTRAN 77), 'assign' added, 'else if' and 'end if' with
15  *         optional blank before 'if'
16  *       - comments only as complete lines starting with [cC\*] (FORTRAN 77)
17  *       - case-insensitive regexp with the `i' option at the end of the regexp
18  */
19
20 state fortran_string extends Highlight
21 {
22   /[\']/ {
23     language_print ($0);
24     debug ("Finishing fortran_string state.");
25     return;
26   }
27 }
28
29 state fortran_io extends Highlight
30 {
31   /\(/ {
32     language_print ($0);
33     parentheses_level++;
34     debug (concat("Parenthesis_level = ",string(parentheses_level)));
35   }
36
37   /\)/ {
38     language_print ($0);
39     parentheses_level--;
40     debug (concat("Parenthesis_level = ",string(parentheses_level)));
41     if (parentheses_level == 0) {
42       debug ("Finishing fortran_io state.");
43       return;
44     }
45   }
46
47   /* IO Specifiers.
48      (build-re '(FMT UNIT REC END ERR FILE STATUS ACCESS FORM RECL BLANK
49      IOSTAT EXIST OPENED NUMBER NAME NAMED SEQUENTIAL DIRECT FORMATTED
50      UNFORMATTED NEXTREC))
51    */
52   /\b(ACCESS|BLANK|DIRECT|E(ND|RR|XIST)|F(ILE|MT|ORM(|ATTED))|IOSTAT\
53 |N(AMED?|EXTREC|UMBER)|OPENED|REC(|L)|S(EQUENTIAL|TATUS)\
54 |UN(FORMATTED|IT))\b/i {
55     debug (concat("This is an io specifier: ",$0));
56     builtin_face (true);
57     language_print ($0);
58     builtin_face (false);
59   }
60
61   /* String within io statement */
62   /[\']/ {
63     debug ("String in io statement found.");
64     string_face (true);
65     language_print ($0);
66     call (fortran_string);
67     string_face (false);
68   }
69 }
70
71 state fortran extends HighlightEntry
72 {
73   BEGIN {
74     parentheses_level = 0;
75     debug ("Starting fortran state.");
76   }
77
78   END {
79     debug ("Finishing fortran state.");
80   }
81
82   /* Comments. */
83   /^[cC\*]/ {
84     debug ("Comment line found.");
85     comment_face (true);
86     language_print ($0);
87     call (eat_one_line);
88     comment_face (false);
89   }
90
91   /* String constants. */
92   /[\']/ {
93     debug ("String constant found.");
94     string_face (true);
95     language_print ($0);
96     call (fortran_string);
97     string_face (false);
98   }
99
100   /* Relational/logical operators.  We have to roll by hand because of the
101      dots - "\b" doesn't delimit here. */
102   /\.(AND|EQV?|G(E|T)|L(E|T)|NE(QV)?|NOT|OR)\./i {
103     debug (concat("This is an rel/log operator: ",$0));
104     builtin_face (true);
105     language_print ($0);
106     builtin_face (false);
107   }
108
109   /* IO Statement (build-re '(OPEN CLOSE READ PRINT
110      WRITE INQUIRE BACKSPACE ENDFILE REWIND )) */
111   /\b(BACKSPACE|CLOSE|ENDFILE|INQUIRE|OPEN|PRINT|RE(AD|WIND)|WRITE)(\(?)/i {
112     debug (concat("This is an io statement: ",$1));
113     keyword_face (true);
114     language_print ($1);
115     keyword_face (false);
116     if (strcmp ($3, "") != 0) {
117         language_print ($3);
118         parentheses_level=1;
119         call (fortran_io);
120     }
121   }
122
123   /* Type statements. */
124   /\b((CHARACTER|COMPLEX|INTEGER|LOGICAL|REAL)(\*([0-9]+|\())?\
125 |(DOUBLE *PRECISION))( *\(?[a-zA-Z0-9]+)/i {
126     debug (concat("This is a type statement: ",$2,$5));
127     type_face (true);
128     language_print ($2);
129     language_print ($5);
130     type_face (false);
131     language_print ($3);
132     next_word = $6;
133     if (regmatch (next_word, / *FUNCTION/i)) {
134         debug ("... for a function");
135         keyword_face (true);
136         language_print (next_word);
137         keyword_face (false);
138     } else {
139         language_print (next_word);
140     }
141   }
142
143   /* Keywords other than type and io statements.
144      (build-re '(ASSIGN BLOCK_sDATA CALL COMMON CONTINUE DATA DIMENSION DO
145      ELSE ELSE_sIF END END_sIF ENTRY EQUIVALENCE EXTERNAL FORMAT FUNCTION
146      GO_sTO IF IMPLICIT INCLUDE INTRINSIC PARAMETER PAUSE PROGRAM RETURN
147      SAVE STOP SUBROUTINE THEN ))
148    */
149   /\b(ASSIGN|BLOCK \*DATA|C(ALL|O(MMON|NTINUE))|D(ATA|IMENSION|O)\
150 |E(LSE(| \*IF)|N(D(| \*IF)|TRY)|QUIVALENCE|XTERNAL)|F(ORMAT|UNCTION)\
151 |GO \*TO|I(F|MPLICIT|N(CLUDE|TRINSIC))|P(A(RAMETER|USE)|ROGRAM)|RETURN\
152 |S(AVE|TOP|UBROUTINE)|THEN)\b/i {
153     debug (concat("Other keyword found: ",$0));
154     keyword_face (true);
155     language_print ($0);
156     keyword_face (false);
157   }
158 }
159
160 \f
161 /*
162 Local variables:
163 mode: c
164 End:
165 */