data.c
1 //! @file data.c
2 //! @author J. Marcel van der Veer
3 //
4 //! @section Copyright
5 //
6 // This file is part of VIF - vintage FORTRAN compiler.
7 // Copyright 2020-2024 J. Marcel van der Veer <algol68g@xs4all.nl>.
8 //
9 //! @section License
10 //
11 // This program is free software; you can redistribute it and/or modify it
12 // under the terms of the GNU General Public License as published by the
13 // Free Software Foundation; either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful, but
17 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 // more details. You should have received a copy of the GNU General Public
20 // License along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 //! @section Synopsis
23 //!
24 //! Compile DATA statements.
25
26 #include <vif.h>
27
28 //
29 // DATA STATEMENT
30 //
31
32 void const_list (MODE * mode, int_4 *items)
33 {
34 while (WITHIN) {
35 int_4 rc = scan (NULL);
36 if (!WITHIN) {
37 ;
38 } else {
39 int_8 repeat = 1;
40 if (curret == INT_NUMBER) {
41 repeat = strtoll (curlex, NULL, 10);
42 rc = scan (NULL);
43 if (TOKEN ("*")) {
44 rc = scan (NULL);
45 } else {
46 repeat = 1;
47 UNSCAN;
48 }
49 }
50 EXPR reg;
51 factor (®);
52 if (reg.variant != EXPR_CONST) {
53 EXPECT (701, "constant");
54 } else if (!accept_mode (reg.mode.type, reg.mode.len, mode->type, mode->len)) {
55 MODE_ERROR (702, qtype (&(reg.mode)), qtype (mode));
56 }
57 for (int_4 k = 0; k < repeat; k++) {
58 if (reg.mode.type == CHARACTER && mode->type == INTEGER) {
59 RECORD str, buf;
60 _srecordf (str, "%d", _int4 (get_uniq_str (reg.str, buf)));
61 code (nprocs, DATA, str);
62 } else {
63 code (nprocs, DATA, reg.str);
64 }
65 if (k < repeat - 1) {
66 code (nprocs, DATA, ",\n");
67 }
68 }
69 (*items) += (int_4) repeat;
70 rc = scan (NULL);
71 if (TOKEN ("/")) {
72 return;
73 } else if (TOKEN (",")) {
74 code (nprocs, DATA, ",\n");
75 }
76 }
77 (void) rc;
78 }
79 }
80
81 void data_elem (char *data, char *datk, char *datn, MODE * mode, int_4 *items)
82 {
83 #define CIRCULAR\
84 {\
85 _srecordf (str, "if (%s >= %s) {\n", datk, datn);\
86 code (nprocs, BODY, str);\
87 _srecordf (str, "%s = 0;\n", datk);\
88 code (nprocs, BODY, str);\
89 code (nprocs, BODY, "}\n");\
90 }
91 //
92 EXPR reg;
93 factor (®);
94 if (reg.idf != NULL && reg.idf->mode.save == AUTOMATIC) {
95 ERROR (703, "variable is automatic", CID (reg.idf));
96 }
97 if (reg.variant == EXPR_VAR && reg.mode.dim == 0) {
98 RECORD str;
99 *mode = reg.idf->mode;
100 CIRCULAR;
101 if (mode->type == CHARACTER) {
102 if (mode->len == 0) {
103 _srecordf (str, "strcpy (%s, %s[%s++]);\n", reg.str, data, datk);
104 } else {
105 _srecordf (str, "bufcpy (%s, %s[%s++], %d);\n", reg.str, data, datk, mode->len);
106 }
107 } else {
108 _srecordf (str, "%s = %s[%s++];\n", reg.str, data, datk);
109 }
110 code (nprocs, BODY, str);
111 (*items)++;
112 } else if (reg.variant == EXPR_SLICE) {
113 RECORD str;
114 *mode = reg.idf->mode;
115 CIRCULAR;
116 if (mode->type == CHARACTER) {
117 if (mode->len == 0) {
118 _srecordf (str, "strcpy (%s, %s[%s++]);\n", reg.str, data, datk);
119 } else {
120 _srecordf (str, "bufcpy (%s, %s[%s++], %d);\n", reg.str, data, datk, mode->len);
121 }
122 } else {
123 _srecordf (str, "%s = %s[%s++];\n", reg.str, data, datk);
124 }
125 code (nprocs, BODY, str);
126 (*items)++;
127 } else if (reg.variant == EXPR_VAR && reg.mode.dim > 0) {
128 RECORD str, tmpa, tmpk;
129 IDENT *ptr;
130 *mode = reg.idf->mode;
131 mode->dim = 0;
132 _srecordf (tmpa, "_arr_%d", nloctmps++);
133 ptr = add_local (tmpa, mode->type, mode->len, NOUNIQ, NOPATCH, NOARG, LOCAL, TEMP);
134 ptr->alias = reg.idf;
135 _srecordf (tmpk, "_k_%d", nloctmps++);
136 add_local (tmpk, INTEGER, 4, NOUNIQ, NOPATCH, NOARG, LOCAL, TEMP);
137 _srecordf (str, "for (%s = (%s *) %s, %s = 0; %s < ", tmpa, wtype (mode, NOARG, NOFUN), reg.str, tmpk, tmpk);
138 code (nprocs, BODY, str);
139 code_arrlen (reg.idf);
140 _srecordf (str, "; %s++, %s++) {\n", tmpa, tmpk);
141 code (nprocs, BODY, str);
142 CIRCULAR;
143 if (mode->type == CHARACTER) {
144 if (mode->len == 0) {
145 _srecordf (str, "strcpy (*(%s), %s[%s++]);\n", tmpa, data, datk);
146 } else {
147 _srecordf (str, "bufcpy (*(%s), %s[%s++], %d);\n", tmpa, data, datk, mode->len);
148 }
149 } else {
150 _srecordf (str, "%s[%s] = %s[%s++];\n", reg.str, tmpk, data, datk);
151 }
152 code (nprocs, BODY, str);
153 code (nprocs, BODY, "}\n");
154 (*mode) = reg.idf->mode;
155 (*items)++;
156 } else {
157 ERROR (704, "cannot initialise", reg.str);
158 }
159 #undef CIRCULAR
160 }
161
162 void data_list (char *data, char *datk, char *datn, MODE * mode, int_4 lpatch, int_4 *nest, int_4 *items)
163 {
164 while (WITHIN) {
165 int_4 rc = scan (NULL);
166 if (!WITHIN) {
167 ;
168 } else if (TOKEN ("/")) {
169 return;
170 } else if (TOKEN (",")) {
171 if (*nest == 0) {
172 code (nprocs, DATA, "\n");
173 }
174 } else if (TOKEN ("(")) {
175 SAVE_PRE;
176 // Quick lookahead.
177 int_4 loop = impl_do ();
178 // Restore.
179 RESTORE_POS;
180 rc = scan ("(");
181 // Decide.
182 if (loop) {
183 (*nest)++;
184 int_4 where = code (nprocs, BODY, NULL);
185 data_list (data, datk, datn, mode, where, nest, items);
186 } else {
187 data_elem (data, datk, datn, mode, items);
188 }
189 } else if (TOKEN (")")) {
190 // Expression closed by ')'
191 (*nest)--;
192 return;
193 } else if (rc == WORD) {
194 if (*nest == 0) {
195 data_elem (data, datk, datn, mode, items);
196 } else {
197 // Implied do-loop?
198 SAVE_PRE;
199 rc = scan (NULL);
200 if (!TOKEN ("=")) {
201 // Not an implied do-loop.
202 RESTORE_POS;
203 rc = scan (NULL);
204 data_elem (data, datk, datn, mode, items);
205 } else {
206 // Implied do-loop!
207 RECORD lid, loop;
208 EXPR from, to, by;
209 MODE nmode;
210 IDENT *idf = impl_decl (prelex, &nmode);
211 if (idf->arg || idf->alias != NULL) {
212 _srecordf (lid, "*%s", CID (idf));
213 } else if (idf->common == EXTERN) {
214 _srecordf (lid, "%s->%s", commons[idf->common], CID (idf));
215 } else if (idf->common > 0) {
216 _srecordf (lid, "%s.%s", commons[idf->common], CID (idf));
217 } else {
218 _srecordf (lid, "%s", CID (idf));
219 }
220 rc = scan (NULL);
221 express (&from, idf->mode.type, idf->mode.len);
222 rc = scan (",");
223 rc = scan (NULL);
224 express (&to, idf->mode.type, idf->mode.len);
225 rc = scan (NULL);
226 if (TOKEN (",")) {
227 rc = scan (NULL);
228 express (&by, idf->mode.type, idf->mode.len);
229 _srecordf (loop, "for (%s = %s; %s <= %s; %s += %s) {\n", lid, from.str, lid, to.str, lid, by.str);
230 rc = scan (NULL);
231 } else {
232 _srecordf (loop, "for (%s = %s; %s <= %s; %s++) {\n", lid, from.str, lid, to.str, lid);
233 }
234 patch (lpatch, loop);
235 if (TOKEN (")")) {
236 // Implied DO loop closed by ')'.
237 (*nest)--;
238 code (nprocs, BODY, "}; // implied DO \n");
239 } else {
240 EXPECT (705, ")");
241 }
242 return;
243 }
244 }
245 } else {
246 data_elem (data, datk, datn, mode, items);
247 }
248 }
249 }
250
251 void do_data (int_4 *nest)
252 {
253 int_4 rc, go_on = TRUE;
254 RECORD str;
255 _srecordf (str, "if (__calls[%d].calls == 0) {\n", nprocs - 1);
256 code (nprocs, BODY, str);
257 while (go_on) {
258 int_4 items = 0, dpatch;
259 RECORD data, datk, datn;
260 MODE mode;
261 _srecordf (data, "_data_l_%d", nglobtmps);
262 _srecordf (datk, "_data_k_%d", nglobtmps);
263 _srecordf (datn, "_data_n_%d", nglobtmps++);
264 add_local (datk, INTEGER, 4, NOUNIQ, NOPATCH, NOARG, LOCAL, TEMP);
265 _srecordf (str, "%s = 0;\n", datk);
266 code (nprocs, BODY, str);
267 data_list (data, datk, datn, &mode, ERR, nest, &items);
268 if (!TOKEN ("/")) {
269 EXPECT (706, "/");
270 }
271 mode.dim = 0;
272 code (nprocs, DATA, "\n");
273 cpp_direct (nprocs, curlin, DATA);
274 _srecordf (str, "#define %s ", datn);
275 code (nprocs, DATA, str);
276 dpatch = code (nprocs, DATA, NULL);
277 code (nprocs, DATA, "\n");
278 _srecordf (str, "static %s %s[%s] = {\n", wtype (&mode, NOARG, NOFUN), data, datn);
279 code (nprocs, DATA, str);
280 items = 0;
281 const_list (&mode, &items);
282 _srecordf (str, "%d", items);
283 patch (dpatch, str);
284 code (nprocs, DATA, "\n");
285 code (nprocs, DATA, "};\n");
286 if (!TOKEN ("/")) {
287 EXPECT (707, "/");
288 }
289 rc = scan (NULL);
290 go_on = TOKEN (",");
291 }
292 code (nprocs, BODY, "}\n");
293 if (WITHIN) {
294 SYNTAX (708, curlex);
295 }
296 (void) rc;
297 }
298
299 void decl_data (void)
300 {
301 int_4 go_on = TRUE;
302 while (go_on) {
303 SAVE_POS;
304 int_4 rc = scan (NULL);
305 if (rc == DECLAR) {
306 skip_card ();
307 } else if (TOKEN ("implicit")) {
308 skip_card ();
309 } else if (TOKEN ("save")) {
310 skip_card ();
311 } else if (TOKEN ("automatic")) {
312 skip_card ();
313 } else if (TOKEN ("parameter")) {
314 skip_card ();
315 } else if (TOKEN ("common")) {
316 skip_card ();
317 } else if (TOKEN ("dimension")) {
318 skip_card ();
319 } else if (TOKEN ("equivalence")) {
320 skip_card ();
321 } else if (TOKEN ("external")) {
322 skip_card ();
323 } else if (TOKEN ("intrinsic")) {
324 skip_card ();
325 } else if (TOKEN ("data")) {
326 int_4 nest = 0;
327 do_data (&nest);
328 skip_card ();
329 } else if (strlen (curlex) > 0) {
330 // Backspace and done.
331 RESTORE_POS;
332 go_on = FALSE;
333 }
334 }
335 }
336
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|