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

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

Update SBI to rev. 157.

  • Property mode set to 100644
File size: 8.5 KB
RevLine 
[09ababb7]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);
[fa36f29]42static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
43 stree_ident_t *name, stree_csi_t *csi);
[09ababb7]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
[1ebc1a62]77/** Lookup symbol reference in CSI.
78 *
79 * @param prog Program to look in.
80 * @param scope CSI in @a prog which is the base for references.
81 * @param name Identifier of the symbol.
82 *
83 * @return Symbol or @c NULL if symbol not found.
84 */
[09ababb7]85stree_symbol_t *symbol_lookup_in_csi(stree_program_t *prog, stree_csi_t *scope,
86 stree_ident_t *name)
87{
88 stree_symbol_t *symbol;
89
90 /* This CSI node should have been processed. */
91 assert(scope == NULL || scope->ancr_state == ws_visited);
92
93 symbol = NULL;
94 while (scope != NULL && symbol == NULL) {
95 symbol = symbol_search_csi(prog, scope, name);
96 scope = csi_to_symbol(scope)->outer_csi;
97 }
98
99 if (symbol == NULL)
100 symbol = symbol_search_global(prog, name);
101
102 return symbol;
103}
104
105/** Look for symbol strictly in CSI.
106 *
107 * Look for symbol in definition of a CSI and its ancestors. (But not
108 * in lexically enclosing CSI.)
109 */
110stree_symbol_t *symbol_search_csi(stree_program_t *prog,
111 stree_csi_t *scope, stree_ident_t *name)
112{
113 list_node_t *node;
114 stree_csimbr_t *csimbr;
115 stree_symbol_t *symbol;
116 stree_ident_t *mbr_name;
[fa36f29]117 stree_symbol_t *base_csi_sym;
118 stree_csi_t *base_csi;
119
120 (void) prog;
121
122 /* Look in new members in this class. */
[09ababb7]123
124 node = list_first(&scope->members);
125 while (node != NULL) {
126 csimbr = list_node_data(node, stree_csimbr_t *);
127 switch (csimbr->cc) {
128 case csimbr_csi: mbr_name = csimbr->u.csi->name; break;
129 case csimbr_fun: mbr_name = csimbr->u.fun->name; break;
130 case csimbr_var: mbr_name = csimbr->u.var->name; break;
131 case csimbr_prop: mbr_name = csimbr->u.prop->name; break;
132 default: assert(b_false);
133 }
134
135 if (name->sid == mbr_name->sid) {
136 /* Match */
137 switch (csimbr->cc) {
138 case csimbr_csi:
139 symbol = csi_to_symbol(csimbr->u.csi);
140 break;
141 case csimbr_fun:
142 symbol = fun_to_symbol(csimbr->u.fun);
143 break;
144 case csimbr_var:
145 symbol = var_to_symbol(csimbr->u.var);
146 break;
147 case csimbr_prop:
148 symbol = prop_to_symbol(csimbr->u.prop);
149 break;
150 default:
151 assert(b_false);
152 }
153 return symbol;
154 }
155 node = list_next(&scope->members, node);
156 }
157
[fa36f29]158 /* Try inherited members. */
159 if (scope->base_csi_ref != NULL) {
160 base_csi_sym = symbol_xlookup_in_csi(prog,
161 csi_to_symbol(scope)->outer_csi, scope->base_csi_ref);
162 base_csi = symbol_to_csi(base_csi_sym);
163 assert(base_csi != NULL);
164
165 return symbol_search_csi(prog, base_csi, name);
166 }
167
168 /* No match */
[09ababb7]169 return NULL;
170}
171
172static stree_symbol_t *symbol_search_global(stree_program_t *prog,
173 stree_ident_t *name)
174{
175 list_node_t *node;
176 stree_modm_t *modm;
177 stree_symbol_t *symbol;
178
179 node = list_first(&prog->module->members);
180 while (node != NULL) {
181 modm = list_node_data(node, stree_modm_t *);
182 if (name->sid == modm->u.csi->name->sid) {
183 /* Match */
184 switch (modm->mc) {
185 case mc_csi:
186 symbol = csi_to_symbol(modm->u.csi);
187 break;
188 default:
189 assert(b_false);
190 }
191 return symbol;
192 }
193 node = list_next(&prog->module->members, node);
194 }
195
196 return NULL;
197}
198
[fa36f29]199/** Find entry point. */
200stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name)
201{
202 list_node_t *node;
203 stree_modm_t *modm;
204 stree_symbol_t *entry, *etmp;
205
206 entry = NULL;
207
208 node = list_first(&prog->module->members);
209 while (node != NULL) {
210 modm = list_node_data(node, stree_modm_t *);
211 if (modm->mc == mc_csi) {
212 etmp = symbol_find_epoint_rec(prog, name, modm->u.csi);
213 if (etmp != NULL) {
214 if (entry != NULL) {
215 printf("Error: Duplicate entry point.\n");
216 exit(1);
217 }
218 entry = etmp;
219 }
220 }
221 node = list_next(&prog->module->members, node);
222 }
223
224 return entry;
225}
226
227static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
228 stree_ident_t *name, stree_csi_t *csi)
229{
230 list_node_t *node;
231 stree_csimbr_t *csimbr;
232 stree_symbol_t *entry, *etmp;
233
234 entry = NULL;
235
236 node = list_first(&csi->members);
237 while (node != NULL) {
238 csimbr = list_node_data(node, stree_csimbr_t *);
239
240 switch (csimbr->cc) {
241 case csimbr_csi:
242 etmp = symbol_find_epoint_rec(prog, name, csimbr->u.csi);
243 if (etmp != NULL) {
244 if (entry != NULL) {
245 printf("Error: Duplicate entry point.\n");
246 exit(1);
247 }
248 entry = etmp;
249 }
250 break;
251 case csimbr_fun:
252 if (csimbr->u.fun->name->sid == name->sid) {
253 if (entry != NULL) {
254 printf("Error: Duplicate entry point.\n");
255 exit(1);
256 }
257 entry = fun_to_symbol(csimbr->u.fun);
258 }
259 default:
260 break;
261 }
262
263 node = list_next(&csi->members, node);
264 }
265
266 return entry;
267}
268
[09ababb7]269stree_csi_t *symbol_to_csi(stree_symbol_t *symbol)
270{
271 if (symbol->sc != sc_csi)
272 return NULL;
273
274 return symbol->u.csi;
275}
276
277stree_symbol_t *csi_to_symbol(stree_csi_t *csi)
278{
279 assert(csi->symbol);
280 return csi->symbol;
281}
282
283stree_fun_t *symbol_to_fun(stree_symbol_t *symbol)
284{
285 if (symbol->sc != sc_fun)
286 return NULL;
287
288 return symbol->u.fun;
289}
290
291stree_symbol_t *fun_to_symbol(stree_fun_t *fun)
292{
293 assert(fun->symbol);
294 return fun->symbol;
295}
296
297stree_var_t *symbol_to_var(stree_symbol_t *symbol)
298{
299 if (symbol->sc != sc_var)
300 return NULL;
301
302 return symbol->u.var;
303}
304
305stree_symbol_t *var_to_symbol(stree_var_t *var)
306{
307 assert(var->symbol);
308 return var->symbol;
309}
310
311stree_prop_t *symbol_to_prop(stree_symbol_t *symbol)
312{
313 if (symbol->sc != sc_prop)
314 return NULL;
315
316 return symbol->u.prop;
317}
318
319stree_symbol_t *prop_to_symbol(stree_prop_t *prop)
320{
321 assert(prop->symbol);
322 return prop->symbol;
323}
324
325/** Print fully qualified name of symbol. */
[39e8406]326void symbol_print_fqn(stree_symbol_t *symbol)
[09ababb7]327{
328 stree_ident_t *name;
329 stree_symbol_t *outer_sym;
330
331 if (symbol->outer_csi != NULL) {
332 outer_sym = csi_to_symbol(symbol->outer_csi);
[37f527b]333 symbol_print_fqn(outer_sym);
[09ababb7]334 printf(".");
335 }
336
337 name = symbol_get_ident(symbol);
338 printf("%s", strtab_get_str(name->sid));
339}
340
341static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol)
342{
343 stree_ident_t *ident;
344
345 switch (symbol->sc) {
346 case sc_csi: ident = symbol->u.csi->name; break;
347 case sc_fun: ident = symbol->u.fun->name; break;
348 case sc_var: ident = symbol->u.var->name; break;
349 case sc_prop: ident = symbol->u.prop->name; break;
350 }
351
352 return ident;
353}
Note: See TracBrowser for help on using the repository browser.