STATIC ICACHE_FLASH_ATTR mp_obj_t mod_esp_queue_test(mp_obj_t self_in, mp_obj_t add_obj) { #if 1 esp_queue_obj_t *self = self_in; if (self->items >= self->max_items) { nlr_raise(mp_obj_new_exception(&mp_type_Full)); } if (MP_OBJ_IS_TYPE(self->obj_instances[self->last], &mp_type_list)) { printf("list type of list\n"); if (!MP_OBJ_IS_TYPE(add_obj, &mp_type_list)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "pass a list only")); } mp_obj_list_t *in = (mp_obj_list_t *)add_obj; uint8_t vars[in->len]; for (int ii = 0; ii < in->len; ii++) { vars[ii] = MP_OBJ_SMALL_INT_VALUE(in->items[ii]); } esp_queue_dalist_8(self, in->len, vars); } else if (MP_OBJ_IS_SMALL_INT(self->obj_instances[self->last])) { printf("smallint type of list\n"); if (!MP_OBJ_IS_SMALL_INT(add_obj)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "pass an int only")); } printf("is small int\n"); esp_queue_daint_8(self, MP_OBJ_SMALL_INT_VALUE(add_obj)); } #endif return mp_const_none; }
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)type_in; (void)n_kw; int family = AF_INET; int type = SOCK_STREAM; int proto = 0; if (n_args > 0) { assert(MP_OBJ_IS_SMALL_INT(args[0])); family = MP_OBJ_SMALL_INT_VALUE(args[0]); if (n_args > 1) { assert(MP_OBJ_IS_SMALL_INT(args[1])); type = MP_OBJ_SMALL_INT_VALUE(args[1]); if (n_args > 2) { assert(MP_OBJ_IS_SMALL_INT(args[2])); proto = MP_OBJ_SMALL_INT_VALUE(args[2]); } } } int fd = socket(family, type, proto); RAISE_ERRNO(fd, errno); return MP_OBJ_FROM_PTR(socket_new(fd)); }
STATIC void push_result_token(parser_t *parser, const rule_t *rule) { mp_parse_node_t pn; mp_lexer_t *lex = parser->lexer; if (lex->tok_kind == MP_TOKEN_NAME) { qstr id = qstr_from_strn(lex->vstr.buf, lex->vstr.len); #if MICROPY_COMP_CONST // if name is a standalone identifier, look it up in the table of dynamic constants mp_map_elem_t *elem; if (rule->rule_id == RULE_atom && (elem = mp_map_lookup(&parser->consts, MP_OBJ_NEW_QSTR(id), MP_MAP_LOOKUP)) != NULL) { if (MP_OBJ_IS_SMALL_INT(elem->value)) { pn = mp_parse_node_new_small_int(MP_OBJ_SMALL_INT_VALUE(elem->value)); } else { pn = make_node_const_object(parser, lex->tok_line, elem->value); } } else { pn = mp_parse_node_new_leaf(MP_PARSE_NODE_ID, id); } #else (void)rule; pn = mp_parse_node_new_leaf(MP_PARSE_NODE_ID, id); #endif } else if (lex->tok_kind == MP_TOKEN_INTEGER) { mp_obj_t o = mp_parse_num_integer(lex->vstr.buf, lex->vstr.len, 0, lex); if (MP_OBJ_IS_SMALL_INT(o)) { pn = mp_parse_node_new_small_int(MP_OBJ_SMALL_INT_VALUE(o)); } else { pn = make_node_const_object(parser, lex->tok_line, o); } } else if (lex->tok_kind == MP_TOKEN_FLOAT_OR_IMAG) { mp_obj_t o = mp_parse_num_decimal(lex->vstr.buf, lex->vstr.len, true, false, lex); pn = make_node_const_object(parser, lex->tok_line, o); } else if (lex->tok_kind == MP_TOKEN_STRING || lex->tok_kind == MP_TOKEN_BYTES) { // Don't automatically intern all strings/bytes. doc strings (which are usually large) // will be discarded by the compiler, and so we shouldn't intern them. qstr qst = MP_QSTR_NULL; if (lex->vstr.len <= MICROPY_ALLOC_PARSE_INTERN_STRING_LEN) { // intern short strings qst = qstr_from_strn(lex->vstr.buf, lex->vstr.len); } else { // check if this string is already interned qst = qstr_find_strn(lex->vstr.buf, lex->vstr.len); } if (qst != MP_QSTR_NULL) { // qstr exists, make a leaf node pn = mp_parse_node_new_leaf(lex->tok_kind == MP_TOKEN_STRING ? MP_PARSE_NODE_STRING : MP_PARSE_NODE_BYTES, qst); } else { // not interned, make a node holding a pointer to the string/bytes object mp_obj_t o = mp_obj_new_str_of_type( lex->tok_kind == MP_TOKEN_STRING ? &mp_type_str : &mp_type_bytes, (const byte*)lex->vstr.buf, lex->vstr.len); pn = make_node_const_object(parser, lex->tok_line, o); } } else { pn = mp_parse_node_new_leaf(MP_PARSE_NODE_TOKEN, lex->tok_kind); } push_result_node(parser, pn); }
STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) { if (MP_OBJ_IS_SMALL_INT(o1_in) && MP_OBJ_IS_SMALL_INT(o2_in)) { mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in); mp_small_int_t i2 = MP_OBJ_SMALL_INT_VALUE(o2_in); mp_obj_t args[2]; args[0] = MP_OBJ_NEW_SMALL_INT(i1 / i2); args[1] = MP_OBJ_NEW_SMALL_INT(i1 % i2); return mp_obj_new_tuple(2, args); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in))); } }
// this function implements the '==' operator (and so the inverse of '!=') // from the python language reference: // "The objects need not have the same type. If both are numbers, they are converted // to a common type. Otherwise, the == and != operators always consider objects of // different types to be unequal." // note also that False==0 and True==1 are true expressions bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { if (o1 == o2) { return true; } if (o1 == mp_const_none || o2 == mp_const_none) { return false; } // fast path for small ints if (MP_OBJ_IS_SMALL_INT(o1)) { if (MP_OBJ_IS_SMALL_INT(o2)) { // both SMALL_INT, and not equal if we get here return false; } else { mp_obj_t temp = o2; o2 = o1; o1 = temp; // o2 is now the SMALL_INT, o1 is not // fall through to generic op } } // fast path for strings if (MP_OBJ_IS_STR(o1)) { if (MP_OBJ_IS_STR(o2)) { // both strings, use special function return mp_obj_str_equal(o1, o2); } else { // a string is never equal to anything else return false; } } else if (MP_OBJ_IS_STR(o2)) { // o1 is not a string (else caught above), so the objects are not equal return false; } // generic type, call binary_op(MP_BINARY_OP_EQUAL) mp_obj_type_t *type = mp_obj_get_type(o1); if (type->binary_op != NULL) { mp_obj_t r = type->binary_op(MP_BINARY_OP_EQUAL, o1, o2); if (r != MP_OBJ_NULL) { return r == mp_const_true ? true : false; } } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError, "equality for given types not yet implemented")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError, "equality for '%s' and '%s' types not yet implemented", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2))); } }
mp_obj_t rt_unary_op(int op, mp_obj_t arg) { DEBUG_OP_printf("unary %d %p\n", op, arg); if (MP_OBJ_IS_SMALL_INT(arg)) { mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(arg); switch (op) { case RT_UNARY_OP_NOT: if (val != 0) { return mp_const_true;} else { return mp_const_false; } case RT_UNARY_OP_POSITIVE: break; case RT_UNARY_OP_NEGATIVE: val = -val; break; case RT_UNARY_OP_INVERT: val = ~val; break; default: assert(0); val = 0; } if (fit_small_int(val)) { return MP_OBJ_NEW_SMALL_INT(val); } else { // TODO make a bignum assert(0); return mp_const_none; } } else { // will be an object (small ints are caught in previous if) mp_obj_base_t *o = arg; if (o->type->unary_op != NULL) { mp_obj_t result = o->type->unary_op(op, arg); if (result != NULL) { return result; } } // TODO specify in error message what the operator is nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "bad operand type for unary operator: '%s'", o->type->name)); } }
static int _socket_getaddrinfo2(const mp_obj_t host, const mp_obj_t portx, struct addrinfo **resp) { const struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_STREAM, }; mp_obj_t port = portx; if (MP_OBJ_IS_SMALL_INT(port)) { // This is perverse, because lwip_getaddrinfo promptly converts it back to an int, but // that's the API we have to work with ... port = mp_obj_str_binary_op(MP_BINARY_OP_MODULO, mp_obj_new_str_via_qstr("%s", 2), port); } const char *host_str = mp_obj_str_get_str(host); const char *port_str = mp_obj_str_get_str(port); if (host_str[0] == '\0') { // a host of "" is equivalent to the default/all-local IP address host_str = "0.0.0.0"; } MP_THREAD_GIL_EXIT(); int res = lwip_getaddrinfo(host_str, port_str, &hints, resp); MP_THREAD_GIL_ENTER(); return res; }
machine_int_t mp_obj_hash(mp_obj_t o_in) { if (o_in == mp_const_false) { return 0; // needs to hash to same as the integer 0, since False==0 } else if (o_in == mp_const_true) { return 1; // needs to hash to same as the integer 1, since True==1 } else if (MP_OBJ_IS_SMALL_INT(o_in)) { return MP_OBJ_SMALL_INT_VALUE(o_in); } else if (MP_OBJ_IS_STR(o_in)) { return mp_obj_str_get_hash(o_in); } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_NoneType)) { return (machine_int_t)o_in; } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_fun_native) || MP_OBJ_IS_TYPE(o_in, &mp_type_fun_bc)) { return (machine_int_t)o_in; } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_tuple)) { return mp_obj_tuple_hash(o_in); } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_type)) { return (machine_int_t)o_in; // TODO hash class and instances // TODO delegate to __hash__ method if it exists } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unhashable type: '%s'", mp_obj_get_type_str(o_in))); } }
bool mp_obj_is_true(mp_obj_t arg) { if (arg == mp_const_false) { return 0; } else if (arg == mp_const_true) { return 1; } else if (arg == mp_const_none) { return 0; } else if (MP_OBJ_IS_SMALL_INT(arg)) { if (MP_OBJ_SMALL_INT_VALUE(arg) == 0) { return 0; } else { return 1; } } else { mp_obj_type_t *type = mp_obj_get_type(arg); if (type->unary_op != NULL) { mp_obj_t result = type->unary_op(MP_UNARY_OP_BOOL, arg); if (result != MP_OBJ_NULL) { return result == mp_const_true; } } mp_obj_t len = mp_obj_len_maybe(arg); if (len != MP_OBJ_NULL) { // obj has a length, truth determined if len != 0 return len != MP_OBJ_NEW_SMALL_INT(0); } else { // any other obj is true per Python semantics return 1; } } }
mp_obj_t mp_builtin_abs(mp_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o_in); if (val < 0) { val = -val; } return MP_OBJ_NEW_SMALL_INT(val); #if MICROPY_ENABLE_FLOAT } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_float)) { mp_float_t value = mp_obj_float_get(o_in); // TODO check for NaN etc if (value < 0) { return mp_obj_new_float(-value); } else { return o_in; } } else if (MP_OBJ_IS_TYPE(o_in, &mp_type_complex)) { mp_float_t real, imag; mp_obj_complex_get(o_in, &real, &imag); return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag)); #endif } else { assert(0); return mp_const_none; } }
// convert a Micro Python object to a sensible value for inline asm machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { // TODO for byte_array, pass pointer to the array if (MP_OBJ_IS_SMALL_INT(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); } else if (obj == mp_const_none) { return 0; } else if (obj == mp_const_false) { return 0; } else if (obj == mp_const_true) { return 1; } else if (MP_OBJ_IS_TYPE(obj, &str_type)) { // pointer to the string (it's probably constant though!) return (machine_uint_t)qstr_str(mp_obj_str_get(obj)); #if MICROPY_ENABLE_FLOAT } else if (MP_OBJ_IS_TYPE(obj, &float_type)) { // convert float to int (could also pass in float registers) return (machine_int_t)mp_obj_float_get(obj); #endif } else if (MP_OBJ_IS_TYPE(obj, &tuple_type)) { // pointer to start of tuple (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_tuple_get(obj, &len, &items); return (machine_uint_t)items; } else if (MP_OBJ_IS_TYPE(obj, &list_type)) { // pointer to start of list (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { // just pass along a pointer to the object return (machine_uint_t)obj; } }
void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { if (arg == mp_const_false) { *real = 0; *imag = 0; } else if (arg == mp_const_true) { *real = 1; *imag = 0; } else if (MP_OBJ_IS_SMALL_INT(arg)) { *real = MP_OBJ_SMALL_INT_VALUE(arg); *imag = 0; } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { *real = mp_obj_int_as_float(arg); *imag = 0; } else if (mp_obj_is_float(arg)) { *real = mp_obj_float_get(arg); *imag = 0; } else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) { mp_obj_complex_get(arg, real, imag); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "can't convert to complex")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg))); } } }
STATIC void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = MP_OBJ_TO_PTR(o_in); mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; bool is_subclass = kind & PRINT_EXC_SUBCLASS; if (!is_subclass && (k == PRINT_REPR || k == PRINT_EXC)) { mp_print_str(print, qstr_str(o->base.type->name)); } if (k == PRINT_EXC) { mp_print_str(print, ": "); } if (k == PRINT_STR || k == PRINT_EXC) { if (o->args == NULL || o->args->len == 0) { mp_print_str(print, ""); return; } else if (o->args->len == 1) { #if MICROPY_PY_UERRNO // try to provide a nice OSError error message if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) { qstr qst = mp_errno_to_str(o->args->items[0]); if (qst != MP_QSTR_NULL) { mp_printf(print, "[Errno %d] %q", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), qst); return; } } #endif mp_obj_print_helper(print, o->args->items[0], PRINT_STR); return; } } mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); }
// is_slice determines whether the index is a slice index uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index, bool is_slice) { int i; if (MP_OBJ_IS_SMALL_INT(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (MP_OBJ_IS_TYPE(index, &mp_type_bool)) { i = (index == mp_const_true ? 1 : 0); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%s indices must be integers, not %s", qstr_str(type->name), mp_obj_get_type_str(index))); } if (i < 0) { i += len; } if (is_slice) { if (i < 0) { i = 0; } else if (i > len) { i = len; } } else { if (i < 0 || i >= len) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "%s index out of range", qstr_str(type->name))); } } return i; }
bool ICACHE_FLASH_ATTR esp_queue_check_for_daint_8(esp_queue_obj_t *queue_in) { mp_obj_t *inst = queue_in->obj_instances[queue_in->last]; if (!MP_OBJ_IS_SMALL_INT(inst)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "not smallint")); } return true; }
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 } }
// This function implements the '==' operator (and so the inverse of '!='). // // From the Python language reference: // (https://docs.python.org/3/reference/expressions.html#not-in) // "The objects need not have the same type. If both are numbers, they are converted // to a common type. Otherwise, the == and != operators always consider objects of // different types to be unequal." // // This means that False==0 and True==1 are true expressions. // // Furthermore, from the v3.4.2 code for object.c: "Practical amendments: If rich // comparison returns NotImplemented, == and != are decided by comparing the object // pointer." bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { if (o1 == o2) { return true; } if (o1 == mp_const_none || o2 == mp_const_none) { return false; } // fast path for small ints if (MP_OBJ_IS_SMALL_INT(o1)) { if (MP_OBJ_IS_SMALL_INT(o2)) { // both SMALL_INT, and not equal if we get here return false; } else { mp_obj_t temp = o2; o2 = o1; o1 = temp; // o2 is now the SMALL_INT, o1 is not // fall through to generic op } } // fast path for strings if (MP_OBJ_IS_STR(o1)) { if (MP_OBJ_IS_STR(o2)) { // both strings, use special function return mp_obj_str_equal(o1, o2); } else { // a string is never equal to anything else return false; } } else if (MP_OBJ_IS_STR(o2)) { // o1 is not a string (else caught above), so the objects are not equal return false; } // generic type, call binary_op(MP_BINARY_OP_EQUAL) mp_obj_type_t *type = mp_obj_get_type(o1); if (type->binary_op != NULL) { mp_obj_t r = type->binary_op(MP_BINARY_OP_EQUAL, o1, o2); if (r != MP_OBJ_NULL) { return r == mp_const_true ? true : false; } } // equality not implemented, and objects are not the same object, so // they are defined as not equal return false; }
// this function implements the '==' operator (and so the inverse of '!=') // from the python language reference: // "The objects need not have the same type. If both are numbers, they are converted // to a common type. Otherwise, the == and != operators always consider objects of // different types to be unequal." // note also that False==0 and True==1 are true expressions bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { if (o1 == o2) { return true; } else if (o1 == mp_const_none || o2 == mp_const_none) { return false; } else if (MP_OBJ_IS_SMALL_INT(o1) || MP_OBJ_IS_SMALL_INT(o2)) { if (MP_OBJ_IS_SMALL_INT(o1) && MP_OBJ_IS_SMALL_INT(o2)) { return false; } else { if (MP_OBJ_IS_SMALL_INT(o2)) { mp_obj_t temp = o1; o1 = o2; o2 = temp; } // o1 is the SMALL_INT, o2 is not mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o1); if (o2 == mp_const_false) { return val == 0; } else if (o2 == mp_const_true) { return val == 1; } else if (MP_OBJ_IS_TYPE(o2, &mp_type_int)) { // If o2 is long int, dispatch to its virtual methods mp_obj_base_t *o = o2; if (o->type->binary_op != NULL) { mp_obj_t r = o->type->binary_op(MP_BINARY_OP_EQUAL, o2, o1); return r == mp_const_true ? true : false; } } return false; } } else if (MP_OBJ_IS_STR(o1) && MP_OBJ_IS_STR(o2)) { return mp_obj_str_equal(o1, o2); } else { mp_obj_base_t *o = o1; if (o->type->binary_op != NULL) { mp_obj_t r = o->type->binary_op(MP_BINARY_OP_EQUAL, o1, o2); if (r != MP_OBJ_NULL) { return r == mp_const_true ? true : false; } } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError, "Equality for '%s' and '%s' types not yet implemented", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2))); return false; } }
mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { return (mp_obj_t)&mp_type_int; } else if (MP_OBJ_IS_QSTR(o_in)) { return (mp_obj_t)&mp_type_str; } else { mp_obj_base_t *o = o_in; return (mp_obj_t)o->type; } }
STATIC mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t); mp_const_obj_t type = type_in; const char *mode_s; if (n_args > 1) { mode_s = mp_obj_str_get_str(args[1]); } else { mode_s = "r"; } int mode = 0; while (*mode_s) { switch (*mode_s++) { // Note: these assume O_RDWR = O_RDONLY | O_WRONLY case 'r': mode |= O_RDONLY; break; case 'w': mode |= O_WRONLY | O_CREAT | O_TRUNC; break; case 'a': mode |= O_APPEND; break; case '+': mode |= O_RDWR; break; #if MICROPY_PY_IO_FILEIO // If we don't have io.FileIO, then files are in text mode implicitly case 'b': type = &mp_type_fileio; break; case 't': type = &mp_type_textio; break; #endif } } o->base.type = type; if (MP_OBJ_IS_SMALL_INT(args[0])) { o->fd = MP_OBJ_SMALL_INT_VALUE(args[0]); return o; } const char *fname = mp_obj_str_get_str(args[0]); int fd = open(fname, mode, 0644); if (fd == -1) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno))); } o->fd = fd; return o; }
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; } }
// Convert an index into a pointer to its lead byte. Out of bounds indexing will raise IndexError or // be capped to the first/last character of the string, depending on is_slice. const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, mp_obj_t index, bool is_slice) { (void)type; mp_int_t i; // Copied from mp_get_index; I don't want bounds checking, just give me // the integer as-is. (I can't bounds-check without scanning the whole // string; an out-of-bounds index will be caught in the loops below.) if (MP_OBJ_IS_SMALL_INT(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "string indices must be integers, not %s", mp_obj_get_type_str(index))); } const byte *s, *top = self_data + self_len; if (i < 0) { // Negative indexing is performed by counting from the end of the string. for (s = top - 1; i; --s) { if (s < self_data) { if (is_slice) { return self_data; } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "string index out of range")); } if (!UTF8_IS_CONT(*s)) { ++i; } } ++s; } else if (!i) { return self_data; // Shortcut - str[0] is its base pointer } else { // Positive indexing, correspondingly, counts from the start of the string. // It's assumed that negative indexing will generally be used with small // absolute values (eg str[-1], not str[-1000000]), which means it'll be // more efficient this way. for (s = self_data; true; ++s) { if (s >= top) { if (is_slice) { return top; } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "string index out of range")); } while (UTF8_IS_CONT(*s)) { ++s; } if (!i--) { return s; } } } return s; }
static mp_obj_t socket_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { int family = AF_INET; int type = SOCK_STREAM; int proto = 0; if (n_args > 0) { assert(MP_OBJ_IS_SMALL_INT(args[0])); family = MP_OBJ_SMALL_INT_VALUE(args[0]); if (n_args > 1) { assert(MP_OBJ_IS_SMALL_INT(args[1])); type = MP_OBJ_SMALL_INT_VALUE(args[1]); if (n_args > 2) { assert(MP_OBJ_IS_SMALL_INT(args[2])); proto = MP_OBJ_SMALL_INT_VALUE(args[2]); } } } int fd = socket(family, type, proto); RAISE_ERRNO(fd, errno); return socket_new(fd); }
// returns false if arg is not of integral type // returns true and sets *value if it is of integral type // can throw OverflowError if arg is of integral type, but doesn't fit in a mp_int_t bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value) { if (arg == mp_const_false) { *value = 0; } else if (arg == mp_const_true) { *value = 1; } else if (MP_OBJ_IS_SMALL_INT(arg)) { *value = MP_OBJ_SMALL_INT_VALUE(arg); } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { *value = mp_obj_int_get_checked(arg); } else { return false; } return true; }
mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { return (mp_obj_type_t*)&mp_type_int; } else if (MP_OBJ_IS_QSTR(o_in)) { return (mp_obj_type_t*)&mp_type_str; #if MICROPY_PY_BUILTINS_FLOAT } else if (mp_obj_is_float(o_in)) { return (mp_obj_type_t*)&mp_type_float; #endif } else { const mp_obj_base_t *o = MP_OBJ_TO_PTR(o_in); return (mp_obj_type_t*)o->type; } }
STATIC mp_obj_t fdfile_open(const mp_obj_type_t *type, mp_arg_val_t *args) { mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t); const char *mode_s = mp_obj_str_get_str(args[1].u_obj); int mode_rw = 0, mode_x = 0; while (*mode_s) { switch (*mode_s++) { case 'r': mode_rw = O_RDONLY; break; case 'w': mode_rw = O_WRONLY; mode_x = O_CREAT | O_TRUNC; break; case 'a': mode_rw = O_WRONLY; mode_x = O_CREAT | O_APPEND; break; case '+': mode_rw = O_RDWR; break; #if MICROPY_PY_IO_FILEIO // If we don't have io.FileIO, then files are in text mode implicitly case 'b': type = &mp_type_fileio; break; case 't': type = &mp_type_textio; break; #endif } } o->base.type = type; mp_obj_t fid = args[0].u_obj; if (MP_OBJ_IS_SMALL_INT(fid)) { o->fd = MP_OBJ_SMALL_INT_VALUE(fid); return MP_OBJ_FROM_PTR(o); } const char *fname = mp_obj_str_get_str(fid); int fd = open(fname, mode_x | mode_rw, 0644); if (fd == -1) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno))); } o->fd = fd; return MP_OBJ_FROM_PTR(o); }
bool ICACHE_FLASH_ATTR esp_queue_check_for_dalist_8(esp_queue_obj_t *queue_in, uint32_t len) { mp_obj_t *inst = queue_in->obj_instances[queue_in->last]; if (!MP_OBJ_IS_TYPE(inst, &mp_type_list)) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "storage needs to be a list")); } else { mp_obj_list_t *al = (mp_obj_list_t *)inst; if (al->len < len) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "queue data is too small")); } if (!MP_OBJ_IS_SMALL_INT(al->items[0])) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "not smallint")); } } return true; }
mp_float_t mp_obj_get_float(mp_obj_t arg) { if (arg == mp_const_false) { return 0; } else if (arg == mp_const_true) { return 1; } else if (MP_OBJ_IS_SMALL_INT(arg)) { return MP_OBJ_SMALL_INT_VALUE(arg); } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { return mp_obj_int_as_float(arg); } else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) { return mp_obj_float_get(arg); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg))); } }
machine_int_t mp_obj_get_int(mp_obj_t arg) { // This function essentially performs implicit type conversion to int // Note that Python does NOT provide implicit type conversion from // float to int in the core expression language, try some_list[1.0]. if (arg == mp_const_false) { return 0; } else if (arg == mp_const_true) { return 1; } else if (MP_OBJ_IS_SMALL_INT(arg)) { return MP_OBJ_SMALL_INT_VALUE(arg); } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { return mp_obj_int_get_checked(arg); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg))); } }