summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/obj.h2
-rw-r--r--py/objlist.c32
-rw-r--r--py/objtuple.c21
-rw-r--r--py/objtype.c2
-rw-r--r--py/qstrdefs.h3
-rw-r--r--py/runtime.c2
-rw-r--r--py/sequence.c36
7 files changed, 68 insertions, 30 deletions
diff --git a/py/obj.h b/py/obj.h
index 43c0ed5e78..48d332e200 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -402,3 +402,5 @@ bool m_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, machine_ui
#define m_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, len1 * sizeof(item_t)); memcpy(dest + len1, src2, len2 * sizeof(item_t)); }
bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, uint len2);
bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *items2, uint len2);
+mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args);
+mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
diff --git a/py/objlist.c b/py/objlist.c
index 9f20acbd41..35bab2a398 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -233,8 +233,8 @@ mp_obj_t mp_obj_list_sort(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
}
mp_obj_list_t *self = args[0];
if (self->len > 1) {
- mp_map_elem_t *keyfun = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(QSTR_FROM_STR_STATIC("key")), MP_MAP_LOOKUP);
- mp_map_elem_t *reverse = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(QSTR_FROM_STR_STATIC("reverse")), MP_MAP_LOOKUP);
+ mp_map_elem_t *keyfun = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(MP_QSTR_key), MP_MAP_LOOKUP);
+ mp_map_elem_t *reverse = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(MP_QSTR_reverse), MP_MAP_LOOKUP);
mp_quicksort(self->items, self->items + self->len - 1,
keyfun ? keyfun->value : NULL,
reverse && reverse->value ? rt_is_true(reverse->value) : false);
@@ -260,38 +260,14 @@ static mp_obj_t list_copy(mp_obj_t self_in) {
static mp_obj_t list_count(mp_obj_t self_in, mp_obj_t value) {
assert(MP_OBJ_IS_TYPE(self_in, &list_type));
mp_obj_list_t *self = self_in;
- int count = 0;
- for (int i = 0; i < self->len; i++) {
- if (mp_obj_equal(self->items[i], value)) {
- count++;
- }
- }
-
- return mp_obj_new_int(count);
+ return mp_seq_count_obj(self->items, self->len, value);
}
static mp_obj_t list_index(uint n_args, const mp_obj_t *args) {
assert(2 <= n_args && n_args <= 4);
assert(MP_OBJ_IS_TYPE(args[0], &list_type));
mp_obj_list_t *self = args[0];
- mp_obj_t *value = args[1];
- uint start = 0;
- uint stop = self->len;
-
- if (n_args >= 3) {
- start = mp_get_index(self->base.type, self->len, args[2]);
- if (n_args >= 4) {
- stop = mp_get_index(self->base.type, self->len, args[3]);
- }
- }
-
- for (uint i = start; i < stop; i++) {
- if (mp_obj_equal(self->items[i], value)) {
- return mp_obj_new_int(i);
- }
- }
-
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "object not in list"));
+ return mp_seq_index_obj(self->items, self->len, n_args, args);
}
static mp_obj_t list_insert(mp_obj_t self_in, mp_obj_t idx, mp_obj_t obj) {
diff --git a/py/objtuple.c b/py/objtuple.c
index 18eb6df4de..7221db7746 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -153,6 +153,26 @@ static mp_obj_t tuple_getiter(mp_obj_t o_in) {
return mp_obj_new_tuple_iterator(o_in, 0);
}
+static mp_obj_t tuple_count(mp_obj_t self_in, mp_obj_t value) {
+ assert(MP_OBJ_IS_TYPE(self_in, &tuple_type));
+ mp_obj_tuple_t *self = self_in;
+ return mp_seq_count_obj(self->items, self->len, value);
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(tuple_count_obj, tuple_count);
+
+static mp_obj_t tuple_index(uint n_args, const mp_obj_t *args) {
+ assert(MP_OBJ_IS_TYPE(args[0], &tuple_type));
+ mp_obj_tuple_t *self = args[0];
+ return mp_seq_index_obj(self->items, self->len, n_args, args);
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(tuple_index_obj, 2, 4, tuple_index);
+
+static const mp_method_t tuple_type_methods[] = {
+ { "count", &tuple_count_obj },
+ { "index", &tuple_index_obj },
+ { NULL, NULL }, // end-of-list sentinel
+};
+
const mp_obj_type_t tuple_type = {
{ &mp_const_type },
"tuple",
@@ -161,6 +181,7 @@ const mp_obj_type_t tuple_type = {
.unary_op = tuple_unary_op,
.binary_op = tuple_binary_op,
.getiter = tuple_getiter,
+ .methods = tuple_type_methods,
};
// the zero-length tuple
diff --git a/py/objtype.c b/py/objtype.c
index 6ff18b47bf..55f4227364 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -239,7 +239,7 @@ static bool class_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
bool class_store_item(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
mp_obj_class_t *self = self_in;
- mp_obj_t member = mp_obj_class_lookup(self->base.type, QSTR_FROM_STR_STATIC("__setitem__"));
+ mp_obj_t member = mp_obj_class_lookup(self->base.type, MP_QSTR___setitem__);
if (member != MP_OBJ_NULL) {
mp_obj_t args[3] = {self_in, index, value};
rt_call_function_n_kw(member, 3, 0, args);
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index afd238c1ae..680c4bcf73 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -17,6 +17,7 @@ Q(__repl_print__)
Q(__bool__)
Q(__len__)
Q(__getitem__)
+Q(__setitem__)
Q(__add__)
Q(__sub__)
@@ -97,6 +98,8 @@ Q(sort)
Q(join)
Q(strip)
Q(format)
+Q(key)
+Q(reverse)
Q(<module>)
Q(<lambda>)
diff --git a/py/runtime.c b/py/runtime.c
index ab83e380cc..aaac884d65 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -969,7 +969,7 @@ mp_obj_t rt_getiter(mp_obj_t o_in) {
} else {
// check for __getitem__ method
mp_obj_t dest[2];
- rt_load_method_maybe(o_in, qstr_from_str("__getitem__"), dest);
+ rt_load_method_maybe(o_in, MP_QSTR___getitem__, dest);
if (dest[0] != MP_OBJ_NULL) {
// __getitem__ exists, create an iterator
return mp_obj_new_getitem_iter(dest);
diff --git a/py/sequence.c b/py/sequence.c
index b344ed00b4..f5310737a7 100644
--- a/py/sequence.c
+++ b/py/sequence.c
@@ -140,3 +140,39 @@ bool mp_seq_cmp_objs(int op, const mp_obj_t *items1, uint len1, const mp_obj_t *
return true;
}
+
+// Special-case of index() which searches for mp_obj_t
+mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp_obj_t *args) {
+ mp_obj_type_t *type = mp_obj_get_type(args[0]);
+ mp_obj_t *value = args[1];
+ uint start = 0;
+ uint stop = len;
+
+ if (n_args >= 3) {
+ start = mp_get_index(type, len, args[2]);
+ if (n_args >= 4) {
+ stop = mp_get_index(type, len, args[3]);
+ }
+ }
+
+ for (machine_uint_t i = start; i < stop; i++) {
+ if (mp_obj_equal(items[i], value)) {
+ // Common sense says this cannot overflow small int
+ return MP_OBJ_NEW_SMALL_INT(i);
+ }
+ }
+
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "object not in sequence"));
+}
+
+mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value) {
+ machine_uint_t count = 0;
+ for (uint i = 0; i < len; i++) {
+ if (mp_obj_equal(items[i], value)) {
+ count++;
+ }
+ }
+
+ // Common sense says this cannot overflow small int
+ return MP_OBJ_NEW_SMALL_INT(count);
+}