Parse/elaborate class derivation
This gets us down to working classes, but does not yet implement calls to the parent constructor, implicitly or explicitly.
This commit is contained in:
parent
bfb14fbbc6
commit
9f83882bcc
|
|
@ -349,13 +349,33 @@ static void blend_class_constructors(PClass*pclass)
|
|||
static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
{
|
||||
class_type_t*use_type = pclass->type;
|
||||
netclass_t*use_class = new netclass_t(use_type->name);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() <<": elaborate_scope_class: "
|
||||
<< "Elaborate scope class " << pclass->pscope_name() << endl;
|
||||
}
|
||||
|
||||
class_type_t*base_class = dynamic_cast<class_type_t*> (use_type->base_type);
|
||||
if (use_type->base_type && !base_class) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base type of " << use_type->name
|
||||
<< " is not a class." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
netclass_t*use_base_class = 0;
|
||||
if (base_class) {
|
||||
use_base_class = scope->find_class(base_class->name);
|
||||
if (use_base_class == 0) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base class " << base_class->name
|
||||
<< " not found." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
netclass_t*use_class = new netclass_t(use_type->name, use_base_class);
|
||||
|
||||
// Class scopes have no parent scope, because references are
|
||||
// not allowed to escape a class method.
|
||||
NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()),
|
||||
|
|
|
|||
70
netclass.cc
70
netclass.cc
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
netclass_t::netclass_t(perm_string name)
|
||||
: name_(name), class_scope_(0)
|
||||
netclass_t::netclass_t(perm_string name, netclass_t*sup)
|
||||
: name_(name), super_(sup), class_scope_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -61,43 +61,85 @@ ivl_variable_type_t netclass_t::base_type() const
|
|||
return IVL_VT_CLASS;
|
||||
}
|
||||
|
||||
size_t netclass_t::get_properties(void) const
|
||||
{
|
||||
size_t res = properties_.size();
|
||||
if (super_) res += super_->get_properties();
|
||||
return res;
|
||||
}
|
||||
|
||||
int netclass_t::property_idx_from_name(perm_string pname) const
|
||||
{
|
||||
map<perm_string,size_t>::const_iterator cur;
|
||||
cur = properties_.find(pname);
|
||||
if (cur == properties_.end())
|
||||
return -1;
|
||||
if (cur == properties_.end()) {
|
||||
if (super_)
|
||||
return super_->property_idx_from_name(pname);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cur->second;
|
||||
int pidx = cur->second;
|
||||
if (super_) pidx += super_->get_properties();
|
||||
return pidx;
|
||||
}
|
||||
|
||||
const char*netclass_t::get_prop_name(size_t idx) const
|
||||
{
|
||||
assert(idx < property_table_.size());
|
||||
return property_table_[idx].name;
|
||||
size_t super_size = 0;
|
||||
if (super_) super_size = super_->get_properties();
|
||||
|
||||
assert(idx < (super_size + property_table_.size()));
|
||||
if (idx < super_size)
|
||||
return super_->get_prop_name(idx);
|
||||
else
|
||||
return property_table_[idx-super_size].name;
|
||||
}
|
||||
|
||||
property_qualifier_t netclass_t::get_prop_qual(size_t idx) const
|
||||
{
|
||||
assert(idx < property_table_.size());
|
||||
return property_table_[idx].qual;
|
||||
size_t super_size = 0;
|
||||
if (super_) super_size = super_->get_properties();
|
||||
|
||||
assert(idx < (super_size+property_table_.size()));
|
||||
if (idx < super_size)
|
||||
return super_->get_prop_qual(idx);
|
||||
else
|
||||
return property_table_[idx-super_size].qual;
|
||||
}
|
||||
|
||||
ivl_type_t netclass_t::get_prop_type(size_t idx) const
|
||||
{
|
||||
assert(idx < property_table_.size());
|
||||
return property_table_[idx].type;
|
||||
size_t super_size = 0;
|
||||
if (super_) super_size = super_->get_properties();
|
||||
|
||||
assert(idx < (super_size+property_table_.size()));
|
||||
if (idx < super_size)
|
||||
return super_->get_prop_type(idx);
|
||||
else
|
||||
return property_table_[idx-super_size].type;
|
||||
}
|
||||
|
||||
bool netclass_t::get_prop_initialized(size_t idx) const
|
||||
{
|
||||
assert(idx < property_table_.size());
|
||||
return property_table_[idx].initialized_flag;
|
||||
size_t super_size = 0;
|
||||
if (super_) super_size = super_->get_properties();
|
||||
|
||||
assert(idx < (super_size+property_table_.size()));
|
||||
if (idx < super_size)
|
||||
return super_->get_prop_initialized(idx);
|
||||
else
|
||||
return property_table_[idx].initialized_flag;
|
||||
}
|
||||
|
||||
void netclass_t::set_prop_initialized(size_t idx) const
|
||||
{
|
||||
assert(idx < property_table_.size());
|
||||
size_t super_size = 0;
|
||||
if (super_) super_size = super_->get_properties();
|
||||
|
||||
assert(idx >= super_size && idx < (super_size+property_table_.size()));
|
||||
idx -= super_size;
|
||||
|
||||
assert(! property_table_[idx].initialized_flag);
|
||||
property_table_[idx].initialized_flag = true;
|
||||
}
|
||||
|
|
|
|||
13
netclass.h
13
netclass.h
|
|
@ -33,7 +33,7 @@ class PClass;
|
|||
|
||||
class netclass_t : public ivl_type_s {
|
||||
public:
|
||||
netclass_t(perm_string class_name);
|
||||
netclass_t(perm_string class_name, netclass_t*par);
|
||||
~netclass_t();
|
||||
|
||||
// Set the property of the class during elaboration. Set the
|
||||
|
|
@ -52,7 +52,13 @@ class netclass_t : public ivl_type_s {
|
|||
// This is the name of the class type
|
||||
inline perm_string get_name() const { return name_; }
|
||||
|
||||
inline size_t get_properties(void) const { return properties_.size(); }
|
||||
// If this is derived from another class, then this method
|
||||
// returns a pointer to the super-class.
|
||||
inline const netclass_t* get_super() const { return super_; }
|
||||
|
||||
// Get the number of properties in this class. Include
|
||||
// properties in the parent class.
|
||||
size_t get_properties(void) const;
|
||||
// Get information about each property.
|
||||
const char*get_prop_name(size_t idx) const;
|
||||
property_qualifier_t get_prop_qual(size_t idx) const;
|
||||
|
|
@ -92,6 +98,9 @@ class netclass_t : public ivl_type_s {
|
|||
|
||||
private:
|
||||
perm_string name_;
|
||||
// If this is derived from another base class, point to it
|
||||
// here.
|
||||
netclass_t*super_;
|
||||
// Map properrty names to property table index.
|
||||
std::map<perm_string,size_t> properties_;
|
||||
// Vector of properties.
|
||||
|
|
|
|||
6
parse.y
6
parse.y
|
|
@ -683,11 +683,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);
|
||||
if ($4) {
|
||||
yyerror(@4, "sorry: Class extends not supported yet.");
|
||||
}
|
||||
}
|
||||
{ pform_start_class_declaration(@2, $3, $4); }
|
||||
class_items_opt K_endclass
|
||||
{ // Process a class.
|
||||
pform_end_class_declaration(@8);
|
||||
|
|
|
|||
3
pform.h
3
pform.h
|
|
@ -181,7 +181,8 @@ extern void pform_endmodule(const char*, bool inside_celldefine,
|
|||
Module::UCDriveType uc_drive_def);
|
||||
|
||||
extern void pform_start_class_declaration(const struct vlltype&loc,
|
||||
class_type_t*type);
|
||||
class_type_t*type,
|
||||
data_type_t*base_type);
|
||||
extern void pform_class_property(const struct vlltype&loc,
|
||||
property_qualifier_t pq,
|
||||
data_type_t*data_type,
|
||||
|
|
|
|||
|
|
@ -182,12 +182,16 @@ void class_type_t::pform_dump(ostream&out, unsigned indent) const
|
|||
{
|
||||
out << setw(indent) << "" << "class " << name << " {";
|
||||
|
||||
if (base_type) out << " (extends)";
|
||||
|
||||
for (map<perm_string,prop_info_t>::const_iterator cur = properties.begin()
|
||||
; cur != properties.end() ; ++cur) {
|
||||
out << " " << cur->first;
|
||||
}
|
||||
|
||||
out << " }" << endl;
|
||||
|
||||
if (base_type) base_type->pform_dump(out, indent+4);
|
||||
}
|
||||
|
||||
void class_type_t::pform_dump_init(ostream&out, unsigned indent) const
|
||||
|
|
|
|||
|
|
@ -26,12 +26,15 @@
|
|||
*/
|
||||
static PClass*pform_cur_class = 0;
|
||||
|
||||
void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type)
|
||||
void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type)
|
||||
{
|
||||
PClass*class_scope = pform_push_class_scope(loc, type->name);
|
||||
class_scope->type = type;
|
||||
assert(pform_cur_class == 0);
|
||||
pform_cur_class = class_scope;
|
||||
|
||||
assert(type->base_type == 0);
|
||||
type->base_type = base_type;
|
||||
}
|
||||
|
||||
void pform_class_property(const struct vlltype&loc,
|
||||
|
|
|
|||
|
|
@ -225,13 +225,19 @@ struct string_type_t : public data_type_t {
|
|||
struct class_type_t : public data_type_t {
|
||||
|
||||
inline explicit class_type_t(perm_string n)
|
||||
: name(n) { }
|
||||
: name(n), base_type(0) { }
|
||||
|
||||
void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
void pform_dump_init(std::ostream&out, unsigned indent) const;
|
||||
|
||||
// This is the name of the class type.
|
||||
perm_string name;
|
||||
|
||||
// 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.
|
||||
data_type_t*base_type;
|
||||
|
||||
// This is a map of the properties. Map the name to the type.
|
||||
struct prop_info_t {
|
||||
inline prop_info_t() : qual(property_qualifier_t::make_none()), type(0) { }
|
||||
|
|
|
|||
Loading…
Reference in New Issue