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))); } } }
// This dispatcher function is expected to be independent of the implementation of long int STATIC mp_obj_t mp_obj_int_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; mp_arg_check_num(n_args, n_kw, 0, 2, false); switch (n_args) { case 0: return MP_OBJ_NEW_SMALL_INT(0); case 1: if (MP_OBJ_IS_INT(args[0])) { // already an int (small or long), just return it return args[0]; } else if (MP_OBJ_IS_STR_OR_BYTES(args[0])) { // a string, parse it size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, 0, NULL); #if MICROPY_PY_BUILTINS_FLOAT } else if (mp_obj_is_float(args[0])) { return mp_obj_new_int_from_float(mp_obj_float_get(args[0])); #endif } else { return mp_unary_op(MP_UNARY_OP_INT, args[0]); } case 2: default: { // should be a string, parse it size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, mp_obj_get_int(args[1]), NULL); } } }
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; } }
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_float(arg)) { return mp_obj_float_get(arg); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "can't convert to float")); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg))); } } }
STATIC mp_obj_t mp_builtin_abs(mp_obj_t o_in) { #if MICROPY_PY_BUILTINS_FLOAT if (mp_obj_is_float(o_in)) { 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; } #if MICROPY_PY_BUILTINS_COMPLEX } 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 } #endif // this will raise a TypeError if the argument is not integral return mp_obj_int_abs(o_in); }
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) { mp_float_t val; if (arg == mp_const_false) { val = 0; } else if (arg == mp_const_true) { val = 1; } else if (MP_OBJ_IS_SMALL_INT(arg)) { val = MP_OBJ_SMALL_INT_VALUE(arg); #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { val = mp_obj_int_as_float_impl(arg); #endif } else if (mp_obj_is_float(arg)) { val = mp_obj_float_get(arg); } else { return false; } *value = val; return true; }
// This dispatcher function is expected to be independent of the implementation of long int STATIC mp_obj_t mp_obj_int_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, 2, false); switch (n_args) { case 0: return MP_OBJ_NEW_SMALL_INT(0); case 1: if (MP_OBJ_IS_INT(args[0])) { // already an int (small or long), just return it return args[0]; } else if (MP_OBJ_IS_STR_OR_BYTES(args[0])) { // a string, parse it mp_uint_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, 0, NULL); #if MICROPY_PY_BUILTINS_FLOAT } else if (mp_obj_is_float(args[0])) { return mp_obj_new_int_from_float(mp_obj_float_get(args[0])); #endif } else { // try to convert to small int (eg from bool) return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0])); } case 2: default: { // should be a string, parse it // TODO proper error checking of argument types mp_uint_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, mp_obj_get_int(args[1]), NULL); } } }
STATIC mp_obj_t float_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 mp_obj_new_float(0); case 1: default: if (MP_OBJ_IS_STR(args[0])) { // a string, parse it mp_uint_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_decimal(s, l, false, false, NULL); } else if (mp_obj_is_float(args[0])) { // a float, just return it return args[0]; } else { // something else, try to cast it to a float return mp_obj_new_float(mp_obj_get_float(args[0])); } } }
mp_float_t mp_obj_float_get(mp_obj_t self_in) { assert(mp_obj_is_float(self_in)); mp_obj_float_t *self = MP_OBJ_TO_PTR(self_in); return self->value; }
// 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) { // Float (and complex) NaN is never equal to anything, not even itself, // so we must have a special check here to cover those cases. if (o1 == o2 #if MICROPY_PY_BUILTINS_FLOAT && !mp_obj_is_float(o1) #endif #if MICROPY_PY_BUILTINS_COMPLEX && !MP_OBJ_IS_TYPE(o1, &mp_type_complex) #endif ) { 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 goto str_cmp_err; } } else if (MP_OBJ_IS_STR(o2)) { // o1 is not a string (else caught above), so the objects are not equal str_cmp_err: #if MICROPY_PY_STR_BYTES_CMP_WARN if (MP_OBJ_IS_TYPE(o1, &mp_type_bytes) || MP_OBJ_IS_TYPE(o2, &mp_type_bytes)) { mp_warning("Comparison between bytes and str"); } #endif 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; }