Add indices() support to slice.
This commit is contained in:
parent
12fa5b3a66
commit
e0ef7e3092
|
@ -43,6 +43,7 @@
|
|||
#define MICROPY_PY_BUILTINS_REVERSED (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (1)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (1)
|
||||
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (1)
|
||||
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
|
||||
#define MICROPY_PY___FILE__ (1)
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/runtime0.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -58,6 +59,58 @@ STATIC void slice_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
|
|||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_SLICE_ATTRS
|
||||
STATIC mp_obj_t slice_indices(mp_obj_t self_in, mp_obj_t length_obj) {
|
||||
mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (!MP_OBJ_IS_SMALL_INT(length_obj)) {
|
||||
mp_raise_TypeError("Length must be an int");
|
||||
}
|
||||
|
||||
int length = MP_OBJ_SMALL_INT_VALUE(length_obj);
|
||||
if (length < 0) {
|
||||
mp_raise_ValueError("Length must be non-negative");
|
||||
}
|
||||
|
||||
mp_obj_t indices[3] = {MP_OBJ_NEW_SMALL_INT(0), length_obj, MP_OBJ_NEW_SMALL_INT(1)};
|
||||
mp_obj_t slice[2] = {self->start, self->stop};
|
||||
|
||||
int step = 1;
|
||||
if (self->step != mp_const_none) {
|
||||
indices[2] = self->step;
|
||||
step = MP_OBJ_SMALL_INT_VALUE(self->step);
|
||||
if (step < 0) {
|
||||
indices[0] = MP_OBJ_NEW_SMALL_INT(length - 1);
|
||||
indices[1] = MP_OBJ_NEW_SMALL_INT(-1);
|
||||
}
|
||||
if (step == 0) {
|
||||
mp_raise_ValueError("slice step cannot be zero");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (slice[i] == mp_const_none) {
|
||||
continue;
|
||||
}
|
||||
int value = MP_OBJ_SMALL_INT_VALUE(slice[i]);
|
||||
if (value < 0) {
|
||||
value += length;
|
||||
}
|
||||
if (value < 0) {
|
||||
if (step > 0) {
|
||||
value = 0;
|
||||
} else if (step < 0) {
|
||||
value = -1;
|
||||
}
|
||||
} else if (value > length) {
|
||||
value = length;
|
||||
}
|
||||
indices[i] = MP_OBJ_NEW_SMALL_INT(value);
|
||||
}
|
||||
|
||||
mp_obj_t tuple = mp_obj_new_tuple(3, indices);
|
||||
|
||||
return tuple;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(slice_indices_obj, slice_indices);
|
||||
|
||||
STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
if (dest[0] != MP_OBJ_NULL) {
|
||||
// not load attribute
|
||||
|
@ -70,8 +123,13 @@ STATIC void slice_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||
dest[0] = self->stop;
|
||||
} else if (attr == MP_QSTR_step) {
|
||||
dest[0] = self->step;
|
||||
} else if (attr == MP_QSTR_indices) {
|
||||
mp_convert_member_lookup(self_in, self->base.type, (mp_obj_t) &slice_indices_obj, dest);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type,
|
||||
mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
#endif
|
||||
|
||||
const mp_obj_type_t mp_type_slice = {
|
||||
|
@ -79,6 +137,7 @@ const mp_obj_type_t mp_type_slice = {
|
|||
.name = MP_QSTR_slice,
|
||||
.print = slice_print,
|
||||
#if MICROPY_PY_BUILTINS_SLICE_ATTRS
|
||||
.make_new = slice_make_new,
|
||||
.attr = slice_attr,
|
||||
#endif
|
||||
};
|
||||
|
@ -92,6 +151,30 @@ 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);
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_SLICE_ATTRS
|
||||
STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type,
|
||||
mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check number of arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, 3, false);
|
||||
|
||||
// 1st argument is the pin
|
||||
mp_obj_t start = mp_const_none;
|
||||
mp_obj_t stop = mp_const_none;
|
||||
mp_obj_t step = mp_const_none;
|
||||
if (n_args == 1) {
|
||||
stop = args[0];
|
||||
} else {
|
||||
start = args[0];
|
||||
stop = args[1];
|
||||
if (n_args == 3) {
|
||||
step = args[2];
|
||||
}
|
||||
}
|
||||
|
||||
return mp_obj_new_slice(start, stop, step);
|
||||
}
|
||||
#endif
|
||||
|
||||
void mp_obj_slice_get(mp_obj_t self_in, mp_obj_t *start, mp_obj_t *stop, mp_obj_t *step) {
|
||||
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_slice));
|
||||
mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
|
|
@ -9,3 +9,35 @@ s = A()[1:2:3]
|
|||
|
||||
# check type
|
||||
print(type(s) is slice)
|
||||
|
||||
s = slice(10)
|
||||
print(s)
|
||||
|
||||
s = slice(0, 4)
|
||||
print(s)
|
||||
|
||||
s = slice(0, 4, 2)
|
||||
print(s)
|
||||
|
||||
s = slice(-1)
|
||||
print(s)
|
||||
print(s.indices(10))
|
||||
|
||||
s = slice(-5, -1)
|
||||
print(s)
|
||||
print(s.indices(10))
|
||||
|
||||
s = slice(-100, -2, -1)
|
||||
print(s)
|
||||
print(s.indices(10))
|
||||
|
||||
s = slice(None, None, -2)
|
||||
print(s)
|
||||
print(s.indices(10))
|
||||
|
||||
s = slice(-100, -2, 0)
|
||||
print(s)
|
||||
try:
|
||||
print(s.indices(10))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
|
Loading…
Reference in New Issue