/* S C O P E M E C H A N I S M */ static char *RcsId = "$Header$"; #include #include #include #include #include "LLlex.h" #include "idf.h" #include "scope.h" #include "type.h" #include "def.h" #include "debug.h" static int maxscope; /* maximum assigned scope number */ struct scope *CurrentScope, *GlobalScope; /* STATICALLOCDEF "scope" */ open_scope(scopetype, scope) { /* Open a scope that is either open (automatic imports) or closed. A closed scope is handled by adding an extra entry to the list with scope number 0. This has two purposes: it makes scope 0 visible, and it marks the end of a visibility list. Scope 0 is the pervasive scope, the one that is always visible. A disadvantage of this method is that we cannot open scope 0 explicitly. */ register struct scope *sc = new_scope(); register struct scope *sc1; sc->sc_scope = scope == 0 ? ++maxscope : scope; sc->sc_forw = 0; sc->sc_def = 0; assert(scopetype == OPENSCOPE || scopetype == CLOSEDSCOPE); DO_DEBUG(debug(1, "Opening a %s scope", scopetype == OPENSCOPE ? "open" : "closed")); sc1 = CurrentScope; if (scopetype == CLOSEDSCOPE) { sc1 = new_scope(); sc1->sc_scope = 0; /* Pervasive scope nr */ sc1->sc_forw = 0; sc1->sc_def = 0; sc1->next = CurrentScope; } sc->next = sc1; CurrentScope = sc; } static rem_forwards(); close_scope() { register struct scope *sc = CurrentScope; assert(sc != 0); DO_DEBUG(debug(1, "Closing a scope")); if (sc->sc_forw) rem_forwards(sc->sc_forw); if (sc->next && (sc->next->sc_scope == 0)) { struct scope *sc1 = sc; sc = sc->next; free_scope(sc1); } CurrentScope = sc->next; free_scope(sc); } init_scope() { register struct scope *sc = new_scope(); sc->sc_scope = 0; sc->sc_forw = 0; sc->sc_def = 0; CurrentScope = sc; } int uniq_scope() { return ++maxscope; } struct forwards { struct forwards *next; struct token fo_tok; struct type **fo_ptyp; }; /* STATICALLOCDEF "forwards" */ Forward(tk, ptp) struct token *tk; struct type **ptp; { /* Enter a forward reference into a list belonging to the current scope. This is used for POINTER declarations, which may have forward references that must howewer be declared in the same scope. */ register struct forwards *f = new_forwards(); f->fo_tok = *tk; f->fo_ptyp = ptp; f->next = CurrentScope->sc_forw; CurrentScope->sc_forw = f; } static rem_forwards(fo) struct forwards *fo; { /* When closing a scope, all forward references must be resolved */ register struct forwards *f; struct token savetok; register struct def *df; struct def *lookfor(); savetok = dot; while (f = fo) { dot = f->fo_tok; df = lookfor(dot.TOK_IDF, CurrentScope, 1); if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) { error("identifier \"%s\" not a type", df->df_idf->id_text); } *(f->fo_ptyp) = df->df_type; fo = f->next; free_forwards(f); } dot = savetok; }