Pristine Ack-5.5
[Ack-5.5.git] / lang / occam / comp / symtab.c
1 /* $Id: symtab.c,v 1.8 1994/06/24 12:27:22 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 "symtab.h"
7 #include "expr.h"
8 #include "sizes.h"
9
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 */
13
14 static struct symtab *sym_table=nil;
15
16 char *Malloc();
17
18 static struct symbol **search_sym(tree, name)
19         struct symbol **tree;
20         char *name;
21 /* Returns a hook in the tree to the where the given name is or should be. */
22 {
23         register struct symbol **aps=tree, *ps;
24         register cmp;
25
26         while ((ps= *aps)!=nil && (cmp=strcmp(name, ps->s_name))!=0)
27                 aps= cmp<0 ? &ps->s_left : &ps->s_right;
28
29         return aps;
30 }
31
32 struct symbol *insert(name, type, arr_siz, info)
33         char *name;
34         int type, arr_siz;
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.
39  */
40 {
41         register struct symbol **aps, *ps;
42         extern included;
43
44         if (*(aps=search_sym(&sym_table->local, name))!=nil) {
45                 report("%s redeclared", name);
46                 return nil;
47         }
48
49         ps= (struct symbol *) Malloc(sizeof *ps);
50
51         ps->s_name=name;
52
53         if (included && curr_level==0)  /* Top_level symbol in include file */
54                 type|=T_USED;           /* are always used */
55         ps->s_type=type;
56         ps->s_arr_siz=arr_siz;
57         ps->s_info= *info;
58         ps->s_left=ps->s_right=nil;
59         *aps=ps;
60
61         return ps;
62 }
63
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.
67  */
68 {
69         register struct symtab *tab=sym_table;
70         register struct symbol *ps;
71
72         while (tab!=nil) {
73                 if ((ps= *search_sym(&tab->local, name))!=nil) return ps;
74
75                 tab=tab->global;
76         }
77         report("%s not declared", name);
78         return insert(name, T_NOTDECL, 0, &none);
79 }
80
81 void check_recursion(proc)
82         register struct expr *proc;
83 {
84         if (proc->kind==E_VAR && proc->u.var->s_type&T_RECURS)
85                 warning("recursion not allowed");
86 }
87
88 void sym_down()
89 {
90         register struct symtab *ps;
91
92         ps= (struct symtab *) Malloc(sizeof *ps);
93
94         ps->local=nil;
95         ps->global=sym_table;
96         ps->old_offset=curr_offset;
97
98         sym_table=ps;
99 }
100
101 static void sym_destroy(ps) register struct symbol *ps;
102 {
103         if (ps!=nil) {
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);
109                         else
110                         if ( !(ps->s_type&T_ASSIGNED) && (ps->s_type&T_TYPE)==T_VAR)
111                                 warning("%s: never assigned", ps->s_name);
112                 }
113                 if ((ps->s_type&T_TYPE)==T_PROC) {
114                         register struct par_list *par, *junk;
115
116                         par=ps->s_info.proc.pars;
117                         while (par!=nil) {
118                                 junk=par;
119                                 par=par->pr_next;
120                                 free((char *)junk);
121                         }
122                 } else
123                 if ((ps->s_type&T_TYPE)==T_CONST)
124                         destroy(ps->s_info.t_const);
125                 free((char *)(ps->s_name));
126                 free((char *)ps);
127         }
128 }
129
130 void sym_up()
131 {
132         register struct symtab *ps;
133
134         ps=sym_table->global;
135         curr_offset=sym_table->old_offset;
136
137         sym_destroy(sym_table->local);
138         free(sym_table);
139
140         sym_table=ps;
141 }
142
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. */
145 {
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;
150 }
151
152 void chan_memory(info, n) register union type_info *info; int n;
153 {
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;
157 }
158
159 int memory(z) int z;
160 /* Reserves z memory bytes */
161 {
162         curr_offset-=z;
163         if (curr_offset<min_offset) min_offset=curr_offset;
164         return curr_offset;
165 }
166
167 void pars_add(aapars, type, var)
168         register struct par_list ***aapars;
169         int type;
170         struct symbol *var;
171 /* Add a formal variable to a parameter list using a hook to a hook. */
172 {
173         register struct par_list *pl;
174
175         pl= (struct par_list *) Malloc(sizeof *pl);
176
177         pl->pr_type=type;
178         pl->pr_var=var;
179         pl->pr_next= **aapars;
180
181         **aapars=pl;
182         *aapars= &pl->pr_next;
183 }
184
185 int form_offsets(pars) register struct par_list *pars;
186 /* Recursively assign offsets to formal variables. */
187 {
188         register struct symbol *var;
189
190         if (pars==nil) return pz;
191
192         if ((var=pars->pr_var)!=nil) {
193                 register offset=form_offsets(pars->pr_next);
194
195                 switch (var->s_type&T_TYPE) {
196                 case T_VAR:
197                 case T_CHAN:
198                         var->s_info.vc.st.level=curr_level;
199                         var->s_info.vc.offset=offset;
200                         return offset+pz;
201                 case T_VALUE:
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);
205                 }
206         }
207         return pz;
208 }