Pristine Ack-5.5
[Ack-5.5.git] / lang / m2 / comp / def.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  *
5  * Author: Ceriel J.H. Jacobs
6  */
7
8 /* D E F I N I T I O N   M E C H A N I S M */
9
10 /* $Id: def.c,v 1.66 1995/04/26 13:54:56 ceriel Exp $ */
11
12 #include        "debug.h"
13
14 #include        <alloc.h>
15 #include        <em_arith.h>
16 #include        <em_label.h>
17 #include        <em_code.h>
18 #include        <assert.h>
19
20 #include        "LLlex.h"
21 #include        "main.h"
22 #include        "def.h"
23 #include        "type.h"
24 #include        "idf.h"
25 #include        "scope.h"
26 #include        "node.h"
27 #include        "Lpars.h"
28 #include        "warning.h"
29
30 extern char *sprint();
31
32 STATIC
33 internal(c)
34         register char *c;
35 {
36         if (options['x']) {
37                 C_exp(c);
38         }
39         else    C_inp(c);
40 }
41
42 STATIC
43 DefInFront(df)
44         register t_def *df;
45 {
46         /*      Put definition "df" in front of the list of definitions
47                 in its scope.
48                 This is neccessary because in some cases the order in this
49                 list is important.
50         */
51         register t_def *df1 = df->df_scope->sc_def;
52
53         if (df1 != df) {
54                 /* Definition "df" is not in front of the list
55                 */
56                 while (df1) {
57                         /* Find definition "df"
58                         */
59                         if (df1->df_nextinscope == df) {
60                                 /* It already was in the list. Remove it
61                                 */
62                                 df1->df_nextinscope = df->df_nextinscope;
63                                 break;
64                         }
65                         df1 = df1->df_nextinscope;
66                 }
67
68                 /* Now put it in front
69                 */
70                 df->df_nextinscope = df->df_scope->sc_def;
71                 df->df_scope->sc_def = df;
72         }
73 }
74
75 t_def *
76 MkDef(id, scope, kind)
77         register t_idf *id;
78         register t_scope *scope;
79 {
80         /*      Create a new definition structure in scope "scope", with
81                 id "id" and kind "kind".
82         */
83         register t_def *df;
84
85         df = new_def();
86         df->df_idf = id;
87         df->df_scope = scope;
88         df->df_kind = kind;
89         df->df_next = id->id_def;
90         id->id_def = df;
91         if (kind == D_ERROR || kind == D_FORWARD) df->df_type = error_type;
92         if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
93                 df->df_flags = D_DEFINED;
94         }
95
96         /* enter the definition in the list of definitions in this scope
97         */
98         df->df_nextinscope = scope->sc_def;
99         scope->sc_def = df;
100         return df;
101 }
102
103 t_def *
104 define(id, scope, kind)
105         register t_idf *id;
106         register t_scope *scope;
107         int kind;
108 {
109         /*      Declare an identifier in a scope, but first check if it
110                 already has been defined.
111                 If so, then check for the cases in which this is legal,
112                 and otherwise give an error message.
113         */
114         register t_def *df;
115
116         DO_DEBUG(options['S'], print("define %s, %x\n", id->id_text, kind));
117         df = lookup(id, scope, D_IMPORT, 0);
118         if (    /* Already in this scope */
119                 df
120            ) {
121                 switch(df->df_kind) {
122                 case D_INUSE:
123                         if (kind != D_INUSE && kind != D_ERROR) {
124                                 error("identifier \"%s\" already used; may not be redefined in this scope", df->df_idf->id_text);
125                                 df->df_kind = D_ERROR;
126                                 break;
127                         }
128                         return df;
129
130                 case D_HIDDEN:
131                         /* An opaque type. We may now have found the
132                            definition of this type.
133                         */
134                         if (kind == D_TYPE && df->df_scope == CurrentScope &&
135                             !DefinitionModule) {
136                                 df->df_kind = D_TYPE;
137                                 return df;
138                         }
139                         break;
140
141                 case D_FORWMODULE:
142                         /* A forward reference to a module. We may have found
143                            another one, or we may have found the definition
144                            for this module.
145                         */
146                         if (kind & (D_FORWMODULE|D_FORWARD)) {
147                                 return df;
148                         }
149
150                         if (kind == D_MODULE) {
151                                 FreeNode(df->for_node);
152                                 df->mod_vis = df->for_vis;
153                                 df->df_kind = kind;
154                                 DefInFront(df);
155                                 return df;
156                         }
157                         break;
158
159                 case D_TYPE:
160                         if (kind == D_FORWTYPE) return df;
161                         break;
162                 case D_FORWTYPE:
163                         if (kind & (D_FORWTYPE|D_TYPE)) return df;
164                         error("identifier \"%s\" must be a type", id->id_text);
165                         df->df_kind = D_ERROR;
166                         break;
167                 case D_FORWARD:
168                         /* A forward reference, for which we may now have
169                            found a definition.
170                         */
171                         if (! (kind & (D_FORWARD | D_FORWMODULE))) {
172                                 FreeNode(df->for_node);
173                         }
174                         df->df_kind = D_ERROR;  /* avoiding error message */
175                         break;
176                 }
177
178                 if (kind != D_ERROR && df->df_kind != D_ERROR) {
179                         /* Avoid spurious error messages
180                         */
181                         error("identifier \"%s\" already declared",
182                               id->id_text);
183                 }
184                 if (df->df_scope == scope || df->df_kind == D_ERROR) {
185                         df->df_kind = kind;
186                         if (kind & (D_TYPE|D_PROCEDURE|D_CONST)) {
187                                 df->df_flags = D_DEFINED;
188                         }
189
190                         return df;
191                 }
192         }
193
194         return MkDef(id, scope, kind);
195 }
196
197 end_definition_list(pdf)
198         register t_def **pdf;
199 {
200         /*      Remove all imports from a definition module. This is
201                 neccesary because the implementation module might import
202                 them again.
203                 Also, mark all other definitions "QUALIFIED EXPORT".
204         */
205         register t_def *df;
206
207         while (df = *pdf) {
208                 if (df->df_kind & D_IMPORTED) {
209                         if (! (df->df_flags & D_USED)) {
210                                 warning(W_ORDINARY, "identifier \"%s\" imported but not used", df->df_idf->id_text);
211                         }
212                         RemoveFromIdList(df);
213                         *pdf = df->df_nextinscope;
214                         free_def(df);
215                 }
216                 else {
217                         df->df_flags |= D_QEXPORTED;
218                         pdf = &(df->df_nextinscope);
219                 }
220         }
221 }
222
223 RemoveFromIdList(df)
224         register t_def *df;
225 {
226         /*      Remove definition "df" from the definition list
227         */
228         register t_idf *id = df->df_idf;
229         register t_def *df1;
230
231         if ((df1 = id->id_def) == df) id->id_def = df->df_next;
232         else {
233                 while (df1->df_next != df) {
234                         assert(df1->df_next != 0);
235                         df1 = df1->df_next;
236                 }
237                 df1->df_next = df->df_next;
238         }
239 }
240
241 t_def *
242 DeclProc(type, id)
243         register t_idf *id;
244 {
245         /*      A procedure is declared, either in a definition or a program
246                 module. Create a def structure for it (if neccessary).
247                 Also create a name for it.
248         */
249         register t_def *df;
250         register t_scope *scope;
251         static int nmcount;
252         char buf[256];
253
254         assert(type & (D_PROCEDURE | D_PROCHEAD));
255
256         if (type == D_PROCHEAD) {
257                 /* In a definition module
258                 */
259                 df = define(id, CurrentScope, type);
260                 df->for_node = dot2leaf(Name);
261                 df->df_flags |= D_USED | D_DEFINED;
262                 if (CurrentScope->sc_definedby->df_flags & D_FOREIGN) {
263                         df->prc_name = id->id_text;
264                 }
265                 else {
266                         sprint(buf,"%s_%s",CurrentScope->sc_name,id->id_text);
267                         df->prc_name = Salloc(buf, (unsigned) (strlen(buf)+1));
268                 }
269                 if (CurrVis == Defined->mod_vis) {
270                         /* The current module will define this routine.
271                            make sure the name is exported.
272                         */
273                         C_exp(df->prc_name);
274                 }
275         }
276         else {
277                 df = lookup(id, CurrentScope, D_IMPORTED, 0);
278                 if (df && df->df_kind == D_PROCHEAD) {
279                         /* C_exp already generated when we saw the definition
280                            in the definition module
281                         */
282                         DefInFront(df);
283                 }
284                 else {
285                         df = define(id, CurrentScope, type);
286                         sprint(buf,"_%d_%s",++nmcount,id->id_text);
287                         df->prc_name = Salloc(buf, (unsigned)(strlen(buf)+1));
288                         internal(buf);
289                         df->df_flags |= D_DEFINED;
290                 }
291                 open_scope(OPENSCOPE);
292                 scope = CurrentScope;
293                 scope->sc_name = df->prc_name;
294                 scope->sc_definedby = df;
295         }
296         df->prc_vis = CurrVis;
297
298         return df;
299 }
300
301 EndProc(df, id)
302         register t_def *df;
303         t_idf *id;
304 {
305         /*      The end of a procedure declaration.
306                 Check that the closing identifier matches the name of the
307                 procedure, close the scope, and check that a function
308                 procedure has at least one RETURN statement.
309         */
310         extern int return_occurred;
311
312         match_id(id, df->df_idf);
313         close_scope(SC_CHKFORW|SC_REVERSE);
314         if (! return_occurred && ResultType(df->df_type)) {
315                 error("function procedure %s does not return a value",
316                       df->df_idf->id_text);
317         }
318 }
319
320 t_def *
321 DefineLocalModule(id)
322         t_idf *id;
323 {
324         /*      Create a definition for a local module. Also give it
325                 a name to be used for code generation.
326         */
327         register t_def *df = define(id, CurrentScope, D_MODULE);
328         register t_scope *sc;
329         static int modulecount = 0;
330         char buf[256];
331         extern int proclevel;
332
333         sprint(buf, "_%d%s_", ++modulecount, id->id_text);
334
335         if (!df->mod_vis) {     
336                 /* We never saw the name of this module before. Create a
337                    scope for it.
338                 */
339                 open_scope(CLOSEDSCOPE);
340                 df->mod_vis = CurrVis;
341         }
342
343         CurrVis = df->mod_vis;
344
345         sc = CurrentScope;
346         sc->sc_level = proclevel;
347         sc->sc_definedby = df;
348         sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
349
350         /* Create a type for it
351         */
352         df->df_type = standard_type(T_RECORD, 1, (arith) 0);
353         df->df_type->rec_scope = sc;
354
355         /* Generate code that indicates that the initialization procedure
356            for this module is local.
357         */
358         internal(buf);
359         return df;
360 }
361
362 CheckWithDef(df, tp)
363         register t_def *df;
364         t_type *tp;
365 {
366         /*      Check the header of a procedure declaration against a
367                 possible earlier definition in the definition module.
368         */
369
370         if (df->df_kind == D_PROCHEAD &&
371             df->df_type &&
372             df->df_type != error_type) {
373                 /* We already saw a definition of this type
374                    in the definition module.
375                 */
376
377                 if (!TstProcEquiv(tp, df->df_type)) {
378                         error("inconsistent procedure declaration for \"%s\"",
379                               df->df_idf->id_text); 
380                 }
381                 FreeType(df->df_type);
382                 df->df_kind = D_PROCEDURE;
383         }
384         df->df_type = tp;
385 }
386
387 #ifdef DEBUG
388 PrDef(df)
389         register t_def *df;
390 {
391         print("n: %s, k: %d\n", df->df_idf->id_text, df->df_kind);
392 }
393 #endif /* DEBUG */