support methods (atomic fields) as switch parameters

This commit is contained in:
David Rose 2005-05-24 18:29:21 +00:00
parent b0276d5ddd
commit 90c52414db
4 changed files with 47 additions and 10 deletions

View File

@ -158,6 +158,7 @@ dc_cleanup_parser() {
%type <u.parameter> parameter %type <u.parameter> parameter
%type <u.parameter> parameter_with_default %type <u.parameter> parameter_with_default
%type <u.parameter> parameter_definition %type <u.parameter> parameter_definition
%type <u.field> parameter_or_atomic
%type <str> import_identifier %type <str> import_identifier
%type <str> slash_identifier %type <str> slash_identifier
%type <str> optional_name %type <str> optional_name
@ -471,7 +472,13 @@ atomic_field:
optional_name '(' optional_name '('
{ {
$$ = current_atomic; $$ = current_atomic;
current_atomic = new DCAtomicField($1, current_class); if (current_class == (DCClass *)NULL) {
yyerror("Cannot define a method outside of a struct or class.");
DCClass *temp_class = new DCClass(dc_file, "temp", false, false); // memory leak.
current_atomic = new DCAtomicField($1, temp_class);
} else {
current_atomic = new DCAtomicField($1, current_class);
}
} }
parameter_list ')' parameter_list ')'
{ {
@ -584,6 +591,17 @@ parameter_with_default:
| unnamed_parameter_with_default | unnamed_parameter_with_default
; ;
parameter_or_atomic:
parameter
{
$$ = $1;
}
| atomic_field
{
$$ = $1;
}
;
parameter_description: parameter_description:
atomic_field no_server_flags atomic_field no_server_flags
{ {
@ -1211,7 +1229,7 @@ optional_name:
; ;
switch: switch:
KW_SWITCH optional_name '(' parameter ')' '{' KW_SWITCH optional_name '(' parameter_or_atomic ')' '{'
{ {
$$ = current_switch; $$ = current_switch;
current_switch = new DCSwitch($2, $4); current_switch = new DCSwitch($2, $4);
@ -1253,6 +1271,7 @@ switch_case:
{ {
if (!current_packer->end_pack()) { if (!current_packer->end_pack()) {
yyerror("Invalid value for switch parameter"); yyerror("Invalid value for switch parameter");
current_switch->add_invalid_case();
} else { } else {
int case_index = current_switch->add_case(current_packer->get_string()); int case_index = current_switch->add_case(current_packer->get_string());
if (case_index == -1) { if (case_index == -1) {

View File

@ -31,7 +31,7 @@
// destructs. // destructs.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCSwitch:: DCSwitch::
DCSwitch(const string &name, DCParameter *key_parameter) : DCSwitch(const string &name, DCField *key_parameter) :
_name(name), _name(name),
_key_parameter(key_parameter) _key_parameter(key_parameter)
{ {
@ -46,7 +46,7 @@ DCSwitch(const string &name, DCParameter *key_parameter) :
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCSwitch:: DCSwitch::
~DCSwitch() { ~DCSwitch() {
nassertv(_key_parameter != (DCParameter *)NULL); nassertv(_key_parameter != (DCField *)NULL);
delete _key_parameter; delete _key_parameter;
Cases::iterator ci; Cases::iterator ci;
@ -106,7 +106,7 @@ get_name() const {
// determines which one of the several cases within the // determines which one of the several cases within the
// switch will be used. // switch will be used.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DCParameter *DCSwitch:: DCField *DCSwitch::
get_key_parameter() const { get_key_parameter() const {
return _key_parameter; return _key_parameter;
} }
@ -231,6 +231,7 @@ int DCSwitch::
add_case(const string &value) { add_case(const string &value) {
int case_index = (int)_cases.size(); int case_index = (int)_cases.size();
if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) { if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) {
add_invalid_case();
return -1; return -1;
} }
@ -240,6 +241,20 @@ add_case(const string &value) {
return case_index; return case_index;
} }
////////////////////////////////////////////////////////////////////
// Function: DCSwitch::add_invalid_case
// Access: Public
// Description: Adds a new case to the switch that will never be
// matched. This is only used by the parser, to handle
// an error condition more gracefully without bitching
// the parsing (which behaves differently according to
// whether a case has been encountered or not).
////////////////////////////////////////////////////////////////////
void DCSwitch::
add_invalid_case() {
start_new_case();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCSwitch::add_default // Function: DCSwitch::add_default
// Access: Public // Access: Public
@ -251,10 +266,12 @@ add_case(const string &value) {
bool DCSwitch:: bool DCSwitch::
add_default() { add_default() {
if (_default_case != (SwitchFields *)NULL) { if (_default_case != (SwitchFields *)NULL) {
add_invalid_case();
return false; return false;
} }
_default_case = start_new_case(); SwitchFields *fields = start_new_case();
_default_case = fields;
return true; return true;
} }

View File

@ -36,7 +36,7 @@ class DCField;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_DIRECT DCSwitch : public DCDeclaration { class EXPCL_DIRECT DCSwitch : public DCDeclaration {
public: public:
DCSwitch(const string &name, DCParameter *key_parameter); DCSwitch(const string &name, DCField *key_parameter);
virtual ~DCSwitch(); virtual ~DCSwitch();
PUBLISHED: PUBLISHED:
@ -44,7 +44,7 @@ PUBLISHED:
virtual const DCSwitch *as_switch() const; virtual const DCSwitch *as_switch() const;
const string &get_name() const; const string &get_name() const;
DCParameter *get_key_parameter() const; DCField *get_key_parameter() const;
int get_num_cases() const; int get_num_cases() const;
int get_case_by_value(const string &case_value) const; int get_case_by_value(const string &case_value) const;
@ -58,6 +58,7 @@ PUBLISHED:
public: public:
bool is_field_valid() const; bool is_field_valid() const;
int add_case(const string &value); int add_case(const string &value);
void add_invalid_case();
bool add_default(); bool add_default();
bool add_field(DCField *field); bool add_field(DCField *field);
void add_break(); void add_break();
@ -118,7 +119,7 @@ private:
private: private:
string _name; string _name;
DCParameter *_key_parameter; DCField *_key_parameter;
typedef pvector<SwitchCase *> Cases; typedef pvector<SwitchCase *> Cases;
Cases _cases; Cases _cases;

View File

@ -44,7 +44,7 @@ DCSwitchParameter(const DCSwitch *dswitch) :
_pack_type = PT_switch; _pack_type = PT_switch;
DCParameter *key_parameter = dswitch->get_key_parameter(); DCField *key_parameter = dswitch->get_key_parameter();
_has_fixed_byte_size = _has_fixed_byte_size && key_parameter->has_fixed_byte_size(); _has_fixed_byte_size = _has_fixed_byte_size && key_parameter->has_fixed_byte_size();
_has_range_limits = _has_range_limits || key_parameter->has_range_limits(); _has_range_limits = _has_range_limits || key_parameter->has_range_limits();
_has_default_value = _has_default_value || key_parameter->has_default_value(); _has_default_value = _has_default_value || key_parameter->has_default_value();