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".
5 * Author: Ceriel J.H. Jacobs
8 /* S C O P E M E C H A N I S M */
10 /* $Id: scope.C,v 1.48 1994/06/24 12:42:28 ceriel Exp $ */
26 t_scope *PervasiveScope;
27 t_scopelist *CurrVis, *GlobalVis;
29 extern char options[];
31 /* STATICALLOCDEF "scope" 10 */
33 /* STATICALLOCDEF "scopelist" 10 */
39 /* Open a scope that is either open (automatic imports) or closed.
41 register t_scope *sc = new_scope();
42 register t_scopelist *ls = new_scopelist();
44 assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE);
46 sc->sc_scopeclosed = scopetype == CLOSEDSCOPE;
47 sc->sc_level = proclevel;
49 ls->sc_encl = CurrVis;
50 if (! sc->sc_scopeclosed) {
51 ls->sc_next = ls->sc_encl;
53 ls->sc_count = sc_count++;
58 open_and_close_scope(scopetype)
62 open_scope(scopetype);
70 register t_scope *sc = new_scope();
71 register t_scopelist *ls = new_scopelist();
73 sc->sc_level = proclevel;
75 ls->sc_scope = PervasiveScope;
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.
88 if (df->df_kind == D_HIDDEN) {
89 error("hidden type \"%s\" not declared",
92 else if (df->df_kind == D_PROCHEAD) {
93 /* A not defined procedure
95 error("procedure \"%s\" not defined",
97 FreeNode(df->for_node);
99 df = df->df_nextinscope;
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.
114 if (df->df_kind == D_FORWTYPE) {
115 pdf = &df->df_nextinscope;
116 ForceForwardTypeDef(df); /* removes df */
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!
124 if (scopeclosed(CurrentScope)) {
125 /* Indeed, the scope was a closed
126 scope, so give error message
128 node_error(df->for_node, "identifier \"%s\" not declared",
129 df->df_idf->id_text);
132 /* This scope was an open scope.
133 Maybe the definitions are in the
136 register t_scopelist *ls =
137 nextvisible(CurrVis);
138 register t_def *df1 = lookup(df->df_idf, ls->sc_scope, 0, 0);
140 *pdf = df->df_nextinscope;
143 if (df->df_kind == D_FORWMODULE) {
144 df->for_vis->sc_next = ls;
146 df->df_nextinscope = ls->sc_scope->sc_def;
147 ls->sc_scope->sc_def = df;
148 df->df_scope = ls->sc_scope;
151 /* leave it like this ??? */
153 FreeNode(df->for_node);
155 pdf = &df->df_nextinscope;
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
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)
174 if (df1->df_kind & INTERESTING) {
178 df1 = df1->df_nextinscope;
179 df->df_nextinscope = prev;
181 else df1 = df1->df_nextinscope;
189 /* Close a scope. If "flag" is set, check for forward declarations,
190 either POINTER declarations, or EXPORTs, or forward references
193 register t_scope *sc = CurrentScope;
197 FreeNode(sc->sc_end);
198 sc->sc_end = dot2leaf(Link);
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));
206 CurrVis = enclosing(CurrVis);
215 df = df->df_nextinscope;