vhdlpp: Variables are moved to respective process scopes.
This commit is contained in:
parent
b037d533f9
commit
03e85850e1
|
|
@ -29,7 +29,7 @@ using namespace std;
|
|||
|
||||
Architecture::Architecture(perm_string name, const ActiveScope&ref,
|
||||
list<Architecture::Statement*>&s)
|
||||
: Scope(ref), name_(name), cur_component_(NULL)
|
||||
: Scope(ref), name_(name), cur_component_(NULL), cur_process_(NULL)
|
||||
{
|
||||
statements_.splice(statements_.end(), s);
|
||||
}
|
||||
|
|
@ -68,6 +68,14 @@ bool Architecture::find_constant(perm_string by_name, const VType*&typ, Expressi
|
|||
return false;
|
||||
}
|
||||
|
||||
Variable* Architecture::find_variable(perm_string by_name) const
|
||||
{
|
||||
if(cur_process_)
|
||||
return cur_process_->find_variable(by_name);
|
||||
|
||||
return ScopeBase::find_variable(by_name);
|
||||
}
|
||||
|
||||
void Architecture::push_genvar_type(perm_string gname, const VType*gtype)
|
||||
{
|
||||
genvar_type_t tmp;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class Entity;
|
|||
class Expression;
|
||||
class ExpName;
|
||||
class GenerateStatement;
|
||||
class ProcessStatement;
|
||||
class SequentialStmt;
|
||||
class Signal;
|
||||
class named_expr_t;
|
||||
|
|
@ -65,9 +66,20 @@ class Architecture : public Scope, public LineInfo {
|
|||
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
// Sets the currently processed component (to be able to reach its parameters).
|
||||
void set_cur_component(ComponentInstantiation*component) { cur_component_ = component; }
|
||||
bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
|
||||
Variable* find_variable(perm_string by_name) const;
|
||||
|
||||
// Sets the currently processed component (to be able to reach its parameters).
|
||||
void set_cur_component(ComponentInstantiation*component) {
|
||||
assert(!cur_component_ || !component);
|
||||
cur_component_ = component;
|
||||
}
|
||||
|
||||
// Sets the currently elaborated process (to use its scope for variable resolving).
|
||||
void set_cur_process(ProcessStatement*process) {
|
||||
assert(!cur_process_ || !process);
|
||||
cur_process_ = process;
|
||||
}
|
||||
|
||||
// Elaborate this architecture in the context of the given entity.
|
||||
int elaborate(Entity*entity);
|
||||
|
|
@ -113,7 +125,8 @@ class Architecture : public Scope, public LineInfo {
|
|||
// Currently processed component (or NULL if none).
|
||||
ComponentInstantiation*cur_component_;
|
||||
|
||||
private: // Not implemented
|
||||
// Currently elaborated process (or NULL if none).
|
||||
ProcessStatement*cur_process_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -239,8 +252,16 @@ class StatementList : public Architecture::Statement {
|
|||
StatementList(std::list<SequentialStmt*>*statement_list);
|
||||
virtual ~StatementList();
|
||||
|
||||
virtual int elaborate(Entity*ent, Architecture*arc);
|
||||
virtual int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
int elaborate(Entity*ent, Architecture*arc) {
|
||||
return elaborate(ent, static_cast<ScopeBase*>(arc));
|
||||
}
|
||||
|
||||
int emit(ostream&out, Entity*ent, Architecture*arc) {
|
||||
return emit(out, ent, static_cast<ScopeBase*>(arc));
|
||||
}
|
||||
|
||||
virtual int elaborate(Entity*ent, ScopeBase*scope);
|
||||
virtual int emit(ostream&out, Entity*entity, ScopeBase*scope);
|
||||
virtual void dump(ostream&out, int indent =0) const;
|
||||
|
||||
std::list<SequentialStmt*>& stmt_list() { return statements_; }
|
||||
|
|
@ -256,7 +277,7 @@ class InitialStatement : public StatementList {
|
|||
InitialStatement(std::list<SequentialStmt*>*statement_list)
|
||||
: StatementList(statement_list) {}
|
||||
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
int emit(ostream&out, Entity*entity, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent =0) const;
|
||||
};
|
||||
|
||||
|
|
@ -267,7 +288,7 @@ class FinalStatement : public StatementList {
|
|||
FinalStatement(std::list<SequentialStmt*>*statement_list)
|
||||
: StatementList(statement_list) {}
|
||||
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
int emit(ostream&out, Entity*entity, ScopeBase*scope);
|
||||
void dump(ostream&out, int indent =0) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -186,13 +186,13 @@ int IfGenerate::elaborate(Entity*ent, Architecture*arc)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int StatementList::elaborate(Entity*ent, Architecture*arc)
|
||||
int StatementList::elaborate(Entity*ent, ScopeBase*scope)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
|
||||
it != statements_.end(); ++it) {
|
||||
errors += (*it)->elaborate(ent, arc);
|
||||
errors += (*it)->elaborate(ent, scope);
|
||||
}
|
||||
|
||||
return errors;
|
||||
|
|
@ -202,8 +202,17 @@ int ProcessStatement::elaborate(Entity*ent, Architecture*arc)
|
|||
{
|
||||
int errors = 0;
|
||||
|
||||
arc->set_cur_process(this);
|
||||
|
||||
for (map<perm_string,Variable*>::iterator cur = new_variables_.begin()
|
||||
; cur != new_variables_.end() ; ++cur) {
|
||||
cur->second->elaborate(ent, arc);
|
||||
}
|
||||
|
||||
StatementList::elaborate(ent, arc);
|
||||
|
||||
arc->set_cur_process(NULL);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,38 +28,28 @@
|
|||
# include <typeinfo>
|
||||
# include <ivl_assert.h>
|
||||
|
||||
int Scope::emit_signals(ostream&out, Entity*entity, Architecture*arc)
|
||||
int Scope::emit_signals(ostream&out, Entity*entity, ScopeBase*scope)
|
||||
{
|
||||
int errors = 0;
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,Signal*>::iterator cur = old_signals_.begin()
|
||||
; cur != old_signals_.end() ; ++cur) {
|
||||
for (map<perm_string,Signal*>::iterator cur = new_signals_.begin()
|
||||
; cur != new_signals_.end() ; ++cur) {
|
||||
errors += cur->second->emit(out, entity, scope);
|
||||
}
|
||||
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
for (map<perm_string,Signal*>::iterator cur = new_signals_.begin()
|
||||
; cur != new_signals_.end() ; ++cur) {
|
||||
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
return errors;
|
||||
return errors;
|
||||
}
|
||||
|
||||
int Scope::emit_variables(ostream&out, Entity*entity, Architecture*arc)
|
||||
int Scope::emit_variables(ostream&out, Entity*entity, ScopeBase*scope)
|
||||
{
|
||||
int errors = 0;
|
||||
int errors = 0;
|
||||
|
||||
for (map<perm_string,Variable*>::iterator cur = old_variables_.begin()
|
||||
; cur != old_variables_.end() ; ++cur) {
|
||||
for (map<perm_string,Variable*>::iterator cur = new_variables_.begin()
|
||||
; cur != new_variables_.end() ; ++cur) {
|
||||
errors += cur->second->emit(out, entity, scope);
|
||||
}
|
||||
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
for (map<perm_string,Variable*>::iterator cur = new_variables_.begin()
|
||||
; cur != new_variables_.end() ; ++cur) {
|
||||
|
||||
errors += cur->second->emit(out, entity, arc);
|
||||
}
|
||||
return errors;
|
||||
return errors;
|
||||
}
|
||||
|
||||
int Architecture::emit(ostream&out, Entity*entity)
|
||||
|
|
@ -310,31 +300,31 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
return errors;
|
||||
}
|
||||
|
||||
int StatementList::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
int StatementList::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
|
||||
it != statements_.end(); ++it) {
|
||||
errors += (*it)->emit(out, ent, arc);
|
||||
errors += (*it)->emit(out, ent, scope);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int InitialStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
int InitialStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||
{
|
||||
out << "initial begin" << endl;
|
||||
int errors = StatementList::emit(out, ent, arc);
|
||||
int errors = StatementList::emit(out, ent, scope);
|
||||
out << "end" << endl;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
int FinalStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
int FinalStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||
{
|
||||
out << "final begin" << endl;
|
||||
int errors = StatementList::emit(out, ent, arc);
|
||||
int errors = StatementList::emit(out, ent, scope);
|
||||
out << "end" << endl;
|
||||
|
||||
return errors;
|
||||
|
|
@ -348,22 +338,25 @@ int FinalStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
* beginning. In VHDL, all the statements are initially executed once
|
||||
* before blocking in the first wait on the sensitivity list.
|
||||
*/
|
||||
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||
int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
/* Check if the process has no sensitivity list and ends up with
|
||||
* a final wait. If so, convert the process to an initial block. */
|
||||
const WaitStmt*wait_stmt = NULL;
|
||||
if (! stmt_list().empty())
|
||||
if (!stmt_list().empty())
|
||||
wait_stmt = dynamic_cast<const WaitStmt*>(stmt_list().back());
|
||||
|
||||
if (wait_stmt && wait_stmt->type() == WaitStmt::FINAL)
|
||||
out << "initial begin" << endl;
|
||||
out << "initial begin : ";
|
||||
else
|
||||
out << "always begin" << endl;
|
||||
out << "always begin : ";
|
||||
|
||||
emit_variables(out, ent, arc);
|
||||
out << peek_name() << endl;
|
||||
|
||||
int errors = StatementList::emit(out, ent, arc);
|
||||
errors += emit_variables(out, ent, this);
|
||||
errors += StatementList::emit(out, ent, this);
|
||||
|
||||
if (! sensitivity_list_.empty()) {
|
||||
out << "@(";
|
||||
|
|
@ -372,12 +365,12 @@ int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
|||
; cur != sensitivity_list_.end() ; ++cur) {
|
||||
|
||||
if (comma) out << comma;
|
||||
errors += (*cur)->emit(out, ent, arc);
|
||||
errors += (*cur)->emit(out, ent, this);
|
||||
comma = ", ";
|
||||
}
|
||||
out << ") /* sensitivity list for process */;" << endl;
|
||||
out << "); /* sensitivity list for process */" << endl;
|
||||
}
|
||||
|
||||
out << "end" << endl;
|
||||
out << "end /* " << peek_name() << " */" << endl;
|
||||
return errors;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,3 +21,5 @@
|
|||
StringHeapLex lex_strings;
|
||||
|
||||
StringHeapLex filename_strings;
|
||||
|
||||
StringHeapLex gen_strings;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ extern bool verbose_flag;
|
|||
extern bool debug_elaboration;
|
||||
extern std::ofstream debug_log_file;
|
||||
|
||||
// Stores strings created by the lexer
|
||||
extern StringHeapLex lex_strings;
|
||||
|
||||
// Stores file names
|
||||
extern StringHeapLex filename_strings;
|
||||
|
||||
// Stores generated strigns (e.g. scope names)
|
||||
extern StringHeapLex gen_strings;
|
||||
|
||||
#endif /* IVL_compiler_H */
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ extern int yylex(union YYSTYPE*yylvalp,YYLTYPE*yyllocp,yyscan_t yyscanner);
|
|||
static ActiveScope*active_scope = new ActiveScope;
|
||||
static stack<ActiveScope*> scope_stack;
|
||||
static SubprogramHeader*active_sub = NULL;
|
||||
static ActiveScope*arc_scope = NULL;
|
||||
|
||||
/*
|
||||
* When a scope boundary starts, call the push_scope function to push
|
||||
|
|
@ -353,7 +354,7 @@ static void touchup_interface_for_functions(std::list<InterfacePort*>*ports)
|
|||
%type <record_elements> element_declaration element_declaration_list
|
||||
|
||||
%type <text> architecture_body_start package_declaration_start
|
||||
%type <text> package_body_start
|
||||
%type <text> package_body_start process_start
|
||||
%type <text> identifier_opt identifier_colon_opt logical_name suffix instantiated_unit
|
||||
|
||||
%type <name_list> logical_name_list identifier_list
|
||||
|
|
@ -412,6 +413,8 @@ architecture_body
|
|||
delete[]$3;
|
||||
delete $8;
|
||||
pop_scope();
|
||||
assert(arc_scope);
|
||||
arc_scope = NULL;
|
||||
if ($11) delete[]$11;
|
||||
}
|
||||
;
|
||||
|
|
@ -420,6 +423,8 @@ architecture_body_start
|
|||
: K_architecture IDENTIFIER
|
||||
{ $$ = $2;
|
||||
push_scope();
|
||||
assert(!arc_scope);
|
||||
arc_scope = active_scope;
|
||||
}
|
||||
;
|
||||
/*
|
||||
|
|
@ -1293,17 +1298,19 @@ file_declaration
|
|||
std::list<Expression*> params;
|
||||
|
||||
// add file_open() call in 'initial' block
|
||||
params.push_back(new ExpName(*cur));
|
||||
params.push_back(new ExpScopedName(active_scope->peek_name(), new ExpName(*cur)));
|
||||
params.push_back($5->filename()->clone());
|
||||
params.push_back($5->kind()->clone());
|
||||
ProcedureCall*fopen_call = new ProcedureCall(perm_string::literal("file_open"), ¶ms);
|
||||
active_scope->add_initializer(fopen_call);
|
||||
ProcedureCall*fopen_call = new ProcedureCall(
|
||||
perm_string::literal("file_open"), ¶ms);
|
||||
arc_scope->add_initializer(fopen_call);
|
||||
|
||||
// add file_close() call in 'final' block
|
||||
params.clear();
|
||||
params.push_back(new ExpName(*cur));
|
||||
ProcedureCall*fclose_call = new ProcedureCall(perm_string::literal("file_close"), ¶ms);
|
||||
active_scope->add_finalizer(fclose_call);
|
||||
params.push_back(new ExpScopedName(active_scope->peek_name(), new ExpName(*cur)));
|
||||
ProcedureCall*fclose_call = new ProcedureCall(
|
||||
perm_string::literal("file_close"), ¶ms);
|
||||
arc_scope->add_finalizer(fclose_call);
|
||||
|
||||
delete $5;
|
||||
}
|
||||
|
|
@ -2090,37 +2097,40 @@ process_declarative_part_opt
|
|||
|
|
||||
;
|
||||
|
||||
process_statement
|
||||
process_start
|
||||
: identifier_colon_opt K_postponed_opt K_process
|
||||
{
|
||||
push_scope();
|
||||
}
|
||||
process_sensitivity_list_opt K_is_opt
|
||||
{ push_scope();
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
process_statement
|
||||
: process_start process_sensitivity_list_opt K_is_opt
|
||||
process_declarative_part_opt
|
||||
K_begin sequence_of_statements
|
||||
K_end K_postponed_opt K_process identifier_opt ';'
|
||||
{ perm_string iname = $1? lex_strings.make($1) : empty_perm_string;
|
||||
if ($1) delete[]$1;
|
||||
if ($13) {
|
||||
if ($10) {
|
||||
if (iname.nil()) {
|
||||
errormsg(@13, "Process end name %s for un-named processes.\n", $13);
|
||||
} else if (iname != $13) {
|
||||
errormsg(@13, "Process name %s does not match opening name %s.\n",
|
||||
$13, $1);
|
||||
errormsg(@10, "Process end name %s for un-named processes.\n", $10);
|
||||
} else if (iname != $10) {
|
||||
errormsg(@10, "Process name %s does not match opening name %s.\n",
|
||||
$10, $1);
|
||||
}
|
||||
delete[]$13;
|
||||
delete[]$10;
|
||||
}
|
||||
|
||||
ProcessStatement*tmp = new ProcessStatement(iname, *active_scope, $5, $9);
|
||||
pop_scope();
|
||||
FILE_NAME(tmp, @4);
|
||||
delete $5;
|
||||
delete $9;
|
||||
ProcessStatement*tmp = new ProcessStatement(iname, *active_scope, $2, $6);
|
||||
arc_scope->bind_scope(tmp->peek_name(), tmp);
|
||||
pop_scope();
|
||||
FILE_NAME(tmp, @3);
|
||||
delete $2;
|
||||
delete $6;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
| identifier_colon_opt K_postponed_opt K_process
|
||||
process_sensitivity_list_opt K_is_opt
|
||||
| process_start process_sensitivity_list_opt K_is_opt
|
||||
process_declarative_part_opt
|
||||
K_begin error
|
||||
K_end K_postponed_opt K_process identifier_opt ';'
|
||||
|
|
|
|||
120
vhdlpp/scope.cc
120
vhdlpp/scope.cc
|
|
@ -24,61 +24,30 @@
|
|||
# include "entity.h"
|
||||
# include "std_funcs.h"
|
||||
# include "std_types.h"
|
||||
# include "compiler.h"
|
||||
# include <algorithm>
|
||||
# include <iostream>
|
||||
# include <iterator>
|
||||
# include <cstdio>
|
||||
# include <cstring>
|
||||
# include <cassert>
|
||||
# include <StringHeap.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
* If the merge_flag is passed in, then the new scope is a merge of
|
||||
* the parent scopes. This brings in all of the parent scopes into the
|
||||
* "old_*_" variables. This clears up the "new_*_" variables to
|
||||
* accumulate new scope values.
|
||||
*/
|
||||
static int scope_counter = 0;
|
||||
|
||||
ScopeBase::ScopeBase(const ActiveScope&ref)
|
||||
: use_constants_(ref.use_constants_), cur_constants_(ref.cur_constants_)
|
||||
: old_signals_(ref.old_signals_), new_signals_(ref.new_signals_),
|
||||
old_variables_(ref.old_variables_), new_variables_(ref.new_variables_),
|
||||
old_components_(ref.old_components_), new_components_(ref.new_components_),
|
||||
use_types_(ref.use_types_), cur_types_(ref.cur_types_),
|
||||
use_constants_(ref.use_constants_), cur_constants_(ref.cur_constants_),
|
||||
use_subprograms_(ref.use_subprograms_), cur_subprograms_(ref.cur_subprograms_),
|
||||
scopes_(ref.scopes_), use_enums_(ref.use_enums_),
|
||||
initializers_(ref.initializers_), finalizers_(ref.finalizers_),
|
||||
name_(ref.name_)
|
||||
{
|
||||
merge(ref.old_signals_.begin(), ref.old_signals_.end(),
|
||||
ref.new_signals_.begin(), ref.new_signals_.end(),
|
||||
insert_iterator<map<perm_string, Signal*> >(
|
||||
old_signals_, old_signals_.end())
|
||||
);
|
||||
merge(ref.old_variables_.begin(), ref.old_variables_.end(),
|
||||
ref.new_variables_.begin(), ref.new_variables_.end(),
|
||||
insert_iterator<map<perm_string, Variable*> >(
|
||||
old_variables_, old_variables_.end())
|
||||
);
|
||||
merge(ref.old_components_.begin(), ref.old_components_.end(),
|
||||
ref.new_components_.begin(), ref.new_components_.end(),
|
||||
insert_iterator<map<perm_string, ComponentBase*> >(
|
||||
old_components_, old_components_.end())
|
||||
);
|
||||
use_types_ = ref.use_types_;
|
||||
cur_types_ = ref.cur_types_;
|
||||
|
||||
use_subprograms_ = ref.use_subprograms_;
|
||||
cur_subprograms_ = ref.cur_subprograms_;
|
||||
|
||||
use_enums_ = ref.use_enums_;
|
||||
|
||||
initializers_ = ref.initializers_;
|
||||
finalizers_ = ref.finalizers_;
|
||||
|
||||
// This constructor is invoked when the parser is finished with
|
||||
// an active scope and is making the actual scope. At this point
|
||||
// we know that "this" is the parent scope for the subprograms,
|
||||
// so set it now.
|
||||
for (map<perm_string,SubHeaderList>::iterator cur = cur_subprograms_.begin()
|
||||
; cur != cur_subprograms_.end(); ++cur) {
|
||||
SubHeaderList& subp_list = cur->second;
|
||||
|
||||
for (SubHeaderList::iterator it = subp_list.begin();
|
||||
it != subp_list.end(); ++it) {
|
||||
(*it)->set_parent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScopeBase::~ScopeBase()
|
||||
|
|
@ -105,6 +74,16 @@ void ScopeBase::cleanup()
|
|||
}
|
||||
}
|
||||
|
||||
ScopeBase*ScopeBase::find_scope(perm_string name) const
|
||||
{
|
||||
map<perm_string, ScopeBase*>::const_iterator it = scopes_.find(name);
|
||||
|
||||
if(it != scopes_.end())
|
||||
return it->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const VType*ScopeBase::find_type(perm_string by_name)
|
||||
{
|
||||
map<perm_string,const VType*>::const_iterator cur = cur_types_.find(by_name);
|
||||
|
|
@ -339,9 +318,15 @@ SubprogramHeader*ScopeBase::match_subprogram(perm_string name,
|
|||
}
|
||||
|
||||
void ActiveScope::set_package_header(Package*pkg)
|
||||
void ScopeBase::generate_name()
|
||||
{
|
||||
assert(package_header_ == 0);
|
||||
package_header_ = pkg;
|
||||
char buf[64];
|
||||
|
||||
// Generate a name for the scope
|
||||
snprintf(buf, sizeof(buf), "__scope_%d", scope_counter++);
|
||||
name_ = gen_strings.make(buf);
|
||||
}
|
||||
|
||||
SubprogramHeader* ActiveScope::recall_subprogram(const SubprogramHeader*subp) const
|
||||
|
|
@ -384,15 +369,6 @@ bool ActiveScope::is_vector_name(perm_string name) const
|
|||
return false;
|
||||
}
|
||||
|
||||
Scope::Scope(const ActiveScope&ref)
|
||||
: ScopeBase(ref)
|
||||
{
|
||||
}
|
||||
|
||||
Scope::~Scope()
|
||||
{
|
||||
}
|
||||
|
||||
ComponentBase* Scope::find_component(perm_string by_name)
|
||||
{
|
||||
map<perm_string,ComponentBase*>::const_iterator cur = new_components_.find(by_name);
|
||||
|
|
@ -405,3 +381,37 @@ ComponentBase* Scope::find_component(perm_string by_name)
|
|||
} else
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
ActiveScope::ActiveScope(const ActiveScope*par)
|
||||
: ScopeBase(*par), context_entity_(par->context_entity_)
|
||||
{
|
||||
generate_name();
|
||||
|
||||
// Move all the objects available in higher level scopes to use*/old* maps.
|
||||
// This way we can store the new items in now empty cur*/new* maps.
|
||||
merge(par->old_signals_.begin(), par->old_signals_.end(),
|
||||
par->new_signals_.begin(), par->new_signals_.end(),
|
||||
insert_iterator<map<perm_string, Signal*> >(
|
||||
old_signals_, old_signals_.end())
|
||||
);
|
||||
merge(par->old_variables_.begin(), par->old_variables_.end(),
|
||||
par->new_variables_.begin(), par->new_variables_.end(),
|
||||
insert_iterator<map<perm_string, Variable*> >(
|
||||
old_variables_, old_variables_.end())
|
||||
);
|
||||
merge(par->old_components_.begin(), par->old_components_.end(),
|
||||
par->new_components_.begin(), par->new_components_.end(),
|
||||
insert_iterator<map<perm_string, ComponentBase*> >(
|
||||
old_components_, old_components_.end())
|
||||
);
|
||||
merge(par->use_types_.begin(), par->use_types_.end(),
|
||||
par->cur_types_.begin(), par->cur_types_.end(),
|
||||
insert_iterator<map<perm_string, const VType*> >(
|
||||
use_types_, use_types_.end())
|
||||
);
|
||||
merge(par->use_subprograms_.begin(), par->use_subprograms_.end(),
|
||||
par->cur_subprograms_.begin(), par->cur_subprograms_.end(),
|
||||
insert_iterator<map<perm_string, SubHeaderList> >(
|
||||
use_subprograms_, use_subprograms_.end())
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,10 +55,11 @@ class ScopeBase {
|
|||
explicit ScopeBase(const ActiveScope&ref);
|
||||
virtual ~ScopeBase() =0;
|
||||
|
||||
ScopeBase* find_scope(perm_string name) const;
|
||||
const VType* find_type(perm_string by_name);
|
||||
virtual bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
|
||||
Signal* find_signal(perm_string by_name) const;
|
||||
Variable* find_variable(perm_string by_name) const;
|
||||
virtual Variable* find_variable(perm_string by_name) const;
|
||||
virtual const InterfacePort* find_param(perm_string by_name) const;
|
||||
const InterfacePort* find_param_all(perm_string by_name) const;
|
||||
SubHeaderList find_subprogram(perm_string by_name) const;
|
||||
|
|
@ -98,6 +99,8 @@ class ScopeBase {
|
|||
SubprogramHeader*match_subprogram(perm_string name,
|
||||
const list<const VType*>*params) const;
|
||||
|
||||
perm_string peek_name() const { return name_; }
|
||||
|
||||
protected:
|
||||
void cleanup();
|
||||
|
||||
|
|
@ -143,6 +146,8 @@ class ScopeBase {
|
|||
std::map<perm_string, SubHeaderList> use_subprograms_; //imported
|
||||
std::map<perm_string, SubHeaderList> cur_subprograms_; //current
|
||||
|
||||
std::map<perm_string, ScopeBase*> scopes_;
|
||||
|
||||
std::list<const VTypeEnum*> use_enums_;
|
||||
|
||||
// List of statements that should be emitted in a 'initial' block
|
||||
|
|
@ -152,20 +157,26 @@ class ScopeBase {
|
|||
std::list<SequentialStmt*> finalizers_;
|
||||
|
||||
void do_use_from(const ScopeBase*that);
|
||||
|
||||
// Generates an unique name for the scope
|
||||
void generate_name();
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
class Scope : public ScopeBase {
|
||||
|
||||
public:
|
||||
explicit Scope(const ActiveScope&ref);
|
||||
~Scope();
|
||||
explicit Scope(const ActiveScope&ref) : ScopeBase(ref) {}
|
||||
virtual ~Scope() {}
|
||||
|
||||
ComponentBase* find_component(perm_string by_name);
|
||||
|
||||
protected:
|
||||
// Helper method for emitting signals in the scope.
|
||||
int emit_signals(ostream&out, Entity*ent, Architecture*arc);
|
||||
int emit_variables(ostream&out, Entity*ent, Architecture*arc);
|
||||
int emit_signals(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
int emit_variables(ostream&out, Entity*ent, ScopeBase*scope);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -177,8 +188,8 @@ class Scope : public ScopeBase {
|
|||
class ActiveScope : public ScopeBase {
|
||||
|
||||
public:
|
||||
ActiveScope() : package_header_(0), context_entity_(0) { }
|
||||
explicit ActiveScope(ActiveScope*par) : ScopeBase(*par), package_header_(0), context_entity_(0) { }
|
||||
ActiveScope() : context_entity_(0) { }
|
||||
explicit ActiveScope(const ActiveScope*par);
|
||||
|
||||
~ActiveScope() { }
|
||||
|
||||
|
|
@ -233,6 +244,12 @@ class ActiveScope : public ScopeBase {
|
|||
cur_types_[name] = t;
|
||||
}
|
||||
|
||||
void bind_scope(perm_string name, ScopeBase*scope)
|
||||
{
|
||||
assert(scopes_.find(name) == scopes_.end());
|
||||
scopes_[name] = scope;
|
||||
}
|
||||
|
||||
inline void use_enum(const VTypeEnum* t)
|
||||
{ use_enums_.push_back(t); }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue