00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00031 #include <stdlib.h>
00032 #include <assert.h>
00033 #include "list.h"
00034 #include "mytypes.h"
00035 #include "strtab.h"
00036 #include "stree.h"
00037
00038 #include "symbol.h"
00039
00040 static stree_symbol_t *symbol_search_global(stree_program_t *prog,
00041 stree_ident_t *name);
00042 static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
00043 stree_ident_t *name, stree_csi_t *csi);
00044 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
00045
00058 stree_symbol_t *symbol_xlookup_in_csi(stree_program_t *prog,
00059 stree_csi_t *scope, stree_texpr_t *texpr)
00060 {
00061 stree_symbol_t *a, *b;
00062 stree_csi_t *a_csi;
00063
00064 switch (texpr->tc) {
00065 case tc_tnameref:
00066 return symbol_lookup_in_csi(prog, scope, texpr->u.tnameref->name);
00067 case tc_taccess:
00068 a = symbol_xlookup_in_csi(prog, scope, texpr->u.taccess->arg);
00069 a_csi = symbol_to_csi(a);
00070 if (a_csi == NULL) {
00071 printf("Error: Symbol is not CSI.\n");
00072 exit(1);
00073 }
00074 b = symbol_search_csi(prog, a_csi, texpr->u.taccess->member_name);
00075 if (b == NULL) {
00076 printf("Error: CSI '%s' not found\n", strtab_get_str(texpr->u.taccess->member_name->sid));
00077 exit(1);
00078 }
00079 return b;
00080 case tc_tapply:
00081 return symbol_xlookup_in_csi(prog, scope,
00082 texpr->u.tapply->gtype);
00083 default:
00084 assert(b_false);
00085 }
00086 }
00087
00099 stree_symbol_t *symbol_lookup_in_csi(stree_program_t *prog, stree_csi_t *scope,
00100 stree_ident_t *name)
00101 {
00102 stree_symbol_t *symbol;
00103
00104
00105 assert(scope == NULL || scope->ancr_state == ws_visited);
00106
00107 symbol = NULL;
00108 while (scope != NULL && symbol == NULL) {
00109 symbol = symbol_search_csi(prog, scope, name);
00110 scope = csi_to_symbol(scope)->outer_csi;
00111 }
00112
00113 if (symbol == NULL)
00114 symbol = symbol_search_global(prog, name);
00115
00116 return symbol;
00117 }
00118
00130 stree_symbol_t *symbol_search_csi(stree_program_t *prog,
00131 stree_csi_t *scope, stree_ident_t *name)
00132 {
00133 stree_csi_t *base_csi;
00134 stree_symbol_t *symbol;
00135
00136
00137 symbol = symbol_search_csi_no_base(prog, scope, name);
00138 if (symbol != NULL)
00139 return symbol;
00140
00141
00142 base_csi = symbol_get_base_class(prog, scope);
00143 if (base_csi != NULL)
00144 return symbol_search_csi(prog, base_csi, name);
00145
00146
00147 return NULL;
00148 }
00149
00161 stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog,
00162 stree_csi_t *scope, stree_ident_t *name)
00163 {
00164 list_node_t *node;
00165 stree_csimbr_t *csimbr;
00166 stree_ident_t *mbr_name;
00167
00168 (void) prog;
00169
00170
00171
00172 node = list_first(&scope->members);
00173 while (node != NULL) {
00174 csimbr = list_node_data(node, stree_csimbr_t *);
00175 mbr_name = stree_csimbr_get_name(csimbr);
00176
00177 if (name->sid == mbr_name->sid) {
00178
00179 return csimbr_to_symbol(csimbr);
00180 }
00181
00182 node = list_next(&scope->members, node);
00183 }
00184
00185 return NULL;
00186 }
00187
00195 static stree_symbol_t *symbol_search_global(stree_program_t *prog,
00196 stree_ident_t *name)
00197 {
00198 list_node_t *node;
00199 stree_modm_t *modm;
00200 stree_symbol_t *symbol;
00201 stree_ident_t *mbr_name;
00202
00203 node = list_first(&prog->module->members);
00204 while (node != NULL) {
00205 modm = list_node_data(node, stree_modm_t *);
00206
00207
00208 mbr_name = NULL;
00209
00210 switch (modm->mc) {
00211 case mc_csi: mbr_name = modm->u.csi->name; break;
00212 case mc_enum: mbr_name = modm->u.enum_d->name; break;
00213 }
00214
00215
00216 assert(mbr_name != NULL);
00217
00218 if (name->sid == mbr_name->sid) {
00219
00220 symbol = NULL;
00221
00222
00223 switch (modm->mc) {
00224 case mc_csi:
00225 symbol = csi_to_symbol(modm->u.csi);
00226 break;
00227 case mc_enum:
00228 symbol = enum_to_symbol(modm->u.enum_d);
00229 break;
00230 }
00231 return symbol;
00232 }
00233 node = list_next(&prog->module->members, node);
00234 }
00235
00236 return NULL;
00237 }
00238
00249 stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi)
00250 {
00251 list_node_t *pred_n;
00252 stree_texpr_t *pred;
00253 stree_symbol_t *pred_sym;
00254 stree_csi_t *pred_csi;
00255 stree_csi_t *outer_csi;
00256
00257 outer_csi = csi_to_symbol(csi)->outer_csi;
00258
00259 pred_n = list_first(&csi->inherit);
00260 if (pred_n == NULL)
00261 return NULL;
00262
00263 pred = list_node_data(pred_n, stree_texpr_t *);
00264 pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
00265 pred_csi = symbol_to_csi(pred_sym);
00266 assert(pred_csi != NULL);
00267
00268 if (pred_csi->cc == csi_class)
00269 return pred_csi;
00270
00271 return NULL;
00272 }
00273
00284 stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog,
00285 stree_csi_t *csi)
00286 {
00287 list_node_t *pred_n;
00288 stree_texpr_t *pred;
00289 stree_symbol_t *pred_sym;
00290 stree_csi_t *pred_csi;
00291 stree_csi_t *outer_csi;
00292
00293 outer_csi = csi_to_symbol(csi)->outer_csi;
00294
00295 pred_n = list_first(&csi->inherit);
00296 if (pred_n == NULL)
00297 return NULL;
00298
00299 pred = list_node_data(pred_n, stree_texpr_t *);
00300 pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
00301 pred_csi = symbol_to_csi(pred_sym);
00302 assert(pred_csi != NULL);
00303
00304 if (pred_csi->cc == csi_class)
00305 return pred;
00306
00307 return NULL;
00308 }
00309
00319 stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name)
00320 {
00321 list_node_t *node;
00322 stree_modm_t *modm;
00323 stree_symbol_t *entry, *etmp;
00324
00325 entry = NULL;
00326
00327 node = list_first(&prog->module->members);
00328 while (node != NULL) {
00329 modm = list_node_data(node, stree_modm_t *);
00330 if (modm->mc == mc_csi) {
00331 etmp = symbol_find_epoint_rec(prog, name, modm->u.csi);
00332 if (etmp != NULL) {
00333 if (entry != NULL) {
00334 printf("Error: Duplicate entry point.\n");
00335 exit(1);
00336 }
00337 entry = etmp;
00338 }
00339 }
00340 node = list_next(&prog->module->members, node);
00341 }
00342
00343 return entry;
00344 }
00345
00355 static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
00356 stree_ident_t *name, stree_csi_t *csi)
00357 {
00358 list_node_t *node;
00359 stree_csimbr_t *csimbr;
00360 stree_symbol_t *entry, *etmp;
00361 stree_symbol_t *fun_sym;
00362
00363 entry = NULL;
00364
00365 node = list_first(&csi->members);
00366 while (node != NULL) {
00367 csimbr = list_node_data(node, stree_csimbr_t *);
00368
00369 switch (csimbr->cc) {
00370 case csimbr_csi:
00371 etmp = symbol_find_epoint_rec(prog, name, csimbr->u.csi);
00372 if (etmp != NULL) {
00373 if (entry != NULL) {
00374 printf("Error: Duplicate entry point.\n");
00375 exit(1);
00376 }
00377 entry = etmp;
00378 }
00379 break;
00380 case csimbr_fun:
00381 fun_sym = fun_to_symbol(csimbr->u.fun);
00382
00383 if (csimbr->u.fun->name->sid == name->sid &&
00384 stree_symbol_has_attr(fun_sym, sac_static)) {
00385 if (entry != NULL) {
00386 printf("Error: Duplicate entry point.\n");
00387 exit(1);
00388 }
00389 entry = fun_sym;
00390 }
00391 default:
00392 break;
00393 }
00394
00395 node = list_next(&csi->members, node);
00396 }
00397
00398 return entry;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00413 stree_deleg_t *symbol_to_deleg(stree_symbol_t *symbol)
00414 {
00415 if (symbol->sc != sc_deleg)
00416 return NULL;
00417
00418 return symbol->u.deleg;
00419 }
00420
00426 stree_symbol_t *deleg_to_symbol(stree_deleg_t *deleg)
00427 {
00428 assert(deleg->symbol);
00429 return deleg->symbol;
00430 }
00431
00437 stree_enum_t *symbol_to_enum(stree_symbol_t *symbol)
00438 {
00439 if (symbol->sc != sc_enum)
00440 return NULL;
00441
00442 return symbol->u.enum_d;
00443 }
00444
00450 stree_symbol_t *enum_to_symbol(stree_enum_t *enum_d)
00451 {
00452 assert(enum_d->symbol);
00453 return enum_d->symbol;
00454 }
00455
00461 stree_csi_t *symbol_to_csi(stree_symbol_t *symbol)
00462 {
00463 if (symbol->sc != sc_csi)
00464 return NULL;
00465
00466 return symbol->u.csi;
00467 }
00468
00474 stree_symbol_t *csi_to_symbol(stree_csi_t *csi)
00475 {
00476 assert(csi->symbol);
00477 return csi->symbol;
00478 }
00479
00485 stree_ctor_t *symbol_to_ctor(stree_symbol_t *symbol)
00486 {
00487 if (symbol->sc != sc_ctor)
00488 return NULL;
00489
00490 return symbol->u.ctor;
00491 }
00492
00498 stree_symbol_t *ctor_to_symbol(stree_ctor_t *ctor)
00499 {
00500 assert(ctor->symbol);
00501 return ctor->symbol;
00502 }
00503
00504
00510 stree_fun_t *symbol_to_fun(stree_symbol_t *symbol)
00511 {
00512 if (symbol->sc != sc_fun)
00513 return NULL;
00514
00515 return symbol->u.fun;
00516 }
00517
00523 stree_symbol_t *fun_to_symbol(stree_fun_t *fun)
00524 {
00525 assert(fun->symbol);
00526 return fun->symbol;
00527 }
00528
00534 stree_var_t *symbol_to_var(stree_symbol_t *symbol)
00535 {
00536 if (symbol->sc != sc_var)
00537 return NULL;
00538
00539 return symbol->u.var;
00540 }
00541
00547 stree_symbol_t *var_to_symbol(stree_var_t *var)
00548 {
00549 assert(var->symbol);
00550 return var->symbol;
00551 }
00552
00558 stree_prop_t *symbol_to_prop(stree_symbol_t *symbol)
00559 {
00560 if (symbol->sc != sc_prop)
00561 return NULL;
00562
00563 return symbol->u.prop;
00564 }
00565
00573 stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
00574 {
00575 stree_symbol_t *symbol;
00576
00577
00578 symbol = NULL;
00579
00580
00581 switch (csimbr->cc) {
00582 case csimbr_csi:
00583 symbol = csi_to_symbol(csimbr->u.csi);
00584 break;
00585 case csimbr_ctor:
00586 symbol = ctor_to_symbol(csimbr->u.ctor);
00587 break;
00588 case csimbr_deleg:
00589 symbol = deleg_to_symbol(csimbr->u.deleg);
00590 break;
00591 case csimbr_enum:
00592 symbol = enum_to_symbol(csimbr->u.enum_d);
00593 break;
00594 case csimbr_fun:
00595 symbol = fun_to_symbol(csimbr->u.fun);
00596 break;
00597 case csimbr_var:
00598 symbol = var_to_symbol(csimbr->u.var);
00599 break;
00600 case csimbr_prop:
00601 symbol = prop_to_symbol(csimbr->u.prop);
00602 break;
00603 }
00604
00605 return symbol;
00606 }
00607
00608
00614 stree_symbol_t *prop_to_symbol(stree_prop_t *prop)
00615 {
00616 assert(prop->symbol);
00617 return prop->symbol;
00618 }
00619
00624 void symbol_print_fqn(stree_symbol_t *symbol)
00625 {
00626 stree_ident_t *name;
00627 stree_symbol_t *outer_sym;
00628
00629 if (symbol->outer_csi != NULL) {
00630 outer_sym = csi_to_symbol(symbol->outer_csi);
00631 symbol_print_fqn(outer_sym);
00632 printf(".");
00633 }
00634
00635 name = symbol_get_ident(symbol);
00636 printf("%s", strtab_get_str(name->sid));
00637 }
00638
00644 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol)
00645 {
00646 stree_ident_t *ident;
00647
00648
00649 ident = NULL;
00650
00651 switch (symbol->sc) {
00652 case sc_csi: ident = symbol->u.csi->name; break;
00653 case sc_ctor: ident = symbol->u.ctor->name; break;
00654 case sc_deleg: ident = symbol->u.deleg->name; break;
00655 case sc_enum: ident = symbol->u.enum_d->name; break;
00656 case sc_fun: ident = symbol->u.fun->name; break;
00657 case sc_var: ident = symbol->u.var->name; break;
00658 case sc_prop: ident = symbol->u.prop->name; break;
00659 }
00660
00661 return ident;
00662 }