mp_obj_t mp_obj_tuple_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_tuple_t *o = lhs; switch (op) { case MP_BINARY_OP_ADD: { if (!mp_obj_is_subclass_fast(mp_obj_get_type(rhs), (mp_obj_t)&mp_type_tuple)) { return MP_OBJ_NULL; // op not supported } mp_obj_tuple_t *p = rhs; mp_obj_tuple_t *s = mp_obj_new_tuple(o->len + p->len, NULL); mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case MP_BINARY_OP_MULTIPLY: { mp_int_t n; if (!mp_obj_get_int_maybe(rhs, &n)) { return MP_OBJ_NULL; // op not supported } if (n <= 0) { return mp_const_empty_tuple; } mp_obj_tuple_t *s = mp_obj_new_tuple(o->len * n, NULL); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return s; } case MP_BINARY_OP_EQUAL: case MP_BINARY_OP_LESS: case MP_BINARY_OP_LESS_EQUAL: case MP_BINARY_OP_MORE: case MP_BINARY_OP_MORE_EQUAL: return MP_BOOL(tuple_cmp_helper(op, lhs, rhs)); default: return MP_OBJ_NULL; // op not supported } }
mp_obj_t mp_obj_tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_tuple_t *o = lhs; switch (op) { case MP_BINARY_OP_ADD: { if (!mp_obj_is_subclass_fast(mp_obj_get_type(rhs), (mp_obj_t)&mp_type_tuple)) { return MP_OBJ_NULL; // op not supported } mp_obj_tuple_t *p = rhs; mp_obj_tuple_t *s = mp_obj_new_tuple(o->len + p->len, NULL); mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case MP_BINARY_OP_MULTIPLY: { if (!MP_OBJ_IS_SMALL_INT(rhs)) { return MP_OBJ_NULL; // op not supported } int n = MP_OBJ_SMALL_INT_VALUE(rhs); mp_obj_tuple_t *s = mp_obj_new_tuple(o->len * n, NULL); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return s; } case MP_BINARY_OP_EQUAL: case MP_BINARY_OP_LESS: case MP_BINARY_OP_LESS_EQUAL: case MP_BINARY_OP_MORE: case MP_BINARY_OP_MORE_EQUAL: return MP_BOOL(tuple_cmp_helper(op, lhs, rhs)); default: return MP_OBJ_NULL; // op not supported } }
STATIC mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_list_t *o = lhs; switch (op) { case MP_BINARY_OP_SUBSCR: { #if MICROPY_ENABLE_SLICE if (MP_OBJ_IS_TYPE(rhs, &mp_type_slice)) { machine_uint_t start, stop; if (!m_seq_get_fast_slice_indexes(o->len, rhs, &start, &stop)) { assert(0); } mp_obj_list_t *res = list_new(stop - start); m_seq_copy(res->items, o->items + start, res->len, mp_obj_t); return res; } #endif uint index = mp_get_index(o->base.type, o->len, rhs, false); return o->items[index]; } case MP_BINARY_OP_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { return NULL; } mp_obj_list_t *p = rhs; mp_obj_list_t *s = list_new(o->len + p->len); m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case MP_BINARY_OP_INPLACE_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { return NULL; } list_extend(lhs, rhs); return o; } case MP_BINARY_OP_MULTIPLY: { machine_int_t n; if (!mp_obj_get_int_maybe(rhs, &n)) { return NULL; } mp_obj_list_t *s = list_new(o->len * n); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return s; } case MP_BINARY_OP_EQUAL: case MP_BINARY_OP_LESS: case MP_BINARY_OP_LESS_EQUAL: case MP_BINARY_OP_MORE: case MP_BINARY_OP_MORE_EQUAL: return MP_BOOL(list_cmp_helper(op, lhs, rhs)); case MP_BINARY_OP_NOT_EQUAL: return MP_BOOL(!list_cmp_helper(MP_BINARY_OP_EQUAL, lhs, rhs)); default: // op not supported return NULL; } }
STATIC mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_tuple_t *o = lhs; switch (op) { case RT_BINARY_OP_SUBSCR: { #if MICROPY_ENABLE_SLICE if (MP_OBJ_IS_TYPE(rhs, &slice_type)) { machine_uint_t start, stop; if (!m_seq_get_fast_slice_indexes(o->len, rhs, &start, &stop)) { assert(0); } mp_obj_tuple_t *res = mp_obj_new_tuple(stop - start, NULL); m_seq_copy(res->items, o->items + start, res->len, mp_obj_t); return res; } #endif uint index = mp_get_index(o->base.type, o->len, rhs); return o->items[index]; } case RT_BINARY_OP_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &tuple_type)) { return NULL; } mp_obj_tuple_t *p = rhs; mp_obj_tuple_t *s = mp_obj_new_tuple(o->len + p->len, NULL); m_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case RT_BINARY_OP_MULTIPLY: { if (!MP_OBJ_IS_SMALL_INT(rhs)) { return NULL; } int n = MP_OBJ_SMALL_INT_VALUE(rhs); mp_obj_tuple_t *s = mp_obj_new_tuple(o->len * n, NULL); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return s; } case RT_BINARY_OP_EQUAL: case RT_BINARY_OP_LESS: case RT_BINARY_OP_LESS_EQUAL: case RT_BINARY_OP_MORE: case RT_BINARY_OP_MORE_EQUAL: return MP_BOOL(tuple_cmp_helper(op, lhs, rhs)); case RT_BINARY_OP_NOT_EQUAL: return MP_BOOL(!tuple_cmp_helper(RT_BINARY_OP_EQUAL, lhs, rhs)); default: // op not supported return NULL; } }
static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_list_t *o = lhs; switch (op) { case RT_BINARY_OP_SUBSCR: { // list load uint index = mp_get_index(o->base.type, o->len, rhs); return o->items[index]; } case RT_BINARY_OP_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &list_type)) { return NULL; } mp_obj_list_t *p = rhs; mp_obj_list_t *s = list_new(o->len + p->len); memcpy(s->items, o->items, sizeof(mp_obj_t) * o->len); memcpy(s->items + o->len, p->items, sizeof(mp_obj_t) * p->len); return s; } case RT_BINARY_OP_INPLACE_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &list_type)) { return NULL; } list_extend(lhs, rhs); return o; } case RT_BINARY_OP_MULTIPLY: { if (!MP_OBJ_IS_SMALL_INT(rhs)) { return NULL; } int n = MP_OBJ_SMALL_INT_VALUE(rhs); mp_obj_list_t *s = list_new(o->len * n); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return s; } case RT_COMPARE_OP_EQUAL: case RT_COMPARE_OP_LESS: case RT_COMPARE_OP_LESS_EQUAL: case RT_COMPARE_OP_MORE: case RT_COMPARE_OP_MORE_EQUAL: return MP_BOOL(list_cmp_helper(op, lhs, rhs)); case RT_COMPARE_OP_NOT_EQUAL: return MP_BOOL(!list_cmp_helper(RT_COMPARE_OP_EQUAL, lhs, rhs)); default: // op not supported return NULL; } }
STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_list_t *o = MP_OBJ_TO_PTR(lhs); switch (op) { case MP_BINARY_OP_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { return MP_OBJ_NULL; // op not supported } mp_obj_list_t *p = MP_OBJ_TO_PTR(rhs); mp_obj_list_t *s = list_new(o->len + p->len); mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return MP_OBJ_FROM_PTR(s); } case MP_BINARY_OP_INPLACE_ADD: { list_extend(lhs, rhs); return lhs; } case MP_BINARY_OP_MULTIPLY: { mp_int_t n; if (!mp_obj_get_int_maybe(rhs, &n)) { return MP_OBJ_NULL; // op not supported } if (n < 0) { n = 0; } mp_obj_list_t *s = list_new(o->len * n); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return MP_OBJ_FROM_PTR(s); } case MP_BINARY_OP_EQUAL: case MP_BINARY_OP_LESS: case MP_BINARY_OP_LESS_EQUAL: case MP_BINARY_OP_MORE: case MP_BINARY_OP_MORE_EQUAL: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { if (op == MP_BINARY_OP_EQUAL) { return mp_const_false; } return MP_OBJ_NULL; // op not supported } mp_obj_list_t *another = MP_OBJ_TO_PTR(rhs); bool res = mp_seq_cmp_objs(op, o->items, o->len, another->items, another->len); return mp_obj_new_bool(res); } default: return MP_OBJ_NULL; // op not supported } }
STATIC mp_obj_t list_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_list_t *o = lhs; switch (op) { case MP_BINARY_OP_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { return MP_OBJ_NULL; // op not supported } mp_obj_list_t *p = rhs; mp_obj_list_t *s = list_new(o->len + p->len); mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); return s; } case MP_BINARY_OP_INPLACE_ADD: { if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) { return MP_OBJ_NULL; // op not supported } list_extend(lhs, rhs); return o; } case MP_BINARY_OP_MULTIPLY: { mp_int_t n; if (!mp_obj_get_int_maybe(rhs, &n)) { return MP_OBJ_NULL; // op not supported } if (n < 0) { n = 0; } mp_obj_list_t *s = list_new(o->len * n); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); return s; } case MP_BINARY_OP_EQUAL: case MP_BINARY_OP_LESS: case MP_BINARY_OP_LESS_EQUAL: case MP_BINARY_OP_MORE: case MP_BINARY_OP_MORE_EQUAL: return MP_BOOL(list_cmp_helper(op, lhs, rhs)); default: return MP_OBJ_NULL; // op not supported } }
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 }