Enumeration element values can be expressions

Allow more complex enumeration expressions, which means putting
off the evaluation of the expression values until elaboration.
This commit is contained in:
Stephen Williams 2010-11-12 18:47:06 -08:00
parent 2f474358d9
commit 27dfdf99dd
7 changed files with 188 additions and 213 deletions

View File

@ -226,12 +226,40 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
scope->add_enumeration_set(use_enum); scope->add_enumeration_set(use_enum);
for (list<named_number_t>::const_iterator cur = enum_type->names->begin() verinum cur_value (0);
verinum one_value (1);
for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin()
; cur != enum_type->names->end() ; ++ cur) { ; cur != enum_type->names->end() ; ++ cur) {
if (cur->parm) {
// There is an explicit value. elaborate/evaluate
// the value and assign it to the enumeration name.
NetExpr*val = elab_and_eval(des, scope, cur->parm, -1);
NetEConst*val_const = dynamic_cast<NetEConst*> (val);
if (val_const == 0) {
cerr << "<>:0: error: Enumeration expression is not constant." << endl;
des->errors += 1;
continue;
}
cur_value = val_const->value();
if (enum_type->base_type==IVL_VT_BOOL && ! cur_value.is_defined()) {
cerr << "<>:0: error: Enumeration name " << cur->name
<< " cannot have a logic value." << endl;
des->errors += 1;
}
} else if (! cur_value.is_defined()) {
cerr << "<>:0: error: Enumeration name " << cur->name
<< " cannot have an inferred value." << endl;
des->errors += 1;
continue;
}
// The values are explicitly sized to the width of the // The values are explicitly sized to the width of the
// base type of the enumeration. // base type of the enumeration.
verinum tmp_val (cur->parm, use_enum->base_width()); verinum tmp_val (cur_value, use_enum->base_width());
tmp_val.has_sign(enum_type->signed_flag); tmp_val.has_sign(enum_type->signed_flag);
rc_flag = use_enum->insert_name(cur->name, tmp_val); rc_flag = use_enum->insert_name(cur->name, tmp_val);
@ -240,6 +268,11 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
cerr << "<>:0: error: Duplicate enumeration name " << cur->name << endl; cerr << "<>:0: error: Duplicate enumeration name " << cur->name << endl;
des->errors += 1; des->errors += 1;
} }
// In case the next name has an implicit value,
// increment the current value by one.
if (cur_value.is_defined())
cur_value = cur_value + one_value;
} }
} }

View File

@ -1102,7 +1102,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
// the new signal. This turns it into an enumeration. // the new signal. This turns it into an enumeration.
if (enum_type_) { if (enum_type_) {
ivl_assert(*this, enum_type_->names->size() > 0); ivl_assert(*this, enum_type_->names->size() > 0);
list<named_number_t>::const_iterator sample_name = enum_type_->names->begin(); list<named_pexpr_t>::const_iterator sample_name = enum_type_->names->begin();
netenum_t*use_enum = scope->enumeration_for_name(sample_name->name); netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
sig->set_enumeration(use_enum); sig->set_enumeration(use_enum);
} }

195
parse.y
View File

@ -193,35 +193,26 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
return tmp; return tmp;
} }
static list<named_number_t>* make_named_number(perm_string name) static list<named_pexpr_t>* make_named_numbers(perm_string name, long first, long last, PExpr*val =0)
{ {
list<named_number_t>*lst = new list<named_number_t>; list<named_pexpr_t>*lst = new list<named_pexpr_t>;
named_number_t tmp; named_pexpr_t tmp;
tmp.name = name;
lst->push_back(tmp);
return lst;
}
static list<named_number_t>* make_named_numbers(perm_string name, long first, long last, verinum*val =0)
{
list<named_number_t>*lst = new list<named_number_t>;
named_number_t tmp;
assert(first <= last); assert(first <= last);
for (long idx = first ; idx <= last ; idx += 1) { for (long idx = first ; idx <= last ; idx += 1) {
ostringstream buf; ostringstream buf;
buf << name.str() << idx << ends; buf << name.str() << idx << ends;
tmp.name = lex_strings.make(buf.str()); tmp.name = lex_strings.make(buf.str());
tmp.parm = val ? *val : verinum(); tmp.parm = val;
val = 0; val = 0;
lst->push_back(tmp); lst->push_back(tmp);
} }
return lst; return lst;
} }
static list<named_number_t>* make_named_number(perm_string name, const verinum&val) static list<named_pexpr_t>* make_named_number(perm_string name, PExpr*val =0)
{ {
list<named_number_t>*lst = new list<named_number_t>; list<named_pexpr_t>*lst = new list<named_pexpr_t>;
named_number_t tmp; named_pexpr_t tmp;
tmp.name = name; tmp.name = name;
tmp.parm = val; tmp.parm = val;
lst->push_back(tmp); lst->push_back(tmp);
@ -267,7 +258,7 @@ static list<named_number_t>* make_named_number(perm_string name, const verinum&v
list<named_number_t>* named_numbers; list<named_number_t>* named_numbers;
named_pexpr_t*named_pexpr; named_pexpr_t*named_pexpr;
svector<named_pexpr_t*>*named_pexprs; list<named_pexpr_t>*named_pexprs;
struct parmvalue_t*parmvalue; struct parmvalue_t*parmvalue;
PExpr*expr; PExpr*expr;
@ -418,7 +409,7 @@ static list<named_number_t>* make_named_number(perm_string name, const verinum&v
%type <value_range> parameter_value_ranges_opt %type <value_range> parameter_value_ranges_opt
%type <expr> value_range_expression %type <expr> value_range_expression
%type <named_numbers> enum_name_list enum_name %type <named_pexprs> enum_name_list enum_name
%type <enum_type> enum_data_type %type <enum_type> enum_data_type
%type <wires> task_item task_item_list task_item_list_opt %type <wires> task_item task_item_list task_item_list_opt
@ -531,18 +522,19 @@ attribute_list_opt
; ;
attribute_list attribute_list
: attribute_list ',' attribute : attribute_list ',' attribute
{ svector<named_pexpr_t*>*tmp = { list<named_pexpr_t>*tmp = $1;
new svector<named_pexpr_t*>(*$1,$3); tmp->push_back(*$3);
delete $1; delete $3;
$$ = tmp; $$ = tmp;
} }
| attribute | attribute
{ svector<named_pexpr_t*>*tmp = new svector<named_pexpr_t*>(1); { list<named_pexpr_t>*tmp = new list<named_pexpr_t>;
(*tmp)[0] = $1; tmp->push_back(*$1);
$$ = tmp; delete $1;
} $$ = tmp;
; }
;
attribute attribute
@ -719,7 +711,7 @@ enum_name_list
{ $$ = $1; { $$ = $1;
} }
| enum_name_list ',' enum_name | enum_name_list ',' enum_name
{ list<named_number_t>*lst = $1; { list<named_pexpr_t>*lst = $1;
lst->splice(lst->end(), *$3); lst->splice(lst->end(), *$3);
delete $3; delete $3;
$$ = lst; $$ = lst;
@ -746,27 +738,24 @@ enum_name
delete $3; delete $3;
delete $5; delete $5;
} }
| IDENTIFIER '=' number | IDENTIFIER '=' expression
{ perm_string name = lex_strings.make($1); { perm_string name = lex_strings.make($1);
delete[]$1; delete[]$1;
$$ = make_named_number(name, *$3); $$ = make_named_number(name, $3);
delete $3;
} }
| IDENTIFIER '[' DEC_NUMBER ']' '=' number | IDENTIFIER '[' DEC_NUMBER ']' '=' expression
{ perm_string name = lex_strings.make($1); { perm_string name = lex_strings.make($1);
long count = $3->as_ulong(); long count = $3->as_ulong();
$$ = make_named_numbers(name, 0, count-1, $6); $$ = make_named_numbers(name, 0, count-1, $6);
delete[]$1; delete[]$1;
delete $3; delete $3;
delete $6;
} }
| IDENTIFIER '[' DEC_NUMBER ':' DEC_NUMBER ']' '=' number | IDENTIFIER '[' DEC_NUMBER ':' DEC_NUMBER ']' '=' expression
{ perm_string name = lex_strings.make($1); { perm_string name = lex_strings.make($1);
$$ = make_named_numbers(name, $3->as_long(), $5->as_long(), $8); $$ = make_named_numbers(name, $3->as_long(), $5->as_long(), $8);
delete[]$1; delete[]$1;
delete $3; delete $3;
delete $5; delete $5;
delete $8;
} }
; ;
@ -3165,18 +3154,19 @@ parameter_value_byname
; ;
parameter_value_byname_list parameter_value_byname_list
: parameter_value_byname : parameter_value_byname
{ svector<named_pexpr_t*>*tmp = new svector<named_pexpr_t*>(1); { list<named_pexpr_t>*tmp = new list<named_pexpr_t>;
(*tmp)[0] = $1; tmp->push_back(*$1);
$$ = tmp; delete $1;
} $$ = tmp;
| parameter_value_byname_list ',' parameter_value_byname }
{ svector<named_pexpr_t*>*tmp = | parameter_value_byname_list ',' parameter_value_byname
new svector<named_pexpr_t*>(*$1,$3); { list<named_pexpr_t>*tmp = $1;
delete $1; tmp->push_back(*$3);
$$ = tmp; delete $3;
} $$ = tmp;
; }
;
/* The port (of a module) is a fairly complex item. Each port is /* The port (of a module) is a fairly complex item. Each port is
@ -3234,6 +3224,58 @@ port_opt
| { $$ = 0; } | { $$ = 0; }
; ;
/* The port_name rule is used with a module is being *instantiated*,
and not when it is being declared. See the port rule if you are
looking for the ports of a module declaration. */
port_name
: '.' IDENTIFIER '(' expression ')'
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = $4;
delete[]$2;
$$ = tmp;
}
| '.' IDENTIFIER '(' error ')'
{ yyerror(@3, "error: invalid port connection expression.");
named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = 0;
delete[]$2;
$$ = tmp;
}
| '.' IDENTIFIER '(' ')'
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = 0;
delete[]$2;
$$ = tmp;
}
| '.' IDENTIFIER
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = new PEIdent(lex_strings.make($2), true);
FILE_NAME(tmp->parm, @1);
delete[]$2;
$$ = tmp;
}
;
port_name_list
: port_name_list ',' port_name
{ list<named_pexpr_t>*tmp = $1;
tmp->push_back(*$3);
delete $3;
$$ = tmp;
}
| port_name
{ list<named_pexpr_t>*tmp = new list<named_pexpr_t>;
tmp->push_back(*$1);
delete $1;
$$ = tmp;
}
;
/* A port reference is an internal (to the module) name of the port, /* A port reference is an internal (to the module) name of the port,
possibly with a part of bit select to attach it to specific bits possibly with a part of bit select to attach it to specific bits
@ -3324,57 +3366,6 @@ port_reference_list
} }
; ;
/* The port_name rule is used with a module is being *instantiated*,
and not when it is being declared. See the port rule if you are
looking for the ports of a module declaration. */
port_name
: '.' IDENTIFIER '(' expression ')'
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = $4;
delete[]$2;
$$ = tmp;
}
| '.' IDENTIFIER '(' error ')'
{ yyerror(@3, "error: invalid port connection expression.");
named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = 0;
delete[]$2;
$$ = tmp;
}
| '.' IDENTIFIER '(' ')'
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = 0;
delete[]$2;
$$ = tmp;
}
| '.' IDENTIFIER
{ named_pexpr_t*tmp = new named_pexpr_t;
tmp->name = lex_strings.make($2);
tmp->parm = new PEIdent(lex_strings.make($2), true);
FILE_NAME(tmp->parm, @1);
delete[]$2;
$$ = tmp;
}
;
port_name_list
: port_name_list ',' port_name
{ svector<named_pexpr_t*>*tmp;
tmp = new svector<named_pexpr_t*>(*$1, $3);
delete $1;
$$ = tmp;
}
| port_name
{ svector<named_pexpr_t*>*tmp = new svector<named_pexpr_t*>(1);
(*tmp)[0] = $1;
$$ = tmp;
}
;
port_type port_type
: K_input { $$ = NetNet::PINPUT; } : K_input { $$ = NetNet::PINPUT; }
| K_output { $$ = NetNet::POUTPUT; } | K_output { $$ = NetNet::POUTPUT; }

141
pform.cc
View File

@ -350,16 +350,18 @@ PGenerate* pform_parent_generate(void)
} }
void pform_bind_attributes(map<perm_string,PExpr*>&attributes, void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr, bool keep_attrs)
{ {
if (attr == 0) if (attr == 0)
return; return;
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { while (attr->size() > 0) {
named_pexpr_t*tmp = (*attr)[idx]; named_pexpr_t tmp = attr->front();
attributes[tmp->name] = tmp->parm; attr->pop_front();
attributes[tmp.name] = tmp.parm;
} }
delete attr; if (!keep_attrs)
delete attr;
} }
static bool pform_at_module_level() static bool pform_at_module_level()
@ -689,7 +691,7 @@ verinum* pform_verinum_with_size(verinum*siz, verinum*val,
} }
void pform_startmodule(const char*name, const char*file, unsigned lineno, void pform_startmodule(const char*name, const char*file, unsigned lineno,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr)
{ {
assert( pform_cur_module == 0 ); assert( pform_cur_module == 0 );
@ -724,12 +726,7 @@ void pform_startmodule(const char*name, const char*file, unsigned lineno,
cerr << pform_timescale_file << ":" << pform_timescale_line cerr << pform_timescale_file << ":" << pform_timescale_line
<< ": ...: The inherited timescale is here." << endl; << ": ...: The inherited timescale is here." << endl;
} }
if (attr) { pform_bind_attributes(pform_cur_module->attributes, attr);
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
named_pexpr_t*tmp = (*attr)[idx];
pform_cur_module->attributes[tmp->name] = tmp->parm;
}
}
} }
/* /*
@ -1505,11 +1502,11 @@ void pform_make_events(list<perm_string>*names, const char*fn, unsigned ln)
* are ready to be instantiated. The function runs through the list of * are ready to be instantiated. The function runs through the list of
* gates and calls the pform_makegate function to make the individual gate. * gates and calls the pform_makegate function to make the individual gate.
*/ */
void pform_makegate(PGBuiltin::Type type, static void pform_makegate(PGBuiltin::Type type,
struct str_pair_t str, struct str_pair_t str,
list<PExpr*>* delay, list<PExpr*>* delay,
const lgate&info, const lgate&info,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr)
{ {
if (info.parms_by_name) { if (info.parms_by_name) {
cerr << info.file << ":" << info.lineno << ": Gates do not " cerr << info.file << ":" << info.lineno << ": Gates do not "
@ -1528,12 +1525,10 @@ void pform_makegate(PGBuiltin::Type type,
if (info.range[0]) if (info.range[0])
cur->set_range(info.range[0], info.range[1]); cur->set_range(info.range[0], info.range[1]);
if (attr) { // The pform_makegates() that calls me will take care of
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { // deleting the attr pointer, so tell the
named_pexpr_t*tmp = (*attr)[idx]; // pform_bind_attributes function to keep the attr object.
cur->attributes[tmp->name] = tmp->parm; pform_bind_attributes(cur->attributes, attr, true);
}
}
cur->strength0(str.str0); cur->strength0(str.str0);
cur->strength1(str.str1); cur->strength1(str.str1);
@ -1549,20 +1544,13 @@ void pform_makegates(PGBuiltin::Type type,
struct str_pair_t str, struct str_pair_t str,
list<PExpr*>*delay, list<PExpr*>*delay,
svector<lgate>*gates, svector<lgate>*gates,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr)
{ {
for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) { for (unsigned idx = 0 ; idx < gates->count() ; idx += 1) {
pform_makegate(type, str, delay, (*gates)[idx], attr); pform_makegate(type, str, delay, (*gates)[idx], attr);
} }
if (attr) { if (attr) delete attr;
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
named_pexpr_t*cur = (*attr)[idx];
delete cur;
}
delete attr;
}
delete gates; delete gates;
} }
@ -1597,13 +1585,13 @@ static void pform_make_modgate(perm_string type,
cur->set_range(msb,lsb); cur->set_range(msb,lsb);
if (overrides && overrides->by_name) { if (overrides && overrides->by_name) {
unsigned cnt = overrides->by_name->count(); unsigned cnt = overrides->by_name->size();
named<PExpr*>*byname = new named<PExpr*>[cnt]; named<PExpr*>*byname = new named<PExpr*>[cnt];
for (unsigned idx = 0 ; idx < cnt ; idx += 1) { list<named_pexpr_t>::iterator by_name_cur = overrides->by_name->begin();
named_pexpr_t*curp = (*overrides->by_name)[idx]; for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++ by_name_cur) {
byname[idx].name = curp->name; byname[idx].name = by_name_cur->name;
byname[idx].parm = curp->parm; byname[idx].parm = by_name_cur->parm;
} }
cur->set_parameters(byname, cnt); cur->set_parameters(byname, cnt);
@ -1621,17 +1609,17 @@ static void pform_make_modgate(perm_string type,
static void pform_make_modgate(perm_string type, static void pform_make_modgate(perm_string type,
perm_string name, perm_string name,
struct parmvalue_t*overrides, struct parmvalue_t*overrides,
svector<named_pexpr_t*>*bind, list<named_pexpr_t>*bind,
PExpr*msb, PExpr*lsb, PExpr*msb, PExpr*lsb,
const char*fn, unsigned ln) const char*fn, unsigned ln)
{ {
unsigned npins = bind->count(); unsigned npins = bind->size();
named<PExpr*>*pins = new named<PExpr*>[npins]; named<PExpr*>*pins = new named<PExpr*>[npins];
for (unsigned idx = 0 ; idx < npins ; idx += 1) { list<named_pexpr_t>::iterator bind_cur = bind->begin();
named_pexpr_t*curp = (*bind)[idx]; for (unsigned idx = 0 ; idx < npins ; idx += 1, ++bind_cur) {
pins[idx].name = curp->name; pins[idx].name = bind_cur->name;
pins[idx].parm = curp->parm; pins[idx].parm = bind_cur->parm;
pform_declare_implicit_nets(curp->parm); pform_declare_implicit_nets(bind_cur->parm);
} }
PGModule*cur = new PGModule(type, name, pins, npins); PGModule*cur = new PGModule(type, name, pins, npins);
@ -1639,13 +1627,13 @@ static void pform_make_modgate(perm_string type,
cur->set_range(msb,lsb); cur->set_range(msb,lsb);
if (overrides && overrides->by_name) { if (overrides && overrides->by_name) {
unsigned cnt = overrides->by_name->count(); unsigned cnt = overrides->by_name->size();
named<PExpr*>*byname = new named<PExpr*>[cnt]; named<PExpr*>*byname = new named<PExpr*>[cnt];
for (unsigned idx = 0 ; idx < cnt ; idx += 1) { list<named_pexpr_t>::iterator by_name_cur = overrides->by_name->begin();
named_pexpr_t*curp = (*overrides->by_name)[idx]; for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++by_name_cur) {
byname[idx].name = curp->name; byname[idx].name = by_name_cur->name;
byname[idx].parm = curp->parm; byname[idx].parm = by_name_cur->parm;
} }
cur->set_parameters(byname, cnt); cur->set_parameters(byname, cnt);
@ -1809,7 +1797,7 @@ void pform_module_define_port(const struct vlltype&li,
ivl_variable_type_t data_type, ivl_variable_type_t data_type,
bool signed_flag, bool signed_flag,
list<PExpr*>*range, list<PExpr*>*range,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr)
{ {
PWire*cur = pform_get_wire_in_scope(name); PWire*cur = pform_get_wire_in_scope(name);
if (cur) { if (cur) {
@ -1844,12 +1832,7 @@ void pform_module_define_port(const struct vlltype&li,
false); false);
} }
if (attr) { pform_bind_attributes(cur->attributes, attr);
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) {
named_pexpr_t*tmp = (*attr)[idx];
cur->attributes[tmp->name] = tmp->parm;
}
}
pform_put_wire_in_scope(name, cur); pform_put_wire_in_scope(name, cur);
} }
@ -1881,7 +1864,7 @@ void pform_module_define_port(const struct vlltype&li,
void pform_makewire(const vlltype&li, perm_string name, void pform_makewire(const vlltype&li, perm_string name,
NetNet::Type type, NetNet::PortType pt, NetNet::Type type, NetNet::PortType pt,
ivl_variable_type_t dt, ivl_variable_type_t dt,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr)
{ {
PWire*cur = pform_get_wire_in_scope(name); PWire*cur = pform_get_wire_in_scope(name);
@ -1929,9 +1912,9 @@ void pform_makewire(const vlltype&li, perm_string name,
} }
if (attr) { if (attr) {
for (unsigned idx = 0 ; idx < attr->count() ; idx += 1) { for (list<named_pexpr_t>::iterator attr_cur = attr->begin()
named_pexpr_t*tmp = (*attr)[idx]; ; attr_cur != attr->end() ; ++attr_cur) {
cur->attributes[tmp->name] = tmp->parm; cur->attributes[attr_cur->name] = attr_cur->parm;
} }
} }
@ -1951,7 +1934,7 @@ void pform_makewire(const vlltype&li,
NetNet::Type type, NetNet::Type type,
NetNet::PortType pt, NetNet::PortType pt,
ivl_variable_type_t dt, ivl_variable_type_t dt,
svector<named_pexpr_t*>*attr, list<named_pexpr_t>*attr,
PWSRType rt) PWSRType rt)
{ {
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
@ -2484,40 +2467,6 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_st
assert(enum_type->range.get() != 0); assert(enum_type->range.get() != 0);
assert(enum_type->range->size() == 2); assert(enum_type->range->size() == 2);
// Scan the list of enum name declarations and evaluate them
// to a map of names with values. This expands out the
// inferred values (if any) and checks for duplicates.
verinum cur_value (0);
verinum one_value (1);
for (list<named_number_t>::iterator cur = enum_type->names->begin()
; cur != enum_type->names->end() ; ++ cur) {
verinum next_value = cur->parm;
if (next_value.len() == 0) {
if (! cur_value.is_defined()) {
cerr << li.text << ":" << li.first_line << ": "
<< "error: Enumeration name " << cur->name
<< " cannot have inferred value." << endl;
next_value = cur_value;
error_count += 1;
} else {
next_value = cur_value;
cur_value = cur_value + one_value;
}
cur->parm = next_value;
} else {
if (enum_type->base_type==IVL_VT_BOOL && ! next_value.is_defined()) {
cerr << li.text << ":" << li.first_line << ": "
<< "error: Enumeration name " << cur->name
<< " Cannot have logic value " << next_value << "." << endl;
error_count += 1;
}
cur_value = next_value + one_value;
}
}
// Attach the enumeration to the current scope. // Attach the enumeration to the current scope.
pform_put_enum_type_in_scope(enum_type); pform_put_enum_type_in_scope(enum_type);
@ -2554,7 +2503,7 @@ svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
} }
PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st, PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st,
svector<named_pexpr_t*>*attr) list<named_pexpr_t>*attr)
{ {
PProcess*pp = new PProcess(type, st); PProcess*pp = new PProcess(type, st);

20
pform.h
View File

@ -84,11 +84,10 @@ extern bool pform_library_flag;
/* This is information about port name information for named port /* This is information about port name information for named port
connections. */ connections. */
typedef named<PExpr*> named_pexpr_t;
struct parmvalue_t { struct parmvalue_t {
list<PExpr*>*by_order; list<PExpr*>*by_order;
svector<named_pexpr_t*>*by_name; list<named_pexpr_t>*by_name;
}; };
struct str_pair_t { ivl_drive_t str0, str1; }; struct str_pair_t { ivl_drive_t str0, str1; };
@ -110,7 +109,7 @@ struct lgate {
string name; string name;
list<PExpr*>*parms; list<PExpr*>*parms;
svector<named_pexpr_t*>*parms_by_name; list<named_pexpr_t>*parms_by_name;
PExpr*range[2]; PExpr*range[2];
@ -121,7 +120,8 @@ struct lgate {
/* Use this function to transform the parted form of the attribute /* Use this function to transform the parted form of the attribute
list to the attribute map that is used later. */ list to the attribute map that is used later. */
extern void pform_bind_attributes(map<perm_string,PExpr*>&attributes, extern void pform_bind_attributes(map<perm_string,PExpr*>&attributes,
svector<named_pexpr_t*>*attr); list<named_pexpr_t>*attr,
bool keep_attr =false);
/* The lexor calls this function to change the default nettype. */ /* The lexor calls this function to change the default nettype. */
extern void pform_set_default_nettype(NetNet::Type net, extern void pform_set_default_nettype(NetNet::Type net,
@ -143,7 +143,7 @@ extern PWire* pform_get_wire_in_scope(perm_string name);
* pform to close up and finish the named module. * pform to close up and finish the named module.
*/ */
extern void pform_startmodule(const char*, const char*file, unsigned lineno, extern void pform_startmodule(const char*, const char*file, unsigned lineno,
svector<named_pexpr_t*>*attr); list<named_pexpr_t>*attr);
extern void pform_check_timeunit_prec(); extern void pform_check_timeunit_prec();
extern void pform_module_set_ports(vector<Module::port_t*>*); extern void pform_module_set_ports(vector<Module::port_t*>*);
@ -157,7 +157,7 @@ extern void pform_module_define_port(const struct vlltype&li,
ivl_variable_type_t data_type, ivl_variable_type_t data_type,
bool signed_flag, bool signed_flag,
list<PExpr*>*range, list<PExpr*>*range,
svector<named_pexpr_t*>*attr); list<named_pexpr_t>*attr);
extern Module::port_t* pform_module_port_reference(perm_string name, extern Module::port_t* pform_module_port_reference(perm_string name,
const char*file, const char*file,
@ -230,7 +230,7 @@ extern void pform_makewire(const struct vlltype&li, perm_string name,
NetNet::Type type, NetNet::Type type,
NetNet::PortType pt, NetNet::PortType pt,
ivl_variable_type_t, ivl_variable_type_t,
svector<named_pexpr_t*>*attr); list<named_pexpr_t>*attr);
/* This form handles simple declarations */ /* This form handles simple declarations */
extern void pform_makewire(const struct vlltype&li, extern void pform_makewire(const struct vlltype&li,
@ -240,7 +240,7 @@ extern void pform_makewire(const struct vlltype&li,
NetNet::Type type, NetNet::Type type,
NetNet::PortType, NetNet::PortType,
ivl_variable_type_t, ivl_variable_type_t,
svector<named_pexpr_t*>*attr, list<named_pexpr_t>*attr,
PWSRType rt = SR_NET); PWSRType rt = SR_NET);
/* This form handles assignment declarations. */ /* This form handles assignment declarations. */
@ -329,7 +329,7 @@ extern void pform_module_specify_path(PSpecPath*obj);
* or initial items. * or initial items.
*/ */
extern PProcess* pform_make_behavior(ivl_process_type_t, Statement*, extern PProcess* pform_make_behavior(ivl_process_type_t, Statement*,
svector<named_pexpr_t*>*attr); list<named_pexpr_t>*attr);
extern svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*); extern svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*);
@ -349,7 +349,7 @@ extern void pform_makegates(PGBuiltin::Type type,
struct str_pair_t str, struct str_pair_t str,
list<PExpr*>*delay, list<PExpr*>*delay,
svector<lgate>*gates, svector<lgate>*gates,
svector<named_pexpr_t*>*attr); list<named_pexpr_t>*attr);
extern void pform_make_modgates(perm_string type, extern void pform_make_modgates(perm_string type,
struct parmvalue_t*overrides, struct parmvalue_t*overrides,

View File

@ -1112,7 +1112,7 @@ void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const
; cur != enum_sets.end() ; ++ cur) { ; cur != enum_sets.end() ; ++ cur) {
out << setw(indent) << "" << "enum {" << endl; out << setw(indent) << "" << "enum {" << endl;
for (list<named_number_t>::const_iterator idx = (*cur)->names->begin() for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin()
; idx != (*cur)->names->end() ; ++ idx) { ; idx != (*cur)->names->end() ; ++ idx) {
out << setw(indent+4) << "" << idx->name out << setw(indent+4) << "" << idx->name
<< " = " << idx->parm << endl; << " = " << idx->parm << endl;

View File

@ -32,7 +32,9 @@
* parse-form types. * parse-form types.
*/ */
class PExpr;
typedef named<verinum> named_number_t; typedef named<verinum> named_number_t;
typedef named<PExpr*> named_pexpr_t;
struct index_component_t { struct index_component_t {
enum ctype_t { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO }; enum ctype_t { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO };
@ -63,7 +65,7 @@ struct enum_type_t {
ivl_variable_type_t base_type; ivl_variable_type_t base_type;
bool signed_flag; bool signed_flag;
auto_ptr< list<PExpr*> > range; auto_ptr< list<PExpr*> > range;
auto_ptr< list<named_number_t> > names; auto_ptr< list<named_pexpr_t> > names;
}; };