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:
parent
124314576d
commit
e14628193a
38
parse.y
38
parse.y
|
|
@ -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;
|
||||
|
|
|
|||
19
pform.cc
19
pform.cc
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
2
pform.h
2
pform.h
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -19,3 +19,7 @@
|
|||
|
||||
|
||||
# include "pform_types.h"
|
||||
|
||||
data_type_t::~data_type_t()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue