Commit | Line | Data |
---|---|---|
8340f87c BJ |
1 | .NH |
2 | IMPLEMENTATION | |
3 | .PP | |
4 | Ratfor | |
5 | was originally written in | |
6 | C[4] | |
7 | on the | |
8 | .UC UNIX | |
9 | operating system[5]. | |
10 | The language is specified by a context free grammar | |
11 | and the compiler constructed using | |
12 | the | |
13 | .UC YACC | |
14 | compiler-compiler[6]. | |
15 | .PP | |
16 | The | |
17 | Ratfor | |
18 | grammar is simple and straightforward, being essentially | |
19 | .P1 | |
20 | prog : stat | |
21 | | prog stat | |
22 | stat : \f3if\fP (...) stat | |
23 | | \f3if\fP (...) stat \f3else\fP stat | |
24 | | \f3while\fP (...) stat | |
25 | | \f3for\fP (...; ...; ...) stat | |
26 | | \f3do\fP ... stat | |
27 | | \f3repeat\fP stat | |
28 | | \f3repeat\fP stat \f3until\fP (...) | |
29 | | \f3switch\fP (...) { \f3case\fP ...: prog ... | |
30 | \f3default\fP: prog } | |
31 | | \f3return\fP | |
32 | | \f3break\fP | |
33 | | \f3next\fP | |
34 | | digits stat | |
35 | | { prog } | |
36 | | anything unrecognizable | |
37 | .P2 | |
38 | The observation | |
39 | that | |
40 | Ratfor | |
41 | knows no Fortran | |
42 | follows directly from the rule that says a statement is | |
43 | ``anything unrecognizable''. | |
44 | In fact most of Fortran falls into this category, | |
45 | since any statement that does not begin with one of the keywords | |
46 | is by definition ``unrecognizable.'' | |
47 | .PP | |
48 | Code generation is also simple. | |
49 | If the first thing on a source line is | |
50 | not a keyword | |
51 | (like | |
52 | .UL if , | |
53 | .UL else , | |
54 | etc.) | |
55 | the entire statement is simply copied to the output | |
56 | with appropriate character translation and formatting. | |
57 | (Leading digits are treated as a label.) | |
58 | Keywords cause only slightly more complicated actions. | |
59 | For example, when | |
60 | .UL if | |
61 | is recognized, two consecutive labels L and L+1 | |
62 | are generated and the value of L is stacked. | |
63 | The condition is then isolated, and the code | |
64 | .P1 | |
65 | if (.not. (condition)) goto L | |
66 | .P2 | |
67 | is output. | |
68 | The | |
69 | .ul | |
70 | statement | |
71 | part of the | |
72 | .UL if | |
73 | is then translated. | |
74 | When the end of the | |
75 | statement is encountered | |
76 | (which may be some distance away and include nested \f3if\fP's, of course), | |
77 | the code | |
78 | .P1 | |
79 | L continue | |
80 | .P2 | |
81 | is generated, unless there is an | |
82 | .UL else | |
83 | clause, in which case | |
84 | the code is | |
85 | .P1 | |
86 | goto L+1 | |
87 | L continue | |
88 | .P2 | |
89 | In this latter case, | |
90 | the code | |
91 | .P1 | |
92 | L+1 continue | |
93 | .P2 | |
94 | is produced after the | |
95 | .ul | |
96 | statement | |
97 | part of the | |
98 | .UL else. | |
99 | Code generation for the various loops is equally simple. | |
100 | .PP | |
101 | One might argue that more care should be taken | |
102 | in code generation. | |
103 | For example, | |
104 | if there is no trailing | |
105 | .UL else , | |
106 | .P1 | |
107 | if (i > 0) x = a | |
108 | .P2 | |
109 | should be left alone, not converted into | |
110 | .P1 | |
111 | if (.not. (i .gt. 0)) goto 100 | |
112 | x = a | |
113 | 100 continue | |
114 | .P2 | |
115 | But what are optimizing compilers for, if not to improve code? | |
116 | It is a rare program indeed where this kind of ``inefficiency'' | |
117 | will make even a measurable difference. | |
118 | In the few cases where it is important, | |
119 | the offending lines can be protected by `%'. | |
120 | .PP | |
121 | The use of a compiler-compiler is definitely the preferred method | |
122 | of software development. | |
123 | The language is well-defined, | |
124 | with few syntactic irregularities. | |
125 | Implementation is quite simple; | |
126 | the original construction took under a week. | |
127 | The language | |
128 | is sufficiently simple, however, that an | |
129 | .ul | |
130 | ad hoc | |
131 | recognizer can be readily constructed to do the same job | |
132 | if no compiler-compiler is available. | |
133 | .PP | |
134 | The C version of | |
135 | Ratfor | |
136 | is used on | |
137 | .UC UNIX | |
138 | and on the Honeywell | |
139 | .UC GCOS | |
140 | systems. | |
141 | C compilers are not as widely available as Fortran, however, | |
142 | so there is also a | |
143 | Ratfor | |
144 | written in itself | |
145 | and originally bootstrapped with the C version. | |
146 | The | |
147 | Ratfor | |
148 | version | |
149 | was written so as to translate into the portable subset | |
150 | of Fortran described in [1], | |
151 | so it is portable, | |
152 | having been run essentially without change | |
153 | on at least twelve distinct machines. | |
154 | (The main restrictions of the portable subset are: | |
155 | only one character per machine word; | |
156 | subscripts in the | |
157 | form | |
158 | .ul | |
159 | c*v\(+-c; | |
160 | avoiding expressions in places like | |
161 | .UC DO | |
162 | loops; | |
163 | consistency in subroutine argument usage, | |
164 | and in | |
165 | .UC COMMON | |
166 | declarations. | |
167 | Ratfor | |
168 | itself will not gratuitously generate non-standard Fortran.) | |
169 | .PP | |
170 | The | |
171 | Ratfor | |
172 | version is about 1500 lines of | |
173 | Ratfor | |
174 | (compared to about 1000 lines of C); | |
175 | this compiles into 2500 lines of Fortran. | |
176 | This expansion ratio is somewhat higher than average, | |
177 | since the compiled code contains unnecessary occurrences | |
178 | of | |
179 | .UC COMMON | |
180 | declarations. | |
181 | The execution time of the | |
182 | Ratfor | |
183 | version is dominated by | |
184 | two routines that read and write cards. | |
185 | Clearly these routines could be replaced | |
186 | by machine coded local versions; | |
187 | unless this is done, the efficiency of other parts of the translation process | |
188 | is largely irrelevant. |