Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / loglan96 / loglan93 / symtable.cc
1 #include <std.h>\r
2 #include <String.h>\r
3 #include <iostream.h>\r
4 #include "SymTable.h"\r
5 \r
6 int init_offset(type kind) {\r
7 \r
8   switch (kind) {\r
9     case CLASS_S      : \r
10     case PROCESS_S    :\r
11     case COROUTINE_S  :\r
12     case SIGNAL_S     :\r
13     case FUNCTION_S   :\r
14     case PROCEDURE_S  :\r
15     case BLOCK_S      :\r
16     case HANDLERS_S   : break; \r
17    };\r
18 \r
19  return 1; \r
20 \r
21 };\r
22 \r
23 int update_offset(type kind) {\r
24 \r
25   switch (kind) {\r
26     case CLASS_S      : \r
27     case PROCESS_S    :\r
28     case COROUTINE_S  :\r
29     case SIGNAL_S     :\r
30     case FUNCTION_S   :\r
31     case PROCEDURE_S  :\r
32     case HANDLERS_S   : \r
33     case VARIABLE_S   :\r
34     case CONSTANT_S   : break; \r
35    };\r
36 \r
37  return 1; \r
38 \r
39 };\r
40 \r
41 void list::add_elem(entry* e) {\r
42 \r
43   list_elem*  ThisElement;\r
44 \r
45   ThisElement       = new list_elem(e);\r
46   ThisElement->next = end_ptr;\r
47   end_ptr           = ThisElement;\r
48 \r
49 };\r
50 \r
51 \r
52 entry* list::find_virt(String id)\r
53 {\r
54   list_elem* ThisElement;\r
55 \r
56   for( ThisElement = end_ptr;\r
57       (ThisElement != NULL) && ( ThisElement->info_ptr->id != id);\r
58        ThisElement = ThisElement->next\r
59      );\r
60 \r
61   if ( ThisElement )\r
62     return ThisElement->info_ptr;\r
63   else\r
64     return NULL;\r
65 };\r
66 \r
67 \r
68 void spec_list::add(String id)\r
69 {\r
70 \r
71   end_ptr=new spec_elem(id,end_ptr);\r
72 \r
73 };\r
74 \r
75 bool spec_list::present(String id) {\r
76 \r
77   spec_elem*  temp;\r
78 \r
79   temp=end_ptr;\r
80   while ( temp != NULL && temp->info != id ) \r
81     temp=temp->next;\r
82   if (temp != NULL) \r
83     return TRUE;\r
84   else\r
85     return FALSE;\r
86 \r
87 };\r
88 \r
89 \r
90 void pref_list::add_pref(entry* e,sharing sh)\r
91 {\r
92   list* temp;\r
93 \r
94   end_ptr = new pref_list_elem(e,sh,end_ptr);\r
95 \r
96   if ((temp=((c_class*)(e->rest))->my_symtab->formal_param_list) != NULL) {\r
97     if (symtab->last->formal_param_list == NULL)\r
98       symtab->last->formal_param_list=new list;\r
99     symtab->last->formal_param_list->end_ptr=temp->end_ptr;\r
100   };\r
101 \r
102 };\r
103 \r
104 \r
105 entry::entry(String ii,type kk,int oo,spec ss,packet* pp)\r
106 {\r
107   id      = ii;\r
108   kind    = kk;\r
109   offset  = oo;\r
110   visible = ss;\r
111   rest    = pp;\r
112 };\r
113 \r
114 node::node(int ll)\r
115\r
116    level=ll;\r
117    current_offset=OFFSET;\r
118    if (symtab == NULL)\r
119      end_ptr = begin_ptr \r
120              = new entry(NO_IDENT,FATHER,NO_OFFSET,NORMAL,\r
121                          new f_father(NULL,level)\r
122                         );\r
123    else\r
124      end_ptr = begin_ptr\r
125              = new entry(NO_IDENT,FATHER,NO_OFFSET,NORMAL,\r
126                          new f_father(symtab->last,level)\r
127                         );\r
128 \r
129    virtual_list       = NULL;\r
130    begin_ptr->prev    = NULL;\r
131    close=taken=hidden = NULL;\r
132 \r
133 };\r
134 \r
135 void node::close_unit()\r
136 {\r
137   symtab->last=((f_father*)(begin_ptr->rest))->father_ptr;\r
138 };\r
139 \r
140 \r
141 node* node::open_unit()\r
142 {\r
143   node* temp;\r
144  \r
145   temp = new node(level+1);\r
146 \r
147   ((c_class*)(symtab->last->end_ptr->rest))->my_symtab=temp;\r
148 \r
149   temp->current_offset=init_offset(end_ptr->kind);\r
150   symtab->last=temp;\r
151 \r
152   return temp;\r
153  \r
154 };\r
155 \r
156 void node::add_spec(spec kind,String id)\r
157 {\r
158   \r
159   switch (kind) {\r
160 \r
161     case CLOSE :\r
162       if (close==NULL) close=new spec_list;\r
163       close->add(id);\r
164       break;\r
165   \r
166     case HIDDEN :\r
167       if (hidden==NULL) hidden=new spec_list;\r
168       hidden->add(id);\r
169       break;\r
170 \r
171     case TAKEN :\r
172       if (taken==NULL) taken=new spec_list;\r
173       taken->add(id);\r
174       break;\r
175 \r
176   };\r
177 \r
178 };\r
179 \r
180 void node::add_virt(entry* v) {\r
181 \r
182   if (virtual_list == NULL) virtual_list=new list;\r
183   virtual_list->add_elem(v);\r
184 \r
185 };\r
186 \r
187 void node::add_form_param(entry* fp) {\r
188 \r
189   if (formal_param_list == NULL) formal_param_list=new list;\r
190   formal_param_list->add_elem(fp);\r
191 \r
192 };\r
193 \r
194 \r
195 struct find_result* node::local_find(String id,visible vis) {\r
196 \r
197   entry*  temp;\r
198   bool    stop=FALSE;\r
199 \r
200    \r
201   temp=end_ptr;\r
202 \r
203   while ( !stop && temp->kind != FATHER) {\r
204     if (temp->id != id)\r
205       temp=temp->prev; \r
206     else\r
207       switch (temp->visible)\r
208       {\r
209         case HIDDEN :\r
210           if (vis == NOT_HIDDEN)\r
211             temp=temp->prev;\r
212           else\r
213             stop=TRUE;\r
214         break;\r
215 \r
216         case NORMAL :\r
217         case CLOSE  :\r
218           stop=TRUE;\r
219           break;\r
220       };\r
221   };\r
222 \r
223          \r
224   if ( !stop ) \r
225     return new find_result(level,NULL);\r
226   else \r
227     return new find_result(level,temp);\r
228 };\r
229 \r
230 struct find_result* symboltable::find_in_module(node* start,String id,bool dot=DOT,visible vis=ALL) {\r
231 \r
232   struct find_result*  temp1;\r
233   node*                temp2;\r
234   pref_list_elem*      temp3;\r
235   bool                 stop=FALSE;\r
236 \r
237    temp1=start->local_find(id,vis);\r
238   if (temp1->found != NULL && !dot) \r
239      return temp1;\r
240   else if (start->prefix != NULL) {\r
241         \r
242       temp3=start->prefix->end_ptr;\r
243       while ((temp3 != NULL) && !stop) {\r
244         temp1=((c_class*)(temp3->where->rest))->my_symtab->local_find(id,NOT_HIDDEN);\r
245         if (temp1->found != NULL) stop = TRUE;\r
246         temp3=temp3->next;\r
247        };\r
248       if (temp3 != NULL && !dot) return temp1;\r
249      };\r
250 \r
251 return new find_result(temp1->level,NULL);\r
252 \r
253  \r
254 };  \r
255 \r
256 struct find_result* symboltable::find(String id) {\r
257 \r
258   struct find_result*  temp1;\r
259   entry*               temp2;\r
260   node*                temp3;\r
261 \r
262   temp1=symtab->find_in_module(symtab->last,id,FALSE,ALL);\r
263   if (temp1->found != NULL && temp1->found->id == id) return temp1; \r
264   temp3=((f_father*)(symtab->last->begin_ptr->rest))->father_ptr;\r
265   while (temp3 != NULL && temp1->level != MAIN_LEVEL ) { \r
266     temp1=symtab->find_in_module(temp3,id,FALSE,NOT_HIDDEN);  \r
267     temp3=((f_father*)(temp3->begin_ptr->rest))->father_ptr;\r
268   };\r
269 \r
270   if (temp1->found != NULL && temp1->found->id == id)\r
271 \r
272     return temp1;\r
273 \r
274   else\r
275 \r
276     return new find_result(MAIN_LEVEL,NULL);\r
277    \r
278 };\r
279 \r
280 entry* symboltable::inherit(String id,sharing sh=NOT_SHARED) {\r
281 \r
282   entry*        temp;\r
283 \r
284   pref_list_elem*    temp1;\r
285 \r
286 \r
287   temp=symtab->find(id)->found;\r
288 \r
289   if (temp != NULL  && ( temp->kind ==CLASS_S  ||  temp->kind == PROCESS_S  ||  temp->kind == COROUTINE_S) ) {\r
290 \r
291     if (last->prefix == NULL) last->prefix = new pref_list;\r
292     \r
293     if (((c_class*)(temp->rest))->prefix != NULL) {\r
294 \r
295       temp1=((c_class*)(temp->rest))->prefix->end_ptr;\r
296       while (temp1 != NULL) {\r
297         last->prefix->add_pref(temp1->where,temp1->shared);\r
298         temp1=temp1->next;\r
299       };\r
300     }; \r
301     last->prefix->add_pref(temp,sh);\r
302     return temp;\r
303   }\r
304 \r
305   else\r
306   \r
307     return NULL;\r
308 \r
309 };\r
310 \r
311 entry* symboltable::insert(String id,type kind,packet* p) {\r
312 \r
313   entry*    temp;\r
314 \r
315   spec      temp1;\r
316 \r
317    if ( ((symtab->last->local_find(id,ALL))->found == NULL) )\r
318    {\r
319 \r
320     temp1=NORMAL;\r
321     if (symtab->last->close != NULL) \r
322       if (symtab->last->close->present(id) ) temp1=CLOSE;\r
323     if (symtab->last->hidden != NULL) \r
324       if (symtab->last->hidden->present(id) ) temp1=HIDDEN;\r
325     temp=new entry(id,kind,symtab->last->current_offset,temp1,p);\r
326     symtab->last->current_offset += update_offset(kind);\r
327     temp->prev=symtab->last->end_ptr;\r
328     symtab->last->end_ptr=temp;\r
329     if (kind == VARIABLE_S &&  (((v_variable*)p)->type == POINTER)) {\r
330       if (symtab->last->ref_var_list == NULL) \r
331         symtab->last->ref_var_list=new list;\r
332       symtab->last->ref_var_list->add_elem(temp);\r
333     };\r
334     return temp;\r
335 \r
336    }\r
337 \r
338    else return NULL;\r
339 \r
340 };\r