* rangeobject.[ch], bltinmodule.c: incorporate new version of range

object (unchanged from source except "range" -> "xrange").
This commit is contained in:
Guido van Rossum 1993-12-21 22:50:31 +00:00
parent c4f169cc5a
commit 7d6aa51b56
3 changed files with 129 additions and 25 deletions

View File

@ -38,4 +38,4 @@ extern typeobject Rangetype;
#define is_rangeobject(op) ((op)->ob_type == &Rangetype) #define is_rangeobject(op) ((op)->ob_type == &Rangetype)
extern object *newrangeobject PROTO((long, long, long)); extern object *newrangeobject PROTO((long, long, long, int));

View File

@ -1,6 +1,6 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Amsterdam, The Netherlands. Netherlands.
All Rights Reserved All Rights Reserved
@ -31,18 +31,21 @@ typedef struct {
long start; long start;
long step; long step;
long len; long len;
int reps;
} rangeobject; } rangeobject;
object * object *
newrangeobject(start, len, step) newrangeobject(start, len, step, reps)
long start, len, step; long start, len, step;
int reps;
{ {
rangeobject *obj = (rangeobject *) newobject(&Rangetype); rangeobject *obj = (rangeobject *) newobject(&Rangetype);
obj->start = start; obj->start = start;
obj->len = len; obj->len = len;
obj->step = step; obj->step = step;
obj->reps = reps;
return (object *) obj; return (object *) obj;
} }
@ -59,19 +62,42 @@ range_item(r, i)
rangeobject *r; rangeobject *r;
int i; int i;
{ {
if (i < 0 || i >= r->len) { if (i < 0 || i >= r->len * r->reps) {
err_setstr(IndexError, "range object index out of range"); err_setstr(IndexError, "range object index out of range");
return NULL; return NULL;
} }
return newintobject(r->start + i * r->step); return newintobject(r->start + (i % r->len) * r->step);
} }
static int static int
range_length(r) range_length(r)
rangeobject *r; rangeobject *r;
{ {
return r->len; return r->len * r->reps;
}
static int
range_print(r, fp, flags)
rangeobject *r;
FILE *fp;
int flags;
{
int i, j;
fprintf(fp, "(");
for (i = 0; i < r->reps; ++i)
for (j = 0; j < r->len; ++j) {
if (j > 0 || i > 0)
fprintf(fp, ", ");
fprintf(fp, "%d", r->start + j * r->step);
}
if (r->len == 1 && r->reps == 1)
fprintf(fp, ",");
fprintf(fp, ")");
return 0;
} }
static object * static object *
@ -79,11 +105,44 @@ range_repr(r)
rangeobject *r; rangeobject *r;
{ {
char buf[80]; char buf[80];
sprintf(buf, "xrange(%ld, %ld, %ld)", sprintf(buf, "(range(%ld, %ld, %ld) * %d)",
r->start, r->start + r->len * r->step, r->step); r->start,
r->start + r->len * r->step,
r->step,
r->reps);
return newstringobject(buf); return newstringobject(buf);
} }
object *
range_concat(r, obj)
rangeobject *r;
object *obj;
{
err_setstr(TypeError, "cannot concatenate range objects");
return NULL;
}
object *
range_repeat(r, n)
rangeobject *r;
int n;
{
if (n < 0)
return (object *) newrangeobject(0, 0, 1, 1);
else if (n == 1) {
INCREF(r);
return (object *) r;
}
else
return (object *) newrangeobject(
r->start,
r->len,
r->step,
r->reps * n);
}
static int static int
range_compare(r1, r2) range_compare(r1, r2)
rangeobject *r1, *r2; rangeobject *r1, *r2;
@ -96,33 +155,78 @@ range_compare(r1, r2)
else if (r1->len != r2->len) else if (r1->len != r2->len)
return r1->len - r2->len; return r1->len - r2->len;
else
return r1->reps - r2->reps;
} }
static object * static object *
range_concat(r, s) range_slice(r, low, high)
rangeobject *r; rangeobject *r;
object *s; int low, high;
{ {
err_setstr(TypeError, "concat not supported by xrange object"); if (r->reps != 1) {
err_setstr(TypeError, "cannot slice a replicated range");
return NULL; return NULL;
} }
if (low < 0)
low = 0;
else if (low > r->len)
low = r->len;
if (high < 0)
high = 0;
if (high < low)
high = low;
else if (high > r->len)
high = r->len;
if (low == 0 && high == r->len) {
INCREF(r);
return (object *) r;
}
return (object *) newrangeobject(
low * r->step + r->start,
high - low,
r->step,
1);
}
static object * static object *
range_repeat(r, n) range_tolist(self, args)
rangeobject *r; rangeobject *self;
int n; object *args;
{ {
err_setstr(TypeError, "repeat not supported by xrange object"); object *thelist;
int j;
int len = self->len * self->reps;
if (! getargs(args, ""))
return NULL; return NULL;
if ((thelist = newlistobject(len)) == NULL)
return NULL;
for (j = 0; j < len; ++j)
if ((setlistitem(thelist, j,
(object *) newintobject(
self->start + (j % self->len) * self->step))) < 0)
return NULL;
return thelist;
} }
static object * static object *
range_slice(r, i, j) range_getattr(r, name)
rangeobject *r; rangeobject *r;
int i, j; char *name;
{ {
err_setstr(TypeError, "slice not supported by xrange object"); static struct methodlist range_methods[] = {
return NULL; {"tolist", range_tolist},
{NULL, NULL}
};
return findmethod(range_methods, (object *) r, name);
} }
static sequence_methods range_as_sequence = { static sequence_methods range_as_sequence = {
@ -142,8 +246,8 @@ typeobject Rangetype = {
sizeof(rangeobject), /* Basic object size */ sizeof(rangeobject), /* Basic object size */
0, /* Item size for varobject */ 0, /* Item size for varobject */
range_dealloc, /*tp_dealloc*/ range_dealloc, /*tp_dealloc*/
0, /*tp_print*/ range_print, /*tp_print*/
0, /*tp_getattr*/ range_getattr, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
range_compare, /*tp_compare*/ range_compare, /*tp_compare*/
range_repr, /*tp_repr*/ range_repr, /*tp_repr*/

View File

@ -892,7 +892,7 @@ builtin_xrange(self, v)
if (len < 0) if (len < 0)
len = 0; len = 0;
return newrangeobject(start, len, step); return newrangeobject(start, len, step, 1);
} }
static object * static object *