summaryrefslogtreecommitdiffstats
path: root/Modules/parsermodule.c
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-02-01 10:28:51 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-02-01 10:28:51 (GMT)
commit211c6258294bf683935bff73a61ce3dd84070988 (patch)
tree8dc2a5a5fdcd1f7bc0e176bce006b12e1b588a05 /Modules/parsermodule.c
parent776e7014e97a79cc2bd5fffd15908e83ff0273cf (diff)
downloadcpython-211c6258294bf683935bff73a61ce3dd84070988.zip
cpython-211c6258294bf683935bff73a61ce3dd84070988.tar.gz
cpython-211c6258294bf683935bff73a61ce3dd84070988.tar.bz2
Issue #1717, stage 2: remove uses of tp_compare in Modules and most
Objects.
Diffstat (limited to 'Modules/parsermodule.c')
-rw-r--r--Modules/parsermodule.c72
1 files changed, 59 insertions, 13 deletions
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index 6778fb4..32de6bc 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -169,7 +169,7 @@ typedef struct {
static void parser_free(PyST_Object *st);
-static int parser_compare(PyST_Object *left, PyST_Object *right);
+static PyObject* parser_richcompare(PyObject *left, PyObject *right, int op);
static PyObject* parser_compilest(PyST_Object *, PyObject *, PyObject *);
static PyObject* parser_isexpr(PyST_Object *, PyObject *, PyObject *);
static PyObject* parser_issuite(PyST_Object *, PyObject *, PyObject *);
@@ -203,7 +203,7 @@ PyTypeObject PyST_Type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- (cmpfunc)parser_compare, /* tp_compare */
+ 0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -223,7 +223,7 @@ PyTypeObject PyST_Type = {
"Intermediate representation of a Python parse tree.",
0, /* tp_traverse */
0, /* tp_clear */
- 0, /* tp_richcompare */
+ parser_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
@@ -231,6 +231,9 @@ PyTypeObject PyST_Type = {
}; /* PyST_Type */
+/* PyST_Type isn't subclassable, so just check ob_type */
+#define PyST_Object_Check(v) ((v)->ob_type == &PyST_Type)
+
static int
parser_compare_nodes(node *left, node *right)
{
@@ -260,26 +263,69 @@ parser_compare_nodes(node *left, node *right)
return (0);
}
-
-/* int parser_compare(PyST_Object* left, PyST_Object* right)
+/* parser_richcompare(PyObject* left, PyObject* right, int op)
*
* Comparison function used by the Python operators ==, !=, <, >, <=, >=
* This really just wraps a call to parser_compare_nodes() with some easy
* checks and protection code.
*
*/
-static int
-parser_compare(PyST_Object *left, PyST_Object *right)
+
+#define TEST_COND(cond) ((cond) ? Py_True : Py_False)
+
+static PyObject *
+parser_richcompare(PyObject *left, PyObject *right, int op)
{
- if (left == right)
- return (0);
+ int result;
+ PyObject *v;
- if ((left == 0) || (right == 0))
- return (-1);
+ /* neither argument should be NULL, unless something's gone wrong */
+ if (left == NULL || right == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
- return (parser_compare_nodes(left->st_node, right->st_node));
-}
+ /* both arguments should be instances of PyST_Object */
+ if (!PyST_Object_Check(left) || !PyST_Object_Check(right)) {
+ v = Py_NotImplemented;
+ goto finished;
+ }
+ if (left == right)
+ /* if arguments are identical, they're equal */
+ result = 0;
+ else
+ result = parser_compare_nodes(((PyST_Object *)left)->st_node,
+ ((PyST_Object *)right)->st_node);
+
+ /* Convert return value to a Boolean */
+ switch (op) {
+ case Py_EQ:
+ v = TEST_COND(result == 0);
+ break;
+ case Py_NE:
+ v = TEST_COND(result != 0);
+ break;
+ case Py_LE:
+ v = TEST_COND(result <= 0);
+ break;
+ case Py_GE:
+ v = TEST_COND(result >= 0);
+ break;
+ case Py_LT:
+ v = TEST_COND(result < 0);
+ break;
+ case Py_GT:
+ v = TEST_COND(result > 0);
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+ finished:
+ Py_INCREF(v);
+ return v;
+}
/* parser_newstobject(node* st)
*