Elaborate and emit case statements.

This commit is contained in:
Stephen Williams 2011-10-01 11:45:28 -07:00
parent cff0deeacc
commit 8003382b3e
6 changed files with 153 additions and 50 deletions

View File

@ -429,30 +429,29 @@ 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"); FILE_NAME(tmp, @1);
CaseSeqStmt* tmp = new CaseSeqStmt($2, $4); delete $4;
FILE_NAME(tmp, @1); $$ = tmp;
delete $4;
$$ = 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;
tmp->push_back($2); tmp->push_back($2);
$$ = 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;
} }
; ;

View File

@ -102,38 +102,38 @@ SignalSeqAssignment::~SignalSeqAssignment()
delete lval_; delete lval_;
} }
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);
} }
CaseSeqStmt::~CaseSeqStmt() CaseSeqStmt::~CaseSeqStmt()
{ {
delete cond_; delete cond_;
while(alt_.size() > 0) { while(alt_.size() > 0) {
CaseSeqStmt::CaseStmtAlternative* cur = alt_.front(); CaseSeqStmt::CaseStmtAlternative* cur = alt_.front();
alt_.pop_front(); alt_.pop_front();
delete cur; delete cur;
} }
}
CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative() {
delete exp_;
while(stmts_.size() > 0) {
SequentialStmt* cur = stmts_.front();
stmts_.pop_front();
delete cur;
}
} }
CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts) CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(Expression* exp, list<SequentialStmt*>* stmts)
: exp_(exp) : exp_(exp)
{ {
if (stmts) stmts_.splice(stmts_.end(), *stmts); if (stmts) stmts_.splice(stmts_.end(), *stmts);
} }
CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative()
{
delete exp_;
while(stmts_.size() > 0) {
SequentialStmt* cur = stmts_.front();
stmts_.pop_front();
delete cur;
}
}
ProcedureCall::ProcedureCall(perm_string name) ProcedureCall::ProcedureCall(perm_string name)
: name_(name), param_list_(0) : name_(name), param_list_(0)
{ {

View File

@ -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

View File

@ -92,12 +92,17 @@ 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 ";
exp_->dump(out, 0); out << setw(indent) << "" << "when ";
for (std::list<SequentialStmt*>::const_iterator cur = stmts_.begin() if (exp_)
; cur != stmts_.end(); ++cur) exp_->dump(out, 0);
(*cur)->dump(out, indent+1); else
out << "others" << endl;
for (list<SequentialStmt*>::const_iterator cur = stmts_.begin()
; cur != stmts_.end(); ++cur)
(*cur)->dump(out, indent+1);
} }
void ProcedureCall::dump(ostream& out, int indent) const void ProcedureCall::dump(ostream& out, int indent) const

View File

@ -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;

View File

@ -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;