source: mainline/uspace/app/sbi/src/symbol.c@ 37f527b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 37f527b was 37f527b, checked in by Jiri Svoboda <jiri@…>, 15 years ago

Update SBI to rev. 144.

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file Symbols. */
30
31#include <stdlib.h>
32#include <assert.h>
33#include "list.h"
34#include "mytypes.h"
35#include "strtab.h"
36#include "stree.h"
37
38#include "symbol.h"
39
40static stree_symbol_t *symbol_search_global(stree_program_t *prog,
41 stree_ident_t *name);
42static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
43 stree_ident_t *name, stree_csi_t *csi);
44static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
45
46/** Lookup symbol in CSI using a type expression. */
47stree_symbol_t *symbol_xlookup_in_csi(stree_program_t *prog,
48 stree_csi_t *scope, stree_texpr_t *texpr)
49{
50 stree_symbol_t *a, *b;
51 stree_csi_t *a_csi;
52
53 switch (texpr->tc) {
54 case tc_tnameref:
55 return symbol_lookup_in_csi(prog, scope, texpr->u.tnameref->name);
56 case tc_taccess:
57 a = symbol_xlookup_in_csi(prog, scope, texpr->u.taccess->arg);
58 a_csi = symbol_to_csi(a);
59 if (a_csi == NULL) {
60 printf("Error: Symbol is not CSI.\n");
61 exit(1);
62 }
63 b = symbol_search_csi(prog, a_csi, texpr->u.taccess->member_name);
64 if (b == NULL) {
65 printf("Error: CSI '%s' not found\n", strtab_get_str(texpr->u.taccess->member_name->sid));
66 exit(1);
67 }
68 return b;
69 case tc_tapply:
70 printf("Internal error: Generic types not implemented.\n");
71 exit(1);
72 default:
73 assert(b_false);
74 }
75}
76
77/** Lookup symbol reference in CSI. */
78stree_symbol_t *symbol_lookup_in_csi(stree_program_t *prog, stree_csi_t *scope,
79 stree_ident_t *name)
80{
81 stree_symbol_t *symbol;
82
83 /* This CSI node should have been processed. */
84 assert(scope == NULL || scope->ancr_state == ws_visited);
85
86 symbol = NULL;
87 while (scope != NULL && symbol == NULL) {
88 symbol = symbol_search_csi(prog, scope, name);
89 scope = csi_to_symbol(scope)->outer_csi;
90 }
91
92 if (symbol == NULL)
93 symbol = symbol_search_global(prog, name);
94
95 if (symbol == NULL) {
96 printf("Error: Symbol '%s' not found.\n", strtab_get_str(name->sid));
97 exit(1);
98 }
99
100 return symbol;
101}
102
103/** Look for symbol strictly in CSI.
104 *
105 * Look for symbol in definition of a CSI and its ancestors. (But not
106 * in lexically enclosing CSI.)
107 */
108stree_symbol_t *symbol_search_csi(stree_program_t *prog,
109 stree_csi_t *scope, stree_ident_t *name)
110{
111 list_node_t *node;
112 stree_csimbr_t *csimbr;
113 stree_symbol_t *symbol;
114 stree_ident_t *mbr_name;
115 stree_symbol_t *base_csi_sym;
116 stree_csi_t *base_csi;
117
118 (void) prog;
119
120 /* Look in new members in this class. */
121
122 node = list_first(&scope->members);
123 while (node != NULL) {
124 csimbr = list_node_data(node, stree_csimbr_t *);
125 switch (csimbr->cc) {
126 case csimbr_csi: mbr_name = csimbr->u.csi->name; break;
127 case csimbr_fun: mbr_name = csimbr->u.fun->name; break;
128 case csimbr_var: mbr_name = csimbr->u.var->name; break;
129 case csimbr_prop: mbr_name = csimbr->u.prop->name; break;
130 default: assert(b_false);
131 }
132
133 if (name->sid == mbr_name->sid) {
134 /* Match */
135 switch (csimbr->cc) {
136 case csimbr_csi:
137 symbol = csi_to_symbol(csimbr->u.csi);
138 break;
139 case csimbr_fun:
140 symbol = fun_to_symbol(csimbr->u.fun);
141 break;
142 case csimbr_var:
143 symbol = var_to_symbol(csimbr->u.var);
144 break;
145 case csimbr_prop:
146 symbol = prop_to_symbol(csimbr->u.prop);
147 break;
148 default:
149 assert(b_false);
150 }
151 return symbol;
152 }
153 node = list_next(&scope->members, node);
154 }
155
156 /* Try inherited members. */
157 if (scope->base_csi_ref != NULL) {
158 base_csi_sym = symbol_xlookup_in_csi(prog,
159 csi_to_symbol(scope)->outer_csi, scope->base_csi_ref);
160 base_csi = symbol_to_csi(base_csi_sym);
161 assert(base_csi != NULL);
162
163 return symbol_search_csi(prog, base_csi, name);
164 }
165
166 /* No match */
167 return NULL;
168}
169
170static stree_symbol_t *symbol_search_global(stree_program_t *prog,
171 stree_ident_t *name)
172{
173 list_node_t *node;
174 stree_modm_t *modm;
175 stree_symbol_t *symbol;
176
177 node = list_first(&prog->module->members);
178 while (node != NULL) {
179 modm = list_node_data(node, stree_modm_t *);
180 if (name->sid == modm->u.csi->name->sid) {
181 /* Match */
182 switch (modm->mc) {
183 case mc_csi:
184 symbol = csi_to_symbol(modm->u.csi);
185 break;
186 default:
187 assert(b_false);
188 }
189 return symbol;
190 }
191 node = list_next(&prog->module->members, node);
192 }
193
194 return NULL;
195}
196
197/** Find entry point. */
198stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name)
199{
200 list_node_t *node;
201 stree_modm_t *modm;
202 stree_symbol_t *entry, *etmp;
203
204 entry = NULL;
205
206 node = list_first(&prog->module->members);
207 while (node != NULL) {
208 modm = list_node_data(node, stree_modm_t *);
209 if (modm->mc == mc_csi) {
210 etmp = symbol_find_epoint_rec(prog, name, modm->u.csi);
211 if (etmp != NULL) {
212 if (entry != NULL) {
213 printf("Error: Duplicate entry point.\n");
214 exit(1);
215 }
216 entry = etmp;
217 }
218 }
219 node = list_next(&prog->module->members, node);
220 }
221
222 return entry;
223}
224
225static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
226 stree_ident_t *name, stree_csi_t *csi)
227{
228 list_node_t *node;
229 stree_csimbr_t *csimbr;
230 stree_symbol_t *entry, *etmp;
231
232 entry = NULL;
233
234 node = list_first(&csi->members);
235 while (node != NULL) {
236 csimbr = list_node_data(node, stree_csimbr_t *);
237
238 switch (csimbr->cc) {
239 case csimbr_csi:
240 etmp = symbol_find_epoint_rec(prog, name, csimbr->u.csi);
241 if (etmp != NULL) {
242 if (entry != NULL) {
243 printf("Error: Duplicate entry point.\n");
244 exit(1);
245 }
246 entry = etmp;
247 }
248 break;
249 case csimbr_fun:
250 if (csimbr->u.fun->name->sid == name->sid) {
251 if (entry != NULL) {
252 printf("Error: Duplicate entry point.\n");
253 exit(1);
254 }
255 entry = fun_to_symbol(csimbr->u.fun);
256 }
257 default:
258 break;
259 }
260
261 node = list_next(&csi->members, node);
262 }
263
264 return entry;
265}
266
267stree_csi_t *symbol_to_csi(stree_symbol_t *symbol)
268{
269 if (symbol->sc != sc_csi)
270 return NULL;
271
272 return symbol->u.csi;
273}
274
275stree_symbol_t *csi_to_symbol(stree_csi_t *csi)
276{
277 assert(csi->symbol);
278 return csi->symbol;
279}
280
281stree_fun_t *symbol_to_fun(stree_symbol_t *symbol)
282{
283 if (symbol->sc != sc_fun)
284 return NULL;
285
286 return symbol->u.fun;
287}
288
289stree_symbol_t *fun_to_symbol(stree_fun_t *fun)
290{
291 assert(fun->symbol);
292 return fun->symbol;
293}
294
295stree_var_t *symbol_to_var(stree_symbol_t *symbol)
296{
297 if (symbol->sc != sc_var)
298 return NULL;
299
300 return symbol->u.var;
301}
302
303stree_symbol_t *var_to_symbol(stree_var_t *var)
304{
305 assert(var->symbol);
306 return var->symbol;
307}
308
309stree_prop_t *symbol_to_prop(stree_symbol_t *symbol)
310{
311 if (symbol->sc != sc_prop)
312 return NULL;
313
314 return symbol->u.prop;
315}
316
317stree_symbol_t *prop_to_symbol(stree_prop_t *prop)
318{
319 assert(prop->symbol);
320 return prop->symbol;
321}
322
323/** Print fully qualified name of symbol. */
324void symbol_print_fqn(stree_symbol_t *symbol)
325{
326 stree_ident_t *name;
327 stree_symbol_t *outer_sym;
328
329 if (symbol->outer_csi != NULL) {
330 outer_sym = csi_to_symbol(symbol->outer_csi);
331 symbol_print_fqn(outer_sym);
332 printf(".");
333 }
334
335 name = symbol_get_ident(symbol);
336 printf("%s", strtab_get_str(name->sid));
337}
338
339static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol)
340{
341 stree_ident_t *ident;
342
343 switch (symbol->sc) {
344 case sc_csi: ident = symbol->u.csi->name; break;
345 case sc_fun: ident = symbol->u.fun->name; break;
346 case sc_var: ident = symbol->u.var->name; break;
347 case sc_prop: ident = symbol->u.prop->name; break;
348 }
349
350 return ident;
351}
Note: See TracBrowser for help on using the repository browser.