Browse Source

fix unary - in interrogate

David Rose 20 years ago
parent
commit
eaf21c7e2b

+ 1 - 0
dtool/src/cppparser/cppFunctionType.h

@@ -38,6 +38,7 @@ public:
     F_constructor       = 0x04,
     F_destructor        = 0x08,
     F_method_pointer    = 0x10,
+    F_unary_op          = 0x20,
   };
 
   CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,

+ 13 - 0
dtool/src/cppparser/cppInstanceIdentifier.cxx

@@ -133,6 +133,19 @@ add_modifier(CPPInstanceIdentifierType type) {
 ////////////////////////////////////////////////////////////////////
 void CPPInstanceIdentifier::
 add_func_modifier(CPPParameterList *params, int flags) {
+  // As a special hack, if we added a parameter list to an operator
+  // function, check if the parameter list is empty.  If it is, this
+  // is really a unary operator, so set the unary_op flag.  Operators
+  // () and [] are never considered unary operators.
+  if (_ident != NULL && 
+      _ident->get_simple_name().substr(0, 9) == "operator " &&
+      _ident->get_simple_name() != string("operator ()") &&
+      _ident->get_simple_name() != string("operator []")) {
+    if (params->_parameters.empty()) {
+      flags |= CPPFunctionType::F_unary_op;
+    }
+  }
+
   _modifiers.push_back(Modifier::func_type(params, flags));
 }
 

+ 46 - 23
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -73,18 +73,21 @@ RenameSet methodRenameDictionary[] = {
     { "operator="   , "assign",               0 },
     { "operator()"  , "__call__",             0 },
     { "operator[]"  , "__getitem__",          0 },
+    { "operator++unary"  , "increment",            0 },
     { "operator++"  , "increment",            0 },
+    { "operator--unary"  , "decrement",            0 },
     { "operator--"  , "decrement",            0 },
     { "operator^"   , "__xor__",              0 },
     { "operator%"   , "__mod__",              0 },
     { "operator!"   , "logicalNot",           0 },
-    { "operator~"   , "bitwiseNot",           0 },
+    { "operator~unary"   , "__invert__",           0 },
     { "operator&"   , "__and__",              0 },
     { "operator&&"  , "logicalAnd",           0 },
     { "operator|"   , "__or__",               0 },
     { "operator||"  , "logicalOr",            0 },
     { "operator+"   , "__add__",              0 },
     { "operator-"   , "__sub__",              0 },
+    { "operator-unary", "__neg__",            0 },
     { "operator*"   , "__mul__",              0 },
     { "operator/"   , "__div__",              0 },
     { "operator+="  , "__iadd__",             1 },
@@ -270,8 +273,13 @@ std::string nonClassNameFromCppName(const std::string &cppName_in)
 }
 ///////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////
-std::string  methodNameFromCppName(std::string cppName, const std::string &className)
+std::string  methodNameFromCppName(InterfaceMaker::Function *func, const std::string &className)
 {
+    std::string cppName = func->_ifunc.get_name();
+    if (func->_ifunc.is_unary_op()) {
+      cppName += "unary";
+    }
+
     std::string methodName;
     std::string badChars(" ");
     int nextCap = 0;
@@ -344,9 +352,9 @@ std::string make_safe_name(const std::string & name)
         */
 }
 
-bool isInplaceFunction(const std::string &cppName)
+bool isInplaceFunction(InterfaceMaker::Function *func)
 {
-    std::string wname = methodNameFromCppName(cppName,"");
+    std::string wname = methodNameFromCppName(func,"");
 
     for(int x = 0; InPlaceSet[x] != NULL; x++)
         if(InPlaceSet[x] == wname)
@@ -876,7 +884,7 @@ void InterfaceMakerPythonNative::write_module_support(ostream &out,ostream *out_
         if(!func->_itype.is_global() && isFunctionLegal(func))
         {
             {
-                out << "  { \"" << methodNameFromCppName( func->_ifunc.get_name(),"") << "\", (PyCFunction) &" 
+                out << "  { \"" << methodNameFromCppName(func,"") << "\", (PyCFunction) &" 
                     << func->_name << ", METH_VARARGS| METH_KEYWORDS ," << func->_name << "_comment},\n";
             }
         }
@@ -945,6 +953,13 @@ bool GetSlotedFunctinDef(const std::string &thimputstring, std::string &answer_l
             return true;        
         }
 
+        if(thimputstring == "__neg__")
+        {
+            answer_location = "tp_as_number->nb_negative";
+            wraper_type = 2;
+            return true;        
+        }
+
         if(thimputstring == "__mul__")
         {
             answer_location = "tp_as_number->nb_multiply";
@@ -988,6 +1003,13 @@ bool GetSlotedFunctinDef(const std::string &thimputstring, std::string &answer_l
             return true;
         }
 
+        if(thimputstring == "__invert__")
+        {
+            answer_location = "tp_as_number->nb_invert";
+            wraper_type = 2;
+            return true;
+        }
+
 
         if(thimputstring == "__and__")
         {
@@ -1148,10 +1170,10 @@ write_module_class(ostream &out,  Object *obj) {
       Function *func = (*fi);
       std::string temp0;
       int temp1;
-      if(!GetSlotedFunctinDef( methodNameFromCppName( func->_ifunc.get_name(),export_calss_name),temp0,temp1))
+      if(!GetSlotedFunctinDef( methodNameFromCppName(func,export_calss_name),temp0,temp1))
         {
 
-          out << "  { \"" << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) << "\",(PyCFunction ) &" 
+          out << "  { \"" << methodNameFromCppName(func,export_calss_name) << "\",(PyCFunction ) &" 
               << func->_name << ", METH_VARARGS| METH_KEYWORDS ," << func->_name << "_comment},\n";
           if(!isFunctionWithThis(func))
             static_functions[x] = func;
@@ -1162,7 +1184,7 @@ write_module_class(ostream &out,  Object *obj) {
             {
               wraped_Operator_functions[func] = std::pair< std::string, int>(temp0,temp1);
 
-              out << "  { \"" << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) << "\",(PyCFunction ) &" 
+              out << "  { \"" << methodNameFromCppName(func,export_calss_name) << "\",(PyCFunction ) &" 
                   << func->_name << ", METH_VARARGS| METH_KEYWORDS ," << func->_name << "_comment},\n";
               if(!isFunctionWithThis(func))
                 static_functions[x] = func;
@@ -1172,7 +1194,7 @@ write_module_class(ostream &out,  Object *obj) {
             {
               normal_Operator_functions[func] = temp0;
 
-              out << "  { \"" << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) << "\",(PyCFunction ) &" 
+              out << "  { \"" << methodNameFromCppName(func,export_calss_name) << "\",(PyCFunction ) &" 
                   << func->_name << ", METH_VARARGS| METH_KEYWORDS ," << func->_name << "_comment},\n";
               if(!isFunctionWithThis(func))
                 static_functions[x] = func;
@@ -1233,9 +1255,9 @@ write_module_class(ostream &out,  Object *obj) {
             Function *func = rfi->first;
             out << "//////////////////\n";
             out << "//  Required TO Convert the calling Conventions.. \n";
-            out << "//     " <<ClassName<< " ..." << rfi->second.first <<" = "<< methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) <<"\n";
+            out << "//     " <<ClassName<< " ..." << rfi->second.first <<" = "<< methodNameFromCppName(func,export_calss_name) <<"\n";
             out << "//////////////////\n";
-            out << "static PyObject * " <<  func->_name << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) << "( PyObject * self, PyObject * args, PyObject *dict)\n";
+            out << "static PyObject * " <<  func->_name << methodNameFromCppName(func,export_calss_name) << "( PyObject * self, PyObject * args, PyObject *dict)\n";
             out << "{\n";
             out << "    return "<< func->_name <<"(self,args);\n";
             out << "}\n\n";
@@ -1245,9 +1267,9 @@ write_module_class(ostream &out,  Object *obj) {
             Function *func = rfi->first;
             out << "//////////////////\n";
             out << "//  Required TO Convert the calling Conventions.. \n";
-            out << "//     " <<ClassName<< " ..." << rfi->second.first <<" = "<< methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) <<"\n";
+            out << "//     " <<ClassName<< " ..." << rfi->second.first <<" = "<< methodNameFromCppName(func,export_calss_name) <<"\n";
             out << "//////////////////\n";
-            out << "static PyObject * " <<  func->_name << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) << "( PyObject * self)\n";
+            out << "static PyObject * " <<  func->_name << methodNameFromCppName(func,export_calss_name) << "( PyObject * self)\n";
             out << "{\n";
             out << "    return "<< func->_name <<"(self,Py_None,Py_None);\n";
             out << "}\n\n";
@@ -1258,9 +1280,9 @@ write_module_class(ostream &out,  Object *obj) {
             Function *func = rfi->first;
             out << "//////////////////\n";
             out << "//  Required TO Convert the calling Conventions.. \n";
-            out << "//     " <<ClassName<< " ..." << rfi->second.first <<" = "<< methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) <<"\n";
+            out << "//     " <<ClassName<< " ..." << rfi->second.first <<" = "<< methodNameFromCppName(func,export_calss_name) <<"\n";
             out << "//////////////////\n";
-            out << "static PyObject * " <<  func->_name << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) << "( PyObject * self, PyObject * args)\n";
+            out << "static PyObject * " <<  func->_name << methodNameFromCppName(func,export_calss_name) << "( PyObject * self, PyObject * args)\n";
             out << "{\n";
             out << "    return "<< func->_name <<"(self,args,Py_None);\n";
             out << "}\n\n";
@@ -1416,7 +1438,7 @@ write_module_class(ostream &out,  Object *obj) {
   for(ofi = normal_Operator_functions.begin(); ofi != normal_Operator_functions.end(); ofi++)
     {
       Function *func = ofi->first;
-      out << "        // " << ofi->second <<" = "<< methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) <<"\n";
+      out << "        // " << ofi->second <<" = "<< methodNameFromCppName(func,export_calss_name) <<"\n";
       out << "        Dtool_" << ClassName <<".As_PyTypeObject()." << ofi->second <<" = &" << func->_name <<";\n";
     }
 
@@ -1427,8 +1449,8 @@ write_module_class(ostream &out,  Object *obj) {
     for(rfi = wraped_Operator_functions.begin(); rfi != wraped_Operator_functions.end(); rfi++)
       {
         Function *func = rfi->first;
-        out << "        // " << rfi->second.first <<" = "<< methodNameFromCppName( func->_ifunc.get_name(),export_calss_name) <<"\n";
-        out << "        Dtool_" << ClassName <<".As_PyTypeObject()." << rfi->second.first <<" = &" << func->_name << methodNameFromCppName( func->_ifunc.get_name(),export_calss_name)<<";\n";
+        out << "        // " << rfi->second.first <<" = "<< methodNameFromCppName(func,export_calss_name) <<"\n";
+        out << "        Dtool_" << ClassName <<".As_PyTypeObject()." << rfi->second.first <<" = &" << func->_name << methodNameFromCppName(func,export_calss_name)<<";\n";
       }
   }
 
@@ -1504,9 +1526,9 @@ write_module_class(ostream &out,  Object *obj) {
   std::map<int , Function * >::iterator sfi;
   for(sfi= static_functions.begin(); sfi != static_functions.end(); sfi++)
     {
-      out << "        //  Static Method " << methodNameFromCppName( sfi->second->_ifunc.get_name(),export_calss_name) << "\n";
+      out << "        //  Static Method " << methodNameFromCppName(sfi->second,export_calss_name) << "\n";
       out << "        PyDict_SetItemString(Dtool_" << ClassName << ".As_PyTypeObject().tp_dict,\"" ;
-      out << methodNameFromCppName( sfi->second->_ifunc.get_name(),export_calss_name) ;
+      out << methodNameFromCppName(sfi->second,export_calss_name) ;
       out << "\",PyCFunction_New(&Dtool_Methods_"<< ClassName <<"[" << sfi->first << "],&Dtool_"<< ClassName<< ".As_PyObject()));\n";
     }
 
@@ -1663,7 +1685,7 @@ write_function_for_name(ostream &out1, InterfaceMaker::Function *func,
     out << PreProcess;
   }
 
-  bool is_inplace = isInplaceFunction(func->_ifunc.get_name());
+  bool is_inplace = isInplaceFunction(func);
 
   if (MapSets.empty()) {
     return;
@@ -2148,8 +2170,9 @@ void InterfaceMakerPythonNative::write_function_instance(ostream &out, Interface
   }
   expected_params += ")\n";
     
-
-  /*if (!format_specifiers.empty()) */ {
+  // If we got what claimed to be a unary operator, don't check for
+  // parameters, since we won't be getting any anyway.
+  if (!func1->_ifunc.is_unary_op()) {
     std::string format_specifiers1 = format_specifiers + ":" + remap->_cppfunc->get_local_name(&parser);
     indent(out,indent_level)
       << "static char * key_word_list[] = {" << keyword_list << "NULL};\n";

+ 12 - 0
dtool/src/interrogate/interrogateBuilder.cxx

@@ -1587,6 +1587,13 @@ get_function(CPPInstance *function, string description,
   string function_name = TypeManager::get_function_name(function);
   string function_signature = TypeManager::get_function_signature(function);
 
+  if (ftype->_flags & CPPFunctionType::F_unary_op) {
+    // This is a unary operator function.  Name it differently so we
+    // don't consider it an overloaded version of a similarly-named
+    // binary operator.
+    function_name += "unary";
+  }
+
   // First, check to see if it's already there.
   FunctionsByName::const_iterator tni =
     _functions_by_name.find(function_name);
@@ -1638,6 +1645,11 @@ get_function(CPPInstance *function, string description,
     ifunction->_class = get_type(struct_type, false);
   }
 
+  if (ftype->_flags & CPPFunctionType::F_unary_op) {
+    // This is a special unary function.
+    ifunction->_flags |= InterrogateFunction::F_unary_op;
+  }
+
   ifunction->_flags |= flags;
   ifunction->_instances->insert(InterrogateFunction::Instances::value_type(function_signature, function));
   ifunction->_expression = expression;

+ 11 - 0
dtool/src/interrogatedb/interrogateFunction.I

@@ -74,6 +74,17 @@ is_method() const {
   return (_flags & F_method) != 0;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: InterrogateFunction::is_unary_op
+//       Access: Public
+//  Description: Returns true if the function is flagged as a special
+//               unary operator, like operator -() with no parameters.
+////////////////////////////////////////////////////////////////////
+INLINE bool InterrogateFunction::
+is_unary_op() const {
+  return (_flags & F_unary_op) != 0;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: InterrogateFunction::get_class
 //       Access: Public

+ 2 - 0
dtool/src/interrogatedb/interrogateFunction.h

@@ -42,6 +42,7 @@ public:
   INLINE bool is_global() const;
   INLINE bool is_virtual() const;
   INLINE bool is_method() const;
+  INLINE bool is_unary_op() const;
   INLINE TypeIndex get_class() const;
 
   INLINE bool has_scoped_name() const;
@@ -72,6 +73,7 @@ private:
     F_typecast        = 0x0008,
     F_getter          = 0x0010,
     F_setter          = 0x0020,
+    F_unary_op        = 0x0040,
   };
 
   int _flags;