Pristine Ack-5.5
[Ack-5.5.git] / lang / pc / comp / lookup.c
1 /* L O O K U P   R O U T I N E S */
2
3 #include        <alloc.h>
4 #include        <em_arith.h>
5 #include        <em_label.h>
6 #include        <assert.h>
7
8 #include        "LLlex.h"
9 #include        "def.h"
10 #include        "idf.h"
11 #include        "misc.h"
12 #include        "node.h"
13 #include        "scope.h"
14 #include        "type.h"
15
16 remove_def(df)
17         register struct def *df;
18 {
19         struct idf *id= df->df_idf;
20         struct def *df1 = id->id_def;
21
22         if( df1 == df ) id->id_def = df->df_next;
23         else {
24                 while( df1 && df1->df_next != df ) df1 = df1->df_next;
25                 df1->df_next = df->df_next;
26         }
27         free_def(df);
28 }
29
30 struct def *
31 lookup(id, scope, inuse)
32         register struct idf *id;
33         struct scope *scope;
34         long    inuse;
35 {
36         /*      Look up a definition of an identifier in scope "scope".
37                 Make the "def" list self-organizing.
38                 Return a pointer to its "def" structure if it exists,
39                 otherwise return 0.
40         */
41         register struct def *df, *df1;
42
43         /* Look in the chain of definitions of this "id" for one with scope
44            "scope".
45         */
46         for( df = id->id_def, df1 = 0;
47              df && df->df_scope != scope;
48              df1 = df, df = df->df_next ) { /* nothing */ }
49
50         if( df )        {
51                 /* Found it
52                 */
53                 if( df1) {
54                         /* Put the definition in front
55                         */
56                         df1->df_next = df->df_next;
57                         df->df_next = id->id_def;
58                         id->id_def = df;
59                 }
60                 while( df->df_kind & inuse ) {
61                         assert(df->usd_def != 0);
62                         df=df->usd_def;
63                 }
64         }
65
66         return df;
67 }
68
69 struct def *
70 lookfor(id, vis, give_error)
71         register struct node *id;
72         struct scopelist *vis;
73 {
74         /*      Look for an identifier in the visibility range started by "vis".
75                 If it is not defined create a dummy definition and
76                 if give_error is set, give an error message.
77         */
78         register struct def *df, *tmp_df;
79         register struct scopelist *sc = vis;
80
81         while( sc )     {
82                 df = lookup(id->nd_IDF, sc->sc_scope, D_INUSE);
83                 if( df ) {
84                         while( vis->sc_scope->sc_level >
85                                 sc->sc_scope->sc_level ) {
86                                 if( tmp_df = define(id->nd_IDF, vis->sc_scope,
87                                         D_INUSE))
88                                         tmp_df->usd_def = df;
89                             vis = nextvisible(vis);
90                         }
91                 /* Since the scope-level of standard procedures is the
92                  * same as for the user-defined procedures, the procedure
93                  * must be marked as used. Not doing so would mean that
94                  * such a procedure could redefined after usage.
95                  */
96                         if( (vis->sc_scope == GlobalScope) &&
97                             !lookup(id->nd_IDF, GlobalScope, D_INUSE) ) { 
98                                 if( tmp_df = define(id->nd_IDF, vis->sc_scope,
99                                         D_INUSE))
100                                         tmp_df->usd_def = df;
101                         }
102
103                         return df;
104                 }
105                 sc = nextvisible(sc);
106         }
107
108         if( give_error ) id_not_declared(id);
109
110         df = MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
111         return df;
112 }