Elaborate and emit case statements.
This commit is contained in:
parent
cff0deeacc
commit
8003382b3e
|
|
@ -429,18 +429,18 @@ block_declarative_items_opt
|
||||||
: block_declarative_items
|
: block_declarative_items
|
||||||
|
|
|
|
||||||
;
|
;
|
||||||
|
|
||||||
case_statement
|
case_statement
|
||||||
: K_case expression K_is
|
: K_case expression K_is
|
||||||
case_statement_alternative_list
|
case_statement_alternative_list
|
||||||
K_end K_case ';'
|
K_end K_case ';'
|
||||||
{
|
{ CaseSeqStmt* tmp = new CaseSeqStmt($2, $4);
|
||||||
sorrymsg(@1, "Case statement is not yet supported");
|
|
||||||
CaseSeqStmt* tmp = new CaseSeqStmt($2, $4);
|
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
delete $4;
|
delete $4;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
case_statement_alternative_list
|
case_statement_alternative_list
|
||||||
: case_statement_alternative_list case_statement_alternative
|
: case_statement_alternative_list case_statement_alternative
|
||||||
{ std::list<CaseSeqStmt::CaseStmtAlternative*>* tmp = $1;
|
{ std::list<CaseSeqStmt::CaseStmtAlternative*>* tmp = $1;
|
||||||
|
|
@ -448,9 +448,8 @@ case_statement_alternative_list
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| case_statement_alternative
|
| case_statement_alternative
|
||||||
{
|
{ std::list<CaseSeqStmt::CaseStmtAlternative*>*tmp
|
||||||
std::list<CaseSeqStmt::CaseStmtAlternative*>*tmp =
|
= new std::list<CaseSeqStmt::CaseStmtAlternative*>();
|
||||||
new std::list<CaseSeqStmt::CaseStmtAlternative*>();
|
|
||||||
tmp->push_back($1);
|
tmp->push_back($1);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,8 @@ SignalSeqAssignment::~SignalSeqAssignment()
|
||||||
}
|
}
|
||||||
|
|
||||||
CaseSeqStmt::CaseSeqStmt(Expression*cond, list<CaseSeqStmt::CaseStmtAlternative*>* ap)
|
CaseSeqStmt::CaseSeqStmt(Expression*cond, list<CaseSeqStmt::CaseStmtAlternative*>* ap)
|
||||||
: cond_(cond)
|
: cond_(cond)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ap) alt_.splice(alt_.end(), *ap);
|
if (ap) alt_.splice(alt_.end(), *ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +118,14 @@ CaseSeqStmt::~CaseSeqStmt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative() {
|
CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts)
|
||||||
|
: exp_(exp)
|
||||||
|
{
|
||||||
|
if (stmts) stmts_.splice(stmts_.end(), *stmts);
|
||||||
|
}
|
||||||
|
|
||||||
|
CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative()
|
||||||
|
{
|
||||||
delete exp_;
|
delete exp_;
|
||||||
while(stmts_.size() > 0) {
|
while(stmts_.size() > 0) {
|
||||||
SequentialStmt* cur = stmts_.front();
|
SequentialStmt* cur = stmts_.front();
|
||||||
|
|
@ -128,12 +134,6 @@ CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts)
|
|
||||||
: exp_(exp)
|
|
||||||
{
|
|
||||||
if (stmts) stmts_.splice(stmts_.end(), *stmts);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcedureCall::ProcedureCall(perm_string name)
|
ProcedureCall::ProcedureCall(perm_string name)
|
||||||
: name_(name), param_list_(0)
|
: name_(name), param_list_(0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -129,29 +129,29 @@ class CaseSeqStmt : public SequentialStmt {
|
||||||
public:
|
public:
|
||||||
class CaseStmtAlternative : public LineInfo {
|
class CaseStmtAlternative : public LineInfo {
|
||||||
public:
|
public:
|
||||||
CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts);
|
CaseStmtAlternative(Expression* exp, std::list<SequentialStmt*>* stmts);
|
||||||
~CaseStmtAlternative();
|
~CaseStmtAlternative();
|
||||||
void dump(ostream& out, int indent) const;
|
void dump(std::ostream& out, int indent) const;
|
||||||
|
int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype);
|
||||||
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
|
|
||||||
//TODO: implement the following:
|
|
||||||
//int elaborate(Entity*ent, Architecture*arc);
|
|
||||||
//int emit(ostream&out, Entity*entity, Architecture*arc);
|
|
||||||
private:
|
private:
|
||||||
Expression* exp_;
|
Expression* exp_;
|
||||||
list<SequentialStmt*> stmts_;
|
std::list<SequentialStmt*> stmts_;
|
||||||
private: // not implemented
|
private: // not implemented
|
||||||
CaseStmtAlternative(const CaseStmtAlternative&);
|
CaseStmtAlternative(const CaseStmtAlternative&);
|
||||||
CaseStmtAlternative& operator =(const CaseStmtAlternative&);
|
CaseStmtAlternative& operator =(const CaseStmtAlternative&);
|
||||||
};
|
};
|
||||||
CaseSeqStmt(Expression*cond,
|
|
||||||
list<CaseStmtAlternative*>*sp);
|
public:
|
||||||
|
CaseSeqStmt(Expression*cond, std::list<CaseStmtAlternative*>*sp);
|
||||||
~CaseSeqStmt();
|
~CaseSeqStmt();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void dump(ostream&out, int indent) const;
|
void dump(ostream&out, int indent) const;
|
||||||
//TODO: implement the following:
|
int elaborate(Entity*ent, Architecture*arc);
|
||||||
//int elaborate(Entity*ent, Architecture*arc);
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
//int emit(ostream&out, Entity*entity, Architecture*arc);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expression* cond_;
|
Expression* cond_;
|
||||||
|
|
@ -226,4 +226,5 @@ class BasicLoopStatement : public LoopStatement {
|
||||||
int emit(ostream&out, Entity*entity, Architecture*arc);
|
int emit(ostream&out, Entity*entity, Architecture*arc);
|
||||||
void dump(ostream&out, int indent) const;
|
void dump(ostream&out, int indent) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,14 @@ void CaseSeqStmt::dump(ostream& out, int indent) const
|
||||||
void CaseSeqStmt::CaseStmtAlternative::dump(ostream& out, int indent) const
|
void CaseSeqStmt::CaseStmtAlternative::dump(ostream& out, int indent) const
|
||||||
{
|
{
|
||||||
out << setw(indent) << "" << "CaseStmtAlternative at file=" << get_fileline() << endl;
|
out << setw(indent) << "" << "CaseStmtAlternative at file=" << get_fileline() << endl;
|
||||||
|
|
||||||
out << setw(indent) << "" << "when ";
|
out << setw(indent) << "" << "when ";
|
||||||
|
if (exp_)
|
||||||
exp_->dump(out, 0);
|
exp_->dump(out, 0);
|
||||||
for (std::list<SequentialStmt*>::const_iterator cur = stmts_.begin()
|
else
|
||||||
|
out << "others" << endl;
|
||||||
|
|
||||||
|
for (list<SequentialStmt*>::const_iterator cur = stmts_.begin()
|
||||||
; cur != stmts_.end(); ++cur)
|
; cur != stmts_.end(); ++cur)
|
||||||
(*cur)->dump(out, indent+1);
|
(*cur)->dump(out, indent+1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,50 @@ int LoopStatement::elaborate_substatements(Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CaseSeqStmt::elaborate(Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
const VType*ctype = cond_->probe_type(ent, arc);
|
||||||
|
errors += cond_->elaborate_expr(ent, arc, ctype);
|
||||||
|
|
||||||
|
for (list<CaseStmtAlternative*>::iterator cur = alt_.begin()
|
||||||
|
; cur != alt_.end() ; ++cur) {
|
||||||
|
CaseStmtAlternative*curp = *cur;
|
||||||
|
errors += curp->elaborate_expr(ent, arc, ctype);
|
||||||
|
errors += curp->elaborate(ent, arc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method elaborates the case expression for the alternative. The
|
||||||
|
* ltype is the probed type for the main case condition. The
|
||||||
|
* expression needs to elaborate itself in that context.
|
||||||
|
*/
|
||||||
|
int CaseSeqStmt::CaseStmtAlternative::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
if (exp_)
|
||||||
|
errors += exp_->elaborate_expr(ent, arc, ltype);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CaseSeqStmt::CaseStmtAlternative::elaborate(Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
for (list<SequentialStmt*>::iterator cur = stmts_.begin()
|
||||||
|
; cur != stmts_.end() ; ++cur) {
|
||||||
|
SequentialStmt*curp = *cur;
|
||||||
|
errors += curp->elaborate(ent, arc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ForLoopStatement::elaborate(Entity*ent, Architecture*arc)
|
int ForLoopStatement::elaborate(Entity*ent, Architecture*arc)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,60 @@ int LoopStatement::emit_substatements(ostream&out, Entity*ent, Architecture*arc)
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CaseSeqStmt::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
out << "case (";
|
||||||
|
errors += cond_->emit(out, ent, arc);
|
||||||
|
out << ")" << endl;
|
||||||
|
|
||||||
|
for (list<CaseStmtAlternative*>::iterator cur = alt_.begin()
|
||||||
|
; cur != alt_.end() ; ++cur) {
|
||||||
|
CaseStmtAlternative*curp = *cur;
|
||||||
|
errors += curp ->emit(out, ent, arc);
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "endcase" << endl;
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CaseSeqStmt::CaseStmtAlternative::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
if (exp_) {
|
||||||
|
errors += exp_->emit(out, ent, arc);
|
||||||
|
out << ":" << endl;
|
||||||
|
} else {
|
||||||
|
out << "default:" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialStmt*curp;
|
||||||
|
|
||||||
|
switch (stmts_.size()) {
|
||||||
|
case 0:
|
||||||
|
out << "/* no op */;" << endl;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
curp = stmts_.front();
|
||||||
|
errors += curp->emit(out, ent, arc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out << "begin" << endl;
|
||||||
|
for (list<SequentialStmt*>::iterator cur = stmts_.begin()
|
||||||
|
; cur != stmts_.end() ; ++cur) {
|
||||||
|
curp = *cur;
|
||||||
|
errors += curp->emit(out, ent, arc);
|
||||||
|
}
|
||||||
|
out << "end" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
int ForLoopStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
int ForLoopStatement::emit(ostream&out, Entity*ent, Architecture*arc)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue