Made builtins int(), long(), float(), oct() and hex() more generic.

This commit is contained in:
Guido van Rossum 1992-09-12 11:09:23 +00:00
parent 5c85062e1c
commit 1899c2e055
6 changed files with 193 additions and 91 deletions

View File

@ -146,6 +146,11 @@ typedef struct {
object *(*nb_xor) FPROTO((object *, object *)); object *(*nb_xor) FPROTO((object *, object *));
object *(*nb_or) FPROTO((object *, object *)); object *(*nb_or) FPROTO((object *, object *));
int (*nb_coerce) 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; } number_methods;
typedef struct { typedef struct {

View File

@ -714,6 +714,12 @@ instance_coerce(pv, pw)
return 0; 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 = { static number_methods instance_as_number = {
instance_add, /*nb_add*/ instance_add, /*nb_add*/
instance_sub, /*nb_subtract*/ instance_sub, /*nb_subtract*/
@ -733,6 +739,11 @@ static number_methods instance_as_number = {
instance_xor, /*nb_xor*/ instance_xor, /*nb_xor*/
instance_or, /*nb_or*/ instance_or, /*nb_or*/
instance_coerce, /*nb_coerce*/ 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 = { typeobject Instancetype = {

View File

@ -318,6 +318,33 @@ float_coerce(pv, pw)
return 1; /* Can't do it */ 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 = { static number_methods float_as_number = {
float_add, /*nb_add*/ float_add, /*nb_add*/
float_sub, /*nb_subtract*/ float_sub, /*nb_subtract*/
@ -337,6 +364,11 @@ static number_methods float_as_number = {
0, /*nb_xor*/ 0, /*nb_xor*/
0, /*nb_or*/ 0, /*nb_or*/
float_coerce, /*nb_coerce*/ float_coerce, /*nb_coerce*/
float_int, /*nb_int*/
float_long, /*nb_long*/
float_float, /*nb_float*/
0, /*nb_oct*/
0, /*nb_hex*/
}; };
typeobject Floattype = { typeobject Floattype = {

View File

@ -421,6 +421,59 @@ int_or(v, w)
return newintobject(a | b); 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 = { static number_methods int_as_number = {
int_add, /*nb_add*/ int_add, /*nb_add*/
int_sub, /*nb_subtract*/ int_sub, /*nb_subtract*/
@ -439,6 +492,12 @@ static number_methods int_as_number = {
int_and, /*nb_and*/ int_and, /*nb_and*/
int_xor, /*nb_xor*/ int_xor, /*nb_xor*/
int_or, /*nb_or*/ 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 = { typeobject Inttype = {

View File

@ -1268,6 +1268,47 @@ long_coerce(pv, pw)
return 1; /* Can't do it */ 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 UF (object* (*) FPROTO((object *))) /* Unary function */
#define BF (object* (*) FPROTO((object *, object *))) /* Binary function */ #define BF (object* (*) FPROTO((object *, object *))) /* Binary function */
#define IF (int (*) FPROTO((object *))) /* Int function */ #define IF (int (*) FPROTO((object *))) /* Int function */
@ -1292,6 +1333,11 @@ static number_methods long_as_number = {
BF long_or, /*nb_or*/ BF long_or, /*nb_or*/
(int (*) FPROTO((object **, object **))) (int (*) FPROTO((object **, object **)))
long_coerce, /*nb_coerce*/ 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 = { typeobject Longtype = {

View File

@ -253,25 +253,15 @@ builtin_float(self, v)
object *self; object *self;
object *v; object *v;
{ {
if (v == NULL) { 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;
} }
else if (is_intobject(v)) { return (*nb->nb_float)(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__");
}
err_setstr(TypeError, "float() argument must be int, long or float");
return NULL;
} }
static object * static object *
@ -307,22 +297,15 @@ builtin_hex(self, v)
object *self; object *self;
object *v; object *v;
{ {
if (v != NULL) { number_methods *nb;
if (is_intobject(v)) {
char buf[20]; if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
long x = getintvalue(v); nb->nb_hex == NULL) {
if (x >= 0) err_setstr(TypeError,
sprintf(buf, "0x%lx", x); "hex() argument can't be converted to hex");
else return NULL;
sprintf(buf, "-0x%lx", -x);
return newstringobject(buf);
}
if (is_longobject(v)) {
return long_format(v, 16);
}
} }
err_setstr(TypeError, "hex() requires int/long argument"); return (*nb->nb_hex)(v);
return NULL;
} }
static object * static object *
@ -354,30 +337,15 @@ builtin_int(self, v)
object *self; object *self;
object *v; object *v;
{ {
if (v == NULL) { 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;
} }
else if (is_intobject(v)) { return (*nb->nb_int)(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__");
}
err_setstr(TypeError, "int() argument must be int, long or float");
return NULL;
} }
static object * static object *
@ -413,25 +381,15 @@ builtin_long(self, v)
object *self; object *self;
object *v; object *v;
{ {
if (v == NULL) { 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;
} }
else if (is_intobject(v)) { return (*nb->nb_long)(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__");
}
err_setstr(TypeError, "long() argument must be int, long or float");
return NULL;
} }
static object * static object *
@ -491,24 +449,15 @@ builtin_oct(self, v)
object *self; object *self;
object *v; object *v;
{ {
if (v != NULL) { number_methods *nb;
if (is_intobject(v)) {
char buf[20]; if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
long x = getintvalue(v); nb->nb_oct == NULL) {
if (x == 0) err_setstr(TypeError,
strcpy(buf, "0"); "oct() argument can't be converted to oct");
else if (x > 0) return NULL;
sprintf(buf, "0%lo", x);
else
sprintf(buf, "-0%lo", -x);
return newstringobject(buf);
}
if (is_longobject(v)) {
return long_format(v, 8);
}
} }
err_setstr(TypeError, "oct() requires int/long argument"); return (*nb->nb_oct)(v);
return NULL;
} }
static object * static object *