Pristine Ack-5.5
[Ack-5.5.git] / lang / pc / comp / enter.c
1 /* H I G H   L E V E L   S Y M B O L   E N T R Y */
2
3 #include        <alloc.h>
4 #include        <assert.h>
5 #include        <em_arith.h>
6 #include        <em_label.h>
7
8 #include        "LLlex.h"
9 #include        "def.h"
10 #include        "idf.h"
11 #include        "main.h"
12 #include        "node.h"
13 #include        "scope.h"
14 #include        "type.h"
15 #include        "dbsymtab.h"
16
17 extern int      proclevel;
18 extern int      parlevel;
19
20 struct def *
21 Enter(name, kind, type, pnam)
22         char *name;
23         register struct type *type;
24         long kind;
25 {
26         /*      Enter a definition for "name" with kind "kind" and type
27                 "type" in the Current Scope. If it is a standard name, also
28                 put its number in the definition structure, and mark the
29                 name as set, to inhibit warnings about used before set.
30         */
31         register struct def *df;
32
33         df = define(str2idf(name, 0), CurrentScope, kind);
34         df->df_type = type;
35         if( pnam ) {
36                 df->df_value.df_reqname = pnam;
37                 df->df_flags |= D_SET;
38         }
39 #ifdef DBSYMTAB
40         else if (options['g']) stb_string(df, kind);
41 #endif /*  DBSYMTAB */
42         return df;
43 }
44
45 EnterProgList(Idlist)
46         register struct node *Idlist;
47 {
48         register struct node *idlist = Idlist;
49         register struct def *df;
50
51         for( ; idlist; idlist = idlist->nd_next )
52                 if (    !strcmp(input, idlist->nd_IDF->id_text)
53                         ||
54                         !strcmp(output, idlist->nd_IDF->id_text)
55                    ) {
56                         /* the occurence of input or output as program- 
57                          * parameter is their declaration as a GLOBAL
58                          *  variable of type text
59                          */
60                         if( df = define(idlist->nd_IDF, CurrentScope,
61                                                         D_VARIABLE) )   {
62                                 df->df_type = text_type;
63                                 df->df_flags |= (D_SET | D_PROGPAR | D_NOREG);
64                                 if( !strcmp(input, idlist->nd_IDF->id_text) ) {
65                                         df->var_name = input;
66                                         set_inp();
67                                 }
68                                 else {
69                                         df->var_name = output;
70                                         set_outp();
71                                 }
72 #ifdef DBSYMTAB
73                                 if (options['g']) stb_string(df, D_VARIABLE);
74 #endif /*  DBSYMTAB */
75                         }
76                 }
77                 else    {
78                         if( df = define(idlist->nd_IDF, CurrentScope,
79                                                                 D_PARAMETER) ) {
80                                 df->df_type = error_type;
81                                 df->df_flags |= D_PROGPAR;
82                                 df->var_name = idlist->nd_IDF->id_text;
83                         }
84                 }
85         
86         FreeNode(Idlist);
87 }
88
89 EnterEnumList(Idlist, type)
90         struct node *Idlist;
91         register struct type *type;
92 {
93         /*      Put a list of enumeration literals in the symbol table.
94                 They all have type "type". Also assign numbers to them.
95         */
96         register struct def *df, *df1 = 0;
97         register struct node *idlist = Idlist;
98
99         type->enm_ncst = 0;
100         for( ; idlist; idlist = idlist->nd_next )
101                 if( df = define(idlist->nd_IDF, CurrentScope, D_ENUM) ) {
102                         df->df_type = type;
103                         df->enm_val = (type->enm_ncst)++;
104                         df->df_flags |= D_SET;
105                         if (! df1) {
106                                 type->enm_enums = df;
107                         }
108                         else    df1->enm_next = df;
109                         df1 = df;
110                 }
111         FreeNode(Idlist);
112 }
113
114 EnterFieldList(Idlist, type, scope, addr, packed)
115         struct node *Idlist;
116         register struct type *type;
117         struct scope *scope;
118         arith *addr;
119         unsigned short packed;
120 {
121         /*      Put a list of fields in the symbol table.
122                 They all have type "type", and are put in scope "scope".
123         */
124         register struct def *df;
125         register struct node *idlist = Idlist;
126
127         for( ; idlist; idlist = idlist->nd_next )
128                 if( df = define(idlist->nd_IDF, scope, D_FIELD) )       {
129                         df->df_type = type;
130                         if( packed )    {
131                                 df->fld_flags |= F_PACKED;
132                                 df->fld_off = align(*addr, type->tp_palign);
133                                 *addr = df->fld_off + type->tp_psize;
134                         }
135                         else    {
136                                 df->fld_off = align(*addr, type->tp_align);
137                                 *addr = df->fld_off + type->tp_size;
138                         }
139                 }
140         FreeNode(Idlist);
141 }
142
143 EnterVarList(Idlist, type, local)
144         struct node *Idlist;
145         struct type *type;
146 {
147         /*      Enter a list of identifiers representing variables into the
148                 name list. "type" represents the type of the variables.
149                 "local" is set if the variables are declared local to a
150                 procedure.
151         */
152         register struct def *df;
153         register struct node *idlist = Idlist;
154         register struct scopelist *sc = CurrVis;
155
156         for( ; idlist; idlist = idlist->nd_next )       {
157                 if( !(df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE)) )
158                         continue;       /* skip this identifier */
159                 df->df_type = type;
160                 if( local )     {
161                         /* subtract size, which is already aligned, of
162                          * variable to the offset, as the variable list
163                          * exists only local to a procedure
164                          */
165                         sc->sc_scope->sc_off -= type->tp_size;
166                         df->var_off = sc->sc_scope->sc_off;
167                 }
168                 else    { /* Global name */
169                         df->var_name = df->df_idf->id_text;
170                         df->df_flags |= D_NOREG;
171                 }
172 #ifdef DBSYMTAB
173                 if (options['g']) stb_string(df, D_VARIABLE);
174 #endif /*  DBSYMTAB */
175         }
176         FreeNode(Idlist);
177 }
178
179 arith
180 EnterParamList(fpl, parlist)
181         register struct node *fpl;
182         struct paramlist **parlist;
183 {
184         register arith nb_pars = (proclevel > 1) ? pointer_size : 0;
185         register struct node *id;
186         struct type *tp;
187         struct def *df;
188
189         for( ; fpl; fpl = fpl->nd_right )       {
190                 assert(fpl->nd_class == Link);
191
192                 tp = fpl->nd_type;
193                 for( id = fpl->nd_left; id; id = id->nd_next )
194                     if( df = define(id->nd_IDF, CurrentScope, D_VARIABLE) ) {
195                         df->var_off = nb_pars;
196                         if( fpl->nd_INT & D_VARPAR || IsConformantArray(tp) )
197                                 nb_pars += pointer_size;
198                         else
199                                 nb_pars += tp->tp_size;
200                         LinkParam(parlist, df);
201                         df->df_type = tp;
202                         df->df_flags |= fpl->nd_INT;
203                     }
204
205                 while( IsConformantArray(tp) )  {
206                         /* we need room for the descriptors */
207
208                         tp->arr_sclevel = CurrentScope->sc_level;
209                         tp->arr_cfdescr = nb_pars;
210                         nb_pars += 3 * word_size;
211                         tp = tp->arr_elem;
212                 }
213         }
214         return nb_pars;
215 }
216
217 arith
218 EnterParTypes(fpl, parlist)
219         register struct node *fpl;
220         struct paramlist **parlist;
221 {
222         /* Parameters in heading of procedural and functional
223            parameters (only types are important, not the names).
224         */
225         register arith nb_pars = 0;
226         register struct node *id;
227         struct type *tp;
228         struct def *df;
229
230         for( ; fpl; fpl = fpl->nd_right ) {
231                 tp = fpl->nd_type;
232                 for( id = fpl->nd_left; id; id = id->nd_next )
233                         if( df = new_def() )    {
234                                 if( fpl->nd_INT & D_VARPAR ||
235                                     IsConformantArray(tp) )
236                                         nb_pars += pointer_size;
237                                 else
238                                         nb_pars += tp->tp_size;
239                                 LinkParam(parlist, df);
240                                 df->df_type = tp;
241                                 df->df_flags |= fpl->nd_INT;
242                         }
243                 while( IsConformantArray(tp) ) {
244                         nb_pars += 3 * word_size;
245                         tp = tp->arr_elem;
246                 }
247         }
248         return nb_pars;
249 }
250
251 LinkParam(parlist, df)
252         struct paramlist **parlist;
253         struct def *df;
254 {
255         static struct paramlist *pr;
256
257         if( !*parlist )
258                 *parlist = pr = new_paramlist();
259         else    {
260                 pr->next = new_paramlist();
261                 pr = pr->next;
262         }
263         pr->par_def = df;
264 }