コード例 #1
0
ファイル: sequence.c プロジェクト: GordonMcGregor/micropython
bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_uint_t *begin, machine_uint_t *end) {
    machine_int_t start, stop, step;
    mp_obj_slice_get(slice, &start, &stop, &step);
    if (step != 1) {
        return false;
    }

    // Unlike subscription, out-of-bounds slice indexes are never error
    if (start < 0) {
        start = len + start;
        if (start < 0) {
            start = 0;
        }
    } else if (start > len) {
        start = len;
    }
    if (stop <= 0) {
        stop = len + stop;
        // CPython returns empty sequence in such case
        if (stop < 0) {
            stop = start;
        }
    } else if (stop > len) {
        stop = len;
    }
    *begin = start;
    *end = stop;
    return true;
}
コード例 #2
0
ファイル: sequence.c プロジェクト: un33k/micropython
bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes) {
    mp_obj_t ostart, ostop, ostep;
    machine_int_t start, stop;
    mp_obj_slice_get(slice, &ostart, &ostop, &ostep);

    if (ostart == mp_const_none) {
        start = 0;
    } else {
        start = MP_OBJ_SMALL_INT_VALUE(ostart);
    }
    if (ostop == mp_const_none) {
        stop = len;
    } else {
        stop = MP_OBJ_SMALL_INT_VALUE(ostop);
    }

    // Unlike subscription, out-of-bounds slice indexes are never error
    if (start < 0) {
        start = len + start;
        if (start < 0) {
            start = 0;
        }
    } else if (start > len) {
        start = len;
    }
    if (stop < 0) {
        stop = len + stop;
    } else if (stop > len) {
        stop = len;
    }

    // CPython returns empty sequence in such case, or point for assignment is at start
    if (start > stop) {
        stop = start;
    }

    indexes->start = start;
    indexes->stop = stop;

    if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
        indexes->step = MP_OBJ_SMALL_INT_VALUE(ostep);
        return false;
    }
    indexes->step = 1;
    return true;
}
コード例 #3
0
STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    mp_obj_type_t *type = mp_obj_get_type(self_in);
    assert(type == &mp_type_str);
    GET_STR_DATA_LEN(self_in, self_data, self_len);
    if (value == MP_OBJ_SENTINEL) {
        // load
#if MICROPY_PY_BUILTINS_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            mp_obj_t ostart, ostop, ostep;
            mp_obj_slice_get(index, &ostart, &ostop, &ostep);
            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"));
            }

            const byte *pstart, *pstop;
            if (ostart != mp_const_none) {
                pstart = str_index_to_ptr(type, self_data, self_len, ostart, true);
            } else {
                pstart = self_data;
            }
            if (ostop != mp_const_none) {
                // pstop will point just after the stop character. This depends on
                // the \0 at the end of the string.
                pstop = str_index_to_ptr(type, self_data, self_len, ostop, true);
            } else {
                pstop = self_data + self_len;
            }
            if (pstop < pstart) {
                return MP_OBJ_NEW_QSTR(MP_QSTR_);
            }
            return mp_obj_new_str_of_type(type, (const byte *)pstart, pstop - pstart);
        }
#endif
        const byte *s = str_index_to_ptr(type, self_data, self_len, index, false);
        int len = 1;
        if (UTF8_IS_NONASCII(*s)) {
            // Count the number of 1 bits (after the first)
            for (char mask = 0x40; *s & mask; mask >>= 1) {
                ++len;
            }
        }
        return mp_obj_new_str((const char*)s, len, true); // This will create a one-character string
    } else {
        return MP_OBJ_NULL; // op not supported
コード例 #4
0
ファイル: sequence.c プロジェクト: AriZuu/micropython
bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes) {
    mp_obj_t ostart, ostop, ostep;
    mp_int_t start, stop;
    mp_obj_slice_get(slice, &ostart, &ostop, &ostep);

    if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) {
        indexes->step = mp_obj_get_int(ostep);
        if (indexes->step == 0) {
            mp_raise_ValueError("slice step cannot be zero");
        }
    } else {
        indexes->step = 1;
    }

    if (ostart == mp_const_none) {
        if (indexes->step > 0) {
            start = 0;
        } else {
            start = len - 1;
        }
    } else {
        start = mp_obj_get_int(ostart);
    }
    if (ostop == mp_const_none) {
        if (indexes->step > 0) {
            stop = len;
        } else {
            stop = 0;
        }
    } else {
        stop = mp_obj_get_int(ostop);
        if (stop >= 0 && indexes->step < 0) {
            stop += 1;
        }
    }

    // Unlike subscription, out-of-bounds slice indexes are never error
    if (start < 0) {
        start = len + start;
        if (start < 0) {
            if (indexes->step < 0) {
                start = -1;
            } else {
                start = 0;
            }
        }
    } else if (indexes->step > 0 && (mp_uint_t)start > len) {
        start = len;
    } else if (indexes->step < 0 && (mp_uint_t)start >= len) {
        start = len - 1;
    }
    if (stop < 0) {
        stop = len + stop;
        if (stop < 0) {
            stop = -1;
        }
        if (indexes->step < 0) {
            stop += 1;
        }
    } else if ((mp_uint_t)stop > len) {
        stop = len;
    }

    // CPython returns empty sequence in such case, or point for assignment is at start
    if (indexes->step > 0 && start > stop) {
        stop = start;
    } else if (indexes->step < 0 && start < stop) {
        stop = start + 1;
    }

    indexes->start = start;
    indexes->stop = stop;

    return indexes->step == 1;
}
コード例 #5
0
ファイル: objstr.c プロジェクト: kucukkose/micropython
mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
    GET_STR_DATA_LEN(lhs_in, lhs_data, lhs_len);
    switch (op) {
        case RT_BINARY_OP_SUBSCR:
            // TODO: need predicate to check for int-like type (bools are such for example)
            // ["no", "yes"][1 == 2] is common idiom
            if (MP_OBJ_IS_SMALL_INT(rhs_in)) {
                uint index = mp_get_index(mp_obj_get_type(lhs_in), lhs_len, rhs_in);
                return mp_obj_new_str(lhs_data + index, 1, true);
#if MICROPY_ENABLE_SLICE
            } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) {
                machine_int_t start, stop, step;
                mp_obj_slice_get(rhs_in, &start, &stop, &step);
                assert(step == 1);
                if (start < 0) {
                    start = lhs_len + start;
                    if (start < 0) {
                        start = 0;
                    }
                } else if (start > lhs_len) {
                    start = lhs_len;
                }
                if (stop <= 0) {
                    stop = lhs_len + stop;
                    // CPython returns empty string in such case
                    if (stop < 0) {
                        stop = start;
                    }
                } else if (stop > lhs_len) {
                    stop = lhs_len;
                }
                return mp_obj_new_str(lhs_data + start, stop - start, false);
#endif
            } else {
                // Message doesn't match CPython, but we don't have so much bytes as they
                // to spend them on verbose wording
                nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "index must be int"));
            }

        case RT_BINARY_OP_ADD:
        case RT_BINARY_OP_INPLACE_ADD:
            if (MP_OBJ_IS_STR(rhs_in)) {
                // add 2 strings

                GET_STR_DATA_LEN(rhs_in, rhs_data, rhs_len);
                int alloc_len = lhs_len + rhs_len;

                /* code for making qstr
                byte *q_ptr;
                byte *val = qstr_build_start(alloc_len, &q_ptr);
                memcpy(val, lhs_data, lhs_len);
                memcpy(val + lhs_len, rhs_data, rhs_len);
                return MP_OBJ_NEW_QSTR(qstr_build_end(q_ptr));
                */

                // code for non-qstr
                byte *data;
                mp_obj_t s = mp_obj_str_builder_start(alloc_len, &data);
                memcpy(data, lhs_data, lhs_len);
                memcpy(data + lhs_len, rhs_data, rhs_len);
                return mp_obj_str_builder_end(s);
            }
            break;

        case RT_COMPARE_OP_IN:
        case RT_COMPARE_OP_NOT_IN:
            /* NOTE `a in b` is `b.__contains__(a)` */
            if (MP_OBJ_IS_STR(rhs_in)) {
                GET_STR_DATA_LEN(rhs_in, rhs_data, rhs_len);
                return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (find_subbytes(lhs_data, lhs_len, rhs_data, rhs_len) == NULL));
            }
            break;

        case RT_BINARY_OP_MULTIPLY:
        {
            if (!MP_OBJ_IS_SMALL_INT(rhs_in)) {
                return NULL;
            }
            int n = MP_OBJ_SMALL_INT_VALUE(rhs_in);
            byte *data;
            mp_obj_t s = mp_obj_str_builder_start(lhs_len * n, &data);
            mp_seq_multiply(lhs_data, sizeof(*lhs_data), lhs_len, n, data);
            return mp_obj_str_builder_end(s);
        }
    }

    return MP_OBJ_NULL; // op not supported
}