diff --git a/Statement.h b/Statement.h index bcc033937..10def60d2 100644 --- a/Statement.h +++ b/Statement.h @@ -82,6 +82,8 @@ class Statement : public LineInfo { virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; + + map attributes; }; /* diff --git a/parse.y b/parse.y index 4f02bafc7..200a9103e 100644 --- a/parse.y +++ b/parse.y @@ -3591,28 +3591,31 @@ statement FILE_NAME(tmp, @1); $$ = tmp; } - | event_control statement_or_null - { PEventStatement*tmp = $1; - if (tmp == 0) { - yyerror(@1, "error: Invalid event control."); - $$ = 0; - } else { - tmp->set_statement($2); - $$ = tmp; - } - } - | '@' '*' statement_or_null - { PEventStatement*tmp = new PEventStatement; - FILE_NAME(tmp, @1); - tmp->set_statement($3); - $$ = tmp; - } - | '@' '(' '*' ')' statement_or_null - { PEventStatement*tmp = new PEventStatement; - FILE_NAME(tmp, @1); - tmp->set_statement($5); - $$ = tmp; - } + | event_control attribute_list_opt statement_or_null + { PEventStatement*tmp = $1; + if (tmp == 0) { + yyerror(@1, "error: Invalid event control."); + $$ = 0; + } else { + if ($3) pform_bind_attributes($3->attributes,$2); + tmp->set_statement($3); + $$ = tmp; + } + } + | '@' '*' attribute_list_opt statement_or_null + { PEventStatement*tmp = new PEventStatement; + FILE_NAME(tmp, @1); + if ($4) pform_bind_attributes($4->attributes,$3); + tmp->set_statement($4); + $$ = tmp; + } + | '@' '(' '*' ')' attribute_list_opt statement_or_null + { PEventStatement*tmp = new PEventStatement; + FILE_NAME(tmp, @1); + if ($6) pform_bind_attributes($6->attributes,$5); + tmp->set_statement($6); + $$ = tmp; + } | lpvalue '=' expression ';' { PAssign*tmp = new PAssign($1,$3); FILE_NAME(tmp, @1); @@ -3737,14 +3740,15 @@ statement_list ; statement_or_null - : statement - | ';' { $$ = 0; } - ; - + : statement + { $$ = $1; } + | ';' + { $$ = 0; } + ; analog_statement : branch_probe_expression K_CONTRIBUTE expression ';' - { $$ = pform_contribution_statement(@2, $1, $3); } + { $$ = pform_contribution_statement(@2, $1, $3); } ; /* Task items are, other than the statement, task port items and diff --git a/pform.cc b/pform.cc index 51d80236b..c0b1156e4 100644 --- a/pform.cc +++ b/pform.cc @@ -157,6 +157,19 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt) return block; } +void pform_bind_attributes(map&attributes, + svector*attr) +{ + if (attr == 0) + return; + + for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { + named_pexpr_t*tmp = (*attr)[idx]; + attributes[tmp->name] = tmp->parm; + } + delete attr; +} + PWire*pform_get_wire_in_scope(perm_string name) { /* Note that if we are processing a generate, then the @@ -1951,13 +1964,7 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st, { PProcess*pp = new PProcess(type, st); - if (attr) { - for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { - named_pexpr_t*tmp = (*attr)[idx]; - pp->attributes[tmp->name] = tmp->parm; - } - delete attr; - } + pform_bind_attributes(pp->attributes, attr); pform_put_behavior_in_scope(pp); return pp; diff --git a/pform.h b/pform.h index 68d439396..455178804 100644 --- a/pform.h +++ b/pform.h @@ -117,6 +117,10 @@ struct lgate { unsigned lineno; }; + /* Use this function to transform the parted form of the attribute + list to the attribute map that is used later. */ +extern void pform_bind_attributes(map&attributes, + svector*attr); /* The lexor calls this function to change the default nettype. */ extern void pform_set_default_nettype(NetNet::Type net, diff --git a/pform_dump.cc b/pform_dump.cc index cb35237e8..fbda728a3 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -155,6 +155,21 @@ std::ostream& operator << (std::ostream&out, ddomain_t dom) return out; } +static void dump_attributes_map(ostream&out, + const map&attributes, + int ind) +{ + for (map::const_iterator idx = attributes.begin() + ; idx != attributes.end() ; idx++ ) { + + out << setw(ind) << "" << "(* " << (*idx).first; + if ((*idx).second) { + out << " = " << *(*idx).second; + } + out << " *)" << endl; + } +} + void PExpr::dump(ostream&out) const { out << typeid(*this).name(); @@ -360,14 +375,7 @@ void PWire::dump(ostream&out, unsigned ind) const } out << ";" << endl; - for (map::const_iterator idx = attributes.begin() - ; idx != attributes.end() - ; idx ++) { - out << " " << (*idx).first; - if ((*idx).second) - out << " = " << *(*idx).second; - out << endl; - } + dump_attributes_map(out, attributes, 8); } void PGate::dump_pins(ostream&out) const @@ -538,6 +546,7 @@ void Statement::dump(ostream&out, unsigned ind) const out << setw(ind) << ""; out << "/* " << get_fileline() << ": " << typeid(*this).name() << " */ ;" << endl; + dump_attributes_map(out, attributes, ind+2); } void AStatement::dump(ostream&out, unsigned ind) const @@ -631,6 +640,7 @@ void PCase::dump(ostream&out, unsigned ind) const break; } out << " (" << *expr_ << ") /* " << get_fileline() << " */" << endl; + dump_attributes_map(out, attributes, ind+2); for (unsigned idx = 0 ; idx < items_->count() ; idx += 1) { PCase::Item*cur = (*items_)[idx]; @@ -879,15 +889,7 @@ void PProcess::dump(ostream&out, unsigned ind) const out << " /* " << get_fileline() << " */" << endl; - for (map::const_iterator idx = attributes.begin() - ; idx != attributes.end() ; idx++ ) { - - out << setw(ind+2) << "" << "(* " << (*idx).first; - if ((*idx).second) { - out << " = " << *(*idx).second; - } - out << " *)" << endl; - } + dump_attributes_map(out, attributes, ind+2); statement_->dump(out, ind+2); } @@ -905,15 +907,7 @@ void AProcess::dump(ostream&out, unsigned ind) const out << " /* " << get_fileline() << " */" << endl; - for (map::const_iterator idx = attributes.begin() - ; idx != attributes.end() ; idx++ ) { - - out << setw(ind+2) << "" << "(* " << (*idx).first; - if ((*idx).second) { - out << " = " << *(*idx).second; - } - out << " *)" << endl; - } + dump_attributes_map(out, attributes, ind+2); statement_->dump(out, ind+2); }