示例#1
0
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;
    }
}
STATIC mp_obj_t return_ffi_value(ffi_arg val, char type)
{
    switch (type) {
        case 's': {
            const char *s = (const char *)(intptr_t)val;
            if (!s) {
                return mp_const_none;
            }
            return mp_obj_new_str(s, strlen(s), false);
        }
        case 'v':
            return mp_const_none;
        #if MICROPY_PY_BUILTINS_FLOAT
        case 'f': {
            union { ffi_arg ffi; float flt; } val_union = { .ffi = val };
            return mp_obj_new_float(val_union.flt);
        }
        case 'd': {
            double *p = (double*)&val;
            return mp_obj_new_float(*p);
        }
        #endif
        case 'O':
            return (mp_obj_t)(intptr_t)val;
        default:
            return mp_obj_new_int(val);
    }
}
示例#3
0
mp_obj_t mp_math_modf(mp_obj_t x_obj) {
    mp_float_t int_part = 0.0;
    mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(mp_obj_get_float(x_obj), &int_part);
    mp_obj_t tuple[2];
    tuple[0] = mp_obj_new_float(fractional_part);
    tuple[1] = mp_obj_new_float(int_part);
    return mp_obj_new_tuple(2, tuple);
}
示例#4
0
// log(x[, base])
STATIC mp_obj_t mp_math_log(mp_uint_t n_args, const mp_obj_t *args) {
    mp_float_t l = MICROPY_FLOAT_C_FUN(log)(mp_obj_get_float(args[0]));
    if (n_args == 1) {
        return mp_obj_new_float(l);
    } else {
        return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(mp_obj_get_float(args[1])));
    }
}
示例#5
0
mp_obj_t mp_cmath_polar(mp_obj_t z_obj) {
    mp_float_t real, imag;
    mp_obj_get_complex(z_obj, &real, &imag);
    mp_obj_t tuple[2] = {
        mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag)),
        mp_obj_new_float(MICROPY_FLOAT_C_FUN(atan2)(imag, real)),
    };
    return mp_obj_new_tuple(2, tuple);
}
示例#6
0
STATIC void complex_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
    if (dest[0] != MP_OBJ_NULL) {
        // not load attribute
        return;
    }
    mp_obj_complex_t *self = MP_OBJ_TO_PTR(self_in);
    if (attr == MP_QSTR_real) {
        dest[0] = mp_obj_new_float(self->real);
    } else if (attr == MP_QSTR_imag) {
        dest[0] = mp_obj_new_float(self->imag);
    }
}
示例#7
0
  /* store default values so that no crash due to undefined variable */

  if (v->flags & PY_FLAG_ARRAY)
  {
    v->index = MP_OBJ_NEW_SMALL_INT(0);
    v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items);
    obj = v->list;
  }
  else
  {
    obj = v->items[0];
  }

  mp_store_name(v->name, obj);

  if (v->flags & PY_FLAG_FLOAT)
  {
    size = dim * sizeof(mp_float_t);
    data = (void**)&v->data.f;
  }
  else
  {
    size = dim * sizeof(mp_int_t);
    data = (void**)&v->data.i;
  }

  *data = malloc(size);
  if (*data == NULL) goto on_error_2;
  
  return v;

 on_error_2:
  free(v->items);
 on_error_1:
  free(v);
 on_error_0:
  return NULL;
}

static py_var_t* py_create_scalar
(py_handle_t* py, const char* name, uint32_t flags)
{
  return py_create_var(py, name, 1, flags);
}

static py_var_t* py_create_array
(py_handle_t* py, const char* name, size_t dim, uint32_t flags)
{
  return py_create_var(py, name, dim, flags | PY_FLAG_ARRAY);
}

static void py_destroy_var(py_var_t* v)
{
  void* data;

  if (v->flags & PY_FLAG_FLOAT) data = (void*)v->data.f;
  else data = (void*)v->data.i;

  free(data);
  free(v->items);
  free(v);
}

static void py_print_var(py_var_t* v)
{
  size_t i;

  for (i = 0; i != v->dim; ++i)
  {
    if (v->flags & PY_FLAG_INT) printf(" %d", v->data.i[i]);
    else printf(" %lf", v->data.f[i]);
  }
  printf("\n");
}

static void py_print_out_vars(py_handle_t* py)
{
  size_t i;

  for (i = 0; i != py->nvar; ++i)
  {
    py_var_t* const v = py->vars[i];
    if ((v->flags & PY_FLAG_OUT) == 0) continue ;
    py_print_var(v);
  }
}

static int py_compile(py_handle_t* py, const char* s)
{
  static const mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT;
  static const uint emit_opt = MP_EMIT_OPT_NATIVE_PYTHON;
  nlr_buf_t nlr;
  int err = -1;

  if (nlr_push(&nlr)) return -1;

  py->lex = mp_lexer_new_from_str_len
    (MP_QSTR__lt_stdin_gt_, s, strlen(s), false);
  if (py->lex == NULL) goto on_error_0;

  py->parse_tree = mp_parse(py->lex, input_kind);

  py->module_fun = mp_compile
    (&py->parse_tree, py->lex->source_name, emit_opt, false);

  err = 0;

 on_error_0:
  nlr_pop();
  return err;
}

static int py_open(py_handle_t* py)
{
  py->lex = NULL;
  py->nvar = 0;
  return 0;
}

static int py_close(py_handle_t* py)
{
  size_t i;

  for (i = 0; i != py->nvar; ++i) py_destroy_var(py->vars[i]);

  return 0;
}

#if 0 /* does not work, should recompile entirely */
static int py_collect(py_handle_t* py)
{
  mp_obj_t obj;
  size_t i;
  size_t j;

  gc_collect();

  for (i = 0; i != py->nvar; ++i)
  {
    py_var_t* const v = py->vars[i];

    v->name = qstr_from_str(v->_name);

    if (v->flags & PY_FLAG_INT)
    {
      for (j = 0; j != v->dim; ++j)
      {
	if (v->flags & PY_FLAG_IN) obj = MP_OBJ_NEW_SMALL_INT(v->in.i[j]);
	else obj = MP_OBJ_NEW_SMALL_INT(v->data.i[j]);
	v->items[j] = obj;
      }
    }
    else
    {
      for (j = 0; j != v->dim; ++j)
      {
	if (v->flags & PY_FLAG_IN) obj = mp_obj_new_float(v->in.f[j]);
	else obj = mp_obj_new_float(v->data.f[j]);
	v->items[j] = obj;
      }
    }

    /* store default values so that no crash due to undefined variable */

    if (v->flags & PY_FLAG_ARRAY)
    {
      v->index = MP_OBJ_NEW_SMALL_INT(0);
      v->list = mp_obj_new_list((mp_uint_t)v->dim, v->items);
      obj = v->list;
    }
    else
    {
      obj = v->items[0];
    }

    mp_store_name(v->name, obj);
  }

  return 0;
}
示例#8
0
// log(x[, base])
STATIC mp_obj_t mp_math_log(size_t n_args, const mp_obj_t *args) {
    mp_float_t x = mp_obj_get_float(args[0]);
    if (x <= (mp_float_t)0.0) {
        math_error();
    }
    mp_float_t l = MICROPY_FLOAT_C_FUN(log)(x);
    if (n_args == 1) {
        return mp_obj_new_float(l);
    } else {
        mp_float_t base = mp_obj_get_float(args[1]);
        if (base <= (mp_float_t)0.0) {
            math_error();
        }
        return mp_obj_new_float(l / MICROPY_FLOAT_C_FUN(log)(base));
    }
}
示例#9
0
static mp_obj_t float_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
    switch (n_args) {
        case 0:
            return mp_obj_new_float(0);

        case 1:
            // TODO allow string as arg and parse it
            if (MP_OBJ_IS_TYPE(args[0], &float_type)) {
                return args[0];
            } else {
                return mp_obj_new_float(mp_obj_get_float(args[0]));
            }

        default:
            nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "float takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
    }
}
示例#10
0
// Functions that return a tuple
mp_obj_t mp_math_frexp(mp_obj_t x_obj) {
    int int_exponent = 0;
    mp_float_t significand = MICROPY_FLOAT_C_FUN(frexp)(mp_obj_get_float(x_obj), &int_exponent);
    mp_obj_t tuple[2];
    tuple[0] = mp_obj_new_float(significand);
    tuple[1] = mp_obj_new_int(int_exponent);
    return mp_obj_new_tuple(2, tuple);
}
示例#11
0
// Note: this is deprecated since CPy3.3, but pystone still uses it.
STATIC mp_obj_t mod_time_clock() {
//    return mp_obj_new_int((machine_int_t)clock());
    // POSIX requires CLOCKS_PER_SEC equals 1000000, so that's what we assume
    // float cannot represent full range of int32 precisely, so we pre-divide
    // int to reduce resolution, and then actually do float division hoping
    // to preserve integer part resolution.
    return mp_obj_new_float((float)(clock() / 1000) / 1000.0);
}
示例#12
0
mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) {
    mp_int_t val = 0;
    switch (typecode) {
        case 'b':
            val = ((signed char*)p)[index];
            break;
        case BYTEARRAY_TYPECODE:
        case 'B':
            val = ((unsigned char*)p)[index];
            break;
        case 'h':
            val = ((short*)p)[index];
            break;
        case 'H':
            val = ((unsigned short*)p)[index];
            break;
        case 'i':
            return mp_obj_new_int(((int*)p)[index]);
        case 'I':
            return mp_obj_new_int_from_uint(((unsigned int*)p)[index]);
        case 'l':
            return mp_obj_new_int(((long*)p)[index]);
        case 'L':
            return mp_obj_new_int_from_uint(((unsigned long*)p)[index]);
        #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
        case 'q':
            return mp_obj_new_int_from_ll(((long long*)p)[index]);
        case 'Q':
            return mp_obj_new_int_from_ull(((unsigned long long*)p)[index]);
        #endif
#if MICROPY_PY_BUILTINS_FLOAT
        case 'f':
            return mp_obj_new_float(((float*)p)[index]);
        case 'd':
            return mp_obj_new_float(((double*)p)[index]);
#endif
        // Extension to CPython: array of objects
        case 'O':
            return ((mp_obj_t*)p)[index];
        // Extension to CPython: array of pointers
        case 'P':
            return mp_obj_new_int((mp_int_t)((void**)p)[index]);
    }
    return MP_OBJ_NEW_SMALL_INT(val);
}
示例#13
0
mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
    byte *p = *ptr;
    mp_uint_t align;

    size_t size = mp_binary_get_size(struct_type, val_type, &align);
    if (struct_type == '@') {
        // Make pointer aligned
        p = (byte*)(((mp_uint_t)p + align - 1) & ~((mp_uint_t)align - 1));
        #if MP_ENDIANNESS_LITTLE
        struct_type = '<';
        #else
        struct_type = '>';
        #endif
    }
    *ptr = p + size;

    long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p);

    if (val_type == 'O') {
        return (mp_obj_t)(mp_uint_t)val;
    } else if (val_type == 'S') {
        const char *s_val = (const char*)(mp_uint_t)val;
        return mp_obj_new_str(s_val, strlen(s_val), false);
#if MICROPY_PY_BUILTINS_FLOAT
    } else if (val_type == 'f') {
        union { uint32_t i; float f; } fpu = {val};
        return mp_obj_new_float(fpu.f);
    } else if (val_type == 'd') {
        union { uint64_t i; double f; } fpu = {val};
        return mp_obj_new_float(fpu.f);
#endif
    } else if (is_signed(val_type)) {
        if ((long long)MP_SMALL_INT_MIN <= val && val <= (long long)MP_SMALL_INT_MAX) {
            return mp_obj_new_int((mp_int_t)val);
        } else {
            return mp_obj_new_int_from_ll(val);
        }
    } else {
        if ((unsigned long long)val <= (unsigned long long)MP_SMALL_INT_MAX) {
            return mp_obj_new_int_from_uint((mp_uint_t)val);
        } else {
            return mp_obj_new_int_from_ull(val);
        }
    }
}
示例#14
0
STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) {
    mp_float_t val = mp_obj_float_get(o_in);
    switch (op) {
        case MP_UNARY_OP_BOOL: return mp_obj_new_bool(val != 0);
        case MP_UNARY_OP_POSITIVE: return o_in;
        case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val);
        default: return MP_OBJ_NULL; // op not supported
    }
}
示例#15
0
STATIC mp_obj_t microbit_temperature(void) {
    int temp;
    NRF_TEMP->TASKS_START = 1;
    while (NRF_TEMP->EVENTS_DATARDY == 0);
    NRF_TEMP->EVENTS_DATARDY = 0;
    temp = NRF_TEMP->TEMP;
    NRF_TEMP->TASKS_STOP = 1;
    return mp_obj_new_float(temp/4.0);
}
示例#16
0
STATIC mp_obj_t float_unary_op(int op, mp_obj_t o_in) {
    mp_obj_float_t *o = o_in;
    switch (op) {
        case MP_UNARY_OP_BOOL: return MP_BOOL(o->value != 0);
        case MP_UNARY_OP_POSITIVE: return o_in;
        case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value);
        default: return MP_OBJ_NOT_SUPPORTED;
    }
}
示例#17
0
static mp_obj_t float_unary_op(int op, mp_obj_t o_in) {
    mp_obj_float_t *o = o_in;
    switch (op) {
        case RT_UNARY_OP_NOT: if (o->value != 0) { return mp_const_true;} else { return mp_const_false; }
        case RT_UNARY_OP_POSITIVE: return o_in;
        case RT_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value);
        default: return NULL; // op not supported
    }
}
示例#18
0
STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) {
    mp_obj_float_t *o = o_in;
    switch (op) {
        case MP_UNARY_OP_BOOL: return MP_BOOL(o->value != 0);
        case MP_UNARY_OP_POSITIVE: return o_in;
        case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value);
        default: return MP_OBJ_NULL; // op not supported
    }
}
示例#19
0
// Note: this is deprecated since CPy3.3, but pystone still uses it.
STATIC mp_obj_t mod_time_clock() {
#if MICROPY_PY_BUILTINS_FLOAT
    // float cannot represent full range of int32 precisely, so we pre-divide
    // int to reduce resolution, and then actually do float division hoping
    // to preserve integer part resolution.
    return mp_obj_new_float((float)(clock() / 1000) / CLOCK_DIV);
#else
    return mp_obj_new_int((machine_int_t)clock());
#endif
}
示例#20
0
static mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) {
    pyb_obj_adc_all_t *self = self_in;

    if (self->is_enabled) {
        float data  = adc_read_core_vref();
        return mp_obj_new_float(data);
    } else {
        return mp_const_none;
    }
}
示例#21
0
STATIC mp_obj_t mod_time_time() {
#if MICROPY_PY_BUILTINS_FLOAT
    struct timeval tv;
    gettimeofday(&tv, NULL);
    mp_float_t val = tv.tv_sec + (mp_float_t)tv.tv_usec / 1000000;
    return mp_obj_new_float(val);
#else
    return mp_obj_new_int((machine_int_t)time(NULL));
#endif
}
示例#22
0
mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_in) {
    mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible)
    switch (op) {
        case MP_BINARY_OP_ADD:
        case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;
        case MP_BINARY_OP_SUBTRACT:
        case MP_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break;
        case MP_BINARY_OP_MULTIPLY:
        case MP_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break;
        case MP_BINARY_OP_FLOOR_DIVIDE:
        case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
            if (rhs_val == 0) {
                zero_division_error:
                nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero"));
            }
            // Python specs require that x == (x//y)*y + (x%y) so we must
            // call divmod to compute the correct floor division, which
            // returns the floor divide in lhs_val.
            mp_obj_float_divmod(&lhs_val, &rhs_val);
            break;
        case MP_BINARY_OP_TRUE_DIVIDE:
        case MP_BINARY_OP_INPLACE_TRUE_DIVIDE:
            if (rhs_val == 0) {
                goto zero_division_error;
            }
            lhs_val /= rhs_val;
            break;
        case MP_BINARY_OP_MODULO:
        case MP_BINARY_OP_INPLACE_MODULO:
            if (rhs_val == 0) {
                goto zero_division_error;
            }
            lhs_val = MICROPY_FLOAT_C_FUN(fmod)(lhs_val, rhs_val);
            // Python specs require that mod has same sign as second operand
            if (lhs_val == 0.0) {
                lhs_val = MICROPY_FLOAT_C_FUN(copysign)(0.0, rhs_val);
            } else {
                if ((lhs_val < 0.0) != (rhs_val < 0.0)) {
                    lhs_val += rhs_val;
                }
            }
            break;
        case MP_BINARY_OP_POWER:
        case MP_BINARY_OP_INPLACE_POWER: lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val); break;
        case MP_BINARY_OP_LESS: return MP_BOOL(lhs_val < rhs_val);
        case MP_BINARY_OP_MORE: return MP_BOOL(lhs_val > rhs_val);
        case MP_BINARY_OP_EQUAL: return MP_BOOL(lhs_val == rhs_val);
        case MP_BINARY_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val);
        case MP_BINARY_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val);

        default:
            return MP_OBJ_NULL; // op not supported
    }
    return mp_obj_new_float(lhs_val);
}
示例#23
0
STATIC mp_obj_t return_ffi_value(ffi_arg val, char type)
{
    switch (type) {
        case 's': {
            const char *s = (const char *)val;
            return mp_obj_new_str(s, strlen(s), false);
        }
        case 'v':
            return mp_const_none;
        case 'f': {
            union { ffi_arg ffi; float flt; } val_union = { .ffi = val };
            return mp_obj_new_float(val_union.flt);
        }
        case 'd': {
            double *p = (double*)&val;
            return mp_obj_new_float(*p);
        }
        default:
            return mp_obj_new_int(val);
    }
}
示例#24
0
mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) {
    mp_int_t val = 0;
    switch (typecode) {
        case 'b':
            val = ((signed char*)p)[index];
            break;
        case BYTEARRAY_TYPECODE:
        case 'B':
            val = ((unsigned char*)p)[index];
            break;
        case 'h':
            val = ((short*)p)[index];
            break;
        case 'H':
            val = ((unsigned short*)p)[index];
            break;
        case 'i':
            return mp_obj_new_int(((int*)p)[index]);
        case 'I':
            return mp_obj_new_int_from_uint(((unsigned int*)p)[index]);
        case 'l':
            return mp_obj_new_int(((long*)p)[index]);
        case 'L':
            return mp_obj_new_int_from_uint(((unsigned long*)p)[index]);
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
        case 'q':
        case 'Q':
            // TODO: Explode API more to cover signedness
            return mp_obj_new_int_from_ll(((long long*)p)[index]);
#endif
#if MICROPY_PY_BUILTINS_FLOAT
        case 'f':
            return mp_obj_new_float(((float*)p)[index]);
        case 'd':
            return mp_obj_new_float(((double*)p)[index]);
#endif
    }
    return MP_OBJ_NEW_SMALL_INT(val);
}
示例#25
0
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);
}
示例#26
0
mp_obj_t ffifunc_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
    mp_obj_ffifunc_t *self = self_in;
    assert(n_kw == 0);
    assert(n_args == self->cif.nargs);

    ffi_arg values[n_args];
    void *valueptrs[n_args];
    int i;
    for (i = 0; i < n_args; i++) {
        mp_obj_t a = args[i];
        if (a == mp_const_none) {
            values[i] = 0;
        } else if (MP_OBJ_IS_INT(a)) {
            values[i] = mp_obj_int_get(a);
        } else if (MP_OBJ_IS_STR(a)) {
            const char *s = mp_obj_str_get_str(a);
            values[i] = (ffi_arg)s;
        } else if (((mp_obj_base_t*)a)->type->buffer_p.get_buffer != NULL) {
            mp_obj_base_t *o = (mp_obj_base_t*)a;
            mp_buffer_info_t bufinfo;
            int ret = o->type->buffer_p.get_buffer(o, &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ?
            if (ret != 0 || bufinfo.buf == NULL) {
                goto error;
            }
            values[i] = (ffi_arg)bufinfo.buf;
        } else if (MP_OBJ_IS_TYPE(a, &fficallback_type)) {
            mp_obj_fficallback_t *p = a;
            values[i] = (ffi_arg)p->func;
        } else {
            goto error;
        }
        valueptrs[i] = &values[i];
    }

    // If ffi_arg is not big enough to hold a double, then we must pass along a
    // pointer to a memory location of the correct size.
    // TODO check if this needs to be done for other types which don't fit into
    // ffi_arg.
    if (sizeof(ffi_arg) == 4 && self->rettype == 'd') {
        double retval;
        ffi_call(&self->cif, self->func, &retval, valueptrs);
        return mp_obj_new_float(retval);
    } else {
        ffi_arg retval;
        ffi_call(&self->cif, self->func, &retval, valueptrs);
        return return_ffi_value(retval, self->rettype);
    }

error:
    nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Don't know how to pass object to native function"));
}
示例#27
0
STATIC mp_obj_t float_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, 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
                uint l;
                const char *s = mp_obj_str_get_data(args[0], &l);
                return mp_parse_num_decimal(s, l, false, false);
            } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) {
                // 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]));
            }
    }
}
示例#28
0
mp_obj_t mp_binary_get_val(char typecode, void *p, int index) {
    machine_int_t val = 0;
    switch (typecode) {
        case 'b':
            val = ((int8_t*)p)[index];
            break;
        case BYTEARRAY_TYPECODE:
        case 'B':
            val = ((uint8_t*)p)[index];
            break;
        case 'h':
            val = ((int16_t*)p)[index];
            break;
        case 'H':
            val = ((uint16_t*)p)[index];
            break;
        case 'i':
        case 'l':
            return mp_obj_new_int(((int32_t*)p)[index]);
        case 'I':
        case 'L':
            return mp_obj_new_int_from_uint(((uint32_t*)p)[index]);
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
        case 'q':
        case 'Q':
            // TODO: Explode API more to cover signedness
            return mp_obj_new_int_from_ll(((long long*)p)[index]);
#endif
#if MICROPY_ENABLE_FLOAT
        case 'f':
            return mp_obj_new_float(((float*)p)[index]);
        case 'd':
            return mp_obj_new_float(((double*)p)[index]);
#endif
    }
    return MP_OBJ_NEW_SMALL_INT(val);
}
示例#29
0
mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) {
    mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible)
    switch (op) {
        case RT_BINARY_OP_ADD:
        case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;
        case RT_BINARY_OP_SUBTRACT:
        case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break;
        case RT_BINARY_OP_MULTIPLY:
        case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break;
        /* TODO floor(?) the value
        case RT_BINARY_OP_FLOOR_DIVIDE:
        case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break;
        */
        case RT_BINARY_OP_TRUE_DIVIDE:
        case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break;
        return NULL; // op not supported
    }
    return mp_obj_new_float(lhs_val);
}
示例#30
0
// Helper function to compute percentage from timer perion and PWM value.
STATIC mp_obj_t compute_percent_from_pwm_value(uint32_t period, uint32_t cmp) {
    #if MICROPY_PY_BUILTINS_FLOAT
    float percent = (float)cmp * 100.0 / (float)period;
    if (cmp >= period) {
        percent = 100.0;
    } else {
        percent = (float)cmp * 100.0 / (float)period;
    }
    return mp_obj_new_float(percent);
    #else
    mp_int_t percent;
    if (cmp >= period) {
        percent = 100;
    } else {
        percent = cmp * 100 / period;
    }
    return mp_obj_new_int(percent);
    #endif
}