| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /**
- * @constructor
- * @param {Object} start
- * @param {Object=} stop
- * @param {Object=} step
- */
- Sk.builtin.slice = function slice (start, stop, step) {
- Sk.builtin.pyCheckArgs("slice", arguments, 1, 3, false, false);
- if ((step !== undefined) && Sk.misceval.isIndex(step) && (Sk.misceval.asIndex(step) === 0)) {
- throw new Sk.builtin.ValueError("slice step cannot be zero");
- }
- if (!(this instanceof Sk.builtin.slice)) {
- return new Sk.builtin.slice(start, stop, step);
- }
- if (stop === undefined && step === undefined) {
- stop = start;
- start = Sk.builtin.none.none$;
- }
- if (stop === undefined) {
- stop = Sk.builtin.none.none$;
- }
- if (step === undefined) {
- step = Sk.builtin.none.none$;
- }
- this.start = start;
- this.stop = stop;
- this.step = step;
- this.__class__ = Sk.builtin.slice;
- this["$d"] = new Sk.builtin.dict([Sk.builtin.slice$start, this.start,
- Sk.builtin.slice$stop, this.stop,
- Sk.builtin.slice$step, this.step]);
- return this;
- };
- Sk.abstr.setUpInheritance("slice", Sk.builtin.slice, Sk.builtin.object);
- Sk.builtin.slice.prototype["$r"] = function () {
- var a = Sk.builtin.repr(this.start).v;
- var b = Sk.builtin.repr(this.stop).v;
- var c = Sk.builtin.repr(this.step).v;
- return new Sk.builtin.str("slice(" + a + ", " + b + ", " + c + ")");
- };
- Sk.builtin.slice.prototype.tp$richcompare = function (w, op) {
- // w not a slice
- var t1, t2;
- if (!w.__class__ || w.__class__ != Sk.builtin.slice) {
- // shortcuts for eq/not
- if (op === "Eq") {
- return false;
- }
- if (op === "NotEq") {
- return true;
- }
- // todo; other types should have an arbitrary order
- return false;
- }
- // This is how CPython does it
- t1 = new Sk.builtin.tuple([this.start, this.stop, this.step]);
- t2 = new Sk.builtin.tuple([w.start, w.stop, w.step]);
- return t1.tp$richcompare(t2, op);
- };
- /* Internal indices function */
- Sk.builtin.slice.prototype.slice_indices_ = function (length) {
- var start, stop, step;
- if (Sk.builtin.checkNone(this.start)) {
- start = null;
- } else if (Sk.misceval.isIndex(this.start)) {
- start = Sk.misceval.asIndex(this.start);
- } else {
- throw new Sk.builtin.TypeError("slice indices must be integers or None");
- }
- if (Sk.builtin.checkNone(this.stop)) {
- stop = null;
- } else if (Sk.misceval.isIndex(this.stop)) {
- stop = Sk.misceval.asIndex(this.stop);
- } else {
- throw new Sk.builtin.TypeError("slice indices must be integers or None");
- }
- if (Sk.builtin.checkNone(this.step)) {
- step = null;
- } else if (Sk.misceval.isIndex(this.step)) {
- step = Sk.misceval.asIndex(this.step);
- } else {
- throw new Sk.builtin.TypeError("slice indices must be integers or None");
- }
- // this seems ugly, better way?
- if (step === null) {
- step = 1;
- }
- if (step > 0) {
- if (start === null) {
- start = 0;
- }
- if (stop === null) {
- stop = length;
- }
- if (stop > length) {
- stop = length;
- }
- if (start < 0) {
- start = length + start;
- if (start < 0) {
- start = 0;
- }
- }
- if (stop < 0) {
- stop = length + stop;
- }
- } else {
- if (start === null) {
- start = length - 1;
- }
- if (start >= length) {
- start = length - 1;
- }
- if (stop === null) {
- stop = -1;
- } else if (stop < 0) {
- stop = length + stop;
- if (stop < 0) {
- stop = -1;
- }
- }
- if (start < 0) {
- start = length + start;
- }
- }
- return [start, stop, step];
- };
- Sk.builtin.slice.prototype["indices"] = new Sk.builtin.func(function (self, length) {
- Sk.builtin.pyCheckArgs("indices", arguments, 2, 2, false, false);
- length = Sk.builtin.asnum$(length);
- var sss = self.slice_indices_(length);
- return new Sk.builtin.tuple([new Sk.builtin.int_(sss[0]),
- new Sk.builtin.int_(sss[1]),
- new Sk.builtin.int_(sss[2])]);
- });
- Sk.builtin.slice.prototype.sssiter$ = function (wrt, f) {
- var i;
- var wrtv = Sk.builtin.asnum$(wrt);
- var sss = this.slice_indices_(typeof wrtv === "number" ? wrtv : wrt.v.length);
- if (sss[2] > 0) {
- for (i = sss[0]; i < sss[1]; i += sss[2]) {
- if (f(i, wrtv) === false) {
- return;
- }
- } // wrt or wrtv? RNL
- } else {
- for (i = sss[0]; i > sss[1]; i += sss[2]) {
- if (f(i, wrtv) === false) {
- return;
- }
- } // wrt or wrtv? RNL
- }
- };
- Sk.builtin.slice$start = new Sk.builtin.str("start");
- Sk.builtin.slice$stop = new Sk.builtin.str("stop");
- Sk.builtin.slice$step = new Sk.builtin.str("step");
|