objlist: Implement non-growing slice assignment.
Slice value to assign can be only a list so far too.
This commit is contained in:
parent
d915a52eb6
commit
94d8246272
5
py/obj.h
5
py/obj.h
@ -573,3 +573,8 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp
|
|||||||
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
|
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
|
||||||
// Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems
|
// 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_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) \
|
||||||
|
/*printf("memcpy(%p, %p, %d)\n", dest + beg, slice, slice_len * sizeof(item_t));*/ \
|
||||||
|
memcpy(dest + beg, slice, slice_len * sizeof(item_t)); \
|
||||||
|
/*printf("memcpy(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));*/ \
|
||||||
|
memcpy(dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));
|
||||||
|
20
py/objlist.c
20
py/objlist.c
@ -173,6 +173,26 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|||||||
uint index_val = mp_get_index(self->base.type, self->len, index, false);
|
uint index_val = mp_get_index(self->base.type, self->len, index, false);
|
||||||
return self->items[index_val];
|
return self->items[index_val];
|
||||||
} else {
|
} else {
|
||||||
|
#if MICROPY_ENABLE_SLICE
|
||||||
|
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
|
||||||
|
mp_obj_list_t *self = self_in;
|
||||||
|
assert(MP_OBJ_IS_TYPE(value, &mp_type_list));
|
||||||
|
mp_obj_list_t *slice = value;
|
||||||
|
machine_uint_t start, stop;
|
||||||
|
if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
int len_adj = slice->len - (stop - start);
|
||||||
|
//printf("Len adj: %d\n", len_adj);
|
||||||
|
assert(len_adj <= 0);
|
||||||
|
mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t);
|
||||||
|
// Clear "freed" elements at the end of list
|
||||||
|
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
|
||||||
|
self->len += len_adj;
|
||||||
|
// TODO: apply allocation policy re: alloc_size
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mp_obj_list_store(self_in, index, value);
|
mp_obj_list_store(self_in, index, value);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
27
tests/basics/list_slice_assign.py
Normal file
27
tests/basics/list_slice_assign.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# test slices; only 2 argument version supported by Micro Python at the moment
|
||||||
|
x = list(range(10))
|
||||||
|
|
||||||
|
# Assignment
|
||||||
|
l = list(x)
|
||||||
|
l[1:3] = [10, 20]
|
||||||
|
print(l)
|
||||||
|
l = list(x)
|
||||||
|
l[1:3] = [10]
|
||||||
|
print(l)
|
||||||
|
l = list(x)
|
||||||
|
l[1:3] = []
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
l = list(x)
|
||||||
|
l[:3] = [10, 20]
|
||||||
|
print(l)
|
||||||
|
l = list(x)
|
||||||
|
l[:3] = []
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
l = list(x)
|
||||||
|
l[:-3] = [10, 20]
|
||||||
|
print(l)
|
||||||
|
l = list(x)
|
||||||
|
l[:-3] = []
|
||||||
|
print(l)
|
Loading…
Reference in New Issue
Block a user