summaryrefslogtreecommitdiff
path: root/py/objslice.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/objslice.c')
-rw-r--r--py/objslice.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/py/objslice.c b/py/objslice.c
index 5a15be55a..cbbee326e 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -152,6 +152,71 @@ mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
return MP_OBJ_FROM_PTR(o);
}
+// Return the real index and step values for a slice when applied to a sequence of
+// the given length, resolving missing components, negative values and values off
+// the end of the sequence.
+void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *result) {
+ mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_int_t start, stop, step;
+
+ if (self->step == mp_const_none) {
+ step = 1;
+ } else {
+ step = mp_obj_get_int(self->step);
+ if (step == 0) {
+ mp_raise_ValueError(translate("slice step cannot be zero"));
+ }
+ }
+
+ if (step > 0) {
+ // Positive step
+ if (self->start == mp_const_none) {
+ start = 0;
+ } else {
+ start = mp_obj_get_int(self->start);
+ if (start < 0) {
+ start += length;
+ }
+ start = MIN(length, MAX(start, 0));
+ }
+
+ if (self->stop == mp_const_none) {
+ stop = length;
+ } else {
+ stop = mp_obj_get_int(self->stop);
+ if (stop < 0) {
+ stop += length;
+ }
+ stop = MIN(length, MAX(stop, 0));
+ }
+ } else {
+ // Negative step
+ if (self->start == mp_const_none) {
+ start = length - 1;
+ } else {
+ start = mp_obj_get_int(self->start);
+ if (start < 0) {
+ start += length;
+ }
+ start = MIN(length - 1, MAX(start, -1));
+ }
+
+ if (self->stop == mp_const_none) {
+ stop = -1;
+ } else {
+ stop = mp_obj_get_int(self->stop);
+ if (stop < 0) {
+ stop += length;
+ }
+ stop = MIN(length - 1, MAX(stop, -1));
+ }
+ }
+
+ result->start = start;
+ result->stop = stop;
+ result->step = step;
+}
+
#if MICROPY_PY_BUILTINS_SLICE_ATTRS
STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type,
size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {