Finish up parser code for enum types

This gets the parser syntax actions done, up to the pform code.
It is ready for generating pform structures.
This commit is contained in:
Stephen Williams 2010-10-24 11:21:17 -07:00
parent eba8c8ee65
commit eb4ed82893
3 changed files with 113 additions and 1 deletions

91
parse.y
View File

@ -171,6 +171,21 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
return tmp;
}
static named_number_t* make_named_number(perm_string name)
{
named_number_t*res = new named_number_t;
res->name = name;
return res;
}
static named_number_t* make_named_number(perm_string name, const verinum&val)
{
named_number_t*res = new named_number_t;
res->name = name;
res->parm = val;
return res;
}
%}
%union {
@ -206,6 +221,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
LexicalScope::range_t* value_range;
vector<Module::port_t*>*mports;
named_number_t* named_number;
list<named_number_t>* named_numbers;
named_pexpr_t*named_pexpr;
svector<named_pexpr_t*>*named_pexprs;
struct parmvalue_t*parmvalue;
@ -230,6 +248,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
PTaskFuncArg function_type;
net_decl_assign_t*net_decl_assign;
enum_type_t*enum_type;
verinum* number;
@ -357,6 +376,10 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
%type <value_range> parameter_value_ranges_opt
%type <expr> value_range_expression
%type <named_number> enum_name
%type <named_numbers> enum_name_list
%type <enum_type> enum_data_type
%type <wires> task_item task_item_list task_item_list_opt
%type <wires> task_port_item task_port_decl task_port_decl_list
%type <wires> function_item function_item_list
@ -549,6 +572,13 @@ block_item_decl
if ($1) delete $1;
}
/* Enum data types are possible here. */
| attribute_list_opt enum_data_type register_variable_list ';'
{ pform_set_enum(@2, $2, $3);
if ($1) delete $1;
}
/* real declarations are fairly simple as there is no range of
signed flag in the declaration. Create the real as a NetNet::REG
with real value. Note that real and realtime are interchangeable
@ -611,6 +641,67 @@ block_item_decls_opt
|
;
/* The structure for an enumeration data type is the keyword "enum",
followed by the enumeration values in curly braces. Also allow
for an optional base type. The default base type is "int", but it
can be any of the integral or vector types. */
enum_data_type
: K_enum '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
enum_type->names .reset($3);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = true;
enum_type->range.reset( make_range_from_width(32) );
$$ = enum_type;
}
| K_enum atom2_type signed_unsigned_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
enum_type->range.reset( make_range_from_width($2) );
$$ = enum_type;
}
| K_enum K_integer signed_unsigned_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
enum_type->range.reset( make_range_from_width(integer_width) );
$$ = enum_type;
}
;
enum_name_list
: enum_name
{ list<named_number_t>*lst = new list<named_number_t>;
lst->push_back(*$1);
delete $1;
$$ = lst;
}
| enum_name_list ',' enum_name
{ list<named_number_t>*lst = $1;
lst->push_back(*$3);
delete $3;
$$ = lst;
}
;
enum_name
: IDENTIFIER
{ perm_string name = lex_strings.make($1);
delete[]$1;
$$ = make_named_number(name);
}
| IDENTIFIER '=' number
{ perm_string name = lex_strings.make($1);
delete[]$1;
$$ = make_named_number(name, *$3);
delete $3;
}
;
case_item
: expression_list_proper ':' statement_or_null
{ PCase::Item*tmp = new PCase::Item;

View File

@ -2463,6 +2463,15 @@ void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>
delete names;
}
void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names)
{
cerr << li.text << ":" << li.first_line << ": "
<< "sorry: enum types not supported yet." << endl;
error_count += 1;
delete enum_type;
delete names;
}
svector<PWire*>* pform_make_udp_input_ports(list<perm_string>*names)
{
svector<PWire*>*out = new svector<PWire*>(names->size());

14
pform.h
View File

@ -35,6 +35,7 @@
# include <iostream>
# include <string>
# include <list>
# include <memory>
# include <cstdio>
/*
@ -83,9 +84,10 @@ extern bool pform_library_flag;
/* This is information about port name information for named port
connections. */
//typedef struct named<PExpr*> named_pexpr_t;
typedef named<PExpr*> named_pexpr_t;
typedef named<verinum> named_number_t;
struct parmvalue_t {
svector<PExpr*>*by_order;
svector<named_pexpr_t*>*by_name;
@ -93,12 +95,20 @@ struct parmvalue_t {
struct str_pair_t { ivl_drive_t str0, str1; };
struct net_decl_assign_t {
perm_string name;
PExpr*expr;
struct net_decl_assign_t*next;
};
struct enum_type_t {
ivl_variable_type_t base_type;
bool signed_flag;
auto_ptr< svector<PExpr*> > range;
auto_ptr< list<named_number_t> > names;
};
/* The lgate is gate instantiation information. */
struct lgate {
lgate(int =0)
@ -277,6 +287,8 @@ extern void pform_set_reg_time(list<perm_string>*names);
extern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names);
extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names);
/* pform_set_attrib and pform_set_type_attrib exist to support the
$attribute syntax, which can only set string values to
attributes. The functions keep the value strings that are