summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/object.h5
-rw-r--r--Objects/classobject.c11
-rw-r--r--Objects/floatobject.c32
-rw-r--r--Objects/intobject.c59
-rw-r--r--Objects/longobject.c46
-rw-r--r--Python/bltinmodule.c131
6 files changed, 193 insertions, 91 deletions
diff --git a/Include/object.h b/Include/object.h
index 081bb86..f644be3 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -146,6 +146,11 @@ typedef struct {
object *(*nb_xor) FPROTO((object *, object *));
object *(*nb_or) FPROTO((object *, object *));
int (*nb_coerce) FPROTO((object **, object **));
+ object *(*nb_int) FPROTO((object *));
+ object *(*nb_long) FPROTO((object *));
+ object *(*nb_float) FPROTO((object *));
+ object *(*nb_oct) FPROTO((object *));
+ object *(*nb_hex) FPROTO((object *));
} number_methods;
typedef struct {
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 514869c..9026968 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -714,6 +714,12 @@ instance_coerce(pv, pw)
return 0;
}
+UNARY(instance_int, "__int__")
+UNARY(instance_long, "__long__")
+UNARY(instance_float, "__float__")
+UNARY(instance_oct, "__oct__")
+UNARY(instance_hex, "__hex__")
+
static number_methods instance_as_number = {
instance_add, /*nb_add*/
instance_sub, /*nb_subtract*/
@@ -733,6 +739,11 @@ static number_methods instance_as_number = {
instance_xor, /*nb_xor*/
instance_or, /*nb_or*/
instance_coerce, /*nb_coerce*/
+ instance_int, /*nb_int*/
+ instance_long, /*nb_long*/
+ instance_float, /*nb_float*/
+ instance_oct, /*nb_oct*/
+ instance_hex, /*nb_hex*/
};
typeobject Instancetype = {
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 5ce6202..1a1598c 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -318,6 +318,33 @@ float_coerce(pv, pw)
return 1; /* Can't do it */
}
+static object *
+float_int(v)
+ object *v;
+{
+ double x = getfloatvalue(v);
+ /* XXX should check for overflow */
+ /* XXX should define how we round */
+ return newintobject((long)x);
+}
+
+static object *
+float_long(v)
+ object *v;
+{
+ double x = getfloatvalue(v);
+ return dnewlongobject(x);
+}
+
+static object *
+float_float(v)
+ object *v;
+{
+ INCREF(v);
+ return v;
+}
+
+
static number_methods float_as_number = {
float_add, /*nb_add*/
float_sub, /*nb_subtract*/
@@ -337,6 +364,11 @@ static number_methods float_as_number = {
0, /*nb_xor*/
0, /*nb_or*/
float_coerce, /*nb_coerce*/
+ float_int, /*nb_int*/
+ float_long, /*nb_long*/
+ float_float, /*nb_float*/
+ 0, /*nb_oct*/
+ 0, /*nb_hex*/
};
typeobject Floattype = {
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 8ecffc2..e10dab2 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -421,6 +421,59 @@ int_or(v, w)
return newintobject(a | b);
}
+static object *
+int_int(v)
+ object *v;
+{
+ INCREF(v);
+ return v;
+}
+
+static object *
+int_long(v)
+ object *v;
+{
+ long x = getintvalue(v);
+ return newlongobject(x);
+}
+
+static object *
+int_float(v)
+ object *v;
+{
+ long x = getintvalue(v);
+ return newfloatobject((double)x);
+}
+
+static object *
+int_oct(v)
+ object *v;
+{
+ char buf[20];
+ long x = getintvalue(v);
+ if (x == 0)
+ strcpy(buf, "0");
+ else if (x > 0)
+ sprintf(buf, "0%lo", x);
+ else
+ sprintf(buf, "-0%lo", -x);
+ return newstringobject(buf);
+}
+
+static object *
+int_hex(v)
+ object *v;
+{
+ char buf[20];
+ long x = getintvalue(v);
+ if (x >= 0)
+ sprintf(buf, "0x%lx", x);
+ else
+ sprintf(buf, "-0x%lx", -x);
+ return newstringobject(buf);
+}
+
+
static number_methods int_as_number = {
int_add, /*nb_add*/
int_sub, /*nb_subtract*/
@@ -439,6 +492,12 @@ static number_methods int_as_number = {
int_and, /*nb_and*/
int_xor, /*nb_xor*/
int_or, /*nb_or*/
+ 0, /*nb_coerce*/
+ int_int, /*nb_int*/
+ int_long, /*nb_long*/
+ int_float, /*nb_float*/
+ int_oct, /*nb_oct*/
+ int_hex, /*nb_hex*/
};
typeobject Inttype = {
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 7ede30c..25b4c64 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -1268,6 +1268,47 @@ long_coerce(pv, pw)
return 1; /* Can't do it */
}
+static object *
+long_int(v)
+ object *v;
+{
+ long x;
+ x = getlongvalue(v);
+ if (err_occurred())
+ return NULL;
+ return newintobject(x);
+}
+
+static object *
+long_long(v)
+ object *v;
+{
+ INCREF(v);
+ return v;
+}
+
+static object *
+long_float(v)
+ object *v;
+{
+ return newfloatobject(dgetlongvalue(v));
+}
+
+static object *
+long_oct(v)
+ object *v;
+{
+ return long_format(v, 8);
+}
+
+static object *
+long_hex(v)
+ object *v;
+{
+ return long_format(v, 16);
+}
+
+
#define UF (object* (*) FPROTO((object *))) /* Unary function */
#define BF (object* (*) FPROTO((object *, object *))) /* Binary function */
#define IF (int (*) FPROTO((object *))) /* Int function */
@@ -1292,6 +1333,11 @@ static number_methods long_as_number = {
BF long_or, /*nb_or*/
(int (*) FPROTO((object **, object **)))
long_coerce, /*nb_coerce*/
+ UF long_int, /*nb_int*/
+ UF long_long, /*nb_long*/
+ UF long_float, /*nb_float*/
+ UF long_oct, /*nb_oct*/
+ UF long_hex, /*nb_hex*/
};
typeobject Longtype = {
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index b74cdf1..2f46931 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -253,25 +253,15 @@ builtin_float(self, v)
object *self;
object *v;
{
- if (v == NULL) {
- /* */
- }
- else if (is_intobject(v)) {
- long x = getintvalue(v);
- return newfloatobject((double)x);
- }
- else if (is_longobject(v)) {
- return newfloatobject(dgetlongvalue(v));
- }
- else if (is_floatobject(v)) {
- INCREF(v);
- return v;
- }
- else if (is_instanceobject(v)) {
- return instance_convert(v, "__float__");
+ number_methods *nb;
+
+ if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
+ nb->nb_float == NULL) {
+ err_setstr(TypeError,
+ "float() argument can't be converted to float");
+ return NULL;
}
- err_setstr(TypeError, "float() argument must be int, long or float");
- return NULL;
+ return (*nb->nb_float)(v);
}
static object *
@@ -307,22 +297,15 @@ builtin_hex(self, v)
object *self;
object *v;
{
- if (v != NULL) {
- if (is_intobject(v)) {
- char buf[20];
- long x = getintvalue(v);
- if (x >= 0)
- sprintf(buf, "0x%lx", x);
- else
- sprintf(buf, "-0x%lx", -x);
- return newstringobject(buf);
- }
- if (is_longobject(v)) {
- return long_format(v, 16);
- }
+ number_methods *nb;
+
+ if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
+ nb->nb_hex == NULL) {
+ err_setstr(TypeError,
+ "hex() argument can't be converted to hex");
+ return NULL;
}
- err_setstr(TypeError, "hex() requires int/long argument");
- return NULL;
+ return (*nb->nb_hex)(v);
}
static object *
@@ -354,30 +337,15 @@ builtin_int(self, v)
object *self;
object *v;
{
- if (v == NULL) {
- /* */
- }
- else if (is_intobject(v)) {
- INCREF(v);
- return v;
- }
- else if (is_longobject(v)) {
- long x;
- x = getlongvalue(v);
- if (err_occurred())
- return NULL;
- return newintobject(x);
- }
- else if (is_floatobject(v)) {
- double x = getfloatvalue(v);
- /* XXX should check for overflow */
- return newintobject((long)x);
- }
- else if (is_instanceobject(v)) {
- return instance_convert(v, "__int__");
+ number_methods *nb;
+
+ if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
+ nb->nb_int == NULL) {
+ err_setstr(TypeError,
+ "int() argument can't be converted to int");
+ return NULL;
}
- err_setstr(TypeError, "int() argument must be int, long or float");
- return NULL;
+ return (*nb->nb_int)(v);
}
static object *
@@ -413,25 +381,15 @@ builtin_long(self, v)
object *self;
object *v;
{
- if (v == NULL) {
- /* */
- }
- else if (is_intobject(v)) {
- return newlongobject(getintvalue(v));
- }
- else if (is_longobject(v)) {
- INCREF(v);
- return v;
- }
- else if (is_floatobject(v)) {
- double x = getfloatvalue(v);
- return dnewlongobject(x);
- }
- else if (is_instanceobject(v)) {
- return instance_convert(v, "__long__");
+ number_methods *nb;
+
+ if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
+ nb->nb_long == NULL) {
+ err_setstr(TypeError,
+ "long() argument can't be converted to long");
+ return NULL;
}
- err_setstr(TypeError, "long() argument must be int, long or float");
- return NULL;
+ return (*nb->nb_long)(v);
}
static object *
@@ -491,24 +449,15 @@ builtin_oct(self, v)
object *self;
object *v;
{
- if (v != NULL) {
- if (is_intobject(v)) {
- char buf[20];
- long x = getintvalue(v);
- if (x == 0)
- strcpy(buf, "0");
- else if (x > 0)
- sprintf(buf, "0%lo", x);
- else
- sprintf(buf, "-0%lo", -x);
- return newstringobject(buf);
- }
- if (is_longobject(v)) {
- return long_format(v, 8);
- }
+ number_methods *nb;
+
+ if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
+ nb->nb_oct == NULL) {
+ err_setstr(TypeError,
+ "oct() argument can't be converted to oct");
+ return NULL;
}
- err_setstr(TypeError, "oct() requires int/long argument");
- return NULL;
+ return (*nb->nb_oct)(v);
}
static object *