STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { mp_check_self(MP_OBJ_IS_DICT_TYPE(args[0])); mp_obj_dict_t *self = MP_OBJ_TO_PTR(args[0]); mp_arg_check_num(n_args, kwargs->used, 1, 2, true); if (n_args == 2) { // given a positional argument if (MP_OBJ_IS_DICT_TYPE(args[1])) { // update from other dictionary (make sure other is not self) if (args[1] != args[0]) { mp_uint_t cur = 0; mp_map_elem_t *elem = NULL; while ((elem = dict_iter_next((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[1]), &cur)) != NULL) { mp_map_lookup(&self->map, elem->key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = elem->value; } } } else { // update from a generic iterable of pairs mp_obj_t iter = mp_getiter(args[1]); mp_obj_t next = MP_OBJ_NULL; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_obj_t inneriter = mp_getiter(next); mp_obj_t key = mp_iternext(inneriter); mp_obj_t value = mp_iternext(inneriter); mp_obj_t stop = mp_iternext(inneriter); if (key == MP_OBJ_STOP_ITERATION || value == MP_OBJ_STOP_ITERATION || stop != MP_OBJ_STOP_ITERATION) { mp_raise_msg(&mp_type_ValueError, "dictionary update sequence has the wrong length"); } else { mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } } } } // update the dict with any keyword args for (mp_uint_t i = 0; i < kwargs->alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value; } } return mp_const_none; }
STATIC mp_obj_t filter_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 2, false); mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t); o->base.type = type_in; o->fun = args[0]; o->iter = mp_getiter(args[1]); return o; }
STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { mp_obj_t iter = mp_getiter(iterable); mp_obj_t item; while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_obj_list_append(list, item); } return list; }
STATIC mp_obj_t mp_builtin_any(mp_obj_t o_in) { mp_obj_t iterable = mp_getiter(o_in); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (mp_obj_is_true(item)) { return mp_const_true; } } return mp_const_false; }
STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other_in) { check_set_or_frozenset(self_in); // can be frozenset due to call from set_symmetric_difference mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t iter = mp_getiter(other_in, NULL); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND); } return mp_const_none; }
STATIC mp_obj_t mp_builtin_all(mp_obj_t o_in) { mp_obj_t iterable = mp_getiter(o_in); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_NULL) { if (!mp_obj_is_true(item)) { return mp_const_false; } } return mp_const_true; }
STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other_in) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); mp_obj_set_t *self = self_in; mp_obj_t iter = mp_getiter(other_in); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); } return mp_const_none; }
STATIC mp_obj_t filter_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { if (n_args != 2 || n_kw != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "filter expected 2 arguments")); } assert(n_args == 2); mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t); o->base.type = &mp_type_filter; o->fun = args[0]; o->iter = mp_getiter(args[1]); return o; }
STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); o->base.type = type; o->n_iters = n_args; for (mp_uint_t i = 0; i < n_args; i++) { o->iters[i] = mp_getiter(args[i], NULL); } return MP_OBJ_FROM_PTR(o); }
STATIC mp_obj_t zip_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); o->base.type = &mp_type_zip; o->n_iters = n_args; for (int i = 0; i < n_args; i++) { o->iters[i] = mp_getiter(args[i]); } return o; }
STATIC mp_obj_t zip_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); o->base.type = &mp_type_zip; o->n_iters = n_args; for (int i = 0; i < n_args; i++) { o->iters[i] = mp_getiter(args[i]); } return o; }
STATIC mp_obj_t set_isdisjoint(mp_obj_t self_in, mp_obj_t other) { check_set_or_frozenset(self_in); mp_obj_set_t *self = self_in; mp_obj_t iter = mp_getiter(other); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) { return mp_const_false; } } return mp_const_true; }
STATIC mp_obj_t set_isdisjoint(mp_obj_t self_in, mp_obj_t other) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_set)); mp_obj_set_t *self = self_in; mp_obj_t iter = mp_getiter(other); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) { return mp_const_false; } } return mp_const_true; }
STATIC mp_obj_t mp_builtin_sum(uint n_args, const mp_obj_t *args) { assert(1 <= n_args && n_args <= 2); mp_obj_t value; switch (n_args) { case 1: value = mp_obj_new_int(0); break; default: value = args[1]; break; } mp_obj_t iterable = mp_getiter(args[0]); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { value = mp_binary_op(MP_BINARY_OP_ADD, value, item); } return value; }
STATIC mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_dict)); mp_obj_dict_t *self = self_in; /* TODO: check for the "keys" method */ mp_obj_t iter = mp_getiter(iterable); mp_obj_t next = NULL; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_obj_t inneriter = mp_getiter(next); mp_obj_t key = mp_iternext(inneriter); mp_obj_t value = mp_iternext(inneriter); mp_obj_t stop = mp_iternext(inneriter); if (key == MP_OBJ_STOP_ITERATION || value == MP_OBJ_STOP_ITERATION || stop != MP_OBJ_STOP_ITERATION) { nlr_raise(mp_obj_new_exception_msg( &mp_type_ValueError, "dictionary update sequence has the wrong length")); } else { mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } } return mp_const_none; }
static void microbit_display_update(void) { async_tick += FIBER_TICK_PERIOD_MS; if (async_tick < async_delay) { return; } async_tick = 0; switch (async_mode) { case ASYNC_MODE_ANIMATION: { if (MP_STATE_PORT(async_data)[0] == NULL || MP_STATE_PORT(async_data)[1] == NULL) { async_stop(); break; } microbit_display_obj_t *display = (microbit_display_obj_t*)MP_STATE_PORT(async_data)[0]; /* WARNING: We are executing in an interrupt handler. * If an exception is raised here, then a reset is the only way to recover. */ mp_obj_t obj = mp_iternext(async_iterator); if (obj == MP_OBJ_STOP_ITERATION) { if (async_repeat_iterable) { async_iterator = mp_getiter(async_repeat_iterable); } else { microbit_display_show(display, BLANK_IMAGE); async_stop(); } } else if (mp_obj_get_type(obj) == µbit_image_type) { microbit_display_show(display, (microbit_image_obj_t *)obj); } else if (MP_OBJ_IS_STR(obj)) { mp_uint_t len; const char *str = mp_obj_str_get_data(obj, &len); if (len == 1) { microbit_display_show(display, microbit_image_for_char(str[0])); } else { async_error = true; async_stop(); } } else { async_error = true; async_stop(); } break; } case ASYNC_MODE_CLEAR: microbit_display_show(µbit_display_obj, BLANK_IMAGE); async_stop(); break; } }
STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { // bytearrays can be raw-initialised from anything with the buffer protocol // other arrays can only be raw-initialised from bytes and bytearray objects mp_buffer_info_t bufinfo; if (((MICROPY_PY_BUILTINS_BYTEARRAY && typecode == BYTEARRAY_TYPECODE) || (MICROPY_PY_ARRAY && (MP_OBJ_IS_TYPE(initializer, &mp_type_bytes) || (MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(initializer, &mp_type_bytearray))))) && mp_get_buffer(initializer, &bufinfo, MP_BUFFER_READ)) { // construct array from raw bytes // we round-down the len to make it a multiple of sz (CPython raises error) size_t sz = mp_binary_get_size('@', typecode, NULL); mp_uint_t len = bufinfo.len / sz; mp_obj_array_t *o = array_new(typecode, len); memcpy(o->items, bufinfo.buf, len * sz); return o; } mp_uint_t len; // Try to create array of exact len if initializer len is known mp_obj_t len_in = mp_obj_len_maybe(initializer); if (len_in == MP_OBJ_NULL) { len = 0; } else { len = MP_OBJ_SMALL_INT_VALUE(len_in); } mp_obj_array_t *array = array_new(typecode, len); mp_obj_t iterable = mp_getiter(initializer); mp_obj_t item; mp_uint_t i = 0; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (len == 0) { array_append(array, item); } else { mp_binary_set_val_array(typecode, array->items, i++, item); } } return array; }
void microbit_display_animate(microbit_display_obj_t *self, mp_obj_t iterable, mp_int_t delay, bool wait, bool loop) { // Reset the repeat state. MP_STATE_PORT(async_data)[0] = NULL; MP_STATE_PORT(async_data)[1] = NULL; MP_STATE_PORT(async_data)[2] = NULL; async_iterator = mp_getiter(iterable); async_error = false; async_delay = delay; MP_STATE_PORT(async_data)[0] = self; // so it doesn't get GC'd MP_STATE_PORT(async_data)[1] = async_iterator; if (loop) { async_repeat_iterable = iterable; MP_STATE_PORT(async_data)[2] = iterable; } wakeup_event = false; async_mode = ASYNC_MODE_ANIMATION; if (wait) { wait_for_event(); } }
mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: // return a empty tuple return mp_const_empty_tuple; case 1: { // 1 argument, an iterable from which we make a new tuple if (MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)) { return args[0]; } // TODO optimise for cases where we know the length of the iterator uint alloc = 4; uint len = 0; mp_obj_t *items = m_new(mp_obj_t, alloc); mp_obj_t iterable = mp_getiter(args[0]); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_NULL) { if (len >= alloc) { items = m_renew(mp_obj_t, items, alloc, alloc * 2); alloc *= 2; } items[len++] = item; } mp_obj_t tuple = mp_obj_new_tuple(len, items); m_free(items, alloc); return tuple; } default: nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "tuple takes at most 1 argument, %d given", n_args)); } }
STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { (void)type_in; mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { case 0: // return a empty tuple return mp_const_empty_tuple; case 1: default: { // 1 argument, an iterable from which we make a new tuple if (MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)) { return args[0]; } // TODO optimise for cases where we know the length of the iterator mp_uint_t alloc = 4; mp_uint_t len = 0; mp_obj_t *items = m_new(mp_obj_t, alloc); mp_obj_t iterable = mp_getiter(args[0]); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (len >= alloc) { items = m_renew(mp_obj_t, items, alloc, alloc * 2); alloc *= 2; } items[len++] = item; } mp_obj_t tuple = mp_obj_new_tuple(len, items); m_del(mp_obj_t, items, alloc); return tuple; } } }
STATIC mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_t dict; switch (n_args) { case 0: dict = mp_obj_new_dict(0); break; case 1: { if (MP_OBJ_IS_TYPE(args[0], &mp_type_dict)) { return dict_copy(args[0]); } // TODO create dict from an arbitrary mapping! // Make dict from iterable of pairs mp_obj_t iterable = mp_getiter(args[0]); mp_obj_t dict = mp_obj_new_dict(0); // TODO: support arbitrary seq as a pair mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { mp_obj_t *sub_items; mp_obj_get_array_fixed_n(item, 2, &sub_items); mp_obj_dict_store(dict, sub_items[0], sub_items[1]); } return dict; } default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "dict takes at most 1 argument")); } // add to the new dict any keyword args for (const mp_obj_t *a = args + n_args; n_kw > 0; n_kw--, a += 2) { mp_obj_dict_store(dict, a[0], a[1]); } return dict; }
STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 switch (n_args) { case 0: // return a new, empty set return mp_obj_new_set(0, NULL); case 1: { // 1 argument, an iterable from which we make a new set mp_obj_t set = mp_obj_new_set(0, NULL); mp_obj_t iterable = mp_getiter(args[0]); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { mp_obj_set_store(set, item); } return set; } default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "set takes at most 1 argument, %d given", n_args)); } }
STATIC mp_obj_t mp_builtin_iter(mp_obj_t o_in) { return mp_getiter(o_in); }