Пример #1
0
STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in);
        mp_int_t len = range_len(self);
#if MICROPY_PY_BUILTINS_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            mp_bound_slice_t slice;
            mp_seq_get_fast_slice_indexes(len, index, &slice);
            mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
            o->base.type = &mp_type_range;
            o->start = self->start + slice.start * self->step;
            o->stop = self->start + slice.stop * self->step;
            o->step = slice.step * self->step;
            if (slice.step < 0) {
                // Negative slice steps have inclusive stop, so adjust for exclusive
                o->stop -= self->step;
            }
            return MP_OBJ_FROM_PTR(o);
        }
#endif
        size_t index_val = mp_get_index(self->base.type, len, index, false);
        return MP_OBJ_NEW_SMALL_INT(self->start + index_val * self->step);
    } else {
        return MP_OBJ_NULL; // op not supported
    }
}
Пример #2
0
STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
    if (value == MP_OBJ_NULL) {
        // delete item
        // TODO implement
        // TODO: confirmed that both bytearray and array.array support
        // slice deletion
        return MP_OBJ_NULL; // op not supported
    } else {
        mp_obj_array_t *o = self_in;
        if (0) {
#if MICROPY_PY_BUILTINS_SLICE
        } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
            if (value != MP_OBJ_SENTINEL) {
                // Only getting a slice is suported so far, not assignment
                // TODO: confirmed that both bytearray and array.array support
                // slice assignment (incl. of different size)
                return MP_OBJ_NULL; // op not supported
            }
            mp_bound_slice_t slice;
            if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
                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);
            assert(sz > 0);
            byte *p = o->items;
            memcpy(res->items, p + slice.start * sz, (slice.stop - slice.start) * sz);
            return res;
#endif
        } else {
            uint index = mp_get_index(o->base.type, o->len, index_in, false);
            if (value == MP_OBJ_SENTINEL) {
                // load
                return mp_binary_get_val_array(o->typecode, o->items, index);
            } else {
                // store
                mp_binary_set_val_array(o->typecode, o->items, index, value);
                return mp_const_none;
            }
        }
    }
}
Пример #3
0
mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_tuple_t *self = self_in;
#if MICROPY_ENABLE_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            machine_uint_t start, stop;
            if (!mp_seq_get_fast_slice_indexes(self->len, index, &start, &stop)) {
                assert(0);
            }
            mp_obj_tuple_t *res = mp_obj_new_tuple(stop - start, NULL);
            mp_seq_copy(res->items, self->items + start, res->len, mp_obj_t);
            return res;
        }
#endif
        uint index_value = mp_get_index(self->base.type, self->len, index, false);
        return self->items[index_value];
    } else {
        return MP_OBJ_NOT_SUPPORTED;
    }
}
Пример #4
0
mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
#if MICROPY_PY_BUILTINS_SLICE
        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)) {
                mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported");
            }
            mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(slice.stop - slice.start, NULL));
            mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
            return MP_OBJ_FROM_PTR(res);
        }
#endif
        size_t index_value = mp_get_index(self->base.type, self->len, index, false);
        return self->items[index_value];
    } else {
        return MP_OBJ_NULL; // op not supported
    }
}
Пример #5
0
mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_tuple_t *self = self_in;
#if MICROPY_PY_SLICE
        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)) {
                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);
            return res;
        }
#endif
        uint index_value = mp_get_index(self->base.type, self->len, index, false);
        return self->items[index_value];
    } else {
        return MP_OBJ_NULL; // op not supported
    }
}
Пример #6
0
STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_range_t *self = self_in;
        mp_int_t len = range_len(self);
#if MICROPY_PY_BUILTINS_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            mp_bound_slice_t slice;
            mp_seq_get_fast_slice_indexes(len, index, &slice);
            mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
            o->base.type = &mp_type_range;
            o->start = slice.start;
            o->stop = slice.stop;
            o->step = slice.step;
            return o;
        }
#endif
        uint index_val = mp_get_index(self->base.type, len, index, false);
        return MP_OBJ_NEW_SMALL_INT(self->start + index_val * self->step);
    } else {
        return MP_OBJ_NULL; // op not supported
    }
}
Пример #7
0
STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
    if (value == MP_OBJ_NULL) {
        // delete item
        // TODO implement
        // TODO: confirmed that both bytearray and array.array support
        // slice deletion
        return MP_OBJ_NULL; // op not supported
    } else {
        mp_obj_array_t *o = self_in;
        if (0) {
#if MICROPY_PY_BUILTINS_SLICE
        } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
            mp_bound_slice_t slice;
            if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
                mp_not_implemented("only slices with step=1 (aka None) are supported");
            }
            if (value != MP_OBJ_SENTINEL) {
                #if MICROPY_PY_ARRAY_SLICE_ASSIGN
                // Assign
                mp_uint_t src_len;
                void *src_items;
                size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
                if (MP_OBJ_IS_OBJ(value) && ((mp_obj_base_t*)value)->type->subscr == array_subscr) {
                    // value is array, bytearray or memoryview
                    mp_obj_array_t *src_slice = value;
                    if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {
                    compat_error:
                        nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "lhs and rhs should be compatible"));
                    }
                    src_len = src_slice->len;
                    src_items = src_slice->items;
                    #if MICROPY_PY_BUILTINS_MEMORYVIEW
                    if (MP_OBJ_IS_TYPE(value, &mp_type_memoryview)) {
                        src_items = (uint8_t*)src_items + (src_slice->free * item_sz);
                    }
                    #endif
                } else if (MP_OBJ_IS_TYPE(value, &mp_type_bytes)) {
                    if (item_sz != 1) {
                        goto compat_error;
                    }
                    mp_buffer_info_t bufinfo;
                    mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ);
                    src_len = bufinfo.len;
                    src_items = bufinfo.buf;
                } else {
                    mp_not_implemented("array/bytes required on right side");
                }

                // TODO: check src/dst compat
                mp_int_t len_adj = src_len - (slice.stop - slice.start);
                uint8_t* dest_items = o->items;
                #if MICROPY_PY_BUILTINS_MEMORYVIEW
                if (o->base.type == &mp_type_memoryview) {
                    if (len_adj != 0) {
                        goto compat_error;
                    }
                    dest_items += o->free * item_sz;
                }
                #endif
                if (len_adj > 0) {
                    if (len_adj > o->free) {
                        // TODO: alloc policy; at the moment we go conservative
                        o->items = m_renew(byte, o->items, (o->len + o->free) * item_sz, (o->len + len_adj) * item_sz);
                        o->free = 0;
                    }
                    mp_seq_replace_slice_grow_inplace(dest_items, o->len,
                        slice.start, slice.stop, src_items, src_len, len_adj, item_sz);
                } else {
                    mp_seq_replace_slice_no_grow(dest_items, o->len,
                        slice.start, slice.stop, src_items, src_len, item_sz);
                    // Clear "freed" elements at the end of list
                    // TODO: This is actually only needed for typecode=='O'
                    mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz);
                    // TODO: alloc policy after shrinking
                }
                o->len += len_adj;
                return mp_const_none;
                #else
                return MP_OBJ_NULL; // op not supported
                #endif
            }

            mp_obj_array_t *res;
            size_t sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
            assert(sz > 0);
            if (0) {
                // dummy
            #if MICROPY_PY_BUILTINS_MEMORYVIEW
            } else if (o->base.type == &mp_type_memoryview) {
                res = m_new_obj(mp_obj_array_t);
                *res = *o;
                res->free += slice.start;
                res->len = slice.stop - slice.start;
            #endif
            } else {
                res = array_new(o->typecode, slice.stop - slice.start);
                memcpy(res->items, (uint8_t*)o->items + slice.start * sz, (slice.stop - slice.start) * sz);
            }
            return res;
#endif
        } else {
            mp_uint_t index = mp_get_index(o->base.type, o->len, index_in, false);
            #if MICROPY_PY_BUILTINS_MEMORYVIEW
            if (o->base.type == &mp_type_memoryview) {
                index += o->free;
                if (value != MP_OBJ_SENTINEL && (o->typecode & 0x80) == 0) {
                    // store to read-only memoryview
                    return MP_OBJ_NULL;
                }
            }
            #endif
            if (value == MP_OBJ_SENTINEL) {
                // load
                return mp_binary_get_val_array(o->typecode & TYPECODE_MASK, o->items, index);
            } else {
                // store
                mp_binary_set_val_array(o->typecode & TYPECODE_MASK, o->items, index, value);
                return mp_const_none;
            }
        }
    }
}
Пример #8
0
STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_NULL) {
        // delete
#if MICROPY_PY_BUILTINS_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
            mp_bound_slice_t slice;
            if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
                mp_raise_NotImplementedError(NULL);
            }

            mp_int_t len_adj = slice.start - slice.stop;
            //printf("Len adj: %d\n", len_adj);
            assert(len_adj <= 0);
            mp_seq_replace_slice_no_grow(self->items, self->len, slice.start, slice.stop, self->items/*NULL*/, 0, sizeof(*self->items));
            // 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;
            return mp_const_none;
        }
#endif
        mp_obj_t args[2] = {self_in, index};
        list_pop(2, args);
        return mp_const_none;
    } else if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
#if MICROPY_PY_BUILTINS_SLICE
        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)) {
                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);
            return MP_OBJ_FROM_PTR(res);
        }
#endif
        size_t index_val = mp_get_index(self->base.type, self->len, index, false);
        return self->items[index_val];
    } else {
#if MICROPY_PY_BUILTINS_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
            size_t value_len; mp_obj_t *value_items;
            mp_obj_get_array(value, &value_len, &value_items);
            mp_bound_slice_t slice_out;
            if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) {
                mp_raise_NotImplementedError(NULL);
            }
            mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start);
            //printf("Len adj: %d\n", len_adj);
            if (len_adj > 0) {
                if (self->len + len_adj > self->alloc) {
                    // TODO: Might optimize memory copies here by checking if block can
                    // be grown inplace or not
                    self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj);
                    self->alloc = self->len + len_adj;
                }
                mp_seq_replace_slice_grow_inplace(self->items, self->len,
                    slice_out.start, slice_out.stop, value_items, value_len, len_adj, sizeof(*self->items));
            } else {
                mp_seq_replace_slice_no_grow(self->items, self->len,
                    slice_out.start, slice_out.stop, value_items, value_len, sizeof(*self->items));
                // Clear "freed" elements at the end of list
                mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
                // TODO: apply allocation policy re: alloc_size
            }
            self->len += len_adj;
            return mp_const_none;
        }
#endif
        mp_obj_list_store(self_in, index, value);
        return mp_const_none;
    }
}