Support enumeration element ranges.

This also fixes:
Set verinum.has_sign() correctly for enum values.
This commit is contained in:
Stephen Williams 2010-11-09 21:05:47 -08:00
parent e1344745f8
commit 2f474358d9
2 changed files with 63 additions and 16 deletions

View File

@ -232,6 +232,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
// The values are explicitly sized to the width of the
// base type of the enumeration.
verinum tmp_val (cur->parm, use_enum->base_width());
tmp_val.has_sign(enum_type->signed_flag);
rc_flag = use_enum->insert_name(cur->name, tmp_val);
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);

78
parse.y
View File

@ -193,19 +193,39 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
return tmp;
}
static named_number_t* make_named_number(perm_string name)
static list<named_number_t>* make_named_number(perm_string name)
{
named_number_t*res = new named_number_t;
res->name = name;
return res;
list<named_number_t>*lst = new list<named_number_t>;
named_number_t tmp;
tmp.name = name;
lst->push_back(tmp);
return lst;
}
static named_number_t* make_named_number(perm_string name, const verinum&val)
static list<named_number_t>* make_named_numbers(perm_string name, long first, long last, verinum*val =0)
{
named_number_t*res = new named_number_t;
res->name = name;
res->parm = val;
return res;
list<named_number_t>*lst = new list<named_number_t>;
named_number_t tmp;
assert(first <= last);
for (long idx = first ; idx <= last ; idx += 1) {
ostringstream buf;
buf << name.str() << idx << ends;
tmp.name = lex_strings.make(buf.str());
tmp.parm = val ? *val : verinum();
val = 0;
lst->push_back(tmp);
}
return lst;
}
static list<named_number_t>* make_named_number(perm_string name, const verinum&val)
{
list<named_number_t>*lst = new list<named_number_t>;
named_number_t tmp;
tmp.name = name;
tmp.parm = val;
lst->push_back(tmp);
return lst;
}
%}
@ -398,8 +418,7 @@ static named_number_t* make_named_number(perm_string name, const verinum&val)
%type <value_range> parameter_value_ranges_opt
%type <expr> value_range_expression
%type <named_number> enum_name
%type <named_numbers> enum_name_list
%type <named_numbers> enum_name_list enum_name
%type <enum_type> enum_data_type
%type <wires> task_item task_item_list task_item_list_opt
@ -697,14 +716,11 @@ enum_data_type
enum_name_list
: enum_name
{ list<named_number_t>*lst = new list<named_number_t>;
lst->push_back(*$1);
delete $1;
$$ = lst;
{ $$ = $1;
}
| enum_name_list ',' enum_name
{ list<named_number_t>*lst = $1;
lst->push_back(*$3);
lst->splice(lst->end(), *$3);
delete $3;
$$ = lst;
}
@ -716,12 +732,42 @@ enum_name
delete[]$1;
$$ = make_named_number(name);
}
| IDENTIFIER '[' DEC_NUMBER ']'
{ perm_string name = lex_strings.make($1);
long count = $3->as_ulong();
delete[]$1;
$$ = make_named_numbers(name, 0, count-1);
delete $3;
}
| IDENTIFIER '[' DEC_NUMBER ':' DEC_NUMBER ']'
{ perm_string name = lex_strings.make($1);
$$ = make_named_numbers(name, $3->as_long(), $5->as_long());
delete[]$1;
delete $3;
delete $5;
}
| IDENTIFIER '=' number
{ perm_string name = lex_strings.make($1);
delete[]$1;
$$ = make_named_number(name, *$3);
delete $3;
}
| IDENTIFIER '[' DEC_NUMBER ']' '=' number
{ perm_string name = lex_strings.make($1);
long count = $3->as_ulong();
$$ = make_named_numbers(name, 0, count-1, $6);
delete[]$1;
delete $3;
delete $6;
}
| IDENTIFIER '[' DEC_NUMBER ':' DEC_NUMBER ']' '=' number
{ perm_string name = lex_strings.make($1);
$$ = make_named_numbers(name, $3->as_long(), $5->as_long(), $8);
delete[]$1;
delete $3;
delete $5;
delete $8;
}
;
case_item