type.c
1 //! @file type.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 //! Type routines.
25
26 #include <vif.h>
27
28 void norm_mode (MODE *mode)
29 {
30 if (mode != NULL && mode->type == CHARACTER) {
31 if (mode->len == 0) {
32 // CHARACTER*(*)
33 return;
34 }
35 for (int k = 0, lim = 2; k < MAX_STRLENS; k++, lim *= 2) {
36 if (mode->len < lim) {
37 strlens[k] = TRUE;
38 mode->len = lim - 1;
39 return;
40 }
41 }
42 RECORD str;
43 _srecordf (str, "%d", mode->len);
44 ERROR (3001, "character length overflow", str);
45 mode->len = MAX_STRLEN;
46 }
47 }
48
49 int_4 is_array (MODE mode)
50 {
51 if (mode.dim > 0) {
52 return TRUE;
53 } else {
54 return mode.type == CHARACTER;
55 }
56 }
57
58 void default_impl (void)
59 {
60 int_4 k;
61 for (k = ord ('a'); k <= ord ('h'); k++) {
62 if (implicit_r8) {
63 f2c_type ("real*8", &(implic[k].mode), NOARG, NOFUN);
64 } else {
65 f2c_type ("real*4", &(implic[k].mode), NOARG, NOFUN);
66 }
67 implic[k].mode.save = STATIC;
68 }
69 for (k = ord ('i'); k <= ord ('n'); k++) {
70 f2c_type ("integer*4", &(implic[k].mode), NOARG, NOFUN);
71 implic[k].mode.save = STATIC;
72 }
73 for (k = ord ('o'); k <= ord ('z'); k++) {
74 if (implicit_r8) {
75 f2c_type ("real*8", &(implic[k].mode), NOARG, NOFUN);
76 } else {
77 f2c_type ("real*4", &(implic[k].mode), NOARG, NOFUN);
78 }
79 implic[k].mode.save = STATIC;
80 }
81 implic[k].mode.save = STATIC;
82 }
83
84 char *qtype (MODE * mode)
85 {
86 RECORD t;
87 RECCLR (t);
88 if (mode->type == NOTYPE) {
89 _srecordf (t, "%s", "void");
90 } else if (mode->type == ETYPE) {
91 _srecordf (t, "%s", "type error");
92 } else if (mode->len > 0) {
93 switch (mode->type) {
94 case INTEGER:
95 _srecordf (t, "%s*%d", "integer", mode->len);
96 break;
97 case LOGICAL:
98 _srecordf (t, "%s*%d", "logical", mode->len);
99 break;
100 case REAL:
101 _srecordf (t, "%s*%d", "real", mode->len);
102 break;
103 case COMPLEX:
104 _srecordf (t, "%s*%d", "complex", mode->len);
105 break;
106 case CHARACTER:
107 _srecordf (t, "%s*%d", "character", mode->len);
108 break;
109 }
110 } else {
111 switch (mode->type) {
112 case INTEGER:
113 _srecordf (t, "%s", "integer");
114 break;
115 case LOGICAL:
116 _srecordf (t, "%s", "logical");
117 break;
118 case REAL:
119 _srecordf (t, "%s", "real");
120 break;
121 case COMPLEX:
122 _srecordf (t, "%s", "complex");
123 break;
124 case CHARACTER:
125 _srecordf (t, "%s", "character");
126 break;
127 }
128 }
129 return stralloc (t);
130 }
131
132 char *wtype (MODE * mode, int_4 arg, int_4 fun)
133 {
134 switch (mode->type) {
135 case INTEGER:{
136 if (mode->len == 2) {
137 return (arg ? "int_2 _p_ " : "int_2");
138 } else if (mode->len == 4) {
139 return (arg ? "int_4 _p_ " : "int_4");
140 } else if (mode->len == 8) {
141 return (arg ? "int_8 _p_ " : "int_8");
142 } else {
143 return "notype";
144 }
145 }
146 case LOGICAL:
147 if (arg) {
148 return "logical_4 _p_ ";
149 } else {
150 return "logical_4";
151 }
152 case REAL:
153 if (mode->len == 4) {
154 return (arg ? "real_4 _p_ " : "real_4");
155 } else if (mode->len == 8) {
156 return (arg ? "real_8 _p_ " : "real_8");
157 } else if (mode->len == 16) {
158 return (arg ? "real_16 _p_ " : "real_16");
159 } else if (mode->len == 32) {
160 return (arg ? "real_32 _p_ " : "real_32");
161 } else {
162 return "notype";
163 }
164 case COMPLEX:
165 if (mode->len == 8) {
166 return (arg ? "complex_8 _p_ " : "complex_8");
167 } else if (mode->len == 16) {
168 return (arg ? "complex_16 _p_ " : "complex_16");
169 } else if (mode->len == 32) {
170 return (arg ? "complex_32 _p_ " : "complex_32");
171 } else if (mode->len == 64) {
172 return (arg ? "complex_64 _p_ " : "complex_64");
173 } else {
174 return "notype";
175 }
176 case CHARACTER:{
177 if (fun || arg) {
178 return "char _p_ ";
179 } else {
180 RECORD str;
181 _srecordf (str, "char_%d", mode->len);
182 return stralloc (str);
183 }
184 }
185 case NOTYPE: { // C routine type
186 return "int_4";
187 }
188 default: {
189 return "notype";
190 }
191 }
192 }
193
194 char *f2c_type (char *ftype, MODE * mode, int_4 arg, int_4 fun)
195 {
196 MODE m = (MODE) {.type = NOTYPE,.len = NOLEN,.dim = 0 };
197 int_4 found = FALSE;
198 #define TEST(name, f_type, f_len, f_trunc)\
199 if (EQUAL (ftype, name)) {\
200 m = (MODE) {.type = f_type, .len = f_trunc, .dim = 0};\
201 found = TRUE;\
202 }
203 TEST ("none", NOTYPE, 0, 0);
204 TEST ("logical", LOGICAL, 4, 4);
205 TEST ("logical*1", LOGICAL, 1, 4);
206 TEST ("logical*2", LOGICAL, 2, 4);
207 TEST ("logical*4", LOGICAL, 4, 4);
208 TEST ("logical*8", LOGICAL, 8, 4);
209 TEST ("integer", INTEGER, 4, 4);
210 TEST ("integer*1", INTEGER, 2, 2);
211 TEST ("integer*2", INTEGER, 2, 2);
212 TEST ("integer*4", INTEGER, 4, 4);
213 TEST ("integer*8", INTEGER, 8, 8);
214 if (implicit_r8) {
215 TEST ("real", REAL, 8, 8);
216 } else {
217 TEST ("real", REAL, 4, 4);
218 }
219 TEST ("real*4", REAL, 4, 4);
220 TEST ("real*8", REAL, 8, 8);
221 TEST ("real*16", REAL, 16, 16);
222 TEST ("real*32", REAL, 32, 32);
223 if (implicit_r8) {
224 TEST ("complex", COMPLEX, 16, 16);
225 } else {
226 TEST ("complex", COMPLEX, 8, 8);
227 }
228 TEST ("complex*8", COMPLEX, 8, 8);
229 TEST ("complex*16", COMPLEX, 16, 16);
230 TEST ("complex*32", COMPLEX, 32, 32);
231 TEST ("complex*64", COMPLEX, 64, 64);
232 TEST ("character", CHARACTER, 1, 1);
233 if (LEQUAL ("character*", ftype)) {
234 int_4 len;
235 if (strcmp (ftype, "character*(*)") == 0) {
236 m = (MODE) {.type = CHARACTER, .len = 0, .dim = 0};
237 found = TRUE;
238 } else {
239 char *op = strchr (ftype, '('), *cl = strrchr(ftype, ')');
240 if (op != NULL && cl != NULL) {
241 RECORD fact;
242 _srecordf (fact, "%s", ++op);
243 if (strlen (fact) > 0 && fact[strlen (fact) - 1] == ')') {
244 fact[strlen (fact) - 1] = '\0';
245 }
246 if (!isint_4 (fact, &len)) {
247 MODE pm;
248 IDENT *idf = find_local (fact, &pm);
249 if (idf->parm != NULL && idf->mode.type == INTEGER) {
250 (void) isint_4 (idf->parm, &len);
251 } else {
252 ERROR (3002, "invalid length", fact);
253 len = MAX_STRLEN;
254 }
255 }
256 } else {
257 sscanf (ftype, "character*%d", &len);
258 }
259 m = (MODE) {.type = CHARACTER, .len = len, .dim = 0};
260 found = TRUE;
261 }
262 if (found && m.len > 1) {
263 norm_mode (&m);
264 }
265 }
266 if (mode != NULL) {
267 *mode = m;
268 }
269 if (found) {
270 return (wtype (&m, arg, fun));
271 } else {
272 ERROR (3003, "unknown type", ftype);
273 return "notype";
274 }
275 }
276
277 char *ptr_to_array (IDENT * idf, int_4 constant, int_4 cast, int_4 formal)
278 {
279 RECORD str, name;
280 if (formal) {
281 _srecordf (name, "%s", edit_f (CID (idf)));
282 } else {
283 _srecordf (name, "%s", CID (idf));
284 }
285 if (idf->mode.dim <= 1) {
286 if (cast) {
287 _srecordf (str, "(%s _p_)", wtype (&idf->mode, NOARG, NOFUN));
288 } else if (constant) {
289 _srecordf (str, "_p_ const %s", name);
290 } else {
291 _srecordf (str, "_p_ %s", name);
292 }
293 } else {
294 if (cast) {
295 _srecordf (str, "(%s (_p_)", wtype (&idf->mode, NOARG, NOFUN));
296 } else if (constant) {
297 _srecordf (str, "(_p_ const %s)", name);
298 } else {
299 _srecordf (str, "(_p_ %s)", name);
300 }
301 if (cast) {
302 bufcat (str, ")", RECLN);
303 }
304 }
305 return stralloc (str);
306 }
307
308 int_4 accept_mode (int_4 Lt, int_4 Ll, int_4 Rt, int_4 Rl)
309 {
310 // Whether L is acceptable to R.
311 if (Rt == REAL && Lt == REAL) {
312 return Ll <= Rl;
313 }
314 if (Rt == INTEGER && Lt == INTEGER) {
315 return Ll <= Rl;
316 }
317 if (Rt == REAL && Lt == INTEGER) {
318 return Ll <= Rl;
319 }
320 if (Rt == COMPLEX && Lt == REAL) {
321 return 2 * Ll <= Rl;
322 }
323 if (Rt == COMPLEX && Lt == INTEGER) {
324 return 2 * Ll <= Rl;
325 }
326 if (Rt == INTEGER && Lt == CHARACTER) {
327 return Rl == 4;
328 }
329 if (Rt == INTEGER && Lt == REAL) {
330 return FALSE;
331 }
332 // Generic cases.
333 if (Rt == NOTYPE) {
334 return TRUE;
335 } else if (Lt != Rt) {
336 return FALSE;
337 } else if (Rl == NOLEN) {
338 return TRUE;
339 }
340 return Ll <= Rl;
341 }
342
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|