summaryrefslogtreecommitdiffstats
path: root/Python/bltinmodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1991-07-01 18:42:41 (GMT)
committerGuido van Rossum <guido@python.org>1991-07-01 18:42:41 (GMT)
commitc6bb8f7ab290d50934c761b25beb82918f23cf89 (patch)
tree8b589a1d3ea8973a49a3366c95213268acaa018f /Python/bltinmodule.c
parent22825e86f6e13a4d84822ae9ee7c8a807259f37d (diff)
downloadcpython-c6bb8f7ab290d50934c761b25beb82918f23cf89.zip
cpython-c6bb8f7ab290d50934c761b25beb82918f23cf89.tar.gz
cpython-c6bb8f7ab290d50934c761b25beb82918f23cf89.tar.bz2
Add and use coerce() routine for mixed mode arithmetic
Diffstat (limited to 'Python/bltinmodule.c')
-rw-r--r--Python/bltinmodule.c93
1 files changed, 76 insertions, 17 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 98eb231..128d37e 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -82,7 +82,7 @@ builtin_dir(self, v)
else {
if (!is_moduleobject(v)) {
err_setstr(TypeError,
- "dir() argument, must be module or absent");
+ "dir() argument must be module or absent");
return NULL;
}
d = getmoduledict(v);
@@ -96,22 +96,28 @@ builtin_dir(self, v)
}
static object *
-builtin_divmod(self, v)
+builtin_divmod(self, args)
object *self;
- object *v;
+ object *args;
{
- object *x;
- number_methods *nm;
- if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
+ object *v, *w, *x;
+ if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
err_setstr(TypeError, "divmod() requires 2 arguments");
return NULL;
}
- x = gettupleitem(v, 0);
- if ((nm = x->ob_type->tp_as_number) == NULL) {
+ v = gettupleitem(args, 0);
+ w = gettupleitem(args, 1);
+ if (v->ob_type->tp_as_number == NULL ||
+ w->ob_type->tp_as_number == NULL) {
err_setstr(TypeError, "divmod() requires numeric arguments");
return NULL;
}
- return (*nm->nb_divmod)(x, gettupleitem(v, 1));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ x = (*v->ob_type->tp_as_number->nb_divmod)(v, w);
+ DECREF(v);
+ DECREF(w);
+ return x;
}
static object *
@@ -362,22 +368,28 @@ builtin_ord(self, v)
}
static object *
-builtin_pow(self, v)
+builtin_pow(self, args)
object *self;
- object *v;
+ object *args;
{
- object *x;
- number_methods *nm;
- if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2) {
+ object *v, *w, *x;
+ if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
err_setstr(TypeError, "pow() requires 2 arguments");
return NULL;
}
- x = gettupleitem(v, 0);
- if ((nm = x->ob_type->tp_as_number) == NULL) {
+ v = gettupleitem(args, 0);
+ w = gettupleitem(args, 1);
+ if (v->ob_type->tp_as_number == NULL ||
+ w->ob_type->tp_as_number == NULL) {
err_setstr(TypeError, "pow() requires numeric arguments");
return NULL;
}
- return (*nm->nb_power)(x, gettupleitem(v, 1));
+ if (coerce(&v, &w) != 0)
+ return NULL;
+ x = (*v->ob_type->tp_as_number->nb_power)(v, w);
+ DECREF(v);
+ DECREF(w);
+ return x;
}
static object *
@@ -557,3 +569,50 @@ initbuiltin()
initerrors();
(void) dictinsert(builtin_dict, "None", None);
}
+
+/* Coerce two numeric types to the "larger" one.
+ Increment the reference count on each argument.
+ Return -1 and raise an exception if no coercion is possible
+ (and then no reference count is incremented).
+ XXX This should be distributed over the various numeric types,
+ XXX but for now I don't see how to implement that.
+ XXX So, for now, if you add a new numeric type,
+ XXX you must add to this function as well. */
+
+int
+coerce(pv, pw)
+ object **pv, **pw;
+{
+ register object *v = *pv;
+ register object *w = *pw;
+ if (v->ob_type == w->ob_type) {
+ INCREF(v);
+ INCREF(w);
+ return 0;
+ }
+ if (v->ob_type->tp_as_number == NULL ||
+ w->ob_type->tp_as_number == NULL) {
+ err_setstr(TypeError, "mixing number and non-number");
+ return -1;
+ }
+ if (is_floatobject(v) || is_floatobject(w)) {
+ v = builtin_float((object *)0, v);
+ w = builtin_float((object *)0, w);
+ }
+ else if (is_longobject(v) || is_longobject(w)) {
+ v = builtin_long((object *)0, v);
+ w = builtin_long((object *)0, w);
+ }
+ else {
+ err_setstr(TypeError, "can't coerce numeric types?!?!?");
+ return -1;
+ }
+ if (v == NULL || w == NULL) {
+ XDECREF(v);
+ XDECREF(w);
+ return -1;
+ }
+ *pv = v;
+ *pw = w;
+ return 0;
+}