Pristine Ack-5.5
[Ack-5.5.git] / lang / m2 / comp / scope.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 /* S C O P E   M E C H A N I S M */
9
10 /* $Id: scope.C,v 1.48 1994/06/24 12:42:28 ceriel Exp $ */
11
12 #include        "debug.h"
13
14 #include        <assert.h>
15 #include        <alloc.h>
16 #include        <em_arith.h>
17 #include        <em_label.h>
18
19 #include        "LLlex.h"
20 #include        "idf.h"
21 #include        "scope.h"
22 #include        "type.h"
23 #include        "def.h"
24 #include        "node.h"
25
26 t_scope *PervasiveScope;
27 t_scopelist *CurrVis, *GlobalVis;
28 extern int proclevel;
29 extern char options[];
30
31 /* STATICALLOCDEF "scope" 10 */
32
33 /* STATICALLOCDEF "scopelist" 10 */
34
35 static int      sc_count;
36
37 open_scope(scopetype)
38 {
39         /*      Open a scope that is either open (automatic imports) or closed.
40         */
41         register t_scope *sc = new_scope();
42         register t_scopelist *ls = new_scopelist();
43         
44         assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
45
46         sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
47         sc->sc_level = proclevel;
48         ls->sc_scope = sc;
49         ls->sc_encl = CurrVis;
50         if (! sc->sc_scopeclosed) {
51                 ls->sc_next = ls->sc_encl;
52         }
53         ls->sc_count = sc_count++;
54         CurrVis = ls;
55 }
56
57 t_scope *
58 open_and_close_scope(scopetype)
59 {
60         t_scope *sc;
61
62         open_scope(scopetype);
63         sc = CurrentScope;
64         close_scope(0);
65         return sc;
66 }
67
68 InitScope()
69 {
70         register t_scope *sc = new_scope();
71         register t_scopelist *ls = new_scopelist();
72
73         sc->sc_level = proclevel;
74         PervasiveScope = sc;
75         ls->sc_scope = PervasiveScope;
76         CurrVis = ls;
77 }
78
79 STATIC
80 chk_proc(df)
81         register t_def *df;
82 {
83         /*      Called at scope closing. Check all definitions, and if one
84                 is a D_PROCHEAD, the procedure was not defined.
85                 Also check that hidden types are defined.
86         */
87         while (df) {
88                 if (df->df_kind == D_HIDDEN) {
89                         error("hidden type \"%s\" not declared",
90                                 df->df_idf->id_text);
91                 }
92                 else if (df->df_kind == D_PROCHEAD) {
93                         /* A not defined procedure
94                         */
95                         error("procedure \"%s\" not defined",
96                                 df->df_idf->id_text);
97                         FreeNode(df->for_node);
98                 }
99                 df = df->df_nextinscope;
100         }
101 }
102
103 STATIC
104 chk_forw(pdf)
105         t_def **pdf;
106 {
107         /*      Called at scope close. Look for all forward definitions and
108                 if the scope was a closed scope, give an error message for
109                 them, and otherwise move them to the enclosing scope.
110         */
111         register t_def *df;
112
113         while (df = *pdf) {
114                 if (df->df_kind == D_FORWTYPE) {
115                         pdf = &df->df_nextinscope;
116                         ForceForwardTypeDef(df);        /* removes df */
117                         continue;
118                 }
119                 if (df->df_kind & (D_FORWARD|D_FORWMODULE)) {
120                         /* These definitions must be found in
121                            the enclosing closed scope, which of course
122                            may be the scope that is now closed!
123                         */
124                         if (scopeclosed(CurrentScope)) {
125                                 /* Indeed, the scope was a closed
126                                    scope, so give error message
127                                 */
128 node_error(df->for_node, "identifier \"%s\" not declared",
129 df->df_idf->id_text);
130                         }
131                         else {
132                                 /* This scope was an open scope.
133                                    Maybe the definitions are in the
134                                    enclosing scope?
135                                 */
136                                 register t_scopelist *ls =
137                                                 nextvisible(CurrVis);
138                                 register t_def *df1 = lookup(df->df_idf, ls->sc_scope, 0, 0);
139
140                                 *pdf = df->df_nextinscope;
141         
142                                 if (! df1) {
143                                         if (df->df_kind == D_FORWMODULE) {
144                                                 df->for_vis->sc_next = ls;
145                                         }
146                                         df->df_nextinscope = ls->sc_scope->sc_def;
147                                         ls->sc_scope->sc_def = df;
148                                         df->df_scope = ls->sc_scope;
149                                         continue;
150                                 }
151                                 /* leave it like this ??? */
152                         }
153                         FreeNode(df->for_node);
154                 }
155                 pdf = &df->df_nextinscope;
156         }
157 }
158
159 Reverse(pdf)
160         t_def **pdf;
161 {
162         /*      Reverse the order in the list of definitions in a scope.
163                 This is neccesary because this list is built in reverse.
164                 Also, while we're at it, remove uninteresting definitions
165                 from this list.
166         */
167         register t_def *df, *df1;
168 #define INTERESTING (D_MODULE|D_PROCEDURE|D_PROCHEAD|D_VARIABLE|D_IMPORTED|D_TYPE|D_CONST|D_FIELD)
169
170         df = 0;
171         df1 = *pdf;
172
173         while (df1) {
174                 if (df1->df_kind & INTERESTING) {
175                         t_def *prev = df;
176
177                         df = df1;
178                         df1 = df1->df_nextinscope;
179                         df->df_nextinscope = prev;
180                 }
181                 else    df1 = df1->df_nextinscope;
182         }
183         *pdf = df;
184 }
185
186 close_scope(flag)
187         register int flag;
188 {
189         /*      Close a scope. If "flag" is set, check for forward declarations,
190                 either POINTER declarations, or EXPORTs, or forward references
191                 to MODULES
192         */
193         register t_scope *sc = CurrentScope;
194
195         assert(sc != 0);
196
197         FreeNode(sc->sc_end);
198         sc->sc_end = dot2leaf(Link);
199
200         if (flag) {
201                 DO_DEBUG(options['S'],(print("List of definitions in currently ended scope:\n"), DumpScope(sc->sc_def)));
202                 if (flag & SC_CHKPROC) chk_proc(sc->sc_def);
203                 if (flag & SC_CHKFORW) chk_forw(&(sc->sc_def));
204                 if (flag & SC_REVERSE) Reverse(&(sc->sc_def));
205         }
206         CurrVis = enclosing(CurrVis);
207 }
208
209 #ifdef DEBUG
210 DumpScope(df)
211         register t_def *df;
212 {
213         while (df) {
214                 PrDef(df);
215                 df = df->df_nextinscope;
216         }
217 }
218 #endif