Browse Source

add customizable dc keywords

David Rose 20 years ago
parent
commit
2cc8ea03b8

+ 4 - 1
direct/src/dcparser/Sources.pp

@@ -18,7 +18,9 @@
   #define SOURCES \
   #define SOURCES \
      dcAtomicField.h dcClass.h dcClass.I \
      dcAtomicField.h dcClass.h dcClass.I \
      dcDeclaration.h \
      dcDeclaration.h \
-     dcField.h dcFile.h dcLexer.lxx  \
+     dcField.h dcFile.h \
+     dcKeyword.h dcKeywordList.h \
+     dcLexer.lxx  \
      dcLexerDefs.h dcMolecularField.h dcParser.yxx dcParserDefs.h  \
      dcLexerDefs.h dcMolecularField.h dcParser.yxx dcParserDefs.h  \
      dcSubatomicType.h \
      dcSubatomicType.h \
      dcPackData.h dcPackData.I \
      dcPackData.h dcPackData.I \
@@ -38,6 +40,7 @@
      dcAtomicField.cxx dcClass.cxx \
      dcAtomicField.cxx dcClass.cxx \
      dcDeclaration.cxx \
      dcDeclaration.cxx \
      dcField.cxx dcFile.cxx \
      dcField.cxx dcFile.cxx \
+     dcKeyword.cxx dcKeywordList.cxx \
      dcMolecularField.cxx dcSubatomicType.cxx \
      dcMolecularField.cxx dcSubatomicType.cxx \
      dcPackData.cxx \
      dcPackData.cxx \
      dcPacker.cxx \
      dcPacker.cxx \

+ 3 - 2
direct/src/dcparser/dcAtomicField.cxx

@@ -202,7 +202,7 @@ output(ostream &out, bool brief) const {
   }
   }
   out << ")";
   out << ")";
 
 
-  output_flags(out);
+  output_keywords(out);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -237,7 +237,8 @@ generate_hash(HashGenerator &hashgen) const {
   for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
   for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
     (*ei)->generate_hash(hashgen);
     (*ei)->generate_hash(hashgen);
   }
   }
-  hashgen.add_int(get_flags());
+
+  DCKeywordList::generate_hash(hashgen);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 9 - 89
direct/src/dcparser/dcField.cxx

@@ -38,7 +38,6 @@ DCField()
 #endif
 #endif
 {
 {
   _number = -1;
   _number = -1;
-  _flags = 0;
   _has_default_value = false;
   _has_default_value = false;
   _default_value_stale = true;
   _default_value_stale = true;
 
 
@@ -65,7 +64,6 @@ DCField(const string &name, DCClass *dclass) :
 #endif
 #endif
 {
 {
   _number = -1;
   _number = -1;
-  _flags = 0;
   _has_default_value = false;
   _has_default_value = false;
   _default_value_stale = true;
   _default_value_stale = true;
 
 
@@ -288,7 +286,7 @@ get_default_value() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_required() const {
 is_required() const {
-  return (_flags & F_required) != 0;
+  return has_keyword("required");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -299,7 +297,7 @@ is_required() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_broadcast() const {
 is_broadcast() const {
-  return (_flags & F_broadcast) != 0;
+  return has_keyword("broadcast");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -310,7 +308,7 @@ is_broadcast() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_p2p() const {
 is_p2p() const {
-  return (_flags & F_p2p) != 0;
+  return has_keyword("p2p");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -321,7 +319,7 @@ is_p2p() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_ram() const {
 is_ram() const {
-  return (_flags & F_ram) != 0;
+  return has_keyword("ram");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -332,7 +330,7 @@ is_ram() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_db() const {
 is_db() const {
-  return (_flags & F_db) != 0;
+  return has_keyword("db");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -343,7 +341,7 @@ is_db() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_clsend() const {
 is_clsend() const {
-  return (_flags & F_clsend) != 0;
+  return has_keyword("clsend");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -354,7 +352,7 @@ is_clsend() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_clrecv() const {
 is_clrecv() const {
-  return (_flags & F_clrecv) != 0;
+  return has_keyword("clrecv");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -365,7 +363,7 @@ is_clrecv() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_ownsend() const {
 is_ownsend() const {
-  return (_flags & F_ownsend) != 0;
+  return has_keyword("ownsend");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -376,19 +374,7 @@ is_ownsend() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 bool DCField::
 is_airecv() const {
 is_airecv() const {
-  return (_flags & F_airecv) != 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::compare_flags
-//       Access: Published
-//  Description: Returns true if this field has the same flags
-//               settings as the other field, false if some flags
-//               differ.
-////////////////////////////////////////////////////////////////////
-bool DCField::
-compare_flags(const DCField &other) const {
-  return _flags == other._flags;
+  return has_keyword("airecv");
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -720,36 +706,6 @@ set_default_value(const string &default_value) {
   _default_value_stale = false;
   _default_value_stale = false;
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::add_flag
-//       Access: Public
-//  Description: Adds a new flag to the field.
-////////////////////////////////////////////////////////////////////
-void DCField::
-add_flag(enum Flags flag) {
-  _flags |= flag;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::set_flags
-//       Access: Public
-//  Description: Resets the flag bitmask to the indicated value.
-////////////////////////////////////////////////////////////////////
-void DCField::
-set_flags(int flags) {
-  _flags = flags;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::get_flags
-//       Access: Public
-//  Description: Returns the complete flag bitmask.
-////////////////////////////////////////////////////////////////////
-int DCField::
-get_flags() const {
-  return _flags;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DCField::refresh_default_value
 //     Function: DCField::refresh_default_value
 //       Access: Protected
 //       Access: Protected
@@ -768,39 +724,3 @@ refresh_default_value() {
   }
   }
   _default_value_stale = false;
   _default_value_stale = false;
 }
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::output_flags
-//       Access: Protected
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void DCField::
-output_flags(ostream &out) const {
-  if ((_flags & F_required) != 0) {
-    out << " required";
-  }
-  if ((_flags & F_broadcast) != 0) {
-    out << " broadcast";
-  }
-  if ((_flags & F_p2p) != 0) {
-    out << " p2p";
-  }
-  if ((_flags & F_ram) != 0) {
-    out << " ram";
-  }
-  if ((_flags & F_db) != 0) {
-    out << " db";
-  }
-  if ((_flags & F_clsend) != 0) {
-    out << " clsend";
-  }
-  if ((_flags & F_clrecv) != 0) {
-    out << " clrecv";
-  }
-  if ((_flags & F_ownsend) != 0) {
-    out << " ownsend";
-  }
-  if ((_flags & F_airecv) != 0) {
-    out << " airecv";
-  }
-}

+ 2 - 28
direct/src/dcparser/dcField.h

@@ -21,6 +21,7 @@
 
 
 #include "dcbase.h"
 #include "dcbase.h"
 #include "dcPackerInterface.h"
 #include "dcPackerInterface.h"
+#include "dcKeywordList.h"
 #include "dcPython.h"
 #include "dcPython.h"
 
 
 #ifdef WITHIN_PANDA
 #ifdef WITHIN_PANDA
@@ -40,7 +41,7 @@ class HashGenerator;
 // Description : A single field of a Distributed Class, either atomic
 // Description : A single field of a Distributed Class, either atomic
 //               or molecular.
 //               or molecular.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_DIRECT DCField : public DCPackerInterface {
+class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
 public:
 public:
   DCField();
   DCField();
   DCField(const string &name, DCClass *dclass);
   DCField(const string &name, DCClass *dclass);
@@ -76,8 +77,6 @@ PUBLISHED:
   bool is_ownsend() const;
   bool is_ownsend() const;
   bool is_airecv() const;
   bool is_airecv() const;
 
 
-  bool compare_flags(const DCField &other) const;
-
   void output(ostream &out) const;
   void output(ostream &out) const;
   void write(ostream &out, int indent_level) const;
   void write(ostream &out, int indent_level) const;
 
 
@@ -101,31 +100,8 @@ public:
   void set_number(int number);
   void set_number(int number);
   void set_default_value(const string &default_value);
   void set_default_value(const string &default_value);
 
 
-  enum Flags {
-    F_required        = 0x0001,
-    F_broadcast       = 0x0002,
-    F_p2p             = 0x0004,
-    F_ram             = 0x0008,
-    F_db              = 0x0010,
-    F_clsend          = 0x0020,
-    F_clrecv          = 0x0040,
-    F_ownsend         = 0x0080,
-    F_airecv          = 0x0100,
-
-    // These are reserved for client code use; they are not set or
-    // cleared by any code in this module.
-    F_user_1          = 0x1000,
-    F_user_2          = 0x2000,
-    F_user_3          = 0x4000,
-    F_user_4          = 0x8000,
-  };
-  void add_flag(enum Flags flag);
-  void set_flags(int flags);
-  int get_flags() const;
-
 protected:
 protected:
   void refresh_default_value();
   void refresh_default_value();
-  void output_flags(ostream &out) const;
 
 
 protected:
 protected:
   int _number;
   int _number;
@@ -133,8 +109,6 @@ protected:
   bool _has_default_value;
   bool _has_default_value;
 
 
 private:
 private:
-  int _flags;  // A bitmask union of any of the above values.
-
   string _default_value;
   string _default_value;
 
 
 #ifdef WITHIN_PANDA
 #ifdef WITHIN_PANDA

+ 105 - 0
direct/src/dcparser/dcFile.cxx

@@ -22,6 +22,7 @@
 #include "dcParserDefs.h"
 #include "dcParserDefs.h"
 #include "dcLexerDefs.h"
 #include "dcLexerDefs.h"
 #include "dcTypedef.h"
 #include "dcTypedef.h"
+#include "dcKeyword.h"
 #include "hashGenerator.h"
 #include "hashGenerator.h"
 
 
 #ifdef WITHIN_PANDA
 #ifdef WITHIN_PANDA
@@ -41,6 +42,8 @@
 DCFile::
 DCFile::
 DCFile() {
 DCFile() {
   _all_objects_valid = true;
   _all_objects_valid = true;
+
+  setup_default_keywords();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -74,8 +77,10 @@ clear() {
   _things_by_name.clear();
   _things_by_name.clear();
   _typedefs.clear();
   _typedefs.clear();
   _typedefs_by_name.clear();
   _typedefs_by_name.clear();
+  _keywords.clear_keywords();
   _declarations.clear();
   _declarations.clear();
   _things_to_delete.clear();
   _things_to_delete.clear();
+  setup_default_keywords();
 
 
   _all_objects_valid = true;
   _all_objects_valid = true;
 }
 }
@@ -439,6 +444,48 @@ get_typedef_by_name(const string &name) const {
   return NULL;
   return NULL;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_num_keywords
+//       Access: Published
+//  Description: Returns the number of keywords read from the .dc
+//               file(s).
+////////////////////////////////////////////////////////////////////
+int DCFile::
+get_num_keywords() const {
+  return _keywords.get_num_keywords();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_keyword
+//       Access: Published
+//  Description: Returns the nth keyword read from the .dc file(s).
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCFile::
+get_keyword(int n) const {
+  return _keywords.get_keyword(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_keyword_by_name
+//       Access: Published
+//  Description: Returns the keyword that has the indicated name, or
+//               NULL if there is no such keyword name.
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCFile::
+get_keyword_by_name(const string &name) const {
+  const DCKeyword *keyword = _keywords.get_keyword_by_name(name);
+  if (keyword == (const DCKeyword *)NULL) {
+    keyword = _default_keywords.get_keyword_by_name(name);
+    if (keyword != (const DCKeyword *)NULL) {
+      // One of the historical default keywords was used, but wasn't
+      // defined.  Define it implicitly right now.
+      ((DCFile *)this)->_keywords.add_keyword(keyword);
+    }
+  }
+
+  return keyword;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DCFile::get_hash
 //     Function: DCFile::get_hash
 //       Access: Published
 //       Access: Published
@@ -597,6 +644,28 @@ add_typedef(DCTypedef *dtypedef) {
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::add_keyword
+//       Access: Public
+//  Description: Adds the indicated keyword string to the list of
+//               keywords known to the DCFile.  These keywords may
+//               then be added to DCFields.  It is not an error to add
+//               a particular keyword more than once.
+////////////////////////////////////////////////////////////////////
+bool DCFile::
+add_keyword(const string &name) {
+  DCKeyword *keyword = new DCKeyword(name);
+  bool added = _keywords.add_keyword(keyword);
+
+  if (added) {
+    _declarations.push_back(keyword);
+  } else {
+    delete keyword;
+  }
+
+  return added;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: DCFile::add_thing_to_delete
 //     Function: DCFile::add_thing_to_delete
 //       Access: Public
 //       Access: Public
@@ -624,3 +693,39 @@ set_new_index_number(DCField *field) {
   field->set_number((int)_fields_by_index.size());
   field->set_number((int)_fields_by_index.size());
   _fields_by_index.push_back(field);
   _fields_by_index.push_back(field);
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::setup_default_keywords
+//       Access: Public
+//  Description: Adds an entry for each of the default keywords that
+//               are defined for every DCFile for legacy reasons.
+////////////////////////////////////////////////////////////////////
+void DCFile::
+setup_default_keywords() {
+  struct KeywordDef {
+    const char *name;
+    int flag;
+  };
+  static KeywordDef default_keywords[] = {
+    { "required", 0x0001 },
+    { "broadcast", 0x0002 },
+    { "p2p", 0x0004 },
+    { "ram", 0x0008 },
+    { "db", 0x0010 },
+    { "clsend", 0x0020 },
+    { "clrecv", 0x0040 },
+    { "ownsend", 0x0080 },
+    { "airecv", 0x0100 },
+    { NULL, 0 }
+  };
+
+  _default_keywords.clear_keywords();
+  for (int i = 0; default_keywords[i].name != NULL; ++i) {
+    DCKeyword *keyword = 
+      new DCKeyword(default_keywords[i].name, 
+                    default_keywords[i].flag);
+    
+    _default_keywords.add_keyword(keyword);
+    _things_to_delete.push_back(keyword);
+  }
+}

+ 12 - 0
direct/src/dcparser/dcFile.h

@@ -20,12 +20,14 @@
 #define DCFILE_H
 #define DCFILE_H
 
 
 #include "dcbase.h"
 #include "dcbase.h"
+#include "dcKeywordList.h"
 
 
 class DCClass;
 class DCClass;
 class DCSwitch;
 class DCSwitch;
 class DCField;
 class DCField;
 class HashGenerator;
 class HashGenerator;
 class DCTypedef;
 class DCTypedef;
+class DCKeyword;
 class DCDeclaration;
 class DCDeclaration;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -68,6 +70,10 @@ PUBLISHED:
   DCTypedef *get_typedef(int n) const;
   DCTypedef *get_typedef(int n) const;
   DCTypedef *get_typedef_by_name(const string &name) const;
   DCTypedef *get_typedef_by_name(const string &name) const;
 
 
+  int get_num_keywords() const;
+  const DCKeyword *get_keyword(int n) const;
+  const DCKeyword *get_keyword_by_name(const string &name) const;
+
   unsigned long get_hash() const;
   unsigned long get_hash() const;
 
 
 public:
 public:
@@ -77,11 +83,14 @@ public:
   void add_import_module(const string &import_module);
   void add_import_module(const string &import_module);
   void add_import_symbol(const string &import_symbol);
   void add_import_symbol(const string &import_symbol);
   bool add_typedef(DCTypedef *dtypedef);
   bool add_typedef(DCTypedef *dtypedef);
+  bool add_keyword(const string &name);
   void add_thing_to_delete(DCDeclaration *decl);
   void add_thing_to_delete(DCDeclaration *decl);
 
 
   void set_new_index_number(DCField *field);
   void set_new_index_number(DCField *field);
 
 
 private:
 private:
+  void setup_default_keywords();
+
   typedef pvector<DCClass *> Classes;
   typedef pvector<DCClass *> Classes;
   Classes _classes;
   Classes _classes;
 
 
@@ -104,6 +113,9 @@ private:
   typedef pmap<string, DCTypedef *> TypedefsByName;
   typedef pmap<string, DCTypedef *> TypedefsByName;
   TypedefsByName _typedefs_by_name;
   TypedefsByName _typedefs_by_name;
 
 
+  DCKeywordList _keywords;
+  DCKeywordList _default_keywords;
+
   typedef pvector<DCDeclaration *> Declarations;
   typedef pvector<DCDeclaration *> Declarations;
   Declarations _declarations;
   Declarations _declarations;
   Declarations _things_to_delete;
   Declarations _things_to_delete;

+ 111 - 0
direct/src/dcparser/dcKeyword.cxx

@@ -0,0 +1,111 @@
+// Filename: dcKeyword.cxx
+// Created by:  drose (22Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dcKeyword.h"
+#include "hashGenerator.h"
+#include "dcindent.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCKeyword::
+DCKeyword(const string &name, int historical_flag) :
+  _name(name),
+  _historical_flag(historical_flag)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCKeyword::
+~DCKeyword() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::get_name
+//       Access: Published
+//  Description: Returns the name of this keyword.
+////////////////////////////////////////////////////////////////////
+const string &DCKeyword::
+get_name() const {
+  return _name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::get_historical_flag
+//       Access: Public
+//  Description: Returns the bitmask associated with this keyword, if
+//               any.  This is the value that was historically
+//               associated with this keyword, and was used to
+//               generate a hash code before we had user-customizable
+//               keywords.  It will return ~0 if this is not an
+//               historical keyword.
+////////////////////////////////////////////////////////////////////
+int DCKeyword::
+get_historical_flag() const {
+  return _historical_flag;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::clear_historical_flag
+//       Access: Public
+//  Description: Resets the historical flag to ~0, as if the keyword
+//               were not one of the historically defined keywords.
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+clear_historical_flag() {
+  _historical_flag = ~0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function : DCKeyword::output
+//       Access : Public, Virtual
+//  Description : Write a string representation of this instance to
+//                <out>.
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+output(ostream &out, bool brief) const {
+  out << "keyword " << _name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::write
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+write(ostream &out, bool, int indent_level) const {
+  indent(out, indent_level)
+    << "keyword " << _name << ";\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::generate_hash
+//       Access: Public
+//  Description: Accumulates the properties of this keyword into the
+//               hash.
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+generate_hash(HashGenerator &hashgen) const {
+  hashgen.add_string(_name);
+}

+ 59 - 0
direct/src/dcparser/dcKeyword.h

@@ -0,0 +1,59 @@
+// Filename: dcKeyword.h
+// Created by:  drose (22Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DCKEYWORD_H
+#define DCKEYWORD_H
+
+#include "dcbase.h"
+#include "dcDeclaration.h"
+
+class DCParameter;
+class HashGenerator;
+
+////////////////////////////////////////////////////////////////////
+//       Class : DCKeyword
+// Description : This represents a single keyword declaration in the
+//               dc file.  It is used to define a communication
+//               property associated with a field, for instance
+//               "broadcast" or "airecv".
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+public:
+  DCKeyword(const string &name, int historical_flag = ~0);
+  virtual ~DCKeyword();
+
+PUBLISHED:
+  const string &get_name() const;
+
+public:
+  int get_historical_flag() const;
+  void clear_historical_flag();
+
+  virtual void output(ostream &out, bool brief) const;
+  virtual void write(ostream &out, bool brief, int indent_level) const;
+  void generate_hash(HashGenerator &hashgen) const;
+
+private:
+  const string _name;
+
+  // This flag is only kept for historical reasons, so we can preserve
+  // the file's hash code if no new flags are in use.
+  int _historical_flag;
+};
+
+#endif

+ 220 - 0
direct/src/dcparser/dcKeywordList.cxx

@@ -0,0 +1,220 @@
+// Filename: dcKeywordList.cxx
+// Created by:  drose (25Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dcKeywordList.h"
+#include "dcKeyword.h"
+#include "hashGenerator.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCKeywordList::
+DCKeywordList() :
+  _flags(0)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCKeywordList::
+DCKeywordList(const DCKeywordList &copy) :
+  _keywords(copy._keywords),
+  _keywords_by_name(copy._keywords_by_name),
+  _flags(copy._flags)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Copy Assignment Operator
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+operator = (const DCKeywordList &copy) {
+  _keywords = copy._keywords;
+  _keywords_by_name = copy._keywords_by_name;
+  _flags = copy._flags;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCKeywordList::
+~DCKeywordList() {
+  nassertv(_keywords_by_name.size() == _keywords.size());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::has_keyword
+//       Access: Published
+//  Description: Returns true if this list includes the indicated
+//               keyword, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+has_keyword(const string &name) const {
+  return (_keywords_by_name.find(name) != _keywords_by_name.end());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::has_keyword
+//       Access: Published
+//  Description: Returns true if this list includes the indicated
+//               keyword, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+has_keyword(const DCKeyword *keyword) const {
+  return has_keyword(keyword->get_name());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::get_num_keywords
+//       Access: Published
+//  Description: Returns the number of keywords in the list.
+////////////////////////////////////////////////////////////////////
+int DCKeywordList::
+get_num_keywords() const {
+  nassertr(_keywords_by_name.size() == _keywords.size(), 0);
+  return _keywords.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::get_keyword
+//       Access: Published
+//  Description: Returns the nth keyword in the list.
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCKeywordList::
+get_keyword(int n) const {
+  nassertr(n >= 0 && n < (int)_keywords.size(), NULL);
+  return _keywords[n];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::get_keyword_by_name
+//       Access: Published
+//  Description: Returns the keyword in the list with the indicated
+//               name, or NULL if there is no keyword in the list with
+//               that name.
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCKeywordList::
+get_keyword_by_name(const string &name) const {
+  KeywordsByName::const_iterator ni;
+  ni = _keywords_by_name.find(name);
+  if (ni != _keywords_by_name.end()) {
+    return (*ni).second;
+  }
+
+  return NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::compare_keywords
+//       Access: Published
+//  Description: Returns true if this list has the same keywords
+//               as the other list, false if some keywords differ.
+//               Order is not considered important.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+compare_keywords(const DCKeywordList &other) const {
+  return _keywords_by_name == other._keywords_by_name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::copy_keywords
+//       Access: Public
+//  Description: Replaces this keyword list with those from the other
+//               list.
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+copy_keywords(const DCKeywordList &other) {
+  (*this) = other;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::add_keyword
+//       Access: Public
+//  Description: Adds the indicated keyword to the list.  Returns true
+//               if it is added, false if it was already there.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+add_keyword(const DCKeyword *keyword) {
+  bool inserted = _keywords_by_name.insert(KeywordsByName::value_type(keyword->get_name(), keyword)).second;
+  if (inserted) {
+    _keywords.push_back(keyword);
+    _flags |= keyword->get_historical_flag();
+  }
+
+  return inserted;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::clear_keywords
+//       Access: Public
+//  Description: Removes all keywords from the field.
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+clear_keywords() {
+  _keywords.clear();
+  _keywords_by_name.clear();
+  _flags = 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::output_keywords
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+output_keywords(ostream &out) const {
+  Keywords::const_iterator ki;
+  for (ki = _keywords.begin(); ki != _keywords.end(); ++ki) {
+    out << " " << (*ki)->get_name();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::generate_hash
+//       Access: Public
+//  Description: Accumulates the properties of these keywords into the
+//               hash.
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+generate_hash(HashGenerator &hashgen) const {
+  if (_flags != ~0) {
+    // All of the flags are historical flags only, so add just the
+    // flags bitmask to keep the hash code the same as it has
+    // historically been.
+    hashgen.add_int(_flags);
+
+  } else {
+    // There is at least one custom flag, so go ahead and make the
+    // hash code reflect it.
+
+    hashgen.add_int(_keywords_by_name.size());
+    KeywordsByName::const_iterator ni;
+    for (ni = _keywords_by_name.begin(); ni != _keywords_by_name.end(); ++ni) {
+      (*ni).second->generate_hash(hashgen);
+    }
+  }
+}

+ 67 - 0
direct/src/dcparser/dcKeywordList.h

@@ -0,0 +1,67 @@
+// Filename: dcKeywordList.h
+// Created by:  drose (25Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DCKEYWORDLIST_H
+#define DCKEYWORDLIST_H
+
+#include "dcbase.h"
+
+class DCKeyword;
+class HashGenerator;
+
+////////////////////////////////////////////////////////////////////
+//       Class : DCKeywordList
+// Description : This is a list of keywords (see DCKeyword) that may
+//               be set on a particular field.
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT DCKeywordList {
+public:
+  DCKeywordList();
+  DCKeywordList(const DCKeywordList &copy);
+  void operator = (const DCKeywordList &copy);
+  ~DCKeywordList();
+
+PUBLISHED:
+  bool has_keyword(const string &name) const;
+  bool has_keyword(const DCKeyword *keyword) const;
+  int get_num_keywords() const;
+  const DCKeyword *get_keyword(int n) const;
+  const DCKeyword *get_keyword_by_name(const string &name) const;
+
+  bool compare_keywords(const DCKeywordList &other) const;
+
+public:
+  void copy_keywords(const DCKeywordList &other);
+
+  bool add_keyword(const DCKeyword *keyword);
+  void clear_keywords();
+
+  void output_keywords(ostream &out) const;
+  void generate_hash(HashGenerator &hashgen) const;
+
+private:
+  typedef pvector<const DCKeyword *> Keywords;
+  Keywords _keywords;
+
+  typedef pmap<string, const DCKeyword *> KeywordsByName;
+  KeywordsByName _keywords_by_name;
+
+  int _flags;
+};
+
+#endif

+ 218 - 290
direct/src/dcparser/dcLexer.cxx.prebuilt

@@ -300,32 +300,28 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 	*yy_cp = '\0'; \
 	*yy_cp = '\0'; \
 	yy_c_buf_p = yy_cp;
 	yy_c_buf_p = yy_cp;
 
 
-#define YY_NUM_RULES 52
-#define YY_END_OF_BUFFER 53
-static yyconst short int yy_accept[201] =
+#define YY_NUM_RULES 44
+#define YY_END_OF_BUFFER 45
+static yyconst short int yy_accept[165] =
     {   0,
     {   0,
-        0,    0,   53,   51,    2,    1,   47,   48,   51,   51,
-       51,   43,   43,   49,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   50,    1,    0,   44,
-       46,    4,    3,   46,   43,   45,   50,   50,   50,   50,
-       50,   50,   50,   38,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   50,   50,    0,    3,
-       45,   50,   50,   50,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   36,   37,   50,   50,
-       50,   50,   50,    0,   46,   50,   24,   50,   50,   11,
-       33,   50,   50,   50,   50,   50,    7,   50,   50,   50,
-
-       50,   14,   50,   50,   50,   50,   50,   50,   50,   50,
-       50,   13,   50,   50,   50,   50,   50,   50,   50,   15,
-       16,   17,   50,   50,   50,   50,   50,   50,   50,   50,
-       50,   50,   18,   42,   25,   50,   40,   39,    5,   50,
-       50,    8,   50,   50,   50,   50,   50,   23,    6,   10,
-       50,   19,   20,   21,   50,   50,   12,   22,   50,   50,
-       50,   41,   50,    9,   50,   50,   50,   50,   50,   50,
-       50,   50,   34,   50,   50,   50,   50,   35,   50,   50,
-       26,   50,   50,   50,   50,   27,   28,   50,   50,   50,
-       29,   30,   31,   50,   50,   50,   50,   50,   32,    0
-
+        0,    0,   45,   43,    2,    1,   39,   40,   43,   43,
+       43,   35,   35,   41,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,    1,    0,   36,   38,    4,    3,
+       38,   35,   37,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,    0,
+        3,   37,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,    0,   38,   25,
+       42,   12,   34,   42,   42,   42,    7,   42,   42,   42,
+       42,   15,   42,   42,   42,   42,   42,   42,   42,   14,
+       42,   42,   42,   42,   16,   17,   18,   42,   42,   42,
+
+       42,   42,   42,   42,   42,   42,   19,   26,    5,   42,
+       42,    8,   42,   42,   42,   42,   24,    6,   11,   42,
+       20,   21,   22,   42,   13,   23,   42,   42,   42,    9,
+       10,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   27,   42,   42,   42,   42,   28,
+       29,   42,   42,   42,   30,   31,   32,   42,   42,   42,
+       42,   42,   33,    0
     } ;
     } ;
 
 
 static yyconst int yy_ec[256] =
 static yyconst int yy_ec[256] =
@@ -342,8 +338,8 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,   21,    1,   22,   23,   24,   25,
         1,    1,    1,    1,   21,    1,   22,   23,   24,   25,
 
 
        26,   27,   28,   29,   30,   21,   31,   32,   33,   34,
        26,   27,   28,   29,   30,   21,   31,   32,   33,   34,
-       35,   36,   37,   38,   39,   40,   41,   42,   43,   44,
-       45,   21,    1,    1,    1,    1,    1,    1,    1,    1,
+       35,   36,   21,   37,   38,   39,   40,   21,   41,   42,
+       43,   21,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -360,137 +356,123 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,    1
         1,    1,    1,    1,    1
     } ;
     } ;
 
 
-static yyconst int yy_meta[46] =
+static yyconst int yy_meta[44] =
     {   0,
     {   0,
         1,    1,    2,    1,    1,    1,    3,    4,    1,    5,
         1,    1,    2,    1,    1,    1,    3,    4,    1,    5,
         5,    5,    5,    5,    5,    5,    5,    1,    6,    6,
         5,    5,    5,    5,    5,    5,    5,    1,    6,    6,
         7,    6,    6,    6,    6,    6,    6,    7,    7,    7,
         7,    6,    6,    6,    6,    6,    6,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    7,    7,    8,    7
+        7,    8,    7
     } ;
     } ;
 
 
-static yyconst short int yy_base[209] =
+static yyconst short int yy_base[173] =
     {   0,
     {   0,
-        0,    0,  244,  245,  245,    0,  245,  245,  235,    0,
-       40,   39,   40,  245,    0,  212,   18,   29,   29,   22,
-       29,  198,  228,   42,   26,  194,  208,    0,    0,  229,
-       39,  245,    0,    0,    0,    0,    0,  198,  200,   41,
-      195,  211,   32,    0,  200,  204,  195,  194,  192,  187,
-      192,  189,  191,  186,  184,  191,  184,  185,  211,    0,
-        0,  191,  193,  193,  192,  187,  174,  185,  184,  187,
-      186,  185,  173,  170,   61,  165,    0,    0,  162,   45,
-      162,  175,  160,  192,  191,  173,  183,  164,  169,    0,
-        0,  169,  158,  152,  149,  149,    0,  150,  171,  174,
-
-      171,  162,  157,  152,  147,  156,  155,  153,   74,  135,
-      164,    0,  151,  132,  148,  133,  139,  154,  129,  146,
-      145,    0,  128,  131,  126,  135,  122,  132,  134,  143,
-      146,  143,  134,    0,    0,  133,    0,    0,    0,  114,
-      139,    0,  114,  113,  112,  124,  122,    0,    0,    0,
-      120,  124,   51,    0,  107,  105,    0,    0,  105,  104,
-      119,    0,  115,    0,  101,  100,  107,   98,   95,  112,
-      111,   87,    0,   93,   92,   95,  106,    0,   82,   81,
-        0,  103,  101,   73,   61,    0,    0,   60,   49,   72,
-        0,    0,    0,   66,   44,   43,   58,   34,    0,  245,
-
-       92,   97,   52,   99,  103,  111,  115,  119
+        0,    0,  209,  210,  210,    0,  210,  210,  200,    0,
+       38,   37,   38,  210,    0,   16,   27,   26,   22,   24,
+      181,   21,  163,  175,    0,    0,  196,   35,  210,    0,
+        0,    0,    0,    0,  168,  176,  163,  178,  167,  171,
+      162,  161,  159,  155,  150,  155,  161,  154,  155,  181,
+        0,    0,  164,  164,  159,  147,  161,  160,  159,  147,
+      144,   52,  137,   34,  138,  150,  136,  167,  166,  159,
+      140,    0,    0,  132,  129,  129,    0,  130,  150,  153,
+      150,  141,  127,  127,  136,  135,  133,   59,  145,    0,
+      118,  123,  138,  114,  130,  129,    0,  113,  112,  120,
+
+      108,  117,  119,  128,  131,  128,  119,    0,    0,  101,
+      125,    0,  101,  100,   99,  110,    0,    0,    0,  107,
+      111,   44,    0,   95,    0,    0,   94,   93,  107,    0,
+        0,   91,   90,   96,   88,  102,  101,   79,   84,   83,
+       85,   96,   74,   72,    0,   83,   76,   58,   43,    0,
+        0,   40,   39,   64,    0,    0,    0,   56,   40,   36,
+       49,   24,    0,  210,   84,   89,   46,   91,   95,  103,
+      107,  111
     } ;
     } ;
 
 
-static yyconst short int yy_def[209] =
+static yyconst short int yy_def[173] =
     {   0,
     {   0,
-      200,    1,  200,  200,  200,  201,  200,  200,  202,  203,
-      200,  204,  204,  200,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  201,  203,  202,
-      203,  200,  206,   31,   13,  207,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  208,  206,
-      207,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  208,  208,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,    0,
-
-      200,  200,  200,  200,  200,  200,  200,  200
+      164,    1,  164,  164,  164,  165,  164,  164,  166,  167,
+      164,  168,  168,  164,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  165,  167,  166,  167,  164,  170,
+       28,   13,  171,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  172,
+      170,  171,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  172,  172,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,    0,  164,  164,  164,  164,  164,  164,
+      164,  164
     } ;
     } ;
 
 
-static yyconst short int yy_nxt[291] =
+static yyconst short int yy_nxt[254] =
     {   0,
     {   0,
         4,    5,    6,    7,    8,    4,    9,   10,   11,   12,
         4,    5,    6,    7,    8,    4,    9,   10,   11,   12,
        13,   13,   13,   13,   13,   13,   13,   14,   15,   15,
        13,   13,   13,   13,   13,   13,   13,   14,   15,   15,
-       15,   16,   17,   18,   19,   15,   20,   15,   15,   21,
-       15,   15,   15,   15,   22,   23,   15,   24,   25,   26,
-       27,   15,   15,   15,   15,   32,   34,   34,   33,   39,
-       41,   44,   45,   47,   46,   40,   31,   42,   59,   48,
-       43,   49,   50,   53,   59,   55,   64,   54,   56,   68,
-       69,   99,  166,  100,  105,   65,  101,  102,  199,  198,
-      197,  196,   36,  200,  130,  106,  131,  195,  194,  132,
-      133,  167,   28,  193,   28,   28,   28,   28,   28,   28,
-
-       30,   30,   35,   35,  192,  191,   35,   37,   37,   37,
-       37,   60,  190,   60,   60,   60,   60,   60,   60,   61,
-       61,   85,  189,   85,  188,  187,  186,  185,  184,  183,
-      182,  181,  180,  179,  178,  177,  176,  175,  174,  173,
-      172,  171,  170,  169,  168,  165,  164,  163,  162,  161,
-      160,  159,  158,  157,  156,  155,  154,  153,  152,  151,
-      150,  149,  148,  147,  146,  145,  144,  143,  142,  141,
-      140,  139,  138,  137,  136,  135,  134,  129,  128,  127,
-      126,  125,  124,  123,  122,  121,  120,  119,  118,  117,
-      116,  115,  114,  113,  112,  111,  110,  200,  200,  109,
-
-      108,  107,  104,  103,   98,   97,   96,   95,   94,   93,
-       92,   91,   90,   89,   88,   87,   86,   84,   83,   82,
-       81,   80,   79,   78,   77,   76,   75,   74,   73,   72,
-       71,   70,   67,   66,   63,   62,   34,   58,   57,   52,
-       51,   38,   29,  200,    3,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200
+       15,   15,   16,   17,   18,   15,   19,   15,   15,   20,
+       21,   15,   15,   15,   15,   15,   15,   22,   23,   24,
+       15,   15,   15,   29,   31,   31,   30,   35,   37,   39,
+       28,   40,   36,   41,   50,   38,   43,   44,   42,   46,
+       50,   47,   79,   84,   80,  133,  163,   81,   82,  104,
+      162,  105,  161,   85,  106,  107,  160,  159,   33,  164,
+      158,  157,  156,  134,   25,  155,   25,   25,   25,   25,
+       25,   25,   27,   27,   32,   32,  154,  153,   32,   34,
+
+       34,   34,   34,   51,  152,   51,   51,   51,   51,   51,
+       51,   52,   52,   69,  151,   69,  150,  149,  148,  147,
+      146,  145,  144,  143,  142,  141,  140,  139,  138,  137,
+      136,  135,  132,  131,  130,  129,  128,  127,  126,  125,
+      124,  123,  122,  121,  120,  119,  118,  117,  116,  115,
+      114,  113,  112,  111,  110,  109,  108,  103,  102,  101,
+      100,   99,   98,   97,   96,   95,   94,   93,   92,   91,
+       90,   89,  164,  164,   88,   87,   86,   83,   78,   77,
+       76,   75,   74,   73,   72,   71,   70,   68,   67,   66,
+       65,   64,   63,   62,   61,   60,   59,   58,   57,   56,
+
+       55,   54,   53,   31,   49,   48,   45,   26,  164,    3,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164
     } ;
     } ;
 
 
-static yyconst short int yy_chk[291] =
+static yyconst short int yy_chk[254] =
     {   0,
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,   11,   12,   13,   11,   17,
-       18,   19,   19,   20,   19,   17,  203,   18,   31,   20,
-       18,   21,   21,   24,   31,   25,   40,   24,   25,   43,
-       43,   75,  153,   75,   80,   40,   75,   75,  198,  197,
-      196,  195,   12,   13,  109,   80,  109,  194,  190,  109,
-      109,  153,  201,  189,  201,  201,  201,  201,  201,  201,
-
-      202,  202,  204,  204,  188,  185,  204,  205,  205,  205,
-      205,  206,  184,  206,  206,  206,  206,  206,  206,  207,
-      207,  208,  183,  208,  182,  180,  179,  177,  176,  175,
-      174,  172,  171,  170,  169,  168,  167,  166,  165,  163,
-      161,  160,  159,  156,  155,  152,  151,  147,  146,  145,
-      144,  143,  141,  140,  136,  133,  132,  131,  130,  129,
-      128,  127,  126,  125,  124,  123,  121,  120,  119,  118,
-      117,  116,  115,  114,  113,  111,  110,  108,  107,  106,
-      105,  104,  103,  102,  101,  100,   99,   98,   96,   95,
-       94,   93,   92,   89,   88,   87,   86,   85,   84,   83,
-
-       82,   81,   79,   76,   74,   73,   72,   71,   70,   69,
-       68,   67,   66,   65,   64,   63,   62,   59,   58,   57,
-       56,   55,   54,   53,   52,   51,   50,   49,   48,   47,
-       46,   45,   42,   41,   39,   38,   30,   27,   26,   23,
-       22,   16,    9,    3,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200
+        1,    1,    1,   11,   12,   13,   11,   16,   17,   18,
+      167,   18,   16,   19,   28,   17,   20,   20,   19,   22,
+       28,   22,   62,   64,   62,  122,  162,   62,   62,   88,
+      161,   88,  160,   64,   88,   88,  159,  158,   12,   13,
+      154,  153,  152,  122,  165,  149,  165,  165,  165,  165,
+      165,  165,  166,  166,  168,  168,  148,  147,  168,  169,
+
+      169,  169,  169,  170,  146,  170,  170,  170,  170,  170,
+      170,  171,  171,  172,  144,  172,  143,  142,  141,  140,
+      139,  138,  137,  136,  135,  134,  133,  132,  129,  128,
+      127,  124,  121,  120,  116,  115,  114,  113,  111,  110,
+      107,  106,  105,  104,  103,  102,  101,  100,   99,   98,
+       96,   95,   94,   93,   92,   91,   89,   87,   86,   85,
+       84,   83,   82,   81,   80,   79,   78,   76,   75,   74,
+       71,   70,   69,   68,   67,   66,   65,   63,   61,   60,
+       59,   58,   57,   56,   55,   54,   53,   50,   49,   48,
+       47,   46,   45,   44,   43,   42,   41,   40,   39,   38,
+
+       37,   36,   35,   27,   24,   23,   21,    9,    3,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164
     } ;
     } ;
 
 
 static yy_state_type yy_last_accepting_state;
 static yy_state_type yy_last_accepting_state;
@@ -516,6 +498,7 @@ char *yytext;
 #include "dcLexerDefs.h"
 #include "dcLexerDefs.h"
 #include "dcParserDefs.h"
 #include "dcParserDefs.h"
 #include "dcParser.h"
 #include "dcParser.h"
+#include "dcFile.h"
 #include "dcindent.h"
 #include "dcindent.h"
 
 
 
 
@@ -903,7 +886,7 @@ inline void accept() {
   col_number += yyleng;
   col_number += yyleng;
 }
 }
 
 
-#line 908 "lex.yy.c"
+#line 891 "lex.yy.c"
 
 
 /* Macros after this point can all be overridden by user definitions in
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  * section 1.
@@ -1054,7 +1037,7 @@ YY_DECL
 	register char *yy_cp = NULL, *yy_bp = NULL;
 	register char *yy_cp = NULL, *yy_bp = NULL;
 	register int yy_act;
 	register int yy_act;
 
 
-#line 406 "dcLexer.lxx"
+#line 407 "dcLexer.lxx"
 
 
 
 
 
 
@@ -1065,7 +1048,7 @@ YY_DECL
   }
   }
 
 
 
 
-#line 1070 "lex.yy.c"
+#line 1053 "lex.yy.c"
 
 
 	if ( yy_init )
 	if ( yy_init )
 		{
 		{
@@ -1116,13 +1099,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 201 )
+				if ( yy_current_state >= 165 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			++yy_cp;
 			}
 			}
-		while ( yy_base[yy_current_state] != 245 );
+		while ( yy_base[yy_current_state] != 210 );
 
 
 yy_find_action:
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
 		yy_act = yy_accept[yy_current_state];
@@ -1150,7 +1133,7 @@ do_action:	/* This label is used only to access EOF actions. */
 
 
 case 1:
 case 1:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 416 "dcLexer.lxx"
+#line 417 "dcLexer.lxx"
 {
 {
   // New line.  Save a copy of the line so we can print it out for the
   // New line.  Save a copy of the line so we can print it out for the
   // benefit of the user in case we get an error.
   // benefit of the user in case we get an error.
@@ -1167,7 +1150,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 2:
 case 2:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 430 "dcLexer.lxx"
+#line 431 "dcLexer.lxx"
 { 
 { 
   // Eat whitespace.
   // Eat whitespace.
   accept();
   accept();
@@ -1175,7 +1158,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 3:
 case 3:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 435 "dcLexer.lxx"
+#line 436 "dcLexer.lxx"
 { 
 { 
   // Eat C++-style comments.
   // Eat C++-style comments.
   accept();
   accept();
@@ -1183,7 +1166,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 4:
 case 4:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 440 "dcLexer.lxx"
+#line 441 "dcLexer.lxx"
 {
 {
   // Eat C-style comments.
   // Eat C-style comments.
   accept();
   accept();
@@ -1192,7 +1175,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 5:
 case 5:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 447 "dcLexer.lxx"
+#line 448 "dcLexer.lxx"
 {
 {
   accept();
   accept();
   return KW_DCLASS;
   return KW_DCLASS;
@@ -1200,7 +1183,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 6:
 case 6:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 452 "dcLexer.lxx"
+#line 453 "dcLexer.lxx"
 {
 {
   accept();
   accept();
   return KW_STRUCT;
   return KW_STRUCT;
@@ -1208,7 +1191,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 7:
 case 7:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 457 "dcLexer.lxx"
+#line 458 "dcLexer.lxx"
 {
 {
   accept();
   accept();
   return KW_FROM;
   return KW_FROM;
@@ -1216,7 +1199,7 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 8:
 case 8:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 462 "dcLexer.lxx"
+#line 463 "dcLexer.lxx"
 {
 {
   accept();
   accept();
   return KW_IMPORT;
   return KW_IMPORT;
@@ -1224,279 +1207,215 @@ YY_RULE_SETUP
 	YY_BREAK
 	YY_BREAK
 case 9:
 case 9:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 467 "dcLexer.lxx"
+#line 468 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_TYPEDEF;
+  return KW_KEYWORD;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 10:
 case 10:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 472 "dcLexer.lxx"
+#line 473 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_SWITCH;
+  return KW_TYPEDEF;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 11:
 case 11:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 477 "dcLexer.lxx"
+#line 478 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_CASE;
+  return KW_SWITCH;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 12:
 case 12:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 482 "dcLexer.lxx"
+#line 483 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_DEFAULT;
+  return KW_CASE;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 13:
 case 13:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 487 "dcLexer.lxx"
+#line 488 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_BREAK;
+  return KW_DEFAULT;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 14:
 case 14:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 492 "dcLexer.lxx"
+#line 493 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT8;
+  return KW_BREAK;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 15:
 case 15:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 497 "dcLexer.lxx"
+#line 498 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT16;
+  return KW_INT8;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 16:
 case 16:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 502 "dcLexer.lxx"
+#line 503 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT32;
+  return KW_INT16;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 17:
 case 17:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 507 "dcLexer.lxx"
+#line 508 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT64;
+  return KW_INT32;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 18:
 case 18:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 512 "dcLexer.lxx"
+#line 513 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT8;
+  return KW_INT64;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 19:
 case 19:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 517 "dcLexer.lxx"
+#line 518 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT16;
+  return KW_UINT8;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 20:
 case 20:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 522 "dcLexer.lxx"
+#line 523 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT32;
+  return KW_UINT16;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 21:
 case 21:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 527 "dcLexer.lxx"
+#line 528 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT64;
+  return KW_UINT32;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 22:
 case 22:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 532 "dcLexer.lxx"
+#line 533 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_FLOAT64;
+  return KW_UINT64;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 23:
 case 23:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 537 "dcLexer.lxx"
+#line 538 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_STRING;
+  return KW_FLOAT64;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 24:
 case 24:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 542 "dcLexer.lxx"
+#line 543 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_BLOB;
+  return KW_STRING;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 25:
 case 25:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 547 "dcLexer.lxx"
+#line 548 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_BLOB32;
+  return KW_BLOB;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 26:
 case 26:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 552 "dcLexer.lxx"
+#line 553 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT8ARRAY;
+  return KW_BLOB32;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 27:
 case 27:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 557 "dcLexer.lxx"
+#line 558 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT16ARRAY;
+  return KW_INT8ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 28:
 case 28:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 562 "dcLexer.lxx"
+#line 563 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_INT32ARRAY;
+  return KW_INT16ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 29:
 case 29:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 567 "dcLexer.lxx"
+#line 568 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT8ARRAY;
+  return KW_INT32ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 30:
 case 30:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 572 "dcLexer.lxx"
+#line 573 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT16ARRAY;
+  return KW_UINT8ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 31:
 case 31:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 577 "dcLexer.lxx"
+#line 578 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT32ARRAY;
+  return KW_UINT16ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 32:
 case 32:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 582 "dcLexer.lxx"
+#line 583 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_UINT32UINT8ARRAY;
+  return KW_UINT32ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 33:
 case 33:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 587 "dcLexer.lxx"
+#line 588 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_CHAR;
+  return KW_UINT32UINT8ARRAY;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 34:
 case 34:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 592 "dcLexer.lxx"
+#line 593 "dcLexer.lxx"
 {
 {
   accept();
   accept();
-  return KW_REQUIRED;
+  return KW_CHAR;
 }
 }
 	YY_BREAK
 	YY_BREAK
 case 35:
 case 35:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 597 "dcLexer.lxx"
-{
-  accept();
-  return KW_BROADCAST;
-}
-	YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 602 "dcLexer.lxx"
-{
-  accept();
-  return KW_P2P;
-}
-	YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 607 "dcLexer.lxx"
-{
-  accept();
-  return KW_RAM;
-}
-	YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 612 "dcLexer.lxx"
-{
-  accept();
-  return KW_DB;
-}
-	YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 617 "dcLexer.lxx"
-{
-  accept();
-  return KW_CLSEND;
-}
-	YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 622 "dcLexer.lxx"
-{
-  accept();
-  return KW_CLRECV;
-}
-	YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 627 "dcLexer.lxx"
-{
-  accept();
-  return KW_OWNSEND;
-}
-	YY_BREAK
-case 42:
-YY_RULE_SETUP
-#line 632 "dcLexer.lxx"
-{
-  accept();
-  return KW_AIRECV;
-}
-	YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 637 "dcLexer.lxx"
+#line 598 "dcLexer.lxx"
 { 
 { 
   // An unsigned integer number.
   // An unsigned integer number.
   accept();
   accept();
@@ -1520,9 +1439,9 @@ YY_RULE_SETUP
   return UNSIGNED_INTEGER;
   return UNSIGNED_INTEGER;
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 44:
+case 36:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 660 "dcLexer.lxx"
+#line 621 "dcLexer.lxx"
 { 
 { 
   // A signed integer number.
   // A signed integer number.
   accept();
   accept();
@@ -1569,9 +1488,9 @@ YY_RULE_SETUP
   return SIGNED_INTEGER;
   return SIGNED_INTEGER;
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 45:
+case 37:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 706 "dcLexer.lxx"
+#line 667 "dcLexer.lxx"
 {
 {
   // A hexadecimal integer number.
   // A hexadecimal integer number.
   accept(); 
   accept(); 
@@ -1599,9 +1518,9 @@ YY_RULE_SETUP
   return UNSIGNED_INTEGER; 
   return UNSIGNED_INTEGER; 
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 46:
+case 38:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 733 "dcLexer.lxx"
+#line 694 "dcLexer.lxx"
 { 
 { 
   // A floating-point number.
   // A floating-point number.
   accept(); 
   accept(); 
@@ -1610,9 +1529,9 @@ YY_RULE_SETUP
   return REAL; 
   return REAL; 
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 47:
+case 39:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 741 "dcLexer.lxx"
+#line 702 "dcLexer.lxx"
 {
 {
   // Quoted string.
   // Quoted string.
   accept();
   accept();
@@ -1620,9 +1539,9 @@ YY_RULE_SETUP
   return STRING;
   return STRING;
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 48:
+case 40:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 748 "dcLexer.lxx"
+#line 709 "dcLexer.lxx"
 {
 {
   // Single-quoted string.
   // Single-quoted string.
   accept();
   accept();
@@ -1630,9 +1549,9 @@ YY_RULE_SETUP
   return STRING;
   return STRING;
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 49:
+case 41:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 755 "dcLexer.lxx"
+#line 716 "dcLexer.lxx"
 {
 {
   // Long hex string.
   // Long hex string.
   accept();
   accept();
@@ -1640,31 +1559,39 @@ YY_RULE_SETUP
   return HEX_STRING;
   return HEX_STRING;
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 50:
+case 42:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 762 "dcLexer.lxx"
+#line 723 "dcLexer.lxx"
 { 
 { 
-  // Identifier.
+  // Identifier or keyword.
   accept();
   accept();
   dcyylval.str = dcyytext;
   dcyylval.str = dcyytext;
+
+  if (dc_file != (DCFile *)NULL) {
+    const DCKeyword *keyword = dc_file->get_keyword_by_name(dcyylval.str);
+    if (keyword != (DCKeyword *)NULL) {
+      dcyylval.u.keyword = keyword;
+      return KEYWORD;
+    }
+  }
   return IDENTIFIER;
   return IDENTIFIER;
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 51:
+case 43:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 770 "dcLexer.lxx"
+#line 739 "dcLexer.lxx"
 {
 {
   // Send any other printable character as itself.
   // Send any other printable character as itself.
   accept(); 
   accept(); 
   return dcyytext[0];
   return dcyytext[0];
 }
 }
 	YY_BREAK
 	YY_BREAK
-case 52:
+case 44:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 776 "dcLexer.lxx"
+#line 745 "dcLexer.lxx"
 ECHO;
 ECHO;
 	YY_BREAK
 	YY_BREAK
-#line 1669 "lex.yy.c"
+#line 1596 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 	yyterminate();
 
 
@@ -1956,7 +1883,7 @@ static yy_state_type yy_get_previous_state()
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 201 )
+			if ( yy_current_state >= 165 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1991,11 +1918,11 @@ yy_state_type yy_current_state;
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 201 )
+		if ( yy_current_state >= 165 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 200);
+	yy_is_jam = (yy_current_state == 164);
 
 
 	return yy_is_jam ? 0 : yy_current_state;
 	return yy_is_jam ? 0 : yy_current_state;
 	}
 	}
@@ -2046,6 +1973,7 @@ register char *yy_bp;
 #endif	/* ifndef YY_NO_UNPUT */
 #endif	/* ifndef YY_NO_UNPUT */
 
 
 
 
+#ifndef YY_NO_INPUT
 #ifdef __cplusplus
 #ifdef __cplusplus
 static int yyinput()
 static int yyinput()
 #else
 #else
@@ -2117,7 +2045,7 @@ static int input()
 
 
 	return c;
 	return c;
 	}
 	}
-
+#endif /* YY_NO_INPUT */
 
 
 #ifdef YY_USE_PROTOS
 #ifdef YY_USE_PROTOS
 void yyrestart( FILE *input_file )
 void yyrestart( FILE *input_file )
@@ -2545,4 +2473,4 @@ int main()
 	return 0;
 	return 0;
 	}
 	}
 #endif
 #endif
-#line 776 "dcLexer.lxx"
+#line 745 "dcLexer.lxx"

+ 15 - 46
direct/src/dcparser/dcLexer.lxx

@@ -9,6 +9,7 @@
 #include "dcLexerDefs.h"
 #include "dcLexerDefs.h"
 #include "dcParserDefs.h"
 #include "dcParserDefs.h"
 #include "dcParser.h"
 #include "dcParser.h"
+#include "dcFile.h"
 #include "dcindent.h"
 #include "dcindent.h"
 
 
 
 
@@ -464,6 +465,11 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   return KW_IMPORT;
   return KW_IMPORT;
 }
 }
 
 
+"keyword" {
+  accept();
+  return KW_KEYWORD;
+}
+
 "typedef" {
 "typedef" {
   accept();
   accept();
   return KW_TYPEDEF;
   return KW_TYPEDEF;
@@ -589,51 +595,6 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   return KW_CHAR;
   return KW_CHAR;
 }
 }
 
 
-"required" {
-  accept();
-  return KW_REQUIRED;
-}
-
-"broadcast" {
-  accept();
-  return KW_BROADCAST;
-}
-
-"p2p" {
-  accept();
-  return KW_P2P;
-}
-
-"ram" {
-  accept();
-  return KW_RAM;
-}
-
-"db" {
-  accept();
-  return KW_DB;
-}
-
-"clsend" {
-  accept();
-  return KW_CLSEND;
-}
-
-"clrecv" {
-  accept();
-  return KW_CLRECV;
-}
-
-"ownsend" {
-  accept();
-  return KW_OWNSEND;
-}
-
-"airecv" {
-  accept();
-  return KW_AIRECV;
-}
-
 {UNSIGNED_INTEGERNUM} { 
 {UNSIGNED_INTEGERNUM} { 
   // An unsigned integer number.
   // An unsigned integer number.
   accept();
   accept();
@@ -760,9 +721,17 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
 }
 }
 
 
 [A-Za-z_][A-Za-z_0-9]* { 
 [A-Za-z_][A-Za-z_0-9]* { 
-  // Identifier.
+  // Identifier or keyword.
   accept();
   accept();
   dcyylval.str = dcyytext;
   dcyylval.str = dcyytext;
+
+  if (dc_file != (DCFile *)NULL) {
+    const DCKeyword *keyword = dc_file->get_keyword_by_name(dcyylval.str);
+    if (keyword != (DCKeyword *)NULL) {
+      dcyylval.u.keyword = keyword;
+      return KEYWORD;
+    }
+  }
   return IDENTIFIER;
   return IDENTIFIER;
 }
 }
 
 

+ 1 - 1
direct/src/dcparser/dcMolecularField.cxx

@@ -95,7 +95,7 @@ get_atomic(int n) const {
 void DCMolecularField::
 void DCMolecularField::
 add_atomic(DCAtomicField *atomic) {
 add_atomic(DCAtomicField *atomic) {
   if (_fields.empty()) {
   if (_fields.empty()) {
-    set_flags(atomic->get_flags());
+    copy_keywords(*atomic);
   }
   }
   _fields.push_back(atomic);
   _fields.push_back(atomic);
 
 

+ 4 - 4
direct/src/dcparser/dcParameter.cxx

@@ -232,7 +232,7 @@ write_instance(ostream &out, bool brief, int indent_level,
                const string &postname) const {
                const string &postname) const {
   indent(out, indent_level);
   indent(out, indent_level);
   output_instance(out, brief, prename, name, postname);
   output_instance(out, brief, prename, name, postname);
-  output_flags(out);
+  output_keywords(out);
   out << ";";
   out << ";";
   if (!brief && _number >= 0) {
   if (!brief && _number >= 0) {
     out << "  // field " << _number;
     out << "  // field " << _number;
@@ -270,7 +270,7 @@ write_typedef_name(ostream &out, bool brief, int indent_level,
   if (!prename.empty() || !name.empty() || !postname.empty()) {
   if (!prename.empty() || !name.empty() || !postname.empty()) {
     out << " " << prename << name << postname;
     out << " " << prename << name << postname;
   }
   }
-  output_flags(out);
+  output_keywords(out);
   out << ";";
   out << ";";
   if (!brief && _number >= 0) {
   if (!brief && _number >= 0) {
     out << "  // field " << _number;
     out << "  // field " << _number;
@@ -289,7 +289,7 @@ generate_hash(HashGenerator &hashgen) const {
   // We specifically don't call up to DCField::generate_hash(), since
   // We specifically don't call up to DCField::generate_hash(), since
   // the parameter name is not actually significant to the hash.
   // the parameter name is not actually significant to the hash.
 
 
-  if (get_flags() != 0) {
-    hashgen.add_int(get_flags());
+  if (get_num_keywords() != 0) {
+    DCKeywordList::generate_hash(hashgen);
   }
   }
 }
 }

File diff suppressed because it is too large
+ 693 - 556
direct/src/dcparser/dcParser.cxx.prebuilt


+ 124 - 51
direct/src/dcparser/dcParser.h.prebuilt

@@ -1,55 +1,128 @@
-#ifndef BISON_Y_TAB_H
-# define BISON_Y_TAB_H
-
-# define	UNSIGNED_INTEGER	257
-# define	SIGNED_INTEGER	258
-# define	REAL	259
-# define	STRING	260
-# define	HEX_STRING	261
-# define	IDENTIFIER	262
-# define	KW_DCLASS	263
-# define	KW_STRUCT	264
-# define	KW_FROM	265
-# define	KW_IMPORT	266
-# define	KW_TYPEDEF	267
-# define	KW_SWITCH	268
-# define	KW_CASE	269
-# define	KW_DEFAULT	270
-# define	KW_BREAK	271
-# define	KW_INT8	272
-# define	KW_INT16	273
-# define	KW_INT32	274
-# define	KW_INT64	275
-# define	KW_UINT8	276
-# define	KW_UINT16	277
-# define	KW_UINT32	278
-# define	KW_UINT64	279
-# define	KW_FLOAT64	280
-# define	KW_STRING	281
-# define	KW_BLOB	282
-# define	KW_BLOB32	283
-# define	KW_INT8ARRAY	284
-# define	KW_INT16ARRAY	285
-# define	KW_INT32ARRAY	286
-# define	KW_UINT8ARRAY	287
-# define	KW_UINT16ARRAY	288
-# define	KW_UINT32ARRAY	289
-# define	KW_UINT32UINT8ARRAY	290
-# define	KW_CHAR	291
-# define	KW_REQUIRED	292
-# define	KW_BROADCAST	293
-# define	KW_P2P	294
-# define	KW_RAM	295
-# define	KW_DB	296
-# define	KW_CLSEND	297
-# define	KW_CLRECV	298
-# define	KW_OWNSEND	299
-# define	KW_AIRECV	300
-# define	START_DC	301
-# define	START_PARAMETER_VALUE	302
-# define	START_PARAMETER_DESCRIPTION	303
+/* A Bison parser, made by GNU Bison 2.0.  */
 
 
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     UNSIGNED_INTEGER = 258,
+     SIGNED_INTEGER = 259,
+     REAL = 260,
+     STRING = 261,
+     HEX_STRING = 262,
+     IDENTIFIER = 263,
+     KEYWORD = 264,
+     KW_DCLASS = 265,
+     KW_STRUCT = 266,
+     KW_FROM = 267,
+     KW_IMPORT = 268,
+     KW_TYPEDEF = 269,
+     KW_KEYWORD = 270,
+     KW_SWITCH = 271,
+     KW_CASE = 272,
+     KW_DEFAULT = 273,
+     KW_BREAK = 274,
+     KW_INT8 = 275,
+     KW_INT16 = 276,
+     KW_INT32 = 277,
+     KW_INT64 = 278,
+     KW_UINT8 = 279,
+     KW_UINT16 = 280,
+     KW_UINT32 = 281,
+     KW_UINT64 = 282,
+     KW_FLOAT64 = 283,
+     KW_STRING = 284,
+     KW_BLOB = 285,
+     KW_BLOB32 = 286,
+     KW_INT8ARRAY = 287,
+     KW_INT16ARRAY = 288,
+     KW_INT32ARRAY = 289,
+     KW_UINT8ARRAY = 290,
+     KW_UINT16ARRAY = 291,
+     KW_UINT32ARRAY = 292,
+     KW_UINT32UINT8ARRAY = 293,
+     KW_CHAR = 294,
+     START_DC = 295,
+     START_PARAMETER_VALUE = 296,
+     START_PARAMETER_DESCRIPTION = 297
+   };
+#endif
+#define UNSIGNED_INTEGER 258
+#define SIGNED_INTEGER 259
+#define REAL 260
+#define STRING 261
+#define HEX_STRING 262
+#define IDENTIFIER 263
+#define KEYWORD 264
+#define KW_DCLASS 265
+#define KW_STRUCT 266
+#define KW_FROM 267
+#define KW_IMPORT 268
+#define KW_TYPEDEF 269
+#define KW_KEYWORD 270
+#define KW_SWITCH 271
+#define KW_CASE 272
+#define KW_DEFAULT 273
+#define KW_BREAK 274
+#define KW_INT8 275
+#define KW_INT16 276
+#define KW_INT32 277
+#define KW_INT64 278
+#define KW_UINT8 279
+#define KW_UINT16 280
+#define KW_UINT32 281
+#define KW_UINT64 282
+#define KW_FLOAT64 283
+#define KW_STRING 284
+#define KW_BLOB 285
+#define KW_BLOB32 286
+#define KW_INT8ARRAY 287
+#define KW_INT16ARRAY 288
+#define KW_INT32ARRAY 289
+#define KW_UINT8ARRAY 290
+#define KW_UINT16ARRAY 291
+#define KW_UINT32ARRAY 292
+#define KW_UINT32UINT8ARRAY 293
+#define KW_CHAR 294
+#define START_DC 295
+#define START_PARAMETER_VALUE 296
+#define START_PARAMETER_DESCRIPTION 297
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
 
 
 extern YYSTYPE dcyylval;
 extern YYSTYPE dcyylval;
 
 
-#endif /* not BISON_Y_TAB_H */
+
+

+ 48 - 73
direct/src/dcparser/dcParser.yxx

@@ -16,6 +16,7 @@
 #include "dcArrayParameter.h"
 #include "dcArrayParameter.h"
 #include "dcSimpleParameter.h"
 #include "dcSimpleParameter.h"
 #include "dcTypedef.h"
 #include "dcTypedef.h"
+#include "dcKeyword.h"
 #include "dcPacker.h"
 #include "dcPacker.h"
 #include "dcNumericRange.h"
 #include "dcNumericRange.h"
 
 
@@ -27,12 +28,13 @@
 #define YYINITDEPTH 1000
 #define YYINITDEPTH 1000
 #define YYMAXDEPTH 1000
 #define YYMAXDEPTH 1000
 
 
-static DCFile *dc_file = (DCFile *)NULL;
+DCFile *dc_file = (DCFile *)NULL;
 static DCClass *current_class = (DCClass *)NULL;
 static DCClass *current_class = (DCClass *)NULL;
 static DCSwitch *current_switch = (DCSwitch *)NULL;
 static DCSwitch *current_switch = (DCSwitch *)NULL;
 static DCAtomicField *current_atomic = (DCAtomicField *)NULL;
 static DCAtomicField *current_atomic = (DCAtomicField *)NULL;
 static DCMolecularField *current_molecular = (DCMolecularField *)NULL;
 static DCMolecularField *current_molecular = (DCMolecularField *)NULL;
 static DCParameter *current_parameter = (DCParameter *)NULL;
 static DCParameter *current_parameter = (DCParameter *)NULL;
+static DCKeywordList current_keyword_list;
 static DCPacker default_packer;
 static DCPacker default_packer;
 static DCPacker *current_packer;
 static DCPacker *current_packer;
 static DCDoubleRange double_range;
 static DCDoubleRange double_range;
@@ -83,12 +85,14 @@ dc_cleanup_parser() {
 %token <u.int64> SIGNED_INTEGER
 %token <u.int64> SIGNED_INTEGER
 %token <u.real> REAL
 %token <u.real> REAL
 %token <str> STRING HEX_STRING IDENTIFIER
 %token <str> STRING HEX_STRING IDENTIFIER
+%token <u.keyword> KEYWORD
 
 
 %token KW_DCLASS 
 %token KW_DCLASS 
 %token KW_STRUCT 
 %token KW_STRUCT 
 %token KW_FROM 
 %token KW_FROM 
 %token KW_IMPORT 
 %token KW_IMPORT 
 %token KW_TYPEDEF 
 %token KW_TYPEDEF 
+%token KW_KEYWORD 
 %token KW_SWITCH
 %token KW_SWITCH
 %token KW_CASE
 %token KW_CASE
 %token KW_DEFAULT
 %token KW_DEFAULT
@@ -115,16 +119,6 @@ dc_cleanup_parser() {
 %token KW_UINT32UINT8ARRAY
 %token KW_UINT32UINT8ARRAY
 %token KW_CHAR
 %token KW_CHAR
 
 
-%token KW_REQUIRED
-%token KW_BROADCAST
-%token KW_P2P
-%token KW_RAM
-%token KW_DB
-%token KW_CLSEND
-%token KW_CLRECV
-%token KW_OWNSEND
-%token KW_AIRECV
-
 /* These special tokens are used to set the starting state of the
 /* These special tokens are used to set the starting state of the
    parser.  The lexer places the appropriate one of these on the head
    parser.  The lexer places the appropriate one of these on the head
    of the input stream. */
    of the input stream. */
@@ -133,8 +127,6 @@ dc_cleanup_parser() {
 %token START_PARAMETER_DESCRIPTION
 %token START_PARAMETER_DESCRIPTION
 
 
 %type <u.atomic> atomic_name
 %type <u.atomic> atomic_name
-%type <u.s_int> server_flags
-%type <u.s_int> no_server_flags
 %type <u.dclass> dclass_or_struct
 %type <u.dclass> dclass_or_struct
 %type <u.dclass> dclass_name
 %type <u.dclass> dclass_name
 %type <u.dclass> dclass
 %type <u.dclass> dclass
@@ -203,6 +195,7 @@ dc:
 }
 }
         | dc import
         | dc import
         | dc typedef_decl
         | dc typedef_decl
+        | dc keyword_decl
         ;
         ;
 
 
 slash_identifier:
 slash_identifier:
@@ -270,6 +263,21 @@ typedef_decl:
 }
 }
 	;
 	;
 
 
+keyword_decl:
+        KW_KEYWORD IDENTIFIER
+{
+  dc_file->add_keyword($2);
+}
+        | KW_KEYWORD KEYWORD
+{
+  // This keyword has already been defined.  But since we are now
+  // explicitly defining it, clear its bitmask, so that we will have a
+  // new hash code--doing this will allow us to phase out the
+  // historical hash code support later.
+  ((DCKeyword *)$2)->clear_historical_flag();
+}
+	;
+
 dclass_or_struct:
 dclass_or_struct:
         dclass
         dclass
 	| struct
 	| struct
@@ -339,7 +347,7 @@ dclass_base_list:
 dclass_fields:
 dclass_fields:
         empty
         empty
         | dclass_fields ';'
         | dclass_fields ';'
-        | dclass_fields dclass_field
+        | dclass_fields dclass_field ';'
 {
 {
   if ($2 == (DCField *)NULL) {
   if ($2 == (DCField *)NULL) {
     // Pass this error up.
     // Pass this error up.
@@ -352,29 +360,29 @@ dclass_fields:
         ;
         ;
 
 
 dclass_field:
 dclass_field:
-	atomic_field server_flags
+	atomic_field keyword_list
 {
 {
   if ($1 != (DCField *)NULL) {
   if ($1 != (DCField *)NULL) {
     if ($1->get_name().empty()) {
     if ($1->get_name().empty()) {
       yyerror("Field name required.");
       yyerror("Field name required.");
     }
     }
-    $1->set_flags($2);
+    $1->copy_keywords(current_keyword_list);
   }
   }
   $$ = $1;
   $$ = $1;
 }
 }
-	| molecular_field no_server_flags
-	| unnamed_parameter_with_default server_flags ';'
+	| molecular_field no_keyword_list
+	| unnamed_parameter_with_default keyword_list ';'
 {
 {
   yyerror("Unnamed parameters are not allowed on a dclass");
   yyerror("Unnamed parameters are not allowed on a dclass");
   if ($1 != (DCField *)NULL) {
   if ($1 != (DCField *)NULL) {
-    $1->set_flags($2);
+    $1->copy_keywords(current_keyword_list);
   }
   }
   $$ = $1;
   $$ = $1;
 }
 }
-	| named_parameter_with_default server_flags
+	| named_parameter_with_default keyword_list
 {
 {
   if ($1 != (DCField *)NULL) {
   if ($1 != (DCField *)NULL) {
-    $1->set_flags($2);
+    $1->copy_keywords(current_keyword_list);
   }
   }
   $$ = $1;
   $$ = $1;
 }
 }
@@ -439,7 +447,7 @@ struct_base_list:
 struct_fields:
 struct_fields:
         empty
         empty
         | struct_fields ';'
         | struct_fields ';'
-        | struct_fields struct_field
+        | struct_fields struct_field ';'
 {
 {
   if ($2 == (DCField *)NULL) {
   if ($2 == (DCField *)NULL) {
     // Pass this error up.
     // Pass this error up.
@@ -450,19 +458,19 @@ struct_fields:
         ;
         ;
 
 
 struct_field:
 struct_field:
-	atomic_field no_server_flags
+	atomic_field no_keyword_list
 {
 {
   if ($1->get_name().empty()) {
   if ($1->get_name().empty()) {
     yyerror("Field name required.");
     yyerror("Field name required.");
   }
   }
   $$ = $1;
   $$ = $1;
 }
 }
-	| molecular_field no_server_flags
-	| unnamed_parameter_with_default no_server_flags ';'
+	| molecular_field no_keyword_list
+	| unnamed_parameter_with_default no_keyword_list ';'
 {
 {
   $$ = $1;
   $$ = $1;
 }
 }
-	| named_parameter_with_default no_server_flags
+	| named_parameter_with_default no_keyword_list
 {
 {
   $$ = $1;
   $$ = $1;
 }
 }
@@ -603,15 +611,15 @@ parameter_or_atomic:
 	;
 	;
 
 
 parameter_description:
 parameter_description:
-	atomic_field no_server_flags
+	atomic_field no_keyword_list
 {
 {
   $$ = $1;
   $$ = $1;
 }
 }
-	| unnamed_parameter_with_default no_server_flags
+	| unnamed_parameter_with_default no_keyword_list
 {
 {
   $$ = $1;
   $$ = $1;
 }
 }
-	| named_parameter_with_default no_server_flags
+	| named_parameter_with_default no_keyword_list
 {
 {
   $$ = $1;
   $$ = $1;
 }
 }
@@ -1140,56 +1148,23 @@ type_token:
 }
 }
         ;
         ;
 
 
-server_flags:
+keyword_list:
         empty
         empty
 {
 {
-  $$ = 0;
-}
-        | server_flags KW_REQUIRED
-{
-  $$ = $1 | DCAtomicField::F_required;
-}
-        | server_flags KW_BROADCAST
-{
-  $$ = $1 | DCAtomicField::F_broadcast;
-}
-        | server_flags KW_P2P
-{
-  $$ = $1 | DCAtomicField::F_p2p;
+  current_keyword_list.clear_keywords();
 }
 }
-        | server_flags KW_RAM
+        | keyword_list KEYWORD
 {
 {
-  $$ = $1 | DCAtomicField::F_ram;
+  current_keyword_list.add_keyword($2);
 }
 }
-        | server_flags KW_DB
-{
-  $$ = $1 | DCAtomicField::F_db;
-}
-        | server_flags KW_CLSEND
-{
-  $$ = $1 | DCAtomicField::F_clsend;
-}
-        | server_flags KW_CLRECV
-{
-  $$ = $1 | DCAtomicField::F_clrecv;
-}
-        | server_flags KW_OWNSEND
-{
-  $$ = $1 | DCAtomicField::F_ownsend;
-}
-        | server_flags KW_AIRECV
-{
-  $$ = $1 | DCAtomicField::F_airecv;
-}
-        ;
+	;
 
 
-no_server_flags:
-        server_flags
+no_keyword_list:
+        keyword_list
 {
 {
-  if ($1 != 0) {
-    yyerror("Server flags are not allowed here.");
+  if (current_keyword_list.get_num_keywords() != 0) {
+    yyerror("Communication keywords are not allowed here.");
   }
   }
-  $$ = $1;
 }
 }
 	;
 	;
 
 
@@ -1231,8 +1206,8 @@ molecular_atom_list:
 {
 {
   if ($3 != (DCAtomicField *)NULL) {
   if ($3 != (DCAtomicField *)NULL) {
     current_molecular->add_atomic($3);
     current_molecular->add_atomic($3);
-    if (!current_molecular->compare_flags(*$3)) {
-      yyerror("Mismatched flags in molecule between " + 
+    if (!current_molecular->compare_keywords(*$3)) {
+      yyerror("Mismatched keywords in molecule between " + 
               current_molecular->get_atomic(0)->get_name() + " and " +
               current_molecular->get_atomic(0)->get_name() + " and " +
               $3->get_name());
               $3->get_name());
     }
     }

+ 4 - 0
direct/src/dcparser/dcParserDefs.h

@@ -28,6 +28,7 @@ class DCSwitch;
 class DCField;
 class DCField;
 class DCAtomicField;
 class DCAtomicField;
 class DCParameter;
 class DCParameter;
+class DCKeyword;
 class DCPacker;
 class DCPacker;
 
 
 void dc_init_parser(istream &in, const string &filename, DCFile &file);
 void dc_init_parser(istream &in, const string &filename, DCFile &file);
@@ -39,6 +40,8 @@ DCField *dc_get_parameter_description();
 void dc_cleanup_parser();
 void dc_cleanup_parser();
 int dcyyparse();
 int dcyyparse();
 
 
+extern DCFile *dc_file;
+
 // This structure holds the return value for each token.
 // This structure holds the return value for each token.
 // Traditionally, this is a union, and is declared with the %union
 // Traditionally, this is a union, and is declared with the %union
 // declaration in the parser.y file, but unions are pretty worthless
 // declaration in the parser.y file, but unions are pretty worthless
@@ -61,6 +64,7 @@ public:
     DCAtomicField *atomic;
     DCAtomicField *atomic;
     DCSubatomicType subatomic;
     DCSubatomicType subatomic;
     DCParameter *parameter;
     DCParameter *parameter;
+    const DCKeyword *keyword;
   } u;
   } u;
   string str;
   string str;
 };
 };

+ 3 - 0
direct/src/dcparser/dcbase.h

@@ -36,6 +36,7 @@
 #include "numeric_types.h"
 #include "numeric_types.h"
 #include "pvector.h"
 #include "pvector.h"
 #include "pmap.h"
 #include "pmap.h"
+#include "pset.h"
 
 
 #else  // WITHIN_PANDA
 #else  // WITHIN_PANDA
 
 
@@ -100,8 +101,10 @@ typedef string Filename;
 
 
 #include <vector>
 #include <vector>
 #include <map>
 #include <map>
+#include <set>
 #define pvector vector
 #define pvector vector
 #define pmap map
 #define pmap map
+#define pset set
 
 
 #ifdef WIN32
 #ifdef WIN32
 typedef __int64 PN_int64;
 typedef __int64 PN_int64;

+ 2 - 0
direct/src/dcparser/dcparser_composite1.cxx

@@ -4,6 +4,8 @@
 #include "dcAtomicField.cxx"
 #include "dcAtomicField.cxx"
 #include "dcClass.cxx"
 #include "dcClass.cxx"
 #include "dcDeclaration.cxx"
 #include "dcDeclaration.cxx"
+#include "dcKeyword.cxx"
+#include "dcKeywordList.cxx"
 #include "dcPackData.cxx"
 #include "dcPackData.cxx"
 #include "dcPacker.cxx"
 #include "dcPacker.cxx"
 #include "dcPackerCatalog.cxx"
 #include "dcPackerCatalog.cxx"

Some files were not shown because too many files changed in this diff