blob: 05c11654fec167e32aeb454ed07dfbed099a35ed [file] [log] [blame]
#include "vtr_util.h"
#include "vtr_memory.h"
#include "ast_util.h"
STRING_CACHE *copy_param_table_sc(STRING_CACHE *to_copy);
ast_node_t *resolve_hierarchical_name_reference_by_path_search(sc_hierarchy *local_ref, std::string identifier);
ast_node_t *resolve_hierarchical_name_reference_by_upward_search(sc_hierarchy *local_ref, std::string identifier);
sc_hierarchy *init_sc_hierarchy()
{
sc_hierarchy *hierarchy = (sc_hierarchy *)vtr::calloc(1, sizeof(sc_hierarchy));
hierarchy->parent = NULL;
hierarchy->module_children = NULL;
hierarchy->function_children = NULL;
hierarchy->task_children = NULL;
hierarchy->block_children = NULL;
hierarchy->num_module_children = 0;
hierarchy->num_function_children = 0;
hierarchy->num_task_children = 0;
hierarchy->num_block_children = 0;
hierarchy->num_unnamed_genblks = 0;
hierarchy->instance_name_prefix = NULL;
hierarchy->scope_id = NULL;
hierarchy->top_node = NULL;
hierarchy->local_param_table_sc = NULL;
hierarchy->local_defparam_table_sc = NULL;
hierarchy->local_symbol_table_sc = NULL;
hierarchy->local_symbol_table = NULL;
hierarchy->num_local_symbol_table = 0;
return hierarchy;
}
/*---------------------------------------------------------------------------
* (function: copy_sc_hierarchy)
*-------------------------------------------------------------------------*/
sc_hierarchy *copy_sc_hierarchy(sc_hierarchy *to_copy)
{
sc_hierarchy *hierarchy = (sc_hierarchy *)vtr::calloc(1, sizeof(sc_hierarchy));
hierarchy->scope_id = NULL;
hierarchy->instance_name_prefix = NULL;
hierarchy->top_node = NULL;
hierarchy->num_local_symbol_table = to_copy->num_local_symbol_table;
hierarchy->local_symbol_table = (ast_node_t **)vtr::calloc(hierarchy->num_local_symbol_table, sizeof(ast_node_t *));
hierarchy->local_symbol_table_sc = sc_new_string_cache();
for (int i = 0; i < hierarchy->num_local_symbol_table; i++)
{
hierarchy->local_symbol_table[i] = ast_node_deep_copy(to_copy->local_symbol_table[i]);
char *identifier = hierarchy->local_symbol_table[i]->children[0]->types.identifier;
long sc_spot = sc_add_string(hierarchy->local_symbol_table_sc, identifier);
hierarchy->local_symbol_table_sc->data[sc_spot] = (void *)hierarchy->local_symbol_table[i];
}
if (to_copy->local_param_table_sc)
{
hierarchy->local_param_table_sc = copy_param_table_sc(to_copy->local_param_table_sc);
}
return hierarchy;
}
/*---------------------------------------------------------------------------
* (function: copy_param_table_sc)
*-------------------------------------------------------------------------*/
STRING_CACHE *copy_param_table_sc(STRING_CACHE *to_copy)
{
STRING_CACHE *sc;
sc = sc_new_string_cache();
for (long i = 0; i < to_copy->free; i++)
{
long sc_spot = sc_add_string(sc, to_copy->string[i]);
sc->data[sc_spot] = (void *)ast_node_deep_copy((ast_node_t *)to_copy->data[i]);
}
return sc;
}
/*---------------------------------------------------------------------------
* (function: free_sc_hierarchy)
*-------------------------------------------------------------------------*/
void free_sc_hierarchy(sc_hierarchy *to_free)
{
int i;
for (i = 0; i < to_free->num_module_children; i++)
{
free_sc_hierarchy(to_free->module_children[i]);
}
to_free->module_children = (sc_hierarchy **)vtr::free(to_free->module_children);
for (i = 0; i < to_free->num_function_children; i++)
{
free_sc_hierarchy(to_free->function_children[i]);
}
to_free->function_children = (sc_hierarchy **)vtr::free(to_free->function_children);
for (i = 0; i < to_free->num_task_children; i++)
{
free_sc_hierarchy(to_free->task_children[i]);
}
to_free->task_children = (sc_hierarchy **)vtr::free(to_free->task_children);
for (i = 0; i < to_free->num_block_children; i++)
{
free_sc_hierarchy(to_free->block_children[i]);
}
to_free->block_children = (sc_hierarchy **)vtr::free(to_free->block_children);
if (to_free->local_param_table_sc)
{
for(i = 0; i < to_free->local_param_table_sc->free; i++)
{
free_whole_tree((ast_node_t *)to_free->local_param_table_sc->data[i]);
}
to_free->local_param_table_sc = sc_free_string_cache(to_free->local_param_table_sc);
}
for (i = 0; i < to_free->num_local_symbol_table; i++)
{
free_whole_tree(to_free->local_symbol_table[i]);
}
to_free->num_local_symbol_table = 0;
to_free->local_symbol_table = (ast_node_t **)vtr::free(to_free->local_symbol_table);
to_free->local_symbol_table_sc = sc_free_string_cache(to_free->local_symbol_table_sc);
to_free->instance_name_prefix = (char *)vtr::free(to_free->instance_name_prefix);
to_free->scope_id = (char *)vtr::free(to_free->scope_id);
to_free->top_node = NULL;
to_free->num_module_children = 0;
to_free->num_function_children = 0;
to_free->num_task_children = 0;
to_free->num_unnamed_genblks = 0;
vtr::free(to_free);
}
/*---------------------------------------------------------------------------
* (function: resolve_hierarchical_name_reference)
*-------------------------------------------------------------------------*/
ast_node_t *resolve_hierarchical_name_reference(sc_hierarchy *local_ref, char *identifier)
{
// upward search: item identifier only (e.g. my_item)
// path search: series of scopes followed by item identifier (e.g. some_prefix.some_other_prefix.my_item)
if (identifier)
{
ast_node_t *var_declare = NULL;
std::string id(identifier);
size_t pos = id.find_first_of('.', 0);
if (pos == std::string::npos)
{
var_declare = resolve_hierarchical_name_reference_by_upward_search(local_ref, id);
}
else
{
// find parent scope with this name and pass down the rest of the path
std::string scope_id = id.substr(0, pos+1);
id = id.erase(0, pos+1);
sc_hierarchy *this_ref = local_ref;
bool found = false;
while (!found)
{
if (this_ref->scope_id == scope_id)
{
found = true;
}
else
{
/* check for downward search in this scope */
for (int i = 0; !found && i < this_ref->num_module_children; i++)
{
if (this_ref->module_children[i]->scope_id == scope_id)
{
this_ref = this_ref->module_children[i];
found = true;
}
}
for (int i = 0; !found && i < this_ref->num_function_children; i++)
{
if (this_ref->function_children[i]->scope_id == scope_id)
{
this_ref = this_ref->function_children[i];
found = true;
}
}
for (int i = 0; !found && i < this_ref->num_task_children; i++)
{
if (this_ref->task_children[i]->scope_id == scope_id)
{
this_ref = this_ref->task_children[i];
found = true;
}
}
for (int i = 0; !found && i < this_ref->num_block_children; i++)
{
if (this_ref->block_children[i]->scope_id == scope_id)
{
this_ref = this_ref->block_children[i];
found = true;
}
}
}
/* if not found, check upward */
if (!found && this_ref->parent != NULL)
{
this_ref = this_ref->parent;
}
}
if (found)
{
var_declare = resolve_hierarchical_name_reference_by_path_search(this_ref, id);
}
}
return var_declare;
}
return NULL;
}
/*---------------------------------------------------------------------------
* (function: resolve_hierarchical_name_reference_by_path_search)
*-------------------------------------------------------------------------*/
ast_node_t *resolve_hierarchical_name_reference_by_path_search(sc_hierarchy *local_ref, std::string identifier)
{
if (!identifier.empty())
{
ast_node_t *var_declare = NULL;
size_t pos = identifier.find_first_of('.', 0);
if (pos == std::string::npos)
{
// this is the item we're searching for; look for item in current scope
long sc_spot;
bool found = false;
STRING_CACHE *local_symbol_table_sc = local_ref->local_symbol_table_sc;
if ((sc_spot = sc_lookup_string(local_symbol_table_sc, identifier.c_str())) != -1)
{
var_declare = (ast_node_t *)local_symbol_table_sc->data[sc_spot];
found = true;
}
if (!found)
{
STRING_CACHE *local_param_table_sc = local_ref->local_param_table_sc;
if ((sc_spot = sc_lookup_string(local_param_table_sc, identifier.c_str())) != -1)
{
var_declare = (ast_node_t *)local_param_table_sc->data[sc_spot];
found = true;
}
}
if (!found)
{
// TODO check scopes???
}
}
else
{
// find scope with this name and pass down the rest of the path
std::string scope_id = identifier.substr(0, pos+1);
identifier = identifier.erase(0, pos+1);
for (int i = 0; !var_declare && i < local_ref->num_module_children; i++)
{
if (local_ref->module_children[i]->scope_id == scope_id)
{
var_declare = resolve_hierarchical_name_reference_by_path_search(local_ref->module_children[i], identifier);
}
}
for (int i = 0; !var_declare && i < local_ref->num_function_children; i++)
{
if (local_ref->function_children[i]->scope_id == scope_id)
{
var_declare = resolve_hierarchical_name_reference_by_path_search(local_ref->function_children[i], identifier);
}
}
for (int i = 0; !var_declare && i < local_ref->num_task_children; i++)
{
if (local_ref->task_children[i]->scope_id == scope_id)
{
var_declare = resolve_hierarchical_name_reference_by_path_search(local_ref->task_children[i], identifier);
}
}
for (int i = 0; !var_declare && i < local_ref->num_block_children; i++)
{
if (local_ref->block_children[i]->scope_id == scope_id)
{
var_declare = resolve_hierarchical_name_reference_by_path_search(local_ref->block_children[i], identifier);
}
}
}
return var_declare;
}
return NULL;
}
/*---------------------------------------------------------------------------
* (function: resolve_hierarchical_name_reference_by_upward_search)
*-------------------------------------------------------------------------*/
ast_node_t *resolve_hierarchical_name_reference_by_upward_search(sc_hierarchy *local_ref, std::string identifier)
{
if (!identifier.empty())
{
ast_node_t *var_declare = NULL;
long sc_spot;
bool found = false;
STRING_CACHE *local_symbol_table_sc = local_ref->local_symbol_table_sc;
if ((sc_spot = sc_lookup_string(local_symbol_table_sc, identifier.c_str())) != -1)
{
var_declare = (ast_node_t *)local_symbol_table_sc->data[sc_spot];
found = true;
}
if (!found)
{
STRING_CACHE *local_param_table_sc = local_ref->local_param_table_sc;
if ((sc_spot = sc_lookup_string(local_param_table_sc, identifier.c_str())) != -1)
{
var_declare = (ast_node_t *)local_param_table_sc->data[sc_spot];
found = true;
}
}
if (!found && local_ref->parent != NULL)
{
// TODO check scopes???
var_declare = resolve_hierarchical_name_reference_by_upward_search(local_ref->parent, identifier);
}
return var_declare;
}
return NULL;
}