diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index d3229d9ff..06fff7b8d 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -45,6 +45,7 @@ class SequentialStmt : public LineInfo { virtual int elaborate(Entity*ent, ScopeBase*scope); virtual int emit(ostream&out, Entity*entity, ScopeBase*scope); virtual void dump(ostream&out, int indent) const; + virtual void write_to_stream(std::ostream&fd); // Recursively visits a tree of sequential statements. virtual void visit(SeqStmtVisitor& func) { func(this); } @@ -67,6 +68,7 @@ class LoopStatement : public SequentialStmt { protected: int elaborate_substatements(Entity*ent, ScopeBase*scope); int emit_substatements(std::ostream&out, Entity*ent, ScopeBase*scope); + void write_to_stream_substatements(ostream&fd); private: perm_string name_; @@ -85,6 +87,9 @@ class IfSequential : public SequentialStmt { int condition_emit(ostream&out, Entity*entity, ScopeBase*scope); int statement_emit(ostream&out, Entity*entity, ScopeBase*scope); + void condition_write_to_stream(ostream&fd); + void statement_write_to_stream(ostream&fd); + void dump(ostream&out, int indent) const; void visit(SeqStmtVisitor& func); @@ -105,6 +110,7 @@ class IfSequential : public SequentialStmt { public: int elaborate(Entity*ent, ScopeBase*scope); int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void dump(ostream&out, int indent) const; void visit(SeqStmtVisitor& func); @@ -131,6 +137,7 @@ class ReturnStmt : public SequentialStmt { public: int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void dump(ostream&out, int indent) const; const Expression*peek_expr() const { return val_; }; @@ -148,6 +155,7 @@ class SignalSeqAssignment : public SequentialStmt { public: int elaborate(Entity*ent, ScopeBase*scope); int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void dump(ostream&out, int indent) const; private: @@ -165,6 +173,7 @@ class CaseSeqStmt : public SequentialStmt { int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); int elaborate(Entity*ent, ScopeBase*scope); int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void visit(SeqStmtVisitor& func); private: @@ -183,6 +192,7 @@ class CaseSeqStmt : public SequentialStmt { void dump(ostream&out, int indent) const; int elaborate(Entity*ent, ScopeBase*scope); int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void visit(SeqStmtVisitor& func); private: @@ -213,6 +223,7 @@ class VariableSeqAssignment : public SequentialStmt { public: int elaborate(Entity*ent, ScopeBase*scope); int emit(ostream&out, Entity*entity, ScopeBase*scope); + void write_to_stream(std::ostream&fd); void dump(ostream&out, int indent) const; private: @@ -227,7 +238,6 @@ class WhileLoopStatement : public LoopStatement { ~WhileLoopStatement(); int elaborate(Entity*ent, ScopeBase*scope); - int emit(ostream&out, Entity*entity, ScopeBase*scope); void dump(ostream&out, int indent) const; private: @@ -242,6 +252,7 @@ class ForLoopStatement : public LoopStatement { 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: @@ -259,7 +270,6 @@ class BasicLoopStatement : public LoopStatement { ~BasicLoopStatement(); int elaborate(Entity*ent, ScopeBase*scope); - int emit(ostream&out, Entity*entity, ScopeBase*scope); void dump(ostream&out, int indent) const; }; diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index 44846a69d..36e784a4e 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -1,6 +1,8 @@ /* * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) + * Copyright CERN 2015 + * @author Maciej Suminski (maciej.suminski@cern.ch) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -35,6 +37,13 @@ int SequentialStmt::emit(ostream&out, Entity*, ScopeBase*) return 1; } +void SequentialStmt::write_to_stream(std::ostream&fd) +{ + fd << " // " << get_fileline() << ": internal error: " + << "I don't know how to write_to_stream this sequential statement! " + << "type=" << typeid(*this).name() << endl; +} + int IfSequential::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -67,6 +76,35 @@ int IfSequential::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void IfSequential::write_to_stream(std::ostream&fd) +{ + fd << "if "; + cond_->write_to_stream(fd); + fd << " then " << endl; + + for (list::iterator cur = if_.begin() + ; cur != if_.end() ; ++cur) + (*cur)->write_to_stream(fd); + + for (list::iterator cur = elsif_.begin() + ; cur != elsif_.end() ; ++cur) { + fd << "elsif "; + (*cur)->condition_write_to_stream(fd); + fd << " " << endl; + (*cur)->statement_write_to_stream(fd); + } + + if (! else_.empty()) { + fd << " else " << endl; + + for (list::iterator cur = else_.begin() + ; cur != else_.end() ; ++cur) + (*cur)->write_to_stream(fd); + } + + fd << "end if;" << endl; +} + int IfSequential::Elsif::condition_emit(ostream&out, Entity*ent, ScopeBase*scope) { return cond_->emit(out, ent, scope); @@ -83,6 +121,18 @@ int IfSequential::Elsif::statement_emit(ostream&out, Entity*ent, ScopeBase*scope return errors; } +void IfSequential::Elsif::condition_write_to_stream(ostream&fd) +{ + cond_->write_to_stream(fd); +} + +void IfSequential::Elsif::statement_write_to_stream(ostream&fd) +{ + for (list::iterator cur = if_.begin() + ; cur != if_.end() ; ++cur) + (*cur)->write_to_stream(fd); +} + int ReturnStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -92,6 +142,13 @@ int ReturnStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void ReturnStmt::write_to_stream(ostream&fd) +{ + fd << "return "; + val_->write_to_stream(fd); + fd << ";" << endl; +} + int SignalSeqAssignment::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -112,6 +169,21 @@ int SignalSeqAssignment::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void SignalSeqAssignment::write_to_stream(ostream&fd) +{ + lval_->write_to_stream(fd); + + if (waveform_.size() != 1) { + fd << "-- Confusing waveform?" << endl; + + } else { + Expression*tmp = waveform_.front(); + fd << " <= "; + tmp->write_to_stream(fd); + fd << ";" << endl; + } +} + int VariableSeqAssignment::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -125,6 +197,14 @@ int VariableSeqAssignment::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void VariableSeqAssignment::write_to_stream(ostream&fd) +{ + lval_->write_to_stream(fd); + fd << " := "; + rval_->write_to_stream(fd); + fd << ";" << endl; +} + int ProcedureCall::emit(ostream&out, Entity*, ScopeBase*) { out << " // " << get_fileline() << ": internal error: " @@ -144,6 +224,15 @@ int LoopStatement::emit_substatements(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void LoopStatement::write_to_stream_substatements(ostream&fd) +{ + for (list::iterator cur = stmts_.begin() + ; cur != stmts_.end() ; ++cur) { + SequentialStmt*tmp = *cur; + tmp->write_to_stream(fd); + } +} + int CaseSeqStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -163,6 +252,21 @@ int CaseSeqStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void CaseSeqStmt::write_to_stream(ostream&fd) +{ + fd << "case "; + cond_->write_to_stream(fd); + fd << " is" << endl; + + for (list::iterator cur = alt_.begin() + ; cur != alt_.end() ; ++cur) { + CaseStmtAlternative*curp = *cur; + curp ->write_to_stream(fd); + } + + fd << "end case;" << endl; +} + int CaseSeqStmt::CaseStmtAlternative::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -198,6 +302,22 @@ int CaseSeqStmt::CaseStmtAlternative::emit(ostream&out, Entity*ent, ScopeBase*sc return errors; } +void CaseSeqStmt::CaseStmtAlternative::write_to_stream(ostream&fd) +{ + fd << "when "; + if (exp_) { + exp_->write_to_stream(fd); + } else { + fd << "others" << endl; + } + fd << "=>" << endl; + + for (list::iterator cur = stmts_.begin() + ; cur != stmts_.end() ; ++cur) { + (*cur)->write_to_stream(fd); + } +} + int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -238,7 +358,8 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) } else { out << "begin /* Degenerate loop at " << get_fileline() << ": " << start_val - << " downto " << finish_val << " */ end" << endl; + << " downto " << finish_val << " */ end" << endl + << "end" << endl; return errors; } } @@ -249,7 +370,8 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) } else { out << "begin /* Degenerate loop at " << get_fileline() << ": " << start_val - << " to " << finish_val << " */ end" << endl; + << " to " << finish_val << " */ end" << endl + << "end" << endl; return errors; } } @@ -279,6 +401,17 @@ int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) return errors; } +void ForLoopStatement::write_to_stream(ostream&fd) +{ + fd << "for " << it_ << " in "; + range_->expr_left()->write_to_stream(fd); + fd << " to "; + range_->expr_right()->write_to_stream(fd); + fd << " loop" << endl; + write_to_stream_substatements(fd); + fd << "end loop;" << endl; +} + int ForLoopStatement::emit_runtime_(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; @@ -303,19 +436,3 @@ int ForLoopStatement::emit_runtime_(ostream&out, Entity*ent, ScopeBase*scope) return errors; } - -int WhileLoopStatement::emit(ostream&out, Entity*, ScopeBase*) -{ - 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*, ScopeBase*) -{ - out << " // " << get_fileline() << ": internal error: " - << "I don't know how to emit this sequential statement! " - << "type=" << typeid(*this).name() << endl; - return 1; -}