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:
parent
7beb059d90
commit
6f002935d7
|
|
@ -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
58
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
|
||||
|
|
|
|||
21
pform.cc
21
pform.cc
|
|
@ -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;
|
||||
|
|
|
|||
4
pform.h
4
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<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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue