allow undefined typedefs like classes

This commit is contained in:
David Rose 2004-06-18 21:08:02 +00:00
parent 30ae40c21b
commit 02d259fb03
10 changed files with 100 additions and 19 deletions

View File

@ -85,6 +85,18 @@ make_copy() const {
return new DCArrayParameter(*this);
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::is_valid
// Access: Published, Virtual
// Description: Returns false if the type is an invalid type
// (e.g. declared from an undefined typedef), true if
// it is valid.
////////////////////////////////////////////////////////////////////
bool DCArrayParameter::
is_valid() const {
return _element_type->is_valid();
}
////////////////////////////////////////////////////////////////////
// Function: DCArrayParameter::get_element_type
// Access: Published

View File

@ -38,6 +38,7 @@ public:
PUBLISHED:
virtual DCArrayParameter *as_array_parameter();
virtual DCParameter *make_copy() const;
virtual bool is_valid() const;
DCParameter *get_element_type() const;
int get_array_size() const;

View File

@ -37,7 +37,7 @@
////////////////////////////////////////////////////////////////////
DCFile::
DCFile() {
_all_classes_valid = true;
_all_objects_valid = true;
}
////////////////////////////////////////////////////////////////////
@ -237,7 +237,9 @@ write(ostream &out, bool brief) const {
if (!_typedefs.empty()) {
Typedefs::const_iterator ti;
for (ti = _typedefs.begin(); ti != _typedefs.end(); ++ti) {
(*ti)->write(out, brief, 0);
if (!(*ti)->is_bogus_typedef()) {
(*ti)->write(out, brief, 0);
}
}
out << "\n";
}
@ -293,7 +295,7 @@ get_class_by_name(const string &name) const {
}
////////////////////////////////////////////////////////////////////
// Function: DCFile::all_classes_valid
// Function: DCFile::all_objects_valid
// Access: Published
// Description: Returns true if all of the classes read from the DC
// file were defined and valid, or false if any of them
@ -301,8 +303,8 @@ get_class_by_name(const string &name) const {
// we might have read a partial file.
////////////////////////////////////////////////////////////////////
bool DCFile::
all_classes_valid() const {
return _all_classes_valid;
all_objects_valid() const {
return _all_objects_valid;
}
////////////////////////////////////////////////////////////////////
@ -447,7 +449,7 @@ add_class(DCClass *dclass) {
_classes.push_back(dclass);
if (dclass->is_bogus_class()) {
_all_classes_valid = false;
_all_objects_valid = false;
}
return true;
@ -504,5 +506,9 @@ add_typedef(DCTypedef *dtypedef) {
dtypedef->set_number(get_num_typedefs());
_typedefs.push_back(dtypedef);
if (dtypedef->is_bogus_typedef()) {
_all_objects_valid = false;
}
return true;
}

View File

@ -51,7 +51,7 @@ PUBLISHED:
DCClass *get_class(int n) const;
DCClass *get_class_by_name(const string &name) const;
bool all_classes_valid() const;
bool all_objects_valid() const;
int get_num_import_modules() const;
string get_import_module(int n) const;
@ -94,7 +94,7 @@ private:
typedef pmap<string, DCTypedef *> TypedefsByName;
TypedefsByName _typedefs_by_name;
bool _all_classes_valid;
bool _all_objects_valid;
};
#endif

View File

@ -52,6 +52,7 @@ PUBLISHED:
virtual DCArrayParameter *as_array_parameter();
virtual DCParameter *make_copy() const=0;
virtual bool is_valid() const=0;
const DCTypedef *get_typedef() const;

View File

@ -209,7 +209,16 @@ import_symbol_list:
typedef_decl:
KW_TYPEDEF parameter
{
dc_file->add_typedef(new DCTypedef($2));
DCTypedef *dtypedef = new DCTypedef($2);
if (!dc_file->add_typedef(dtypedef)) {
DCTypedef *old_typedef = dc_file->get_typedef_by_name(dtypedef->get_name());
if (old_typedef->is_bogus_typedef()) {
yyerror("typedef defined after its first reference: " + dtypedef->get_name());
} else {
yyerror("Duplicate typedef name: " + dtypedef->get_name());
}
}
}
;
@ -290,14 +299,20 @@ atomic_element:
}
parameter_value
{
if (!current_packer->end_pack()) {
yyerror("Invalid default value for type");
bool is_valid = $1->is_valid();
atomic_element = DCAtomicField::ElementType($1);
if (current_packer->end_pack()) {
atomic_element.set_default_value(current_packer->get_string());
} else {
atomic_element = DCAtomicField::ElementType($1);
atomic_element.set_default_value(current_packer->get_string());
current_atomic->add_element(atomic_element);
if (is_valid) {
yyerror("Invalid default value for type");
}
// If the current parameter isn't valid, we don't mind a pack
// error (there's no way for us to validate the syntax). So we'll
// just ignore the default value in this case.
}
current_atomic->add_element(atomic_element);
}
;
@ -333,11 +348,11 @@ type_name:
{
DCTypedef *dtypedef = dc_file->get_typedef_by_name($1);
if (dtypedef == (DCTypedef *)NULL) {
yyerror("Invalid type name");
} else {
$$ = dtypedef->make_new_parameter();
dtypedef = new DCTypedef($1);
dc_file->add_typedef(dtypedef);
}
$$ = dtypedef->make_new_parameter();
}
;

View File

@ -218,6 +218,18 @@ make_copy() const {
return new DCSimpleParameter(*this);
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::is_valid
// Access: Published, Virtual
// Description: Returns false if the type is an invalid type
// (e.g. declared from an undefined typedef), true if
// it is valid.
////////////////////////////////////////////////////////////////////
bool DCSimpleParameter::
is_valid() const {
return _type != ST_invalid;
}
////////////////////////////////////////////////////////////////////
// Function: DCSimpleParameter::get_type
// Access: Published

View File

@ -40,6 +40,7 @@ public:
PUBLISHED:
virtual DCSimpleParameter *as_simple_parameter();
virtual DCParameter *make_copy() const;
virtual bool is_valid() const;
DCSubatomicType get_type() const;
int get_divisor() const;

View File

@ -23,16 +23,31 @@
////////////////////////////////////////////////////////////////////
// Function: DCTypedef::Constructor
// Access: Protected
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
DCTypedef::
DCTypedef(DCParameter *parameter) :
_parameter(parameter),
_bogus_typedef(false),
_number(-1)
{
}
////////////////////////////////////////////////////////////////////
// Function: DCTypedef::Constructor
// Access: Public
// Description: Creates a bogus typedef reference.
////////////////////////////////////////////////////////////////////
DCTypedef::
DCTypedef(const string &name) :
_parameter(new DCSimpleParameter(ST_invalid)),
_bogus_typedef(true),
_number(-1)
{
_parameter->set_name(name);
}
////////////////////////////////////////////////////////////////////
// Function: DCTypedef::Destructor
// Access: Public, Virtual
@ -78,6 +93,20 @@ get_description() const {
return strm.str();
}
////////////////////////////////////////////////////////////////////
// Function: DCTypedef::is_bogus_typedef
// Access: Public
// Description: Returns true if the typedef has been flagged as a bogus
// typedef. This is set for typedefs that are generated by
// the parser as placeholder for missing typedefs, as
// when reading a partial file; it should not occur in a
// normal valid dc file.
////////////////////////////////////////////////////////////////////
bool DCTypedef::
is_bogus_typedef() const {
return _bogus_typedef;
}
////////////////////////////////////////////////////////////////////
// Function: DCTypedef::make_new_parameter
// Access: Public

View File

@ -32,6 +32,7 @@ class DCParameter;
class EXPCL_DIRECT DCTypedef {
public:
DCTypedef(DCParameter *parameter);
DCTypedef(const string &name);
~DCTypedef();
PUBLISHED:
@ -39,6 +40,8 @@ PUBLISHED:
const string &get_name() const;
string get_description() const;
bool is_bogus_typedef() const;
public:
DCParameter *make_new_parameter() const;
@ -47,6 +50,7 @@ public:
private:
DCParameter *_parameter;
bool _bogus_typedef;
int _number;
};