From 442750ca2c1d2cee567b760fb0bc37f716787996 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 4 Dec 2015 17:44:35 +0100 Subject: [PATCH] vhdlpp: Refactored {Report,Assert}Stmt so they handle expressions instead of strings. --- vhdlpp/parse.y | 5 ++--- vhdlpp/sequential.cc | 12 +++++------- vhdlpp/sequential.h | 13 ++++++++----- vhdlpp/sequential_debug.cc | 16 ++++++++++++---- vhdlpp/sequential_elaborate.cc | 10 +++++++++- vhdlpp/sequential_emit.cc | 22 +++++++++++++--------- 6 files changed, 49 insertions(+), 29 deletions(-) diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 0c6884253..557284ad4 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -452,7 +452,7 @@ assertion_statement : K_assert expression report_statement { ReportStmt*report = dynamic_cast($3); assert(report); - AssertStmt*tmp = new AssertStmt($2, report->message().c_str(), report->severity()); + AssertStmt*tmp = new AssertStmt($2, report->message(), report->severity()); delete report; FILE_NAME(tmp,@2); $$ = tmp; @@ -2185,10 +2185,9 @@ relation ; report_statement - : K_report STRING_LITERAL severity_opt ';' + : K_report expression severity_opt ';' { ReportStmt*tmp = new ReportStmt($2, $3); FILE_NAME(tmp,@2); - delete[]$2; $$ = tmp; } diff --git a/vhdlpp/sequential.cc b/vhdlpp/sequential.cc index 042850426..f3c1d1c4a 100644 --- a/vhdlpp/sequential.cc +++ b/vhdlpp/sequential.cc @@ -278,26 +278,24 @@ BasicLoopStatement::~BasicLoopStatement() { } -ReportStmt::ReportStmt(const char*msg, severity_t sev) +ReportStmt::ReportStmt(Expression*msg, severity_t sev) : msg_(msg), severity_(sev) { if(sev == ReportStmt::UNSPECIFIED) severity_ = ReportStmt::NOTE; } -AssertStmt::AssertStmt(Expression*condition, const char*msg, ReportStmt::severity_t sev) -: ReportStmt("", sev), cond_(condition) +AssertStmt::AssertStmt(Expression*condition, Expression*msg, ReportStmt::severity_t sev) +: ReportStmt(msg, sev), cond_(condition) { if(msg == NULL) - msg_ = default_msg_; - else - msg_ = std::string(msg); + msg_ = new ExpString(default_msg_); if(sev == ReportStmt::UNSPECIFIED) severity_ = ReportStmt::ERROR; } -const std::string AssertStmt::default_msg_ = std::string("Assertion violation."); +const char*AssertStmt::default_msg_ = "Assertion violation."; WaitForStmt::WaitForStmt(Expression*delay) : delay_(delay) diff --git a/vhdlpp/sequential.h b/vhdlpp/sequential.h index a952981c0..2ddd00fd4 100644 --- a/vhdlpp/sequential.h +++ b/vhdlpp/sequential.h @@ -280,24 +280,27 @@ class ReportStmt : public SequentialStmt { public: typedef enum { UNSPECIFIED, NOTE, WARNING, ERROR, FAILURE } severity_t; - ReportStmt(const char*message, severity_t severity = NOTE); + ReportStmt(Expression*message, severity_t severity); virtual ~ReportStmt() {} 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); - inline const std::string& message() const { return msg_; } + inline Expression*message() const { return msg_; } inline severity_t severity() const { return severity_; } protected: - std::string msg_; + void dump_sev_msg(ostream&out, int indent) const; + + Expression*msg_; severity_t severity_; }; class AssertStmt : public ReportStmt { public: - AssertStmt(Expression*condition, const char*message, + AssertStmt(Expression*condition, Expression*message, ReportStmt::severity_t severity = ReportStmt::ERROR); void dump(ostream&out, int indent) const; @@ -309,7 +312,7 @@ class AssertStmt : public ReportStmt { Expression*cond_; // Message displayed when there is no report assigned. - static const std::string default_msg_; + static const char*default_msg_; }; class WaitForStmt : public SequentialStmt { diff --git a/vhdlpp/sequential_debug.cc b/vhdlpp/sequential_debug.cc index 149021440..7abb63d6f 100644 --- a/vhdlpp/sequential_debug.cc +++ b/vhdlpp/sequential_debug.cc @@ -169,16 +169,24 @@ void BasicLoopStatement::dump(ostream&out, int indent) const void ReportStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ReportStmt at file=" << get_fileline() << endl; - out << setw(indent+3) << "" << "severity: " << severity_ << endl; - out << setw(indent+3) << "" << "message: " << msg_ << endl; + dump_sev_msg(out, indent+3); +} + +void ReportStmt::dump_sev_msg(ostream&out, int indent) const +{ + out << setw(indent) << "" << "severity: " << severity_ << endl; + + if(msg_) { + out << setw(indent) << "" << "message: "; + msg_->dump(out, indent); + } } void AssertStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "AssertStmt at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "condition: "; - cond_->dump(out, indent+3); - ReportStmt::dump(out, indent+3); + dump_sev_msg(out, indent+3); } void WaitForStmt::dump(ostream&out, int indent) const diff --git a/vhdlpp/sequential_elaborate.cc b/vhdlpp/sequential_elaborate.cc index 4b033c6e5..98b8766c0 100644 --- a/vhdlpp/sequential_elaborate.cc +++ b/vhdlpp/sequential_elaborate.cc @@ -217,9 +217,17 @@ int BasicLoopStatement::elaborate(Entity*, ScopeBase*) return 0; } +int ReportStmt::elaborate(Entity*ent, ScopeBase*scope) +{ + return msg_->elaborate_expr(ent, scope, &primitive_STRING); +} + int AssertStmt::elaborate(Entity*ent, ScopeBase*scope) { - return cond_->elaborate_expr(ent, scope, cond_->probe_type(ent, scope)); + int errors = 0; + errors += ReportStmt::elaborate(ent, scope); + errors += cond_->elaborate_expr(ent, scope, cond_->probe_type(ent, scope)); + return errors; } int WaitForStmt::elaborate(Entity*ent, ScopeBase*scope) diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index 9e122b213..8c2ea1fa7 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -496,21 +496,23 @@ int ForLoopStatement::emit_runtime_(ostream&out, Entity*ent, ScopeBase*scope) return errors; } -int ReportStmt::emit(ostream&out, Entity*, ScopeBase*) +int ReportStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { - out << "$display(\""; + out << "$display(\"** "; switch(severity_) { - case NOTE: out << "** Note: "; break; - case WARNING: out << "** Warning: "; break; - case ERROR: out << "** Error: "; break; - case FAILURE: out << "** Failure: "; break; + case NOTE: out << "Note"; break; + case WARNING: out << "Warning"; break; + case ERROR: out << "Error"; break; + case FAILURE: out << "Failure"; break; case UNSPECIFIED: ivl_assert(*this, false); break; } - out << ExpString::escape_quot(msg_); - out << " (" << get_fileline() << ")\");"; + out << ": \","; + + msg_->emit(out, ent, scope); + out << ",\" (" << get_fileline() << ")\");"; if(severity_ == FAILURE) out << "$finish();"; @@ -522,7 +524,9 @@ int ReportStmt::emit(ostream&out, Entity*, ScopeBase*) void ReportStmt::write_to_stream(std::ostream&fd) { - fd << "report \"" << ExpString::escape_quot(msg_) << "\"" << std::endl; + fd << "report \""; + msg_->write_to_stream(fd); + fd << "\"" << std::endl; fd << "severity "; switch(severity_)