objlist: Implement support for arbitrary (3-arg) slices.
This commit is contained in:
parent
de4b9329f9
commit
5fd5af98d0
1
py/obj.h
1
py/obj.h
@ -579,6 +579,7 @@ bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, u
|
||||
bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2);
|
||||
mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args);
|
||||
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
|
||||
mp_obj_t mp_seq_extract_slice(uint len, const mp_obj_t *seq, mp_bound_slice_t *indexes);
|
||||
// Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems
|
||||
#define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte*)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz))
|
||||
#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_t) \
|
||||
|
@ -178,7 +178,8 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
|
||||
}
|
||||
mp_bound_slice_t slice;
|
||||
if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
|
||||
assert(0);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
|
||||
"Only slices with step=1 (aka None) are supported"));
|
||||
}
|
||||
mp_obj_array_t *res = array_new(o->typecode, slice.stop - slice.start);
|
||||
int sz = mp_binary_get_size('@', o->typecode, NULL);
|
||||
|
@ -178,7 +178,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||
mp_bound_slice_t slice;
|
||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
|
||||
assert(0);
|
||||
return mp_seq_extract_slice(self->len, self->items, &slice);
|
||||
}
|
||||
mp_obj_list_t *res = list_new(slice.stop - slice.start);
|
||||
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
|
||||
|
@ -353,7 +353,8 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||
mp_bound_slice_t slice;
|
||||
if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) {
|
||||
assert(0);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
|
||||
"Only slices with step=1 (aka None) are supported"));
|
||||
}
|
||||
return str_new(type, self_data + slice.start, slice.stop - slice.start);
|
||||
}
|
||||
|
@ -165,7 +165,8 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||
mp_bound_slice_t slice;
|
||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
|
||||
assert(0);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
|
||||
"Only slices with step=1 (aka None) are supported"));
|
||||
}
|
||||
mp_obj_tuple_t *res = mp_obj_new_tuple(slice.stop - slice.start, NULL);
|
||||
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
|
||||
|
@ -95,8 +95,6 @@ bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_
|
||||
indexes->stop = stop;
|
||||
|
||||
if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
|
||||
"Only slices with step=1 (aka None) are supported"));
|
||||
indexes->step = MP_OBJ_SMALL_INT_VALUE(ostep);
|
||||
return false;
|
||||
}
|
||||
@ -104,6 +102,27 @@ bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_
|
||||
return true;
|
||||
}
|
||||
|
||||
mp_obj_t mp_seq_extract_slice(uint len, const mp_obj_t *seq, mp_bound_slice_t *indexes) {
|
||||
machine_int_t start = indexes->start, stop = indexes->stop;
|
||||
machine_int_t step = indexes->step;
|
||||
|
||||
mp_obj_t res = mp_obj_new_list(0, NULL);
|
||||
|
||||
if (step < 0) {
|
||||
stop--;
|
||||
while (start <= stop) {
|
||||
mp_obj_list_append(res, seq[stop]);
|
||||
stop += step;
|
||||
}
|
||||
} else {
|
||||
while (start < stop) {
|
||||
mp_obj_list_append(res, seq[start]);
|
||||
start += step;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Special-case comparison function for sequences of bytes
|
||||
// Don't pass MP_BINARY_OP_NOT_EQUAL here
|
||||
bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, uint len2) {
|
||||
|
4
tests/basics/list_slice_3arg.py
Normal file
4
tests/basics/list_slice_3arg.py
Normal file
@ -0,0 +1,4 @@
|
||||
x = list(range(10))
|
||||
print(x[::-1])
|
||||
print(x[::2])
|
||||
print(x[::-2])
|
Loading…
Reference in New Issue
Block a user