Properly implement import <pkg>::<name>

This was temporarily implemented to just copy definitions to the
local scope, but the better method is to create a PEIdent that has
the package attached to it.
This commit is contained in:
Stephen Williams 2013-02-17 16:22:24 -08:00
parent 60cb78e4ab
commit 8fa79ceb30
6 changed files with 42 additions and 12 deletions

View File

@ -28,6 +28,7 @@
class PEvent;
class PExpr;
class PFunction;
class PPackage;
class AProcess;
class PProcess;
class PClass;
@ -92,6 +93,10 @@ class LexicalScope {
// Named events in the scope.
map<perm_string,PEvent*>events;
// Symbols that are imported. Bind the imported name to the
// package from which the name is imported.
std::map<perm_string,PPackage*>imports;
// Nets and variables (wires) in the scope
map<perm_string,PWire*>wires;
PWire* wires_find(perm_string name);

12
parse.y
View File

@ -2955,12 +2955,12 @@ expr_primary
/* The hierarchy_identifier rule matches simple identifiers as well as
indexed arrays and part selects */
| hierarchy_identifier
{ PEIdent*tmp = new PEIdent(*$1);
FILE_NAME(tmp, @1);
$$ = tmp;
delete $1;
}
| hierarchy_identifier
{ PEIdent*tmp = pform_new_ident(*$1);
FILE_NAME(tmp, @1);
$$ = tmp;
delete $1;
}
| IDENTIFIER K_SCOPE_RES IDENTIFIER
{ $$ = pform_package_ident(@3, $1, $3); }

View File

@ -419,6 +419,25 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
return block;
}
/*
* Create a new identifier. Check if this is an imported name.
*/
PEIdent* pform_new_ident(const pform_name_t&name)
{
if (name.size() != 1)
return new PEIdent(name);
LexicalScope*scope = pform_peek_scope();
map<perm_string,PPackage*>::const_iterator pkg = scope->imports.find(name.back().name);
if (pkg == scope->imports.end())
return new PEIdent(name);
// XXXX For now, do not support indexed imported names.
assert(name.back().index.size() == 0);
return new PEIdent(pkg->second, name.back().name);
}
PGenerate* pform_parent_generate(void)
{
return pform_cur_generate;

View File

@ -210,6 +210,12 @@ extern void pform_package_import(const struct vlltype&loc,
extern PExpr* pform_package_ident(const struct vlltype&loc,
const char*pkg_name, const char*ident);
/*
* This creates an identifier aware of names that may have been
* imported from other packages.
*/
extern PEIdent* pform_new_ident(const pform_name_t&name);
/*
* Enter/exit name scopes. The push_scope function pushes the scope
* name string onto the scope hierarchy. The pop pulls it off and

View File

@ -98,7 +98,7 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char
return;
}
scope->parameters[cur->first] = cur->second;
scope->imports[cur->first] = pkg;
} else {
@ -107,7 +107,7 @@ void pform_package_import(const struct vlltype&, const char*pkg_name, const char
for (map<perm_string,LexicalScope::param_expr_t>::const_iterator cur = pkg->parameters.begin()
; cur != pkg->parameters.end() ; ++cur) {
scope->parameters[cur->first] = cur->second;
scope->imports[cur->first] = pkg;
}
}
}

View File

@ -611,14 +611,14 @@ bool dll_target::start_design(const Design*des)
assert(idx == des_.disciplines.size());
list<NetScope *> package_scopes = des->find_package_scopes();
for (list<NetScope*>::const_iterator scop = package_scopes.begin();
scop != package_scopes.end(); ++ scop ) {
for (list<NetScope*>::const_iterator scop = package_scopes.begin()
; scop != package_scopes.end(); ++ scop ) {
add_root(des_, *scop);
}
list<NetScope *> root_scopes = des->find_root_scopes();
for (list<NetScope*>::const_iterator scop = root_scopes.begin();
scop != root_scopes.end(); ++ scop ) {
for (list<NetScope*>::const_iterator scop = root_scopes.begin()
; scop != root_scopes.end(); ++ scop ) {
add_root(des_, *scop);
}