Pristine Ack-5.5
[Ack-5.5.git] / lang / m2 / comp / lookup.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 /* L O O K U P   R O U T I N E S */
9
10 /* $Id: lookup.c,v 1.19 1994/06/24 12:41:18 ceriel Exp $ */
11
12 #include        "debug.h"
13
14 #include        <em_arith.h>
15 #include        <em_label.h>
16 #include        <assert.h>
17
18 #include        "LLlex.h"
19 #include        "def.h"
20 #include        "idf.h"
21 #include        "scope.h"
22 #include        "node.h"
23 #include        "type.h"
24 #include        "misc.h"
25
26 extern int      pass_1;
27 #ifdef DEBUG
28 extern char     options[];
29 #endif
30
31 t_def *
32 lookup(id, scope, import, flags)
33         register t_idf *id;
34         t_scope *scope;
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 t_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 && import && scopeclosed(scope)) {
51                 for (df = id->id_def, df1 = 0;
52                      df && df->df_scope != PervasiveScope;
53                      df1 = df, df = df->df_next) { /* nothing */ }
54         }
55
56         if (df) {
57                 /* Found it
58                 */
59                 if (df1) {
60                         /* Put the definition in front
61                         */
62                         df1->df_next = df->df_next;
63                         df->df_next = id->id_def;
64                         id->id_def = df;
65                 }
66                 df->df_flags |= flags;
67                 while (df->df_kind & import) {
68                         assert(df->imp_def != 0);
69                         df = df->imp_def;
70                 }
71                 DO_DEBUG(options['S'], print("lookup %s, %x\n", id->id_text, df->df_kind));
72         }
73         return df;
74 }
75
76 t_def *
77 lookfor(id, vis, message, flags)
78         register t_node *id;
79         register t_scopelist *vis;
80 {
81         /*      Look for an identifier in the visibility range started by "vis".
82                 If it is not defined create a dummy definition and,
83                 if message is set, give an error message
84         */
85         register t_scopelist *sc;
86         t_scopelist *sc1 = 0;
87         t_def *df;
88
89         for (sc = vis; sc; sc = nextvisible(sc)) {
90                 df = lookup(id->nd_IDF, sc->sc_scope, D_IMPORTED, flags);
91                 if (df) {
92                         if (message && df->df_kind == D_FORWARD) {
93                                 if (! sc1) sc1 = sc;
94                                 while (sc && sc->sc_scope != df->df_scope) {
95                                         sc = enclosing(sc);
96                                 }
97                                 if (sc) continue;
98                                 break;
99                         }
100                         if (pass_1 && message) {
101                                 if (sc1) sc = sc1;
102                                 while (vis->sc_scope->sc_level >
103                                        sc->sc_scope->sc_level ||
104                                        (sc1 &&
105                                         vis->sc_scope->sc_level >=
106                                         sc->sc_scope->sc_level)) {
107                                         define( id->nd_IDF,
108                                                 vis->sc_scope,
109                                                 D_INUSE)-> imp_def = df;
110                                         vis = enclosing(vis);
111                                 }
112                         }
113                         return df;
114                 }
115         }
116
117         if (message) id_not_declared(id);
118
119         return MkDef(id->nd_IDF, vis->sc_scope, D_ERROR);
120 }