objslice: Support arbitrary objects start, stop, and step.
Older int-only encoding is not expressive enough to support arbitrary slice assignment operations.
This commit is contained in:
@@ -62,13 +62,20 @@ const mp_obj_ellipsis_t mp_const_ellipsis_obj = {{&mp_type_ellipsis}};
|
||||
// CPython supports 3rd arg (step), plus args can be arbitrary Python objects.
|
||||
typedef struct _mp_obj_slice_t {
|
||||
mp_obj_base_t base;
|
||||
machine_int_t start;
|
||||
machine_int_t stop;
|
||||
mp_obj_t start;
|
||||
mp_obj_t stop;
|
||||
mp_obj_t step;
|
||||
} mp_obj_slice_t;
|
||||
|
||||
void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
|
||||
mp_obj_slice_t *o = o_in;
|
||||
print(env, "slice(" INT_FMT ", " INT_FMT ")", o->start, o->stop);
|
||||
print(env, "slice(");
|
||||
mp_obj_print_helper(print, env, o->start, PRINT_REPR);
|
||||
print(env, ", ");
|
||||
mp_obj_print_helper(print, env, o->stop, PRINT_REPR);
|
||||
print(env, ", ");
|
||||
mp_obj_print_helper(print, env, o->step, PRINT_REPR);
|
||||
print(env, ")");
|
||||
}
|
||||
|
||||
const mp_obj_type_t mp_type_slice = {
|
||||
@@ -77,39 +84,21 @@ const mp_obj_type_t mp_type_slice = {
|
||||
.print = slice_print,
|
||||
};
|
||||
|
||||
// TODO: Make sure to handle "empty" values, which are signified by None in CPython
|
||||
mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
|
||||
assert(ostep == NULL);
|
||||
machine_int_t start = 0, stop = 0;
|
||||
if (ostart != mp_const_none) {
|
||||
start = mp_obj_get_int(ostart);
|
||||
}
|
||||
if (ostop != mp_const_none) {
|
||||
stop = mp_obj_get_int(ostop);
|
||||
if (stop == 0) {
|
||||
// [x:0] is a special case - in our slice object, stop = 0 means
|
||||
// "end of sequence". Fortunately, [x:0] is an empty seqence for
|
||||
// any x (including negative). [x:x] is also always empty sequence.
|
||||
// but x also can be 0. But note that b""[x:x] is b"" for any x (i.e.
|
||||
// no IndexError, at least in Python 3.3.3). So, we just use -1's to
|
||||
// signify that. -1 is catchy "special" number in case someone will
|
||||
// try to print [x:0] slice ever.
|
||||
start = stop = -1;
|
||||
}
|
||||
}
|
||||
mp_obj_slice_t *o = m_new(mp_obj_slice_t, 1);
|
||||
mp_obj_slice_t *o = m_new_obj(mp_obj_slice_t);
|
||||
o->base.type = &mp_type_slice;
|
||||
o->start = start;
|
||||
o->stop = stop;
|
||||
return (mp_obj_t)o;
|
||||
o->start = ostart;
|
||||
o->stop = ostop;
|
||||
o->step = ostep;
|
||||
return o;
|
||||
}
|
||||
|
||||
void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *stop, machine_int_t *step) {
|
||||
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 = self_in;
|
||||
*start = self->start;
|
||||
*stop = self->stop;
|
||||
*step = 1;
|
||||
*step = self->step;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user