Pristine Ack-5.5
[Ack-5.5.git] / util / ego / cs / cs_getent.c
1 /* $Id: cs_getent.c,v 1.8 1994/06/24 10:22:21 ceriel Exp $ */
2 /*
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".
5  */
6 #include <em_mnem.h>
7 #include "../share/types.h"
8 #include "../share/aux.h"
9 #include "../share/debug.h"
10 #include "../share/global.h"
11 #include "cs.h"
12 #include "cs_aux.h"
13 #include "cs_entity.h"
14 #include "cs_stack.h"
15
16 #define WS1     0
17 #define WS2     1
18 #define PS      2
19 #define ARGW    3
20 #define ARDESC3 4
21
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.      */
26 } inf_table[] = {
27         op_adp, ENAOFFSETTED,   PS,
28         op_dee, ENEXTERNAL,     WS1,
29         op_del, ENLOCAL,        WS1,
30         op_ine, ENEXTERNAL,     WS1,
31         op_inl, ENLOCAL,        WS1,
32         op_lae, ENAEXTERNAL,    PS,
33         op_lal, ENALOCAL,       PS,
34         op_lar, ENARRELEM,      ARDESC3,
35         op_ldc, ENCONST,        WS2,
36         op_lde, ENEXTERNAL,     WS2,
37         op_ldf, ENOFFSETTED,    WS2,
38         op_ldl, ENLOCAL,        WS2,
39         op_lil, ENINDIR,        WS1,
40         op_lim, ENIGNMASK,      WS1,
41         op_loc, ENCONST,        WS1,
42         op_loe, ENEXTERNAL,     WS1,
43         op_lof, ENOFFSETTED,    WS1,
44         op_loi, ENINDIR,        ARGW,
45         op_lol, ENLOCAL,        WS1,
46         op_lpi, ENPROC,         PS,
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,
52         op_sdl, ENLOCAL,        WS2,
53         op_sil, ENINDIR,        WS1,
54         op_sim, ENIGNMASK,      WS1,
55         op_ste, ENEXTERNAL,     WS1,
56         op_stf, ENOFFSETTED,    WS1,
57         op_sti, ENINDIR,        ARGW,
58         op_stl, ENLOCAL,        WS1,
59         op_zer, ENCONST,        ARGW,
60         op_zre, ENEXTERNAL,     WS1,
61         op_zrf, ENFZER,         ARGW,
62         op_zrl, ENLOCAL,        WS1,
63         op_nop  /* Delimitor. */
64 };
65
66 #define INFKEY(ip)      (ip->inf_instr & BMASK)
67 #define ENKIND(ip)      ip->inf_used
68 #define SIZEINF(ip)     ip->inf_size
69
70 STATIC struct inf_entity *getinf(n)
71         int n;
72 {
73         struct inf_entity *ip;
74
75         for (ip = &inf_table[0]; INFKEY(ip) != op_nop; ip++) {
76                 if (INFKEY(ip) == n) return ip;
77         }
78         return (struct inf_entity *) 0;
79 }
80
81 entity_p getentity(lnp, l_out)
82         line_p lnp, *l_out;
83 {
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.
88          */
89         struct entity en;
90         struct token tk;
91         struct inf_entity *ip;
92         valnum vn;
93         offset indexsize;
94         struct token adesc, index, arbase;
95
96         *l_out = lnp;
97
98         /* Lor is a special case. */
99         if (INSTR(lnp) == op_lor) {
100                 offset off = off_set(lnp);
101
102                 en.en_static = FALSE;
103                 en.en_size = ps;
104                 switch ((int) off == off ? (int) off : 3) {
105                         default:
106                                 assert(FALSE);
107                                 break;
108                         case 0:
109                                 en.en_kind = ENLOCBASE;
110                                 break;
111                         case 1:
112                                 return (entity_p) 0;
113                         case 2:
114                                 en.en_kind = ENHEAPPTR;
115                                 break;
116                 }
117                 return en_enter(&en);
118         }
119
120         if ( (ip = getinf(INSTR(lnp))) == (struct inf_entity *) 0)
121                 return (entity_p) 0; /* It does not refer to any entity. */
122
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;
130         }
131
132         en.en_static = FALSE;
133         en.en_kind = ENKIND(ip);
134
135         /* Fill in the size of the entity. */
136         switch (SIZEINF(ip)) {
137                 default:
138                         assert(FALSE);
139                         break;
140                 case WS1:
141                         en.en_size = ws;
142                         break;
143                 case WS2:
144                         en.en_size = 2*ws;
145                         break;
146                 case PS:
147                         en.en_size = ps;
148                         break;
149                 case ARGW:
150                         if (TYPE(lnp) != OPNO) {
151                                 en.en_size = off_set(lnp);
152                         } else {
153                                 Pop(&tk, (offset) ws);
154                                 *l_out = tk.tk_lfirst;
155                                 en.en_size = UNKNOWN_SIZE;
156                         }
157                         break;
158                 case ARDESC3:
159                         assert(en.en_kind == ENARRELEM);
160                         if (TYPE(lnp) != OPNO) {
161                                 indexsize = off_set(lnp);
162                         } else {
163                                 Pop(&tk, (offset) ws);
164                                 indexsize = UNKNOWN_SIZE;
165                         }
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);
174                         break;
175         }
176
177         /* Fill in additional information. */
178         switch (en.en_kind) {
179                 case ENFZER:
180                         en.en_static = TRUE;
181                         break;
182                 case ENCONST:
183                         en.en_static = TRUE;
184                         en.en_val = off_set(lnp);
185                         break;
186                 case ENALOCAL:
187                         en.en_static = TRUE;
188                 case ENLOCAL:
189                         en.en_loc = off_set(lnp);
190                         break;
191                 case ENAEXTERNAL:
192                         en.en_static = TRUE;
193                 case ENEXTERNAL:
194                         en.en_ext = OBJ(lnp);
195                         break;
196                 case ENINDIR:
197                         if (INSTR(lnp) == op_loi || INSTR(lnp) == op_sti) {
198                                 Pop(&tk, (offset) ps);
199                                 *l_out = tk.tk_lfirst;
200                                 vn = tk.tk_vn;
201                         }
202                         en.en_ind = vn;
203                         break;
204                 case ENAOFFSETTED:
205                         en.en_static = TRUE;
206                 case ENOFFSETTED:
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);
211                         break;
212                 case ENALOCBASE:
213                 case ENAARGBASE:
214                         en.en_levels = off_set(lnp);
215                         if (en.en_levels == 0) {
216                                 /* otherwise the program could change it */
217                                 en.en_static = TRUE;
218                         }
219                         break;
220                 case ENPROC:
221                         en.en_pro = PROC(lnp);
222                         break;
223                 case ENARRELEM:
224                         /* We gathered the information in the previous switch.
225                          */
226                         break;
227         }
228
229         return en_enter(&en);
230 }