From 90c52414dbb3ebf1353909835aa858569b98936a Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 24 May 2005 18:29:21 +0000 Subject: [PATCH] support methods (atomic fields) as switch parameters --- direct/src/dcparser/dcParser.yxx | 23 +++++++++++++++++++-- direct/src/dcparser/dcSwitch.cxx | 25 +++++++++++++++++++---- direct/src/dcparser/dcSwitch.h | 7 ++++--- direct/src/dcparser/dcSwitchParameter.cxx | 2 +- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/direct/src/dcparser/dcParser.yxx b/direct/src/dcparser/dcParser.yxx index 62b86106a6..fe0f916ac3 100644 --- a/direct/src/dcparser/dcParser.yxx +++ b/direct/src/dcparser/dcParser.yxx @@ -158,6 +158,7 @@ dc_cleanup_parser() { %type parameter %type parameter_with_default %type parameter_definition +%type parameter_or_atomic %type import_identifier %type slash_identifier %type optional_name @@ -471,7 +472,13 @@ atomic_field: optional_name '(' { $$ = 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 ')' { @@ -584,6 +591,17 @@ parameter_with_default: | unnamed_parameter_with_default ; +parameter_or_atomic: + parameter +{ + $$ = $1; +} + | atomic_field +{ + $$ = $1; +} + ; + parameter_description: atomic_field no_server_flags { @@ -1211,7 +1229,7 @@ optional_name: ; switch: - KW_SWITCH optional_name '(' parameter ')' '{' + KW_SWITCH optional_name '(' parameter_or_atomic ')' '{' { $$ = current_switch; current_switch = new DCSwitch($2, $4); @@ -1253,6 +1271,7 @@ switch_case: { if (!current_packer->end_pack()) { yyerror("Invalid value for switch parameter"); + current_switch->add_invalid_case(); } else { int case_index = current_switch->add_case(current_packer->get_string()); if (case_index == -1) { diff --git a/direct/src/dcparser/dcSwitch.cxx b/direct/src/dcparser/dcSwitch.cxx index 666939dbe5..18923eff3d 100644 --- a/direct/src/dcparser/dcSwitch.cxx +++ b/direct/src/dcparser/dcSwitch.cxx @@ -31,7 +31,7 @@ // destructs. //////////////////////////////////////////////////////////////////// DCSwitch:: -DCSwitch(const string &name, DCParameter *key_parameter) : +DCSwitch(const string &name, DCField *key_parameter) : _name(name), _key_parameter(key_parameter) { @@ -46,7 +46,7 @@ DCSwitch(const string &name, DCParameter *key_parameter) : //////////////////////////////////////////////////////////////////// DCSwitch:: ~DCSwitch() { - nassertv(_key_parameter != (DCParameter *)NULL); + nassertv(_key_parameter != (DCField *)NULL); delete _key_parameter; Cases::iterator ci; @@ -106,7 +106,7 @@ get_name() const { // determines which one of the several cases within the // switch will be used. //////////////////////////////////////////////////////////////////// -DCParameter *DCSwitch:: +DCField *DCSwitch:: get_key_parameter() const { return _key_parameter; } @@ -231,6 +231,7 @@ int DCSwitch:: add_case(const string &value) { int case_index = (int)_cases.size(); if (!_cases_by_value.insert(CasesByValue::value_type(value, case_index)).second) { + add_invalid_case(); return -1; } @@ -240,6 +241,20 @@ add_case(const string &value) { 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 // Access: Public @@ -251,10 +266,12 @@ add_case(const string &value) { bool DCSwitch:: add_default() { if (_default_case != (SwitchFields *)NULL) { + add_invalid_case(); return false; } - _default_case = start_new_case(); + SwitchFields *fields = start_new_case(); + _default_case = fields; return true; } diff --git a/direct/src/dcparser/dcSwitch.h b/direct/src/dcparser/dcSwitch.h index 3e413f23b3..6228bb0df5 100644 --- a/direct/src/dcparser/dcSwitch.h +++ b/direct/src/dcparser/dcSwitch.h @@ -36,7 +36,7 @@ class DCField; //////////////////////////////////////////////////////////////////// class EXPCL_DIRECT DCSwitch : public DCDeclaration { public: - DCSwitch(const string &name, DCParameter *key_parameter); + DCSwitch(const string &name, DCField *key_parameter); virtual ~DCSwitch(); PUBLISHED: @@ -44,7 +44,7 @@ PUBLISHED: virtual const DCSwitch *as_switch() const; const string &get_name() const; - DCParameter *get_key_parameter() const; + DCField *get_key_parameter() const; int get_num_cases() const; int get_case_by_value(const string &case_value) const; @@ -58,6 +58,7 @@ PUBLISHED: public: bool is_field_valid() const; int add_case(const string &value); + void add_invalid_case(); bool add_default(); bool add_field(DCField *field); void add_break(); @@ -118,7 +119,7 @@ private: private: string _name; - DCParameter *_key_parameter; + DCField *_key_parameter; typedef pvector Cases; Cases _cases; diff --git a/direct/src/dcparser/dcSwitchParameter.cxx b/direct/src/dcparser/dcSwitchParameter.cxx index 6bbe980a58..e8b83167bb 100755 --- a/direct/src/dcparser/dcSwitchParameter.cxx +++ b/direct/src/dcparser/dcSwitchParameter.cxx @@ -44,7 +44,7 @@ DCSwitchParameter(const DCSwitch *dswitch) : _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_range_limits = _has_range_limits || key_parameter->has_range_limits(); _has_default_value = _has_default_value || key_parameter->has_default_value();