1 /* $Id: symtab.c,v 1.8 1994/06/24 12:27:22 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".
10 int curr_level=0; /* Current local level */
11 int curr_offset=0; /* Current offset within this level */
12 int min_offset=0; /* Minimum of all offsets within current level */
14 static struct symtab *sym_table=nil;
18 static struct symbol **search_sym(tree, name)
21 /* Returns a hook in the tree to the where the given name is or should be. */
23 register struct symbol **aps=tree, *ps;
26 while ((ps= *aps)!=nil && (cmp=strcmp(name, ps->s_name))!=0)
27 aps= cmp<0 ? &ps->s_left : &ps->s_right;
32 struct symbol *insert(name, type, arr_siz, info)
35 union type_info *info;
36 /* Inserts an object with given name and other info into the current symbol
37 * tree. A pointer is returned to the inserted symbol so that more info may
38 * or changed. Nil is returned on redeclaration.
41 register struct symbol **aps, *ps;
44 if (*(aps=search_sym(&sym_table->local, name))!=nil) {
45 report("%s redeclared", name);
49 ps= (struct symbol *) Malloc(sizeof *ps);
53 if (included && curr_level==0) /* Top_level symbol in include file */
54 type|=T_USED; /* are always used */
56 ps->s_arr_siz=arr_siz;
58 ps->s_left=ps->s_right=nil;
64 struct symbol *searchall(name) char *name;
65 /* Searches for name in all symbol trees from the inner to the outermost.
66 * If it can't be found then it is inserted as undefined.
69 register struct symtab *tab=sym_table;
70 register struct symbol *ps;
73 if ((ps= *search_sym(&tab->local, name))!=nil) return ps;
77 report("%s not declared", name);
78 return insert(name, T_NOTDECL, 0, &none);
81 void check_recursion(proc)
82 register struct expr *proc;
84 if (proc->kind==E_VAR && proc->u.var->s_type&T_RECURS)
85 warning("recursion not allowed");
90 register struct symtab *ps;
92 ps= (struct symtab *) Malloc(sizeof *ps);
96 ps->old_offset=curr_offset;
101 static void sym_destroy(ps) register struct symbol *ps;
104 sym_destroy(ps->s_left);
105 sym_destroy(ps->s_right);
106 if ( !(ps->s_type&T_NOTDECL) ) {
107 if ( !(ps->s_type&T_USED) )
108 warning("%s: never used", ps->s_name);
110 if ( !(ps->s_type&T_ASSIGNED) && (ps->s_type&T_TYPE)==T_VAR)
111 warning("%s: never assigned", ps->s_name);
113 if ((ps->s_type&T_TYPE)==T_PROC) {
114 register struct par_list *par, *junk;
116 par=ps->s_info.proc.pars;
123 if ((ps->s_type&T_TYPE)==T_CONST)
124 destroy(ps->s_info.t_const);
125 free((char *)(ps->s_name));
132 register struct symtab *ps;
134 ps=sym_table->global;
135 curr_offset=sym_table->old_offset;
137 sym_destroy(sym_table->local);
143 void var_memory(info, type, n) register union type_info *info; int type, n;
144 /* Reserves local memory for an object, and stores it in its info field. */
146 info->vc.st.level=curr_level;
147 curr_offset-= (type&T_BYTE) ? (n+wz-1) & (~(wz-1)) : n*vz;
148 info->vc.offset=curr_offset;
149 if (curr_offset<min_offset) min_offset=curr_offset;
152 void chan_memory(info, n) register union type_info *info; int n;
154 info->vc.st.level=curr_level;
155 info->vc.offset= curr_offset-=n*(vz+wz);
156 if (curr_offset<min_offset) min_offset=curr_offset;
160 /* Reserves z memory bytes */
163 if (curr_offset<min_offset) min_offset=curr_offset;
167 void pars_add(aapars, type, var)
168 register struct par_list ***aapars;
171 /* Add a formal variable to a parameter list using a hook to a hook. */
173 register struct par_list *pl;
175 pl= (struct par_list *) Malloc(sizeof *pl);
179 pl->pr_next= **aapars;
182 *aapars= &pl->pr_next;
185 int form_offsets(pars) register struct par_list *pars;
186 /* Recursively assign offsets to formal variables. */
188 register struct symbol *var;
190 if (pars==nil) return pz;
192 if ((var=pars->pr_var)!=nil) {
193 register offset=form_offsets(pars->pr_next);
195 switch (var->s_type&T_TYPE) {
198 var->s_info.vc.st.level=curr_level;
199 var->s_info.vc.offset=offset;
202 var->s_info.vc.st.level=curr_level;
203 var->s_info.vc.offset=offset;
204 return offset+ ((var->s_type&T_ARR) ? pz : vz);