decls.c
1 //! @file decls.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-2025 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 declarations.
25
26 #include <vif.h>
27
28 void idfs_reset (void)
29 {
30 // Before explicit declarations reset implicit ones.
31 // Then do explicit declarations, followed by implicit ones.
32 int_4 k;
33 for (k = 0; k < nlocals; k++) {
34 IDENT *idf = &locals[k];
35 if (idf->parm == NO_TEXT && !idf->mode.fun) {
36 idf->mode.type = NOTYPE;
37 }
38 }
39 }
40
41 void idfs_unused (void)
42 {
43 // Before explicit declarations reset implicit ones.
44 // Then do explicit declarations, followed by implicit ones.
45 int_4 k;
46 for (k = 0; k < nlocals; k++) {
47 IDENT *idf = &locals[k];
48 idf->used = FALSE;
49 }
50 }
51
52 void get_init (IDENT *idf, MODE *mode)
53 {
54 EXPR reg;
55 memset (®, 0, sizeof (EXPR));
56 (void) scan (EXPECT_NONE);
57 factor (®);
58 if (accept_mode (reg.mode.type, reg.mode.len, mode->type, mode->len)) {
59 cpp_direct (nprocs, prelin, BODY);
60 RECORD str;
61 if (mode->type == CHARACTER) {
62 _srecordf (str, "bufcpy (%s, %s, %d);\n", C_NAME (idf), reg.str, mode->len);
63 } else {
64 _srecordf (str, "%s = %s;\n", C_NAME (idf), reg.str);
65 }
66 code (nprocs, BODY, str);
67 } else {
68 ERROR (801, "expect type", qtype (mode));
69 }
70 }
71
72 void dec_local (void)
73 {
74 int_4 rc;
75 MODE mode;
76 RECORD base;
77 RECCLR (base);
78 strcpy (base, curlex);
79 // Remove length specification.
80 char *star = strchr (base, '*');
81 if (star != NO_TEXT) {
82 *star = '\0';
83 }
84 //
85 f2c_type (curlex, &mode, NOARG, NOFUN);
86 rc = scan (EXPECT_NONE);
87 if (rc == END_OF_LINE) {
88 EXPECT (802, "identifier");
89 }
90 while (rc != END_OF_LINE) {
91 IDENT *idf = NO_IDENT;
92 // Identifier, store with leading mode unless length N is specified as idf*N.
93 RECORD name;
94 RECCLR (name);
95 if (rc != WORD) {
96 EXPECT (803, "identifier");
97 } else {
98 strcpy (name, curlex);
99 rc = scan (EXPECT_NONE);
100 if (!TOKEN ("*")) {
101 // identifier
102 idf = add_local (name, mode.type, mode.len, UNIQ, NOPATCH, NOARG, LOCAL, SOURCE);
103 } else {
104 // identifier*length
105 RECORD length;
106 rc = scan (EXPECT_NONE);
107 bufcpy (length, curlex, RECLN);
108 if (TOKEN ("(")) {
109 // identifier*(length)
110 rc = scan (EXPECT_NONE);
111 bufcpy (length, curlex, RECLN);
112 (void) scan (")");
113 }
114 if (rc == WORD) {
115 IDENT *ldf = find_local (length, NO_MODE);
116 if (ldf == NO_IDENT || ldf->parm == NO_TEXT) {
117 SYNTAX (804, length);
118 } else if (ldf->mode.type != INTEGER) {
119 EXPECT (805, "integer");
120 } else {
121 RECORD new;
122 RECCLR (new);
123 snprintf (new, RECLN, "%s*%s", base, ldf->parm);
124 MODE mode_n;
125 f2c_type (new, &mode_n, NOARG, NOFUN);
126 norm_mode (&mode_n);
127 idf = add_local (name, mode_n.type, mode_n.len, UNIQ, NOPATCH, NOARG, LOCAL, SOURCE);
128 }
129 rc = scan (EXPECT_NONE);
130 } else if (rc == INT_NUMBER || EQUAL (length, "*")) {
131 RECORD new;
132 RECCLR (new);
133 MODE mode_n;
134 if (EQUAL (length, "*")) {
135 snprintf (new, RECLN, "%s*(*)", base);
136 } else {
137 snprintf (new, RECLN, "%s*%s", base, length);
138 }
139 f2c_type (new, &mode_n, NOARG, NOFUN);
140 norm_mode (&mode_n);
141 idf = add_local (name, mode_n.type, mode_n.len, UNIQ, NOPATCH, NOARG, LOCAL, SOURCE);
142 rc = scan (EXPECT_NONE);
143 } else {
144 SYNTAX (806, name);
145 }
146 }
147 //
148 }
149 if (TOKEN ("(") && idf != NO_IDENT) {
150 if (IS_ROW (idf->mode)) {
151 ERROR (807, "already dimensioned", C_NAME (idf));
152 }
153 get_dims (idf, 1);
154 rc = scan (EXPECT_NONE);
155 if (TOKEN ("*")) {
156 RECORD length;
157 rc = scan (EXPECT_NONE);
158 bufcpy (length, curlex, RECLN);
159 if (TOKEN ("(")) {
160 // identifier*(length)
161 rc = scan (EXPECT_NONE);
162 bufcpy (length, curlex, RECLN);
163 (void) scan (")");
164 }
165 if (rc == WORD) {
166 IDENT *ldf = find_local (length, NO_MODE);
167 if (ldf == NO_IDENT || ldf->parm == NO_TEXT) {
168 SYNTAX (808, length);
169 } else if (ldf->mode.type != INTEGER) {
170 EXPECT (809, "integer");
171 } else {
172 RECORD new;
173 RECCLR (new);
174 snprintf (new, RECLN, "%s*%s", base, ldf->parm);
175 MODE mode_n;
176 f2c_type (new, &mode_n, NOARG, NOFUN);
177 norm_mode (&mode_n);
178 idf->mode.type = mode_n.type;
179 idf->mode.len = mode_n.len;
180 }
181 rc = scan (EXPECT_NONE);
182 } else if (rc == INT_NUMBER || EQUAL (length, "*")) {
183 RECORD new;
184 RECCLR (new);
185 snprintf (new, RECLN, "%s*%s", base, length);
186 MODE mode_n;
187 f2c_type (new, &mode_n, NOARG, NOFUN);
188 norm_mode (&mode_n);
189 idf->mode.type = mode_n.type;
190 idf->mode.len = mode_n.len;
191 rc = scan (EXPECT_NONE);
192 } else {
193 SYNTAX (810, name);
194 }
195 }
196 //
197 } else if (TOKEN ("/") && idf != NO_IDENT) {
198 get_init (idf, &mode);
199 rc = scan (EXPECT_NONE);
200 if (!TOKEN ("/")) {
201 EXPECT (811, "/");
202 }
203 rc = scan (EXPECT_NONE);
204 }
205 if (TOKEN (",")) {
206 rc = scan (EXPECT_NONE);
207 if (! WITHIN) {
208 SYNTAX (812, NO_TEXT);
209 }
210 } else {
211 if (rc != END_OF_LINE) {
212 SYNTAX (813, NO_TEXT);
213 rc = scan (EXPECT_NONE);
214 }
215 }
216 }
217 }
218
219 IDENT *extf_decl (char *name, MODE *mode)
220 {
221 IDENT *idf = impl_decl (name, mode);
222 if (idf->external) {
223 ERROR (814, "already set external", C_NAME (idf));
224 } else if (idf->intrinsic) {
225 ERROR (815, "already set intrinsic", C_NAME (idf));
226 } else {
227 idf->external = TRUE;
228 }
229 return idf;
230 }
231
232 static void externals (void)
233 {
234 int_4 rc;
235 while ((rc = scan (EXPECT_NONE)) != END_OF_LINE) {
236 if (TOKEN (",")) {
237 ;
238 } else if (rc == WORD) {
239 MODE mode;
240 extf_decl (curlex, &mode);
241 } else {
242 EXPECT (816, "subprogram name");
243 }
244 }
245 }
246
247 static void intrinsics (void)
248 {
249 int_4 rc;
250 while ((rc = scan (EXPECT_NONE)) != END_OF_LINE) {
251 if (TOKEN (",")) {
252 ;
253 } else if (!is_intrins (curlex)){
254 EXPECT (817, "intrinsic funcion name");
255 } else {
256 RECORD name;
257 bufcpy (name, curlex, RECLN);
258 IDENT *idf = add_local (name, NOTYPE, NOLEN, UNIQ, NOPATCH, NOARG, LOCAL, TEMP);
259 if (idf->external) {
260 ERROR (818, "already set external", C_NAME (idf));
261 } else if (idf->intrinsic) {
262 ERROR (819, "already set intrinsic", C_NAME (idf));
263 } else {
264 idf->intrinsic = TRUE;
265 }
266 }
267 }
268 }
269
270 void get_decls (void)
271 {
272 int_4 go_on = TRUE;
273 idfs_reset ();
274 while (go_on) {
275 SAVE_POS;
276 int_4 rc = scan (EXPECT_NONE);
277 if (rc == DECLAR) {
278 dec_local ();
279 skip_card (FALSE);
280 } else if (TOKEN ("implicit")) {
281 skip_card (FALSE);
282 } else if (TOKEN ("save")) {
283 skip_card (FALSE);
284 } else if (TOKEN ("automatic")) {
285 skip_card (FALSE);
286 } else if (TOKEN ("parameter")) {
287 parameter ();
288 skip_card (FALSE);
289 } else if (TOKEN ("common")) {
290 common ();
291 skip_card (FALSE);
292 } else if (TOKEN ("dimension")) {
293 dimension ();
294 skip_card (FALSE);
295 } else if (TOKEN ("equivalence")) {
296 skip_card (FALSE);
297 } else if (TOKEN ("external")) {
298 externals ();
299 } else if (TOKEN ("intrinsic")) {
300 intrinsics ();
301 } else if (TOKEN ("data")) {
302 skip_card (FALSE);
303 } else if (strlen (curlex) > 0) {
304 // Backspace and done.
305 RESTORE_POS;
306 go_on = FALSE;
307 }
308 }
309 idfs_impl ();
310 }
© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)
|