Add support for VHDL's loop statements
This commit is contained in:
parent
743cb234c0
commit
60deb775ca
|
|
@ -346,3 +346,10 @@ void named_expr_t::dump(ostream&out, int indent) const
|
|||
out << setw(indent) << "" << name_ << "=>";
|
||||
expr_->dump(out, indent);
|
||||
}
|
||||
|
||||
void range_t::dump(ostream&out, int indent) const
|
||||
{
|
||||
left_->dump(out, indent);
|
||||
out << setw(indent) << "" << (direction_ ? "downto" : "to");
|
||||
right_->dump(out, indent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ const VType*parse_type_by_name(perm_string name)
|
|||
|
||||
const VType* vtype;
|
||||
|
||||
range_t* range;
|
||||
|
||||
std::list<InterfacePort*>* interface_list;
|
||||
|
||||
Architecture::Statement* arch_statement;
|
||||
|
|
@ -211,7 +213,7 @@ const VType*parse_type_by_name(perm_string name)
|
|||
%type <vtype> subtype_indication
|
||||
|
||||
%type <text> architecture_body_start package_declaration_start
|
||||
%type <text> identifier_opt logical_name suffix
|
||||
%type <text> identifier_opt identifier_colon_opt logical_name suffix
|
||||
%type <name_list> logical_name_list identifier_list
|
||||
%type <compound_name> prefix selected_name
|
||||
%type <compound_name_list> selected_names use_clause
|
||||
|
|
@ -219,6 +221,9 @@ const VType*parse_type_by_name(perm_string name)
|
|||
%type <sequ_list> sequence_of_statements if_statement_else
|
||||
%type <sequ> sequential_statement if_statement signal_assignment_statement
|
||||
%type <sequ> case_statement procedure_call procedure_call_statement
|
||||
%type <sequ> loop_statement
|
||||
|
||||
%type <range> range
|
||||
|
||||
%type <case_alt> case_statement_alternative
|
||||
%type <case_alt_list> case_statement_alternative_list
|
||||
|
|
@ -832,6 +837,7 @@ identifier_list
|
|||
|
||||
identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ;
|
||||
|
||||
identifier_colon_opt : IDENTIFIER ':' { $$ = $1; } | { $$ = 0; };
|
||||
|
||||
if_statement
|
||||
: K_if expression K_then sequence_of_statements
|
||||
|
|
@ -993,6 +999,60 @@ logical_name_list
|
|||
}
|
||||
;
|
||||
|
||||
loop_statement
|
||||
: identifier_colon_opt
|
||||
K_while expression_logical K_loop
|
||||
sequence_of_statements
|
||||
K_end K_loop identifier_opt ';'
|
||||
{
|
||||
if($1 && strcmp($1, $8))
|
||||
errormsg(@1, "Loop statement name doesn't match closing name.\n");
|
||||
if($1) delete[]$1;
|
||||
if($8) delete[]$8;
|
||||
|
||||
ExpLogical* cond = dynamic_cast<ExpLogical*>($3);
|
||||
if(!cond) {
|
||||
errormsg(@3, "Iteration condition is not a correct logical expression");
|
||||
}
|
||||
WhileLoopStatement* tmp = new WhileLoopStatement(cond, $5);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported");
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier_colon_opt K_for
|
||||
IDENTIFIER K_in range K_loop
|
||||
sequence_of_statements
|
||||
K_end K_loop identifier_opt ';'
|
||||
{
|
||||
if($1 && strcmp($1, $10))
|
||||
errormsg(@1, "Loop statement name doesn't match closing name.\n");
|
||||
if($1) delete[] $1;
|
||||
if($10) delete[] $10;
|
||||
|
||||
ForLoopStatement* tmp = new ForLoopStatement(lex_strings.make($3), $5, $7);
|
||||
delete[]$3;
|
||||
FILE_NAME(tmp, @1);
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported");
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier_colon_opt K_loop
|
||||
sequence_of_statements
|
||||
K_end K_loop identifier_opt ';'
|
||||
{
|
||||
if($1 && strcmp($1, $6))
|
||||
errormsg(@1, "Loop statement name doesn't match closing name.\n");
|
||||
if($1) delete[]$1;
|
||||
if($6) delete[]$6;
|
||||
|
||||
BasicLoopStatement* tmp = new BasicLoopStatement($3);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
||||
sorrymsg(@1, "Loop statements are not supported");
|
||||
$$ = tmp;
|
||||
};
|
||||
|
||||
mode
|
||||
: K_in { $$ = PORT_IN; }
|
||||
| K_out { $$ = PORT_OUT; }
|
||||
|
|
@ -1278,6 +1338,13 @@ process_sensitivity_list
|
|||
| name_list
|
||||
{ $$ = $1; }
|
||||
;
|
||||
range
|
||||
: simple_expression direction simple_expression
|
||||
{
|
||||
range_t* tmp = new range_t($1, $3, $2);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
relation
|
||||
: shift_expression
|
||||
|
|
@ -1392,6 +1459,7 @@ sequential_statement
|
|||
| signal_assignment_statement { $$ = $1; }
|
||||
| case_statement { $$ = $1; }
|
||||
| procedure_call_statement { $$ = $1; }
|
||||
| loop_statement { $$ = $1; }
|
||||
| K_null ';' { $$ = 0; }
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -66,4 +66,19 @@ class instant_list_t {
|
|||
application_domain_t domain_;
|
||||
std::list<perm_string>* labels_;
|
||||
};
|
||||
|
||||
class range_t {
|
||||
public:
|
||||
range_t(Expression* left, Expression* right, bool dir)
|
||||
: left_(left), right_(right), direction_(dir) {}
|
||||
~range_t() { delete left_; delete right_; }
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
Expression *left_, *right_;
|
||||
bool direction_;
|
||||
private: //not implemented
|
||||
range_t(const range_t&);
|
||||
range_t operator=(const range_t&);
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -152,3 +152,46 @@ ProcedureCall::~ProcedureCall()
|
|||
delete cur;
|
||||
}
|
||||
}
|
||||
|
||||
LoopStatement::LoopStatement(list<SequentialStmt*>* stmts)
|
||||
{
|
||||
if (stmts) stmts_.splice(stmts_.end(), *stmts);
|
||||
}
|
||||
|
||||
LoopStatement::~LoopStatement()
|
||||
{
|
||||
while(stmts_.size() > 0) {
|
||||
SequentialStmt* cur = stmts_.front();
|
||||
stmts_.pop_front();
|
||||
delete cur;
|
||||
}
|
||||
}
|
||||
|
||||
ForLoopStatement::ForLoopStatement(perm_string it, range_t* range, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(stmts), it_(it), range_(range)
|
||||
{
|
||||
}
|
||||
|
||||
ForLoopStatement::~ForLoopStatement()
|
||||
{
|
||||
delete range_;
|
||||
}
|
||||
|
||||
WhileLoopStatement::WhileLoopStatement(ExpLogical* cond, list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(stmts), cond_(cond)
|
||||
{
|
||||
}
|
||||
|
||||
WhileLoopStatement::~WhileLoopStatement()
|
||||
{
|
||||
delete cond_;
|
||||
}
|
||||
|
||||
BasicLoopStatement::BasicLoopStatement(list<SequentialStmt*>* stmts)
|
||||
: LoopStatement(stmts)
|
||||
{
|
||||
}
|
||||
|
||||
BasicLoopStatement::~BasicLoopStatement()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,8 +145,60 @@ class ProcedureCall : public SequentialStmt {
|
|||
int elaborate(Entity*ent, Architecture*arc);
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
std::list<named_expr_t*>* param_list_;
|
||||
};
|
||||
|
||||
class LoopStatement : public SequentialStmt {
|
||||
public:
|
||||
LoopStatement(list<SequentialStmt*>*);
|
||||
virtual ~LoopStatement();
|
||||
|
||||
int elaborate(Entity*ent, Architecture*arc) = 0;
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
protected:
|
||||
std::list<SequentialStmt*> stmts_;
|
||||
};
|
||||
|
||||
class WhileLoopStatement : public LoopStatement {
|
||||
public:
|
||||
WhileLoopStatement(ExpLogical*, list<SequentialStmt*>*);
|
||||
~WhileLoopStatement();
|
||||
|
||||
int elaborate(Entity*ent, Architecture*arc);
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
ExpLogical* cond_;
|
||||
};
|
||||
|
||||
class ForLoopStatement : public LoopStatement {
|
||||
public:
|
||||
ForLoopStatement(perm_string, range_t*, list<SequentialStmt*>*);
|
||||
~ForLoopStatement();
|
||||
|
||||
int elaborate(Entity*ent, Architecture*arc);
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
perm_string it_;
|
||||
range_t* range_;
|
||||
};
|
||||
|
||||
class BasicLoopStatement : public LoopStatement {
|
||||
public:
|
||||
BasicLoopStatement(list<SequentialStmt*>*);
|
||||
~BasicLoopStatement();
|
||||
|
||||
int elaborate(Entity*ent, Architecture*arc);
|
||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -109,3 +109,32 @@ void ProcedureCall::dump(ostream& out, int indent) const
|
|||
(*it)->dump(out, indent);
|
||||
out << ")" << endl;
|
||||
}
|
||||
|
||||
void LoopStatement::dump(ostream&out, int indent) const
|
||||
{
|
||||
for(list<SequentialStmt*>::const_iterator it = stmts_.begin();
|
||||
it != stmts_.end(); ++it)
|
||||
(*it)->dump(out, indent);
|
||||
}
|
||||
|
||||
void ForLoopStatement::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "ForLoopStatement at file=" << get_fileline() << endl;
|
||||
out << setw(indent) << "" << it_ << " in ";
|
||||
range_->dump(out, indent);
|
||||
LoopStatement::dump(out, indent+2);
|
||||
}
|
||||
|
||||
void WhileLoopStatement::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "WhileLoopStatement at file=" << get_fileline() << endl;
|
||||
out << setw(indent) << "" << "condition: ";
|
||||
cond_->dump(out, indent);
|
||||
LoopStatement::dump(out, indent+2);
|
||||
}
|
||||
|
||||
void BasicLoopStatement::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "BasicLoopStatement at file=" << get_fileline() << endl;
|
||||
LoopStatement::dump(out, indent+2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,3 +93,19 @@ int ProcedureCall::elaborate(Entity*, Architecture*)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ForLoopStatement::elaborate(Entity*entity, Architecture*arc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WhileLoopStatement::elaborate(Entity*entity, Architecture*arc)
|
||||
{
|
||||
//TODO:check whether there is any wait statement in the statements (there should be)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BasicLoopStatement::elaborate(Entity*entity, Architecture*arc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,3 +106,35 @@ int ProcedureCall::emit(ostream&out, Entity*, Architecture*)
|
|||
<< "type=" << typeid(*this).name() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||
{
|
||||
out << " // " << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to emit this sequential statement! "
|
||||
<< "type=" << typeid(*this).name() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ForLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||
{
|
||||
out << " // " << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to emit this sequential statement! "
|
||||
<< "type=" << typeid(*this).name() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WhileLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||
{
|
||||
out << " // " << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to emit this sequential statement! "
|
||||
<< "type=" << typeid(*this).name() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BasicLoopStatement::emit(ostream&out, Entity*entity, Architecture*arc)
|
||||
{
|
||||
out << " // " << get_fileline() << ": internal error: "
|
||||
<< "I don't know how to emit this sequential statement! "
|
||||
<< "type=" << typeid(*this).name() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue