diff options
author | Guido van Rossum <guido@python.org> | 1993-10-26 17:58:25 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1993-10-26 17:58:25 (GMT) |
commit | 12d12c5faf4d770160b7975b54e8f9b12694e012 (patch) | |
tree | e5528ca45963a90c5797073228090d221cdc6bba /Objects | |
parent | 444fc7c90cf210ec72f1c4204310f659263b6f75 (diff) | |
download | cpython-12d12c5faf4d770160b7975b54e8f9b12694e012.zip cpython-12d12c5faf4d770160b7975b54e8f9b12694e012.tar.gz cpython-12d12c5faf4d770160b7975b54e8f9b12694e012.tar.bz2 |
* compile.[ch]: support for lambda()
* PROTO.h, mymalloc.h: added #ifdefs for TURBOC and GNUC.
* allobjects.h: added #include "rangeobject.h"
* Grammar: added lambda_input; relaxed syntax for exec.
* bltinmodule.c: added bagof, map, reduce, lambda, xrange.
* tupleobject.[ch]: added resizetuple().
* rangeobject.[ch]: new object type to speed up range operations (not
convinced this is needed!!!)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/rangeobject.c | 205 | ||||
-rw-r--r-- | Objects/tupleobject.c | 57 |
2 files changed, 250 insertions, 12 deletions
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c new file mode 100644 index 0000000..a68d317 --- /dev/null +++ b/Objects/rangeobject.c @@ -0,0 +1,205 @@ +/*********************************************************** +Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, +Amsterdam, The Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/* Range object implementation */ + +#include "allobjects.h" + +typedef struct { + OB_HEAD + long start; + long step; + long len; + int reps; +} rangeobject; + + +object * +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; +} + +static void +range_dealloc(r) + rangeobject *r; +{ + DEL(r); +} + +static object * +range_item(r, i) + rangeobject *r; + int i; +{ + 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->len) * r->step); +} + +static int +range_length(r) + rangeobject *r; +{ + return r->len * r->reps; +} + +static object * +range_repr(r) + rangeobject *r; +{ + char buf[80]; + if (r->reps != 1) + sprintf(buf, "(xrange(%ld, %ld, %ld) * %d)", + r->start, + r->start + r->len * r->step, + r->step, + r->reps); + else + sprintf(buf, "xrange(%ld, %ld, %ld)", + r->start, + r->start + r->len * r->step, + r->step); + return newstringobject(buf); +} + +object * +range_concat(r, obj) + rangeobject *r; + object *obj; +{ + if (is_rangeobject(obj)) { + rangeobject *s = (rangeobject *)obj; + if (r->start == s->start && r->len == s->len && + r->step == s->step) + return newrangeobject(r->start, r->len, r->step, + r->reps + s->reps); + } + err_setstr(TypeError, "cannot concatenate different 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; +{ + if (r1->start != r2->start) + return r1->start - r2->start; + + else if (r1->step != r2->step) + return r1->step - r2->step; + + else if (r1->len != r2->len) + return r1->len - r2->len; + + else + return r1->reps - r2->reps; +} + +static object * +range_slice(r, low, high) + rangeobject *r; + int low, high; +{ + 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; + + return (object *) newrangeobject( + low * r->step + r->start, + high - low, + r->step, + 1); +} + +static sequence_methods range_as_sequence = { + range_length, /*sq_length*/ + range_concat, /*sq_concat*/ + range_repeat, /*sq_repeat*/ + range_item, /*sq_item*/ + range_slice, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ +}; + +typeobject Rangetype = { + OB_HEAD_INIT(&Typetype) + 0, /* Number of items for varobject */ + "range", /* Name of this type */ + sizeof(rangeobject), /* Basic object size */ + 0, /* Item size for varobject */ + range_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + range_compare, /*tp_compare*/ + range_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + &range_as_sequence, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ +}; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index bc68744..0047a09 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -123,21 +123,18 @@ settupleitem(op, i, newitem) { register object *olditem; if (!is_tupleobject(op)) { - if (newitem != NULL) - DECREF(newitem); + XDECREF(newitem); err_badcall(); return -1; } if (i < 0 || i >= ((tupleobject *)op) -> ob_size) { - if (newitem != NULL) - DECREF(newitem); + XDECREF(newitem); err_setstr(IndexError, "tuple assignment index out of range"); return -1; } olditem = ((tupleobject *)op) -> ob_item[i]; ((tupleobject *)op) -> ob_item[i] = newitem; - if (olditem != NULL) - DECREF(olditem); + XDECREF(olditem); return 0; } @@ -148,10 +145,8 @@ tupledealloc(op) register tupleobject *op; { register int i; - for (i = 0; i < op->ob_size; i++) { - if (op->ob_item[i] != NULL) - DECREF(op->ob_item[i]); - } + for (i = 0; i < op->ob_size; i++) + XDECREF(op->ob_item[i]); #if MAXSAVESIZE > 0 if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) { op->ob_item[0] = (object *) free_list[op->ob_size]; @@ -194,8 +189,7 @@ tuplerepr(v) joinstring(&s, comma); t = reprobject(v->ob_item[i]); joinstring(&s, t); - if (t != NULL) - DECREF(t); + XDECREF(t); } DECREF(comma); if (v->ob_size == 1) { @@ -397,3 +391,42 @@ typeobject Tupletype = { 0, /*tp_as_mapping*/ tuplehash, /*tp_hash*/ }; + +/* The following function breaks the notion that tuples are immutable: + it changes the size of a tuple. We get away with this only if there + is only one module referencing the object. You can also think of it + as creating a new tuple object and destroying the old one, only + more efficiently. In any case, don't use this if the tuple may + already be known to some other part of the code... */ + +int +resizetuple(pv, newsize) + object **pv; + int newsize; +{ + register object *v; + register tupleobject *sv; + v = *pv; + if (!is_tupleobject(v) || v->ob_refcnt != 1) { + *pv = 0; + DECREF(v); + err_badcall(); + return -1; + } + /* XXX UNREF/NEWREF interface should be more symmetrical */ +#ifdef REF_DEBUG + --ref_total; +#endif + UNREF(v); + *pv = (object *) + realloc((char *)v, + sizeof(tupleobject) + newsize * sizeof(object *)); + if (*pv == NULL) { + DEL(v); + err_nomem(); + return -1; + } + NEWREF(*pv); + ((tupleobject *) *pv)->ob_size = newsize; + return 0; +} |