Implement class extends arguments.

This implements constructor arguments right after the base class
name in the class extends syntax.
This commit is contained in:
Stephen Williams 2013-11-10 08:21:22 -08:00
parent f16fd03dab
commit 9bd9c8f301
6 changed files with 56 additions and 11 deletions

View File

@ -336,8 +336,7 @@ static void blend_class_constructors(PClass*pclass)
// If we do not have an explicit constructor chain, but there
// is a parent class, then create an implicit chain.
if (chain_new==0 && pclass->type->base_type!=0) {
list<PExpr*>tmp_parms;
chain_new = new PChainConstructor(tmp_parms);
chain_new = new PChainConstructor(pclass->type->base_args);
chain_new->set_line(*pclass);
}

20
parse.y
View File

@ -418,6 +418,11 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
property_qualifier_t property_qualifier;
PPackage*package;
struct {
data_type_t*type;
list<PExpr*>*exprs;
} class_declaration_extends;
verinum* number;
verireal* realtime;
@ -591,12 +596,13 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <decl_assignments> list_of_variable_decl_assignments
%type <data_type> data_type data_type_or_implicit data_type_or_implicit_or_void
%type <data_type> class_declaration_extends_opt
%type <class_type> class_identifier
%type <struct_member> struct_union_member
%type <struct_members> struct_union_member_list
%type <struct_type> struct_data_type
%type <class_declaration_extends> class_declaration_extends_opt
%type <property_qualifier> class_item_qualifier property_qualifier
%type <property_qualifier> class_item_qualifier_list property_qualifier_list
%type <property_qualifier> class_item_qualifier_opt property_qualifier_opt
@ -683,7 +689,7 @@ assignment_pattern /* IEEE1800-2005: A.6.7.1 */
class_declaration /* IEEE1800-2005: A.1.2 */
: K_virtual_opt K_class class_identifier class_declaration_extends_opt ';'
{ pform_start_class_declaration(@2, $3, $4); }
{ pform_start_class_declaration(@2, $3, $4.type, $4.exprs); }
class_items_opt K_endclass
{ // Process a class.
pform_end_class_declaration(@8);
@ -751,9 +757,15 @@ class_declaration_endlabel_opt
class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */
: K_extends TYPE_IDENTIFIER
{ $$ = $2; }
{ $$.type = $2;
$$.exprs= 0;
}
| K_extends TYPE_IDENTIFIER '(' expression_list_with_nuls ')'
{ $$.type = $2;
$$.exprs = $4;
}
|
{ $$ = 0; }
{ $$.type = 0; $$.exprs = 0; }
;
/* The class_items_opt and class_items rules together implement the

View File

@ -182,7 +182,8 @@ extern void pform_endmodule(const char*, bool inside_celldefine,
extern void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type,
data_type_t*base_type);
data_type_t*base_type,
std::list<PExpr*>*base_exprs);
extern void pform_class_property(const struct vlltype&loc,
property_qualifier_t pq,
data_type_t*data_type,

View File

@ -180,10 +180,22 @@ void struct_type_t::pform_dump(ostream&out, unsigned indent) const
void class_type_t::pform_dump(ostream&out, unsigned indent) const
{
out << setw(indent) << "" << "class " << name << " {";
out << setw(indent) << "" << "class " << name;
if (base_type) out << " (extends)";
if (base_type) out << " extends <type>";
if (base_args.size() > 0) {
out << " (";
for (list<PExpr*>::const_iterator cur = base_args.begin()
; cur != base_args.end() ; ++cur) {
const PExpr*curp = *cur;
if (cur != base_args.begin())
out << ", ";
curp->dump(out);
}
out << ")";
}
out << " {";
for (map<perm_string,prop_info_t>::const_iterator cur = properties.begin()
; cur != properties.end() ; ++cur) {
out << " " << cur->first;

View File

@ -26,7 +26,17 @@
*/
static PClass*pform_cur_class = 0;
void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type)
/*
* The base_type is set to the base class if this declaration is
* starting a derived class. For example, for the syntax:
*
* class foo extends bar (exprs) ...
*
* the base_type is the type of the class "bar", and the base_exprs,
* if present, are the "exprs" that would be passed to a chained
* constructor.
*/
void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type, list<PExpr*>*base_exprs)
{
PClass*class_scope = pform_push_class_scope(loc, type->name);
class_scope->type = type;
@ -35,6 +45,15 @@ void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type,
assert(type->base_type == 0);
type->base_type = base_type;
assert(type->base_args.size() == 0);
if (base_exprs) {
for (list<PExpr*>::iterator cur = base_exprs->begin()
; cur != base_exprs->end() ; ++ cur) {
type->base_args.push_back(*cur);
}
delete base_exprs;
}
}
void pform_class_property(const struct vlltype&loc,

View File

@ -235,8 +235,10 @@ struct class_type_t : public data_type_t {
// This is the named type that is supposed to be the base
// class that we are extending. This is nil if there is no
// hierarchy.
// hierarchy. If there are arguments to the base class, then
// put them in the base_args vector.
data_type_t*base_type;
std::list<PExpr*>base_args;
// This is a map of the properties. Map the name to the type.
struct prop_info_t {