HelenOS sources
This source file includes following definitions.
- symbol_xlookup_in_csi
- symbol_lookup_in_csi
- symbol_search_csi
- symbol_search_csi_no_base
- symbol_search_global
- symbol_get_base_class
- symbol_get_base_class_ref
- symbol_find_epoint
- symbol_find_epoint_rec
- symbol_to_deleg
- deleg_to_symbol
- symbol_to_enum
- enum_to_symbol
- symbol_to_csi
- csi_to_symbol
- symbol_to_ctor
- ctor_to_symbol
- symbol_to_fun
- fun_to_symbol
- symbol_to_var
- var_to_symbol
- symbol_to_prop
- csimbr_to_symbol
- prop_to_symbol
- symbol_print_fqn
- symbol_get_ident
#include <stdlib.h>
#include <assert.h>
#include "list.h"
#include "mytypes.h"
#include "strtab.h"
#include "stree.h"
#include "symbol.h"
static stree_symbol_t *symbol_search_global(stree_program_t *prog,
stree_ident_t *name);
static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
stree_ident_t *name, stree_csi_t *csi);
static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
stree_symbol_t *symbol_xlookup_in_csi(stree_program_t *prog,
stree_csi_t *scope, stree_texpr_t *texpr)
{
stree_symbol_t *a, *b;
stree_csi_t *a_csi;
switch (texpr->tc) {
case tc_tnameref:
return symbol_lookup_in_csi(prog, scope, texpr->u.tnameref->name);
case tc_taccess:
a = symbol_xlookup_in_csi(prog, scope, texpr->u.taccess->arg);
a_csi = symbol_to_csi(a);
if (a_csi == NULL) {
printf("Error: Symbol is not CSI.\n");
exit(1);
}
b = symbol_search_csi(prog, a_csi, texpr->u.taccess->member_name);
if (b == NULL) {
printf("Error: CSI '%s' not found\n", strtab_get_str(texpr->u.taccess->member_name->sid));
exit(1);
}
return b;
case tc_tapply:
return symbol_xlookup_in_csi(prog, scope,
texpr->u.tapply->gtype);
default:
assert(b_false);
}
}
stree_symbol_t *symbol_lookup_in_csi(stree_program_t *prog, stree_csi_t *scope,
stree_ident_t *name)
{
stree_symbol_t *symbol;
assert(scope == NULL || scope->ancr_state == ws_visited);
symbol = NULL;
while (scope != NULL && symbol == NULL) {
symbol = symbol_search_csi(prog, scope, name);
scope = csi_to_symbol(scope)->outer_csi;
}
if (symbol == NULL)
symbol = symbol_search_global(prog, name);
return symbol;
}
stree_symbol_t *symbol_search_csi(stree_program_t *prog,
stree_csi_t *scope, stree_ident_t *name)
{
stree_csi_t *base_csi;
stree_symbol_t *symbol;
symbol = symbol_search_csi_no_base(prog, scope, name);
if (symbol != NULL)
return symbol;
base_csi = symbol_get_base_class(prog, scope);
if (base_csi != NULL)
return symbol_search_csi(prog, base_csi, name);
return NULL;
}
stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog,
stree_csi_t *scope, stree_ident_t *name)
{
list_node_t *node;
stree_csimbr_t *csimbr;
stree_ident_t *mbr_name;
(void) prog;
node = list_first(&scope->members);
while (node != NULL) {
csimbr = list_node_data(node, stree_csimbr_t *);
mbr_name = stree_csimbr_get_name(csimbr);
if (name->sid == mbr_name->sid) {
return csimbr_to_symbol(csimbr);
}
node = list_next(&scope->members, node);
}
return NULL;
}
static stree_symbol_t *symbol_search_global(stree_program_t *prog,
stree_ident_t *name)
{
list_node_t *node;
stree_modm_t *modm;
stree_symbol_t *symbol;
stree_ident_t *mbr_name;
node = list_first(&prog->module->members);
while (node != NULL) {
modm = list_node_data(node, stree_modm_t *);
mbr_name = NULL;
switch (modm->mc) {
case mc_csi:
mbr_name = modm->u.csi->name;
break;
case mc_enum:
mbr_name = modm->u.enum_d->name;
break;
}
assert(mbr_name != NULL);
if (name->sid == mbr_name->sid) {
symbol = NULL;
switch (modm->mc) {
case mc_csi:
symbol = csi_to_symbol(modm->u.csi);
break;
case mc_enum:
symbol = enum_to_symbol(modm->u.enum_d);
break;
}
return symbol;
}
node = list_next(&prog->module->members, node);
}
return NULL;
}
stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi)
{
list_node_t *pred_n;
stree_texpr_t *pred;
stree_symbol_t *pred_sym;
stree_csi_t *pred_csi;
stree_csi_t *outer_csi;
outer_csi = csi_to_symbol(csi)->outer_csi;
pred_n = list_first(&csi->inherit);
if (pred_n == NULL)
return NULL;
pred = list_node_data(pred_n, stree_texpr_t *);
pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
pred_csi = symbol_to_csi(pred_sym);
assert(pred_csi != NULL);
if (pred_csi->cc == csi_class)
return pred_csi;
return NULL;
}
stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog,
stree_csi_t *csi)
{
list_node_t *pred_n;
stree_texpr_t *pred;
stree_symbol_t *pred_sym;
stree_csi_t *pred_csi;
stree_csi_t *outer_csi;
outer_csi = csi_to_symbol(csi)->outer_csi;
pred_n = list_first(&csi->inherit);
if (pred_n == NULL)
return NULL;
pred = list_node_data(pred_n, stree_texpr_t *);
pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
pred_csi = symbol_to_csi(pred_sym);
assert(pred_csi != NULL);
if (pred_csi->cc == csi_class)
return pred;
return NULL;
}
stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name)
{
list_node_t *node;
stree_modm_t *modm;
stree_symbol_t *entry, *etmp;
entry = NULL;
node = list_first(&prog->module->members);
while (node != NULL) {
modm = list_node_data(node, stree_modm_t *);
if (modm->mc == mc_csi) {
etmp = symbol_find_epoint_rec(prog, name, modm->u.csi);
if (etmp != NULL) {
if (entry != NULL) {
printf("Error: Duplicate entry point.\n");
exit(1);
}
entry = etmp;
}
}
node = list_next(&prog->module->members, node);
}
return entry;
}
static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
stree_ident_t *name, stree_csi_t *csi)
{
list_node_t *node;
stree_csimbr_t *csimbr;
stree_symbol_t *entry, *etmp;
stree_symbol_t *fun_sym;
entry = NULL;
node = list_first(&csi->members);
while (node != NULL) {
csimbr = list_node_data(node, stree_csimbr_t *);
switch (csimbr->cc) {
case csimbr_csi:
etmp = symbol_find_epoint_rec(prog, name, csimbr->u.csi);
if (etmp != NULL) {
if (entry != NULL) {
printf("Error: Duplicate entry point.\n");
exit(1);
}
entry = etmp;
}
break;
case csimbr_fun:
fun_sym = fun_to_symbol(csimbr->u.fun);
if (csimbr->u.fun->name->sid == name->sid &&
stree_symbol_has_attr(fun_sym, sac_static)) {
if (entry != NULL) {
printf("Error: Duplicate entry point.\n");
exit(1);
}
entry = fun_sym;
}
default:
break;
}
node = list_next(&csi->members, node);
}
return entry;
}
stree_deleg_t *symbol_to_deleg(stree_symbol_t *symbol)
{
if (symbol->sc != sc_deleg)
return NULL;
return symbol->u.deleg;
}
stree_symbol_t *deleg_to_symbol(stree_deleg_t *deleg)
{
assert(deleg->symbol);
return deleg->symbol;
}
stree_enum_t *symbol_to_enum(stree_symbol_t *symbol)
{
if (symbol->sc != sc_enum)
return NULL;
return symbol->u.enum_d;
}
stree_symbol_t *enum_to_symbol(stree_enum_t *enum_d)
{
assert(enum_d->symbol);
return enum_d->symbol;
}
stree_csi_t *symbol_to_csi(stree_symbol_t *symbol)
{
if (symbol->sc != sc_csi)
return NULL;
return symbol->u.csi;
}
stree_symbol_t *csi_to_symbol(stree_csi_t *csi)
{
assert(csi->symbol);
return csi->symbol;
}
stree_ctor_t *symbol_to_ctor(stree_symbol_t *symbol)
{
if (symbol->sc != sc_ctor)
return NULL;
return symbol->u.ctor;
}
stree_symbol_t *ctor_to_symbol(stree_ctor_t *ctor)
{
assert(ctor->symbol);
return ctor->symbol;
}
stree_fun_t *symbol_to_fun(stree_symbol_t *symbol)
{
if (symbol->sc != sc_fun)
return NULL;
return symbol->u.fun;
}
stree_symbol_t *fun_to_symbol(stree_fun_t *fun)
{
assert(fun->symbol);
return fun->symbol;
}
stree_var_t *symbol_to_var(stree_symbol_t *symbol)
{
if (symbol->sc != sc_var)
return NULL;
return symbol->u.var;
}
stree_symbol_t *var_to_symbol(stree_var_t *var)
{
assert(var->symbol);
return var->symbol;
}
stree_prop_t *symbol_to_prop(stree_symbol_t *symbol)
{
if (symbol->sc != sc_prop)
return NULL;
return symbol->u.prop;
}
stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
{
stree_symbol_t *symbol;
symbol = NULL;
switch (csimbr->cc) {
case csimbr_csi:
symbol = csi_to_symbol(csimbr->u.csi);
break;
case csimbr_ctor:
symbol = ctor_to_symbol(csimbr->u.ctor);
break;
case csimbr_deleg:
symbol = deleg_to_symbol(csimbr->u.deleg);
break;
case csimbr_enum:
symbol = enum_to_symbol(csimbr->u.enum_d);
break;
case csimbr_fun:
symbol = fun_to_symbol(csimbr->u.fun);
break;
case csimbr_var:
symbol = var_to_symbol(csimbr->u.var);
break;
case csimbr_prop:
symbol = prop_to_symbol(csimbr->u.prop);
break;
}
return symbol;
}
stree_symbol_t *prop_to_symbol(stree_prop_t *prop)
{
assert(prop->symbol);
return prop->symbol;
}
void symbol_print_fqn(stree_symbol_t *symbol)
{
stree_ident_t *name;
stree_symbol_t *outer_sym;
if (symbol->outer_csi != NULL) {
outer_sym = csi_to_symbol(symbol->outer_csi);
symbol_print_fqn(outer_sym);
printf(".");
}
name = symbol_get_ident(symbol);
printf("%s", strtab_get_str(name->sid));
}
static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol)
{
stree_ident_t *ident;
ident = NULL;
switch (symbol->sc) {
case sc_csi:
ident = symbol->u.csi->name;
break;
case sc_ctor:
ident = symbol->u.ctor->name;
break;
case sc_deleg:
ident = symbol->u.deleg->name;
break;
case sc_enum:
ident = symbol->u.enum_d->name;
break;
case sc_fun:
ident = symbol->u.fun->name;
break;
case sc_var:
ident = symbol->u.var->name;
break;
case sc_prop:
ident = symbol->u.prop->name;
break;
}
return ident;
}
HelenOS homepage, sources at GitHub