vhdlpp: Minor ExpConditional refactoring.

Merged cond_ and true_clause_ to else_clause_ list to make
code more generic.
This commit is contained in:
Maciej Suminski 2015-05-21 14:39:53 +02:00
parent ea12c0fe23
commit 49efe6573c
5 changed files with 25 additions and 70 deletions

View File

@ -279,17 +279,9 @@ void ExpCharacter::dump(ostream&out, int indent) const
void ExpConditional::dump(ostream&out, int indent) const void ExpConditional::dump(ostream&out, int indent) const
{ {
out << setw(indent) << "" << "Conditional expression at "<< get_fileline() << endl; out << setw(indent) << "" << "Conditional expression at "<< get_fileline() << endl;
out << setw(indent) << "" << " when:" << endl;
cond_->dump(out, indent+4);
out << setw(indent) << "" << " do:" << endl; for (list<option_t*>::const_iterator cur = options_.begin()
for (list<Expression*>::const_iterator cur = true_clause_.begin() ; cur != options_.end() ; ++cur) {
; cur != true_clause_.end() ; ++cur) {
(*cur)->dump(out, indent+4);
}
for (list<option_t*>::const_iterator cur = else_clause_.begin()
; cur != else_clause_.end() ; ++cur) {
(*cur)->dump(out, indent); (*cur)->dump(out, indent);
} }
} }

View File

@ -301,51 +301,34 @@ void ExpConcat::visit(ExprVisitor& func)
} }
ExpConditional::ExpConditional(Expression*co, list<Expression*>*tru, ExpConditional::ExpConditional(Expression*co, list<Expression*>*tru,
list<ExpConditional::option_t*>*fal) list<ExpConditional::option_t*>*options)
: cond_(co)
{ {
if (tru) true_clause_.splice(true_clause_.end(), *tru); if(co && tru) options_.push_back(new option_t(co, tru));
if (fal) else_clause_.splice(else_clause_.end(), *fal); if(options) options_.splice(options_.end(), *options);
} }
ExpConditional::~ExpConditional() ExpConditional::~ExpConditional()
{ {
delete cond_; while (!options_.empty()) {
while (! true_clause_.empty()) { option_t*tmp = options_.front();
Expression*tmp = true_clause_.front(); options_.pop_front();
true_clause_.pop_front();
delete tmp;
}
while (! else_clause_.empty()) {
option_t*tmp = else_clause_.front();
else_clause_.pop_front();
delete tmp; delete tmp;
} }
} }
Expression*ExpConditional::clone() const Expression*ExpConditional::clone() const
{ {
std::list<Expression*>*new_true_clause = NULL; std::list<option_t*>*new_options = NULL;
if(!true_clause_.empty()) { if(!options_.empty()) {
new_true_clause = new std::list<Expression*>(); new_options = new std::list<option_t*>();
for(std::list<Expression*>::const_iterator it = true_clause_.begin(); for(std::list<option_t*>::const_iterator it = options_.begin();
it != true_clause_.end(); ++it) { it != options_.end(); ++it) {
new_true_clause->push_back((*it)->clone()); new_options->push_back(new option_t(**it));
} }
} }
std::list<option_t*>*new_else_clause = NULL; return new ExpConditional(NULL, NULL, new_options);
if(!else_clause_.empty()) {
new_else_clause = new std::list<option_t*>();
for(std::list<option_t*>::const_iterator it = else_clause_.begin();
it != else_clause_.end(); ++it) {
new_else_clause->push_back(new option_t(**it));
}
}
return new ExpConditional(cond_->clone(), new_true_clause, new_else_clause);
} }
void ExpConditional::visit(ExprVisitor& func) void ExpConditional::visit(ExprVisitor& func)

View File

@ -480,7 +480,7 @@ class ExpConditional : public Expression {
public: public:
ExpConditional(Expression*cond, std::list<Expression*>*tru, ExpConditional(Expression*cond, std::list<Expression*>*tru,
std::list<option_t*>*fal); std::list<option_t*>*options);
~ExpConditional(); ~ExpConditional();
Expression*clone() const; Expression*clone() const;
@ -493,9 +493,7 @@ class ExpConditional : public Expression {
void visit(ExprVisitor& func); void visit(ExprVisitor& func);
private: private:
Expression*cond_; std::list<option_t*> options_;
std::list<Expression*> true_clause_;
std::list<option_t*> else_clause_;
}; };
/* /*

View File

@ -714,15 +714,9 @@ int ExpConditional::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltyp
/* Note that the type for the condition expression need not /* Note that the type for the condition expression need not
have anything to do with the type of this expression. */ have anything to do with the type of this expression. */
errors += cond_->elaborate_expr(ent, scope, 0);
for (list<Expression*>::const_iterator cur = true_clause_.begin() for (list<option_t*>::const_iterator cur = options_.begin()
; cur != true_clause_.end() ; ++cur) { ; cur != options_.end() ; ++cur) {
errors += (*cur)->elaborate_expr(ent, scope, ltype);
}
for (list<option_t*>::const_iterator cur = else_clause_.begin()
; cur != else_clause_.end() ; ++cur) {
errors += (*cur)->elaborate_expr(ent, scope, ltype); errors += (*cur)->elaborate_expr(ent, scope, ltype);
} }

View File

@ -481,39 +481,27 @@ int ExpConditional::emit(ostream&out, Entity*ent, ScopeBase*scope)
{ {
int errors = 0; int errors = 0;
out << "("; out << "(";
errors += cond_->emit(out, ent, scope);
out << ")? (";
if (true_clause_.size() > 1) {
cerr << get_fileline() << ": sorry: Multiple expression waveforms not supported here." << endl;
errors += 1;
}
Expression*tmp = true_clause_.front();
errors += tmp->emit(out, ent, scope);
out << ") : (";
// Draw out any when-else expressions. These are all the else_ // Draw out any when-else expressions. These are all the else_
// clauses besides the last. // clauses besides the last.
if (else_clause_.size() > 1) { if (options_.size() > 1) {
list<option_t*>::iterator last = else_clause_.end(); list<option_t*>::iterator last = options_.end();
--last; --last;
for (list<option_t*>::iterator cur = else_clause_.begin() for (list<option_t*>::iterator cur = options_.begin()
; cur != last ; ++cur) { ; cur != last ; ++cur) {
errors += (*cur) ->emit_when_else(out, ent, scope); errors += (*cur) ->emit_when_else(out, ent, scope);
} }
} }
errors += else_clause_.back()->emit_else(out, ent, scope); errors += options_.back()->emit_else(out, ent, scope);
out << ")"; out << ")";
// The emit_when_else() functions do not close the last // The emit_when_else() functions do not close the last
// parentheses so that the following expression can be // parentheses so that the following expression can be
// nested. But that means come the end, we have some // nested. But that means come the end, we have some
// expressions to close. // expressions to close.
for (size_t idx = 1 ; idx < else_clause_.size() ; idx += 1) for (size_t idx = 1 ; idx < options_.size() ; idx += 1)
out << ")"; out << ")";
return errors; return errors;