Parse attributes on statements within event statements.

Statements can have attributes attached to them. Handle a few cases in
the parser where attributes may be attached to statements, and get them
as far as the pform.
This commit is contained in:
Stephen Williams 2008-09-04 21:27:21 -07:00
parent 7beb059d90
commit 6f002935d7
5 changed files with 71 additions and 60 deletions

View File

@ -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<perm_string,PExpr*> attributes;
};
/*

58
parse.y
View File

@ -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

View File

@ -157,6 +157,19 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt)
return block;
}
void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
svector<named_pexpr_t*>*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;

View File

@ -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<perm_string,PExpr*>&attributes,
svector<named_pexpr_t*>*attr);
/* The lexor calls this function to change the default nettype. */
extern void pform_set_default_nettype(NetNet::Type net,

View File

@ -155,6 +155,21 @@ std::ostream& operator << (std::ostream&out, ddomain_t dom)
return out;
}
static void dump_attributes_map(ostream&out,
const map<perm_string,PExpr*>&attributes,
int ind)
{
for (map<perm_string,PExpr*>::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<perm_string,PExpr*>::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<perm_string,PExpr*>::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<perm_string,PExpr*>::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);
}