summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/rangeobject.h2
-rw-r--r--Objects/rangeobject.c150
-rw-r--r--Python/bltinmodule.c2
3 files changed, 129 insertions, 25 deletions
diff --git a/Include/rangeobject.h b/Include/rangeobject.h
index f2d6788..39d20c6 100644
--- a/Include/rangeobject.h
+++ b/Include/rangeobject.h
@@ -38,4 +38,4 @@ extern typeobject Rangetype;
#define is_rangeobject(op) ((op)->ob_type == &Rangetype)
-extern object *newrangeobject PROTO((long, long, long));
+extern object *newrangeobject PROTO((long, long, long, int));
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 0bdbb66..f19dad8 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -1,6 +1,6 @@
/***********************************************************
-Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
-Amsterdam, The Netherlands.
+Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
+Netherlands.
All Rights Reserved
@@ -31,18 +31,21 @@ typedef struct {
long start;
long step;
long len;
+ int reps;
} rangeobject;
object *
-newrangeobject(start, len, step)
+newrangeobject(start, len, step, reps)
long start, len, step;
+ int reps;
{
rangeobject *obj = (rangeobject *) newobject(&Rangetype);
obj->start = start;
obj->len = len;
obj->step = step;
+ obj->reps = reps;
return (object *) obj;
}
@@ -59,19 +62,42 @@ range_item(r, i)
rangeobject *r;
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");
return NULL;
}
- return newintobject(r->start + i * r->step);
+ return newintobject(r->start + (i % r->len) * r->step);
}
static int
range_length(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 *
@@ -79,11 +105,44 @@ range_repr(r)
rangeobject *r;
{
char buf[80];
- sprintf(buf, "xrange(%ld, %ld, %ld)",
- r->start, r->start + r->len * r->step, r->step);
+ sprintf(buf, "(range(%ld, %ld, %ld) * %d)",
+ r->start,
+ r->start + r->len * r->step,
+ r->step,
+ r->reps);
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
range_compare(r1, r2)
rangeobject *r1, *r2;
@@ -96,33 +155,78 @@ range_compare(r1, r2)
else if (r1->len != r2->len)
return r1->len - r2->len;
+
+ else
+ return r1->reps - r2->reps;
}
static object *
-range_concat(r, s)
+range_slice(r, low, high)
rangeobject *r;
- object *s;
+ int low, high;
{
- err_setstr(TypeError, "concat not supported by xrange object");
- return NULL;
+ if (r->reps != 1) {
+ err_setstr(TypeError, "cannot slice a replicated range");
+ 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 *
-range_repeat(r, n)
- rangeobject *r;
- int n;
+range_tolist(self, args)
+rangeobject *self;
+object *args;
{
- err_setstr(TypeError, "repeat not supported by xrange object");
- return NULL;
+ object *thelist;
+ int j;
+ int len = self->len * self->reps;
+
+ if (! getargs(args, ""))
+ 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 *
-range_slice(r, i, j)
+range_getattr(r, name)
rangeobject *r;
- int i, j;
+ char *name;
{
- err_setstr(TypeError, "slice not supported by xrange object");
- return NULL;
+ static struct methodlist range_methods[] = {
+ {"tolist", range_tolist},
+ {NULL, NULL}
+ };
+
+ return findmethod(range_methods, (object *) r, name);
}
static sequence_methods range_as_sequence = {
@@ -142,8 +246,8 @@ typeobject Rangetype = {
sizeof(rangeobject), /* Basic object size */
0, /* Item size for varobject */
range_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
+ range_print, /*tp_print*/
+ range_getattr, /*tp_getattr*/
0, /*tp_setattr*/
range_compare, /*tp_compare*/
range_repr, /*tp_repr*/
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index b63f56d..c8a8e83 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -892,7 +892,7 @@ builtin_xrange(self, v)
if (len < 0)
len = 0;
- return newrangeobject(start, len, step);
+ return newrangeobject(start, len, step, 1);
}
static object *