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,
|
Architecture::Architecture(perm_string name, const ActiveScope&ref,
|
||||||
list<Architecture::Statement*>&s)
|
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);
|
statements_.splice(statements_.end(), s);
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +68,14 @@ bool Architecture::find_constant(perm_string by_name, const VType*&typ, Expressi
|
||||||
return false;
|
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)
|
void Architecture::push_genvar_type(perm_string gname, const VType*gtype)
|
||||||
{
|
{
|
||||||
genvar_type_t tmp;
|
genvar_type_t tmp;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class Entity;
|
||||||
class Expression;
|
class Expression;
|
||||||
class ExpName;
|
class ExpName;
|
||||||
class GenerateStatement;
|
class GenerateStatement;
|
||||||
|
class ProcessStatement;
|
||||||
class SequentialStmt;
|
class SequentialStmt;
|
||||||
class Signal;
|
class Signal;
|
||||||
class named_expr_t;
|
class named_expr_t;
|
||||||
|
|
@ -65,9 +66,20 @@ class Architecture : public Scope, public LineInfo {
|
||||||
|
|
||||||
perm_string get_name() const { return name_; }
|
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;
|
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.
|
// Elaborate this architecture in the context of the given entity.
|
||||||
int elaborate(Entity*entity);
|
int elaborate(Entity*entity);
|
||||||
|
|
@ -113,7 +125,8 @@ class Architecture : public Scope, public LineInfo {
|
||||||
// Currently processed component (or NULL if none).
|
// Currently processed component (or NULL if none).
|
||||||
ComponentInstantiation*cur_component_;
|
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);
|
StatementList(std::list<SequentialStmt*>*statement_list);
|
||||||
virtual ~StatementList();
|
virtual ~StatementList();
|
||||||
|
|
||||||
virtual int elaborate(Entity*ent, Architecture*arc);
|
int elaborate(Entity*ent, Architecture*arc) {
|
||||||
virtual int emit(ostream&out, Entity*entity, 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;
|
virtual void dump(ostream&out, int indent =0) const;
|
||||||
|
|
||||||
std::list<SequentialStmt*>& stmt_list() { return statements_; }
|
std::list<SequentialStmt*>& stmt_list() { return statements_; }
|
||||||
|
|
@ -256,7 +277,7 @@ class InitialStatement : public StatementList {
|
||||||
InitialStatement(std::list<SequentialStmt*>*statement_list)
|
InitialStatement(std::list<SequentialStmt*>*statement_list)
|
||||||
: StatementList(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;
|
void dump(ostream&out, int indent =0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -267,7 +288,7 @@ class FinalStatement : public StatementList {
|
||||||
FinalStatement(std::list<SequentialStmt*>*statement_list)
|
FinalStatement(std::list<SequentialStmt*>*statement_list)
|
||||||
: StatementList(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;
|
void dump(ostream&out, int indent =0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,13 +186,13 @@ int IfGenerate::elaborate(Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StatementList::elaborate(Entity*ent, Architecture*arc)
|
int StatementList::elaborate(Entity*ent, ScopeBase*scope)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
|
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
|
||||||
it != statements_.end(); ++it) {
|
it != statements_.end(); ++it) {
|
||||||
errors += (*it)->elaborate(ent, arc);
|
errors += (*it)->elaborate(ent, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
|
|
@ -202,8 +202,17 @@ int ProcessStatement::elaborate(Entity*ent, Architecture*arc)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
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);
|
StatementList::elaborate(ent, arc);
|
||||||
|
|
||||||
|
arc->set_cur_process(NULL);
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,38 +28,28 @@
|
||||||
# include <typeinfo>
|
# include <typeinfo>
|
||||||
# include <ivl_assert.h>
|
# 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()
|
for (map<perm_string,Signal*>::iterator cur = new_signals_.begin()
|
||||||
; cur != old_signals_.end() ; ++cur) {
|
; cur != new_signals_.end() ; ++cur) {
|
||||||
|
errors += cur->second->emit(out, entity, scope);
|
||||||
|
}
|
||||||
|
|
||||||
errors += cur->second->emit(out, entity, arc);
|
return errors;
|
||||||
}
|
|
||||||
for (map<perm_string,Signal*>::iterator cur = new_signals_.begin()
|
|
||||||
; cur != new_signals_.end() ; ++cur) {
|
|
||||||
|
|
||||||
errors += cur->second->emit(out, entity, arc);
|
|
||||||
}
|
|
||||||
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()
|
for (map<perm_string,Variable*>::iterator cur = new_variables_.begin()
|
||||||
; cur != old_variables_.end() ; ++cur) {
|
; cur != new_variables_.end() ; ++cur) {
|
||||||
|
errors += cur->second->emit(out, entity, scope);
|
||||||
|
}
|
||||||
|
|
||||||
errors += cur->second->emit(out, entity, arc);
|
return errors;
|
||||||
}
|
|
||||||
for (map<perm_string,Variable*>::iterator cur = new_variables_.begin()
|
|
||||||
; cur != new_variables_.end() ; ++cur) {
|
|
||||||
|
|
||||||
errors += cur->second->emit(out, entity, arc);
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Architecture::emit(ostream&out, Entity*entity)
|
int Architecture::emit(ostream&out, Entity*entity)
|
||||||
|
|
@ -310,31 +300,31 @@ int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StatementList::emit(ostream&out, Entity*ent, Architecture*arc)
|
int StatementList::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
||||||
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
|
for (std::list<SequentialStmt*>::iterator it = statements_.begin();
|
||||||
it != statements_.end(); ++it) {
|
it != statements_.end(); ++it) {
|
||||||
errors += (*it)->emit(out, ent, arc);
|
errors += (*it)->emit(out, ent, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InitialStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
int InitialStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||||
{
|
{
|
||||||
out << "initial begin" << endl;
|
out << "initial begin" << endl;
|
||||||
int errors = StatementList::emit(out, ent, arc);
|
int errors = StatementList::emit(out, ent, scope);
|
||||||
out << "end" << endl;
|
out << "end" << endl;
|
||||||
|
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FinalStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
int FinalStatement::emit(ostream&out, Entity*ent, ScopeBase*scope)
|
||||||
{
|
{
|
||||||
out << "final begin" << endl;
|
out << "final begin" << endl;
|
||||||
int errors = StatementList::emit(out, ent, arc);
|
int errors = StatementList::emit(out, ent, scope);
|
||||||
out << "end" << endl;
|
out << "end" << endl;
|
||||||
|
|
||||||
return errors;
|
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
|
* beginning. In VHDL, all the statements are initially executed once
|
||||||
* before blocking in the first wait on the sensitivity list.
|
* 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
|
/* Check if the process has no sensitivity list and ends up with
|
||||||
* a final wait. If so, convert the process to an initial block. */
|
* a final wait. If so, convert the process to an initial block. */
|
||||||
const WaitStmt*wait_stmt = NULL;
|
const WaitStmt*wait_stmt = NULL;
|
||||||
if (! stmt_list().empty())
|
if (!stmt_list().empty())
|
||||||
wait_stmt = dynamic_cast<const WaitStmt*>(stmt_list().back());
|
wait_stmt = dynamic_cast<const WaitStmt*>(stmt_list().back());
|
||||||
|
|
||||||
if (wait_stmt && wait_stmt->type() == WaitStmt::FINAL)
|
if (wait_stmt && wait_stmt->type() == WaitStmt::FINAL)
|
||||||
out << "initial begin" << endl;
|
out << "initial begin : ";
|
||||||
else
|
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()) {
|
if (! sensitivity_list_.empty()) {
|
||||||
out << "@(";
|
out << "@(";
|
||||||
|
|
@ -372,12 +365,12 @@ int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
; cur != sensitivity_list_.end() ; ++cur) {
|
; cur != sensitivity_list_.end() ; ++cur) {
|
||||||
|
|
||||||
if (comma) out << comma;
|
if (comma) out << comma;
|
||||||
errors += (*cur)->emit(out, ent, arc);
|
errors += (*cur)->emit(out, ent, this);
|
||||||
comma = ", ";
|
comma = ", ";
|
||||||
}
|
}
|
||||||
out << ") /* sensitivity list for process */;" << endl;
|
out << "); /* sensitivity list for process */" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "end" << endl;
|
out << "end /* " << peek_name() << " */" << endl;
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,5 @@
|
||||||
StringHeapLex lex_strings;
|
StringHeapLex lex_strings;
|
||||||
|
|
||||||
StringHeapLex filename_strings;
|
StringHeapLex filename_strings;
|
||||||
|
|
||||||
|
StringHeapLex gen_strings;
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,13 @@ extern bool verbose_flag;
|
||||||
extern bool debug_elaboration;
|
extern bool debug_elaboration;
|
||||||
extern std::ofstream debug_log_file;
|
extern std::ofstream debug_log_file;
|
||||||
|
|
||||||
|
// Stores strings created by the lexer
|
||||||
extern StringHeapLex lex_strings;
|
extern StringHeapLex lex_strings;
|
||||||
|
|
||||||
|
// Stores file names
|
||||||
extern StringHeapLex filename_strings;
|
extern StringHeapLex filename_strings;
|
||||||
|
|
||||||
|
// Stores generated strigns (e.g. scope names)
|
||||||
|
extern StringHeapLex gen_strings;
|
||||||
|
|
||||||
#endif /* IVL_compiler_H */
|
#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 ActiveScope*active_scope = new ActiveScope;
|
||||||
static stack<ActiveScope*> scope_stack;
|
static stack<ActiveScope*> scope_stack;
|
||||||
static SubprogramHeader*active_sub = NULL;
|
static SubprogramHeader*active_sub = NULL;
|
||||||
|
static ActiveScope*arc_scope = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When a scope boundary starts, call the push_scope function to push
|
* 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 <record_elements> element_declaration element_declaration_list
|
||||||
|
|
||||||
%type <text> architecture_body_start package_declaration_start
|
%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 <text> identifier_opt identifier_colon_opt logical_name suffix instantiated_unit
|
||||||
|
|
||||||
%type <name_list> logical_name_list identifier_list
|
%type <name_list> logical_name_list identifier_list
|
||||||
|
|
@ -412,6 +413,8 @@ architecture_body
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
delete $8;
|
delete $8;
|
||||||
pop_scope();
|
pop_scope();
|
||||||
|
assert(arc_scope);
|
||||||
|
arc_scope = NULL;
|
||||||
if ($11) delete[]$11;
|
if ($11) delete[]$11;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -420,6 +423,8 @@ architecture_body_start
|
||||||
: K_architecture IDENTIFIER
|
: K_architecture IDENTIFIER
|
||||||
{ $$ = $2;
|
{ $$ = $2;
|
||||||
push_scope();
|
push_scope();
|
||||||
|
assert(!arc_scope);
|
||||||
|
arc_scope = active_scope;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
/*
|
/*
|
||||||
|
|
@ -1293,17 +1298,19 @@ file_declaration
|
||||||
std::list<Expression*> params;
|
std::list<Expression*> params;
|
||||||
|
|
||||||
// add file_open() call in 'initial' block
|
// 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->filename()->clone());
|
||||||
params.push_back($5->kind()->clone());
|
params.push_back($5->kind()->clone());
|
||||||
ProcedureCall*fopen_call = new ProcedureCall(perm_string::literal("file_open"), ¶ms);
|
ProcedureCall*fopen_call = new ProcedureCall(
|
||||||
active_scope->add_initializer(fopen_call);
|
perm_string::literal("file_open"), ¶ms);
|
||||||
|
arc_scope->add_initializer(fopen_call);
|
||||||
|
|
||||||
// add file_close() call in 'final' block
|
// add file_close() call in 'final' block
|
||||||
params.clear();
|
params.clear();
|
||||||
params.push_back(new ExpName(*cur));
|
params.push_back(new ExpScopedName(active_scope->peek_name(), new ExpName(*cur)));
|
||||||
ProcedureCall*fclose_call = new ProcedureCall(perm_string::literal("file_close"), ¶ms);
|
ProcedureCall*fclose_call = new ProcedureCall(
|
||||||
active_scope->add_finalizer(fclose_call);
|
perm_string::literal("file_close"), ¶ms);
|
||||||
|
arc_scope->add_finalizer(fclose_call);
|
||||||
|
|
||||||
delete $5;
|
delete $5;
|
||||||
}
|
}
|
||||||
|
|
@ -2090,37 +2097,40 @@ process_declarative_part_opt
|
||||||
|
|
|
|
||||||
;
|
;
|
||||||
|
|
||||||
process_statement
|
process_start
|
||||||
: identifier_colon_opt K_postponed_opt K_process
|
: identifier_colon_opt K_postponed_opt K_process
|
||||||
{
|
{ push_scope();
|
||||||
push_scope();
|
$$ = $1;
|
||||||
}
|
}
|
||||||
process_sensitivity_list_opt K_is_opt
|
;
|
||||||
|
|
||||||
|
process_statement
|
||||||
|
: process_start process_sensitivity_list_opt K_is_opt
|
||||||
process_declarative_part_opt
|
process_declarative_part_opt
|
||||||
K_begin sequence_of_statements
|
K_begin sequence_of_statements
|
||||||
K_end K_postponed_opt K_process identifier_opt ';'
|
K_end K_postponed_opt K_process identifier_opt ';'
|
||||||
{ perm_string iname = $1? lex_strings.make($1) : empty_perm_string;
|
{ perm_string iname = $1? lex_strings.make($1) : empty_perm_string;
|
||||||
if ($1) delete[]$1;
|
if ($1) delete[]$1;
|
||||||
if ($13) {
|
if ($10) {
|
||||||
if (iname.nil()) {
|
if (iname.nil()) {
|
||||||
errormsg(@13, "Process end name %s for un-named processes.\n", $13);
|
errormsg(@10, "Process end name %s for un-named processes.\n", $10);
|
||||||
} else if (iname != $13) {
|
} else if (iname != $10) {
|
||||||
errormsg(@13, "Process name %s does not match opening name %s.\n",
|
errormsg(@10, "Process name %s does not match opening name %s.\n",
|
||||||
$13, $1);
|
$10, $1);
|
||||||
}
|
}
|
||||||
delete[]$13;
|
delete[]$10;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessStatement*tmp = new ProcessStatement(iname, *active_scope, $5, $9);
|
ProcessStatement*tmp = new ProcessStatement(iname, *active_scope, $2, $6);
|
||||||
pop_scope();
|
arc_scope->bind_scope(tmp->peek_name(), tmp);
|
||||||
FILE_NAME(tmp, @4);
|
pop_scope();
|
||||||
delete $5;
|
FILE_NAME(tmp, @3);
|
||||||
delete $9;
|
delete $2;
|
||||||
|
delete $6;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
| identifier_colon_opt K_postponed_opt K_process
|
| process_start process_sensitivity_list_opt K_is_opt
|
||||||
process_sensitivity_list_opt K_is_opt
|
|
||||||
process_declarative_part_opt
|
process_declarative_part_opt
|
||||||
K_begin error
|
K_begin error
|
||||||
K_end K_postponed_opt K_process identifier_opt ';'
|
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 "entity.h"
|
||||||
# include "std_funcs.h"
|
# include "std_funcs.h"
|
||||||
# include "std_types.h"
|
# include "std_types.h"
|
||||||
|
# include "compiler.h"
|
||||||
# include <algorithm>
|
# include <algorithm>
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
# include <iterator>
|
# include <iterator>
|
||||||
|
# include <cstdio>
|
||||||
|
# include <cstring>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
|
# include <StringHeap.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/*
|
static int scope_counter = 0;
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
ScopeBase::ScopeBase(const ActiveScope&ref)
|
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()
|
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)
|
const VType*ScopeBase::find_type(perm_string by_name)
|
||||||
{
|
{
|
||||||
map<perm_string,const VType*>::const_iterator cur = cur_types_.find(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 ActiveScope::set_package_header(Package*pkg)
|
||||||
|
void ScopeBase::generate_name()
|
||||||
{
|
{
|
||||||
assert(package_header_ == 0);
|
assert(package_header_ == 0);
|
||||||
package_header_ = pkg;
|
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
|
SubprogramHeader* ActiveScope::recall_subprogram(const SubprogramHeader*subp) const
|
||||||
|
|
@ -384,15 +369,6 @@ bool ActiveScope::is_vector_name(perm_string name) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope::Scope(const ActiveScope&ref)
|
|
||||||
: ScopeBase(ref)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope::~Scope()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ComponentBase* Scope::find_component(perm_string by_name)
|
ComponentBase* Scope::find_component(perm_string by_name)
|
||||||
{
|
{
|
||||||
map<perm_string,ComponentBase*>::const_iterator cur = new_components_.find(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
|
} else
|
||||||
return cur->second;
|
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);
|
explicit ScopeBase(const ActiveScope&ref);
|
||||||
virtual ~ScopeBase() =0;
|
virtual ~ScopeBase() =0;
|
||||||
|
|
||||||
|
ScopeBase* find_scope(perm_string name) const;
|
||||||
const VType* find_type(perm_string by_name);
|
const VType* find_type(perm_string by_name);
|
||||||
virtual bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
|
virtual bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const;
|
||||||
Signal* find_signal(perm_string by_name) 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;
|
virtual const InterfacePort* find_param(perm_string by_name) const;
|
||||||
const InterfacePort* find_param_all(perm_string by_name) const;
|
const InterfacePort* find_param_all(perm_string by_name) const;
|
||||||
SubHeaderList find_subprogram(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,
|
SubprogramHeader*match_subprogram(perm_string name,
|
||||||
const list<const VType*>*params) const;
|
const list<const VType*>*params) const;
|
||||||
|
|
||||||
|
perm_string peek_name() const { return name_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
|
@ -143,6 +146,8 @@ class ScopeBase {
|
||||||
std::map<perm_string, SubHeaderList> use_subprograms_; //imported
|
std::map<perm_string, SubHeaderList> use_subprograms_; //imported
|
||||||
std::map<perm_string, SubHeaderList> cur_subprograms_; //current
|
std::map<perm_string, SubHeaderList> cur_subprograms_; //current
|
||||||
|
|
||||||
|
std::map<perm_string, ScopeBase*> scopes_;
|
||||||
|
|
||||||
std::list<const VTypeEnum*> use_enums_;
|
std::list<const VTypeEnum*> use_enums_;
|
||||||
|
|
||||||
// List of statements that should be emitted in a 'initial' block
|
// List of statements that should be emitted in a 'initial' block
|
||||||
|
|
@ -152,20 +157,26 @@ class ScopeBase {
|
||||||
std::list<SequentialStmt*> finalizers_;
|
std::list<SequentialStmt*> finalizers_;
|
||||||
|
|
||||||
void do_use_from(const ScopeBase*that);
|
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 {
|
class Scope : public ScopeBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Scope(const ActiveScope&ref);
|
explicit Scope(const ActiveScope&ref) : ScopeBase(ref) {}
|
||||||
~Scope();
|
virtual ~Scope() {}
|
||||||
|
|
||||||
ComponentBase* find_component(perm_string by_name);
|
ComponentBase* find_component(perm_string by_name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Helper method for emitting signals in the scope.
|
// Helper method for emitting signals in the scope.
|
||||||
int emit_signals(ostream&out, Entity*ent, Architecture*arc);
|
int emit_signals(ostream&out, Entity*ent, ScopeBase*scope);
|
||||||
int emit_variables(ostream&out, Entity*ent, Architecture*arc);
|
int emit_variables(ostream&out, Entity*ent, ScopeBase*scope);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -177,8 +188,8 @@ class Scope : public ScopeBase {
|
||||||
class ActiveScope : public ScopeBase {
|
class ActiveScope : public ScopeBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ActiveScope() : package_header_(0), context_entity_(0) { }
|
ActiveScope() : context_entity_(0) { }
|
||||||
explicit ActiveScope(ActiveScope*par) : ScopeBase(*par), package_header_(0), context_entity_(0) { }
|
explicit ActiveScope(const ActiveScope*par);
|
||||||
|
|
||||||
~ActiveScope() { }
|
~ActiveScope() { }
|
||||||
|
|
||||||
|
|
@ -233,6 +244,12 @@ class ActiveScope : public ScopeBase {
|
||||||
cur_types_[name] = t;
|
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)
|
inline void use_enum(const VTypeEnum* t)
|
||||||
{ use_enums_.push_back(t); }
|
{ use_enums_.push_back(t); }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue