1 /* $Id: cs_getent.c,v 1.8 1994/06/24 10:22:21 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
7 #include "../share/types.h"
8 #include "../share/aux.h"
9 #include "../share/debug.h"
10 #include "../share/global.h"
13 #include "cs_entity.h"
22 STATIC struct inf_entity {
23 byte inf_instr; /* Key. */
24 byte inf_used; /* Kind of entity used by key. */
25 byte inf_size; /* Indication of the size. */
27 op_adp, ENAOFFSETTED, PS,
28 op_dee, ENEXTERNAL, WS1,
30 op_ine, ENEXTERNAL, WS1,
32 op_lae, ENAEXTERNAL, PS,
34 op_lar, ENARRELEM, ARDESC3,
36 op_lde, ENEXTERNAL, WS2,
37 op_ldf, ENOFFSETTED, WS2,
40 op_lim, ENIGNMASK, WS1,
42 op_loe, ENEXTERNAL, WS1,
43 op_lof, ENOFFSETTED, WS1,
44 op_loi, ENINDIR, ARGW,
47 op_lxa, ENAARGBASE, PS,
48 op_lxl, ENALOCBASE, PS,
49 op_sar, ENARRELEM, ARDESC3,
50 op_sde, ENEXTERNAL, WS2,
51 op_sdf, ENOFFSETTED, WS2,
54 op_sim, ENIGNMASK, WS1,
55 op_ste, ENEXTERNAL, WS1,
56 op_stf, ENOFFSETTED, WS1,
57 op_sti, ENINDIR, ARGW,
59 op_zer, ENCONST, ARGW,
60 op_zre, ENEXTERNAL, WS1,
63 op_nop /* Delimitor. */
66 #define INFKEY(ip) (ip->inf_instr & BMASK)
67 #define ENKIND(ip) ip->inf_used
68 #define SIZEINF(ip) ip->inf_size
70 STATIC struct inf_entity *getinf(n)
73 struct inf_entity *ip;
75 for (ip = &inf_table[0]; INFKEY(ip) != op_nop; ip++) {
76 if (INFKEY(ip) == n) return ip;
78 return (struct inf_entity *) 0;
81 entity_p getentity(lnp, l_out)
84 /* Build the entities where lnp refers to, and enter them.
85 * If a token needs to be popped, the first line that pushed
86 * it is stored in *l_out.
87 * The main entity lnp refers to, is returned.
91 struct inf_entity *ip;
94 struct token adesc, index, arbase;
98 /* Lor is a special case. */
99 if (INSTR(lnp) == op_lor) {
100 offset off = off_set(lnp);
102 en.en_static = FALSE;
104 switch ((int) off == off ? (int) off : 3) {
109 en.en_kind = ENLOCBASE;
114 en.en_kind = ENHEAPPTR;
117 return en_enter(&en);
120 if ( (ip = getinf(INSTR(lnp))) == (struct inf_entity *) 0)
121 return (entity_p) 0; /* It does not refer to any entity. */
123 /* Lil and sil refer to two entities. */
124 if (INSTR(lnp) == op_lil || INSTR(lnp) == op_sil) {
125 en.en_static = FALSE;
126 en.en_kind = ENLOCAL;
127 en.en_size = ps; /* Local must be a pointer. */
128 en.en_loc = off_set(lnp);
129 vn = en_enter(&en)->en_vn;
132 en.en_static = FALSE;
133 en.en_kind = ENKIND(ip);
135 /* Fill in the size of the entity. */
136 switch (SIZEINF(ip)) {
150 if (TYPE(lnp) != OPNO) {
151 en.en_size = off_set(lnp);
153 Pop(&tk, (offset) ws);
154 *l_out = tk.tk_lfirst;
155 en.en_size = UNKNOWN_SIZE;
159 assert(en.en_kind == ENARRELEM);
160 if (TYPE(lnp) != OPNO) {
161 indexsize = off_set(lnp);
163 Pop(&tk, (offset) ws);
164 indexsize = UNKNOWN_SIZE;
166 Pop(&adesc, (offset) ps);
167 en.en_adesc = adesc.tk_vn;
168 Pop(&index, indexsize);
169 en.en_index = index.tk_vn;
170 Pop(&arbase, (offset) ps);
171 en.en_arbase = arbase.tk_vn;
172 *l_out = arbase.tk_lfirst;
173 en.en_size = array_elemsize(adesc.tk_vn);
177 /* Fill in additional information. */
178 switch (en.en_kind) {
184 en.en_val = off_set(lnp);
189 en.en_loc = off_set(lnp);
194 en.en_ext = OBJ(lnp);
197 if (INSTR(lnp) == op_loi || INSTR(lnp) == op_sti) {
198 Pop(&tk, (offset) ps);
199 *l_out = tk.tk_lfirst;
207 Pop(&tk, (offset) ps);
208 *l_out = tk.tk_lfirst;
209 en.en_base = tk.tk_vn;
210 en.en_off = off_set(lnp);
214 en.en_levels = off_set(lnp);
215 if (en.en_levels == 0) {
216 /* otherwise the program could change it */
221 en.en_pro = PROC(lnp);
224 /* We gathered the information in the previous switch.
229 return en_enter(&en);