Parse simple typedefs

Parse typedefs with structs and enums, but give a sorry message,
because they are not yet supported. Rearrange some of the parse
rules for variables in order to increase comonality with the
typedef rules.
This commit is contained in:
Stephen Williams 2012-01-07 15:37:30 -08:00
parent 124314576d
commit e14628193a
5 changed files with 64 additions and 12 deletions

38
parse.y
View File

@ -337,6 +337,8 @@ static void current_task_set_statement(vector<Statement*>*s)
list<struct_member_t*>*struct_members;
struct_type_t*struct_type;
data_type_t*data_type;
verinum* number;
verireal* realtime;
@ -502,6 +504,7 @@ static void current_task_set_statement(vector<Statement*>*s)
%type <decl_assignment> variable_decl_assignment
%type <decl_assignments> list_of_variable_decl_assignments
%type <data_type> data_type
%type <struct_member> struct_union_member
%type <struct_members> struct_union_member_list
%type <struct_type> struct_data_type
@ -703,17 +706,10 @@ block_item_decl
if ($1) delete $1;
}
/* Enum data types are possible here. */
/* variable declarations */
| attribute_list_opt enum_data_type register_variable_list ';'
{ pform_set_enum(@2, $2, $3);
if ($1) delete $1;
}
/* struct data type declarations */
| attribute_list_opt struct_data_type register_variable_list ';'
{ pform_set_struct_type($2, $3);
| attribute_list_opt data_type register_variable_list ';'
{ pform_set_data_type(@2, $2, $3);
if ($1) delete $1;
}
@ -734,6 +730,10 @@ block_item_decl
| K_parameter parameter_assign_decl ';'
| K_localparam localparam_assign_decl ';'
/* Blocks can have type declarations. */
| type_declaration
/* Recover from errors that happen within variable lists. Use the
trailing semi-colon to resync the parser. */
@ -779,6 +779,18 @@ block_item_decls_opt
|
;
data_type
: struct_data_type
{ $$ = $1; }
| enum_data_type
{ $$ = $1; }
;
type_declaration
: K_typedef data_type IDENTIFIER ';'
{ yyerror(@1, "sorry: typedef not yet supported."); }
;
/* 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
@ -787,6 +799,7 @@ block_item_decls_opt
enum_data_type
: K_enum '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($3);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = true;
@ -795,6 +808,7 @@ enum_data_type
}
| K_enum atom2_type signed_unsigned_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;
@ -803,6 +817,7 @@ enum_data_type
}
| K_enum K_integer signed_unsigned_opt '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($5);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
@ -811,6 +826,7 @@ enum_data_type
}
| K_enum K_logic unsigned_signed_opt range '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
@ -819,6 +835,7 @@ enum_data_type
}
| K_enum K_reg unsigned_signed_opt range '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_LOGIC;
enum_type->signed_flag = $3;
@ -827,6 +844,7 @@ enum_data_type
}
| K_enum K_bit unsigned_signed_opt range '{' enum_name_list '}'
{ enum_type_t*enum_type = new enum_type_t;
FILE_NAME(enum_type, @1);
enum_type->names .reset($6);
enum_type->base_type = IVL_VT_BOOL;
enum_type->signed_flag = $3;

View File

@ -2493,6 +2493,25 @@ void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>
delete names;
}
/*
* This function detects the derived class for the given type and
* dispatches the type to the proper subtype function.
*/
void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<perm_string>*names)
{
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) {
pform_set_struct_type(struct_type, names);
return;
}
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) {
pform_set_enum(li, enum_type, names);
return;
}
assert(0);
}
static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
perm_string name)
{

View File

@ -293,6 +293,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_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names);
extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names);
extern void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names);

View File

@ -19,3 +19,7 @@
# include "pform_types.h"
data_type_t::~data_type_t()
{
}

View File

@ -63,13 +63,22 @@ struct decl_assignment_t {
std::auto_ptr<PExpr> expr;
};
/*
* This is the base class for data types that are matched by the
* "data_type" rule in the parse rule. We make the type virtual so
* that dynamic types will work.
*/
struct data_type_t : public LineInfo {
virtual ~data_type_t() = 0;
};
/*
* The enum_type_t holds the parsed declaration to represent an
* enumeration. Since this is in the pform, it represents the type
* before elaboration to the range, for example, man not be complete
* until it is elaborated in a scope.
*/
struct enum_type_t {
struct enum_type_t : public data_type_t {
ivl_variable_type_t base_type;
bool signed_flag;
std::auto_ptr< list<PExpr*> > range;
@ -83,7 +92,7 @@ struct struct_member_t : public LineInfo {
std::auto_ptr< list<decl_assignment_t*> > names;
};
struct struct_type_t : public LineInfo {
struct struct_type_t : public data_type_t {
bool packed_flag;
std::auto_ptr< list<struct_member_t*> > members;
};