diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index e326658cf..fa5deded7 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -1614,14 +1614,8 @@ loop_statement if($1) delete[]$1; if($8) delete[]$8; - ExpLogical* cond = dynamic_cast($3); - if(!cond) { - errormsg(@3, "Iteration condition is not a correct logical expression.\n"); - } - WhileLoopStatement* tmp = new WhileLoopStatement(loop_name, cond, $5); + WhileLoopStatement* tmp = new WhileLoopStatement(loop_name, $3, $5); FILE_NAME(tmp, @1); - - sorrymsg(@1, "Loop statements are not supported.\n"); $$ = tmp; } diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index a0f2878cb..042850426 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -259,7 +259,7 @@ VariableSeqAssignment::~VariableSeqAssignment() delete rval_; } -WhileLoopStatement::WhileLoopStatement(perm_string lname, ExpLogical* cond, list* stmts) +WhileLoopStatement::WhileLoopStatement(perm_string lname, Expression* cond, list* stmts) : LoopStatement(lname, stmts), cond_(cond) { } diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index 4ee14cdb5..89bd38bfd 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -235,14 +235,16 @@ class VariableSeqAssignment : public SequentialStmt { class WhileLoopStatement : public LoopStatement { public: WhileLoopStatement(perm_string loop_name, - ExpLogical*, list*); + Expression*, list*); ~WhileLoopStatement(); int elaborate(Entity*ent, ScopeBase*scope); + int emit(ostream&out, Entity*ent, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void dump(ostream&out, int indent) const; private: - ExpLogical* cond_; + Expression* cond_; }; class ForLoopStatement : public LoopStatement { diff --git a/vhdlpp/sequential_elaborate.cc b/vhdlpp/sequential_elaborate.cc index 3f90f0f9f..4ba864c2b 100644 --- a/vhdlpp/sequential_elaborate.cc +++ b/vhdlpp/sequential_elaborate.cc @@ -22,6 +22,7 @@ # include "scope.h" # include "library.h" # include "subprogram.h" +# include "std_types.h" int SequentialStmt::elaborate(Entity*, ScopeBase*) { @@ -203,10 +204,12 @@ int VariableSeqAssignment::elaborate(Entity*ent, ScopeBase*scope) return errors; } -int WhileLoopStatement::elaborate(Entity*, ScopeBase*) +int WhileLoopStatement::elaborate(Entity*ent, ScopeBase*scope) { - //TODO:check whether there is any wait statement in the statements (there should be) - return 0; + int errors = 0; + errors += elaborate_substatements(ent, scope); + errors += cond_->elaborate_expr(ent, scope, cond_->probe_type(ent, scope)); + return errors; } int BasicLoopStatement::elaborate(Entity*, ScopeBase*) diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index f762288fd..9e122b213 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -355,6 +355,28 @@ void CaseSeqStmt::CaseStmtAlternative::write_to_stream(ostream&fd) } } +int WhileLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) +{ + int errors = 0; + + out << "while("; + errors += cond_->emit(out, ent, scope); + out << ") begin" << endl; + errors += emit_substatements(out, ent, scope); + out << "end" << endl; + + return errors; +} + +void WhileLoopStatement::write_to_stream(ostream&out) +{ + out << "while("; + cond_->write_to_stream(out); + out << ") loop" << endl; + write_to_stream_substatements(out); + out << "end loop;" << endl; +} + int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0;