Implement ROMable modules. Add math module.

mp_module_obj_t can now be put in ROM.

Configuration of float type is now similar to longint: can now choose
none, float or double as the implementation.

math module has basic math functions.  For STM port, these are not yet
implemented (they are just stub functions).
This commit is contained in:
Damien George 2014-03-08 15:24:39 +00:00
parent 8fd7d7e102
commit 0c36da0b59
21 changed files with 280 additions and 117 deletions

View File

@ -15,6 +15,10 @@
#include "map.h"
#include "builtin.h"
#if MICROPY_ENABLE_FLOAT
#include <math.h>
#endif
// args[0] is function from class body
// args[1] is class name
// args[2:] are base objects
@ -79,7 +83,7 @@ mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
}
return MP_OBJ_NEW_SMALL_INT(val);
#if MICROPY_ENABLE_FLOAT
} else if (MP_OBJ_IS_TYPE(o_in, &float_type)) {
} 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) {
@ -87,10 +91,10 @@ mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
} else {
return o_in;
}
} else if (MP_OBJ_IS_TYPE(o_in, &complex_type)) {
} 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(machine_sqrt(real*real + imag*imag));
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag));
#endif
} else {
assert(0);
@ -158,7 +162,7 @@ STATIC mp_obj_t mp_builtin_dir(uint n_args, const mp_obj_t *args) {
} else { // n_args == 1
// make a list of names in the given object
mp_obj_type_t *type = mp_obj_get_type(args[0]);
if (type == &module_type) {
if (type == &mp_type_module) {
map = mp_obj_module_get_globals(args[0]);
} else if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &dict_type)) {
map = mp_obj_dict_get_map(type->locals_dict);

View File

@ -34,4 +34,5 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_str_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj);
void mp_module_micropython_init(void);
extern const mp_obj_module_t mp_module_math;
extern const mp_obj_module_t mp_module_micropython;

81
py/builtinmath.c Normal file
View File

@ -0,0 +1,81 @@
#include <stdint.h>
#include <math.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "map.h"
#include "builtin.h"
#if MICROPY_ENABLE_FLOAT
#define MATH_FUN_1(py_name, c_name) \
mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
#define MATH_FUN_2(py_name, c_name) \
mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
STATIC const mp_obj_float_t mp_math_pi_obj = {{&mp_type_float}, M_PI};
MATH_FUN_1(sqrt, sqrt)
MATH_FUN_2(pow, pow)
MATH_FUN_1(exp, exp)
MATH_FUN_1(log, log)
MATH_FUN_1(log2, log2)
MATH_FUN_1(log10, log10)
MATH_FUN_1(cosh, cosh)
MATH_FUN_1(sinh, sinh)
MATH_FUN_1(tanh, tanh)
MATH_FUN_1(acosh, acosh)
MATH_FUN_1(asinh, asinh)
MATH_FUN_1(atanh, atanh)
MATH_FUN_1(cos, cos)
MATH_FUN_1(sin, sin)
MATH_FUN_1(tan, tan)
MATH_FUN_1(acos, acos)
MATH_FUN_1(asin, asin)
MATH_FUN_1(atan, atan)
MATH_FUN_2(atan2, atan2)
STATIC const mp_map_elem_t mp_module_math_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_math) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_pi), (mp_obj_t)&mp_math_pi_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&mp_math_sqrt_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_pow), (mp_obj_t)&mp_math_pow_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&mp_math_exp_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&mp_math_log_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&mp_math_log2_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&mp_math_log10_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_cosh), (mp_obj_t)&mp_math_cosh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&mp_math_sinh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&mp_math_tanh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&mp_math_acosh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&mp_math_asinh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&mp_math_atanh_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&mp_math_cos_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&mp_math_sin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&mp_math_tan_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&mp_math_acos_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&mp_math_asin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&mp_math_atan_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan2), (mp_obj_t)&mp_math_atan2_obj },
};
STATIC const mp_map_t mp_module_math_globals = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t),
.alloc = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t),
.table = (mp_map_elem_t*)mp_module_math_globals_table,
};
const mp_obj_module_t mp_module_math = {
.base = { &mp_type_module },
.name = MP_QSTR_math,
.globals = (mp_map_t*)&mp_module_math_globals,
};
#endif // MICROPY_ENABLE_FLOAT

View File

@ -1,45 +1,52 @@
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "map.h"
#include "builtin.h"
// Various builtins specific to MicroPython runtime,
// living in micropython module
#if MICROPY_MEM_STATS
STATIC mp_obj_t mem_total() {
STATIC mp_obj_t mp_micropython_mem_total() {
return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_total_bytes_allocated());
}
STATIC mp_obj_t mem_current() {
STATIC mp_obj_t mp_micropython_mem_current() {
return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_current_bytes_allocated());
}
STATIC mp_obj_t mem_peak() {
STATIC mp_obj_t mp_micropython_mem_peak() {
return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_peak_bytes_allocated());
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_mem_total_obj, mem_total);
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_mem_current_obj, mem_current);
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_mem_peak_obj, mem_peak);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_total_obj, mp_micropython_mem_total);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_current_obj, mp_micropython_mem_current);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_peak_obj, mp_micropython_mem_peak);
#endif
void mp_module_micropython_init(void) {
mp_obj_t m_mp = mp_obj_new_module(MP_QSTR_micropython);
rt_store_name(MP_QSTR_micropython, m_mp);
STATIC const mp_map_elem_t mp_module_micropython_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_micropython) },
#if MICROPY_MEM_STATS
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_total"), (mp_obj_t)&mp_builtin_mem_total_obj);
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_current"), (mp_obj_t)&mp_builtin_mem_current_obj);
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_peak"), (mp_obj_t)&mp_builtin_mem_peak_obj);
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_total), (mp_obj_t)&mp_micropython_mem_total_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_current), (mp_obj_t)&mp_micropython_mem_current_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_peak), (mp_obj_t)&mp_micropython_mem_peak_obj },
#endif
}
};
STATIC const mp_map_t mp_module_micropython_globals = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t),
.alloc = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t),
.table = (mp_map_elem_t*)mp_module_micropython_globals_table,
};
const mp_obj_module_t mp_module_micropython = {
.base = { &mp_type_module },
.name = MP_QSTR_micropython,
.globals = (mp_map_t*)&mp_module_micropython_globals,
};

View File

@ -84,8 +84,24 @@ typedef long long mp_longint_impl_t;
#define MICROPY_ENABLE_SOURCE_LINE (0)
#endif
// Whether to support float and complex types
#ifndef MICROPY_ENABLE_FLOAT
// Float and complex implementation
#define MICROPY_FLOAT_IMPL_NONE (0)
#define MICROPY_FLOAT_IMPL_FLOAT (1)
#define MICROPY_FLOAT_IMPL_DOUBLE (2)
#ifndef MICROPY_FLOAT_IMPL
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
#endif
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
#define MICROPY_ENABLE_FLOAT (1)
#define MICROPY_FLOAT_C_FUN(fun) fun##f
typedef float mp_float_t;
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
#define MICROPY_ENABLE_FLOAT (1)
#define MICROPY_FLOAT_C_FUN(fun) fun
typedef double mp_float_t;
#else
#define MICROPY_ENABLE_FLOAT (0)
#endif

View File

@ -165,14 +165,14 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) {
}
#if MICROPY_ENABLE_FLOAT
machine_float_t mp_obj_get_float(mp_obj_t arg) {
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, &float_type)) {
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
return mp_obj_float_get(arg);
} else {
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg)));
@ -189,10 +189,10 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
*real = MP_OBJ_SMALL_INT_VALUE(arg);
*imag = 0;
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
*real = mp_obj_float_get(arg);
*imag = 0;
} else if (MP_OBJ_IS_TYPE(arg, &complex_type)) {
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) {
mp_obj_complex_get(arg, real, imag);
} else {
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));

View File

@ -9,12 +9,6 @@ typedef machine_const_ptr_t mp_const_obj_t;
typedef machine_int_t mp_small_int_t;
// The machine floating-point type used for float and complex numbers
#if MICROPY_ENABLE_FLOAT
typedef machine_float_t mp_float_t;
#endif
// Anything that wants to be a Micro Python object must have
// mp_obj_base_t as its first member (except NULL and small ints)
@ -318,12 +312,16 @@ extern const mp_obj_type_t bytes_type;
#if MICROPY_ENABLE_FLOAT
// float
extern const mp_obj_type_t float_type;
typedef struct _mp_obj_float_t {
mp_obj_base_t base;
mp_float_t value;
} mp_obj_float_t;
extern const mp_obj_type_t mp_type_float;
mp_float_t mp_obj_float_get(mp_obj_t self_in);
mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs);
// complex
extern const mp_obj_type_t complex_type;
extern const mp_obj_type_t mp_type_complex;
void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
mp_obj_t mp_obj_complex_binary_op(int op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in);
#endif
@ -398,7 +396,12 @@ extern const mp_obj_type_t super_type;
extern const mp_obj_type_t gen_instance_type;
// module
extern const mp_obj_type_t module_type;
typedef struct _mp_obj_module_t {
mp_obj_base_t base;
qstr name;
struct _mp_map_t *globals;
} mp_obj_module_t;
extern const mp_obj_type_t mp_type_module;
mp_obj_t mp_obj_new_module(qstr module_name);
mp_obj_t mp_obj_module_get(qstr module_name);
struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);

View File

@ -39,7 +39,7 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
case 1:
// TODO allow string as first arg and parse it
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
return args[0];
} else {
return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
@ -48,13 +48,13 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
case 2:
{
mp_float_t real, imag;
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
mp_obj_complex_get(args[0], &real, &imag);
} else {
real = mp_obj_get_float(args[0]);
imag = 0;
}
if (MP_OBJ_IS_TYPE(args[1], &complex_type)) {
if (MP_OBJ_IS_TYPE(args[1], &mp_type_complex)) {
mp_float_t real2, imag2;
mp_obj_complex_get(args[1], &real2, &imag2);
real -= imag2;
@ -85,7 +85,7 @@ STATIC mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
return mp_obj_complex_binary_op(op, lhs->real, lhs->imag, rhs_in);
}
const mp_obj_type_t complex_type = {
const mp_obj_type_t mp_type_complex = {
{ &mp_type_type },
.name = MP_QSTR_complex,
.print = complex_print,
@ -96,14 +96,14 @@ const mp_obj_type_t complex_type = {
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) {
mp_obj_complex_t *o = m_new_obj(mp_obj_complex_t);
o->base.type = &complex_type;
o->base.type = &mp_type_complex;
o->real = real;
o->imag = imag;
return o;
}
void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) {
assert(MP_OBJ_IS_TYPE(self_in, &complex_type));
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_complex));
mp_obj_complex_t *self = self_in;
*real = self->real;
*imag = self->imag;

View File

@ -13,11 +13,6 @@
#if MICROPY_ENABLE_FLOAT
typedef struct _mp_obj_float_t {
mp_obj_base_t base;
mp_float_t value;
} mp_obj_float_t;
mp_obj_t mp_obj_new_float(mp_float_t value);
STATIC void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
@ -38,7 +33,7 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
uint l;
const char *s = mp_obj_str_get_data(args[0], &l);
return mp_parse_num_decimal(s, l);
} else if (MP_OBJ_IS_TYPE(args[0], &float_type)) {
} else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) {
return args[0];
} else {
return mp_obj_new_float(mp_obj_get_float(args[0]));
@ -61,14 +56,14 @@ STATIC mp_obj_t float_unary_op(int op, mp_obj_t o_in) {
STATIC mp_obj_t float_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
mp_obj_float_t *lhs = lhs_in;
if (MP_OBJ_IS_TYPE(rhs_in, &complex_type)) {
if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) {
return mp_obj_complex_binary_op(op, lhs->value, 0, rhs_in);
} else {
return mp_obj_float_binary_op(op, lhs->value, rhs_in);
}
}
const mp_obj_type_t float_type = {
const mp_obj_type_t mp_type_float = {
{ &mp_type_type },
.name = MP_QSTR_float,
.print = float_print,
@ -79,13 +74,13 @@ const mp_obj_type_t float_type = {
mp_obj_t mp_obj_new_float(mp_float_t value) {
mp_obj_float_t *o = m_new(mp_obj_float_t, 1);
o->base.type = &float_type;
o->base.type = &mp_type_float;
o->value = value;
return (mp_obj_t)o;
}
mp_float_t mp_obj_float_get(mp_obj_t self_in) {
assert(MP_OBJ_IS_TYPE(self_in, &float_type));
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_float));
mp_obj_float_t *self = self_in;
return self->value;
}

View File

@ -372,7 +372,7 @@ STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) {
uint l;
return (machine_uint_t)mp_obj_str_get_data(obj, &l);
#if MICROPY_ENABLE_FLOAT
} else if (MP_OBJ_IS_TYPE(obj, &float_type)) {
} else if (MP_OBJ_IS_TYPE(obj, &mp_type_float)) {
// convert float to int (could also pass in float registers)
return (machine_int_t)mp_obj_float_get(obj);
#endif

View File

@ -10,12 +10,7 @@
#include "obj.h"
#include "runtime.h"
#include "map.h"
typedef struct _mp_obj_module_t {
mp_obj_base_t base;
qstr name;
mp_map_t *globals;
} mp_obj_module_t;
#include "builtin.h"
STATIC void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_module_t *self = self_in;
@ -37,7 +32,7 @@ STATIC bool module_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
return true;
}
const mp_obj_type_t module_type = {
const mp_obj_type_t mp_type_module = {
{ &mp_type_type },
.name = MP_QSTR_module,
.print = module_print,
@ -46,32 +41,51 @@ const mp_obj_type_t module_type = {
};
mp_obj_t mp_obj_new_module(qstr module_name) {
mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
// We could error out if module already exists, but let C extensions
// add new members to existing modules.
if (el->value != MP_OBJ_NULL) {
return el->value;
}
// create new module object
mp_obj_module_t *o = m_new_obj(mp_obj_module_t);
o->base.type = &module_type;
o->base.type = &mp_type_module;
o->name = module_name;
o->globals = mp_map_new(1);
el->value = o;
// store __name__ entry in the module
mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = MP_OBJ_NEW_QSTR(module_name);
// store the new module into the slot in the global dict holding all modules
el->value = o;
// return the new module
return o;
}
mp_obj_t mp_obj_module_get(qstr module_name) {
// lookup module
mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
if (el == NULL) {
return MP_OBJ_NULL;
// module found, return it
if (el != NULL) {
return el->value;
}
return el->value;
// module not found, look for builtin module names
#if MICROPY_ENABLE_FLOAT
if (module_name == MP_QSTR_math) {
return (mp_obj_t)&mp_module_math;
}
#endif
// no module found, return NULL object
return MP_OBJ_NULL;
}
mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) {
assert(MP_OBJ_IS_TYPE(self_in, &module_type));
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module));
mp_obj_module_t *self = self_in;
return self->globals;
}

View File

@ -73,6 +73,7 @@ PY_O_BASENAME = \
builtinimport.o \
builtinevex.o \
builtinmp.o \
builtinmath.o \
vm.o \
showbc.o \
repl.o \

View File

@ -1,5 +1,6 @@
// All the qstr definitions in this file are available as constants.
// That is, they are in ROM and you can reference them simple as MP_QSTR_xxxx.
// That is, they are in ROM and you can reference them simply as MP_QSTR_xxxx.
// TODO make it so we can use #defines here to select only those words that will be used
Q(__build_class__)
Q(__class__)
@ -115,6 +116,32 @@ Q(iterator)
Q(module)
Q(slice)
Q(math)
Q(pi)
Q(sqrt)
Q(pow)
Q(exp)
Q(log)
Q(log2)
Q(log10)
Q(cosh)
Q(sinh)
Q(tanh)
Q(acosh)
Q(asinh)
Q(atanh)
Q(cos)
Q(sin)
Q(tan)
Q(acos)
Q(asin)
Q(atan)
Q(atan2)
Q(mem_total)
Q(mem_current)
Q(mem_peak)
Q(<module>)
Q(<lambda>)
Q(<listcomp>)

View File

@ -92,13 +92,13 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
// built-in types
{ MP_QSTR_bool, (mp_obj_t)&bool_type },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_complex, (mp_obj_t)&complex_type },
{ MP_QSTR_complex, (mp_obj_t)&mp_type_complex },
#endif
{ MP_QSTR_dict, (mp_obj_t)&dict_type },
{ MP_QSTR_enumerate, (mp_obj_t)&enumerate_type },
{ MP_QSTR_filter, (mp_obj_t)&filter_type },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_float, (mp_obj_t)&float_type },
{ MP_QSTR_float, (mp_obj_t)&mp_type_float },
#endif
{ MP_QSTR_int, (mp_obj_t)&int_type },
{ MP_QSTR_list, (mp_obj_t)&list_type },
@ -203,7 +203,9 @@ void rt_init(void) {
//sys_path = mp_obj_new_list(0, NULL);
//rt_store_attr(m_sys, MP_QSTR_path, sys_path);
mp_module_micropython_init();
// we pre-import the micropython module
// probably shouldn't do this, so we are compatible with CPython
rt_store_name(MP_QSTR_micropython, (mp_obj_t)&mp_module_micropython);
// TODO: wastes one mp_code_t structure in mem
next_unique_code_id = 1; // 0 indicates "no code"
@ -586,9 +588,9 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
}
return mp_obj_new_int(lhs_val);
#if MICROPY_ENABLE_FLOAT
} else if (MP_OBJ_IS_TYPE(rhs, &float_type)) {
} else if (MP_OBJ_IS_TYPE(rhs, &mp_type_float)) {
return mp_obj_float_binary_op(op, lhs_val, rhs);
} else if (MP_OBJ_IS_TYPE(rhs, &complex_type)) {
} else if (MP_OBJ_IS_TYPE(rhs, &mp_type_complex)) {
return mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
#endif
}

View File

@ -47,6 +47,7 @@ LIBS =
SRC_C = \
main.c \
printf.c \
math.c \
system_stm32f4xx.c \
stm32fxxx_it.c \
string0.c \

View File

@ -666,28 +666,3 @@ soft_reset:
first_soft_reset = false;
goto soft_reset;
}
// these 2 functions seem to actually work... no idea why
// replacing with libgcc does not work (probably due to wrong calling conventions)
double __aeabi_f2d(float x) {
// TODO
return 0.0;
}
float __aeabi_d2f(double x) {
// TODO
return 0.0;
}
double sqrt(double x) {
// TODO
return 0.0;
}
machine_float_t machine_sqrt(machine_float_t x) {
asm volatile (
"vsqrt.f32 %[r], %[x]\n"
: [r] "=t" (x)
: [x] "t" (x));
return x;
}

48
stm/math.c Normal file
View File

@ -0,0 +1,48 @@
#include <math.h>
// these 2 functions seem to actually work... no idea why
// replacing with libgcc does not work (probably due to wrong calling conventions)
double __aeabi_f2d(float x) {
// TODO
return 0.0;
}
float __aeabi_d2f(double x) {
// TODO
return 0.0;
}
/*
double sqrt(double x) {
// TODO
return 0.0;
}
*/
float sqrtf(float x) {
asm volatile (
"vsqrt.f32 %[r], %[x]\n"
: [r] "=t" (x)
: [x] "t" (x));
return x;
}
// TODO we need import these functions from some library (eg musl or newlib)
float powf(float x, float y) { return 0.0; }
float expf(float x) { return 0.0; }
float logf(float x) { return 0.0; }
float log2f(float x) { return 0.0; }
float log10f(float x) { return 0.0; }
float coshf(float x) { return 0.0; }
float sinhf(float x) { return 0.0; }
float tanhf(float x) { return 0.0; }
float acoshf(float x) { return 0.0; }
float asinhf(float x) { return 0.0; }
float atanhf(float x) { return 0.0; }
float cosf(float x) { return 0.0; }
float sinf(float x) { return 0.0; }
float tanf(float x) { return 0.0; }
float acosf(float x) { return 0.0; }
float asinf(float x) { return 0.0; }
float atanf(float x) { return 0.0; }
float atan2f(float x, float y) { return 0.0; }

View File

@ -6,8 +6,8 @@
#define MICROPY_EMIT_INLINE_THUMB (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_REPL_HELPERS (1)
#define MICROPY_ENABLE_FLOAT (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#define MICROPY_PATH_MAX (128)
/* Enable FatFS LFNs
0: Disable LFN feature.
@ -29,9 +29,6 @@ typedef int32_t machine_int_t; // must be pointer size
typedef uint32_t machine_uint_t; // must be pointer size
typedef void *machine_ptr_t; // must be of pointer size
typedef const void *machine_const_ptr_t; // must be of pointer size
typedef float machine_float_t;
machine_float_t machine_sqrt(machine_float_t x);
// There is no classical C heap in bare-metal ports, only Python
// garbage-collected heap. For completeness, emulate C heap via

View File

@ -383,12 +383,6 @@ int main(int argc, char **argv) {
return 0;
}
// for sqrt
#include <math.h>
machine_float_t machine_sqrt(machine_float_t x) {
return sqrt(x);
}
#include <sys/stat.h>
uint mp_import_stat(const char *path) {

View File

@ -8,7 +8,7 @@
#define MICROPY_ENABLE_REPL_HELPERS (1)
#define MICROPY_ENABLE_LEXER_UNIX (1)
#define MICROPY_ENABLE_SOURCE_LINE (1)
#define MICROPY_ENABLE_FLOAT (1)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_PATH_MAX (PATH_MAX)
@ -28,9 +28,6 @@ typedef unsigned int machine_uint_t; // must be pointer size
typedef void *machine_ptr_t; // must be of pointer size
typedef const void *machine_const_ptr_t; // must be of pointer size
typedef double machine_float_t;
machine_float_t machine_sqrt(machine_float_t x);
struct _mp_obj_fun_native_t;
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;

View File

@ -28,7 +28,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(mod_time_clock_obj, mod_time_clock);
static mp_obj_t mod_time_sleep(mp_obj_t arg) {
#if MICROPY_ENABLE_FLOAT
struct timeval tv;
machine_float_t val = mp_obj_get_float(arg);
mp_float_t val = mp_obj_get_float(arg);
double ipart;
tv.tv_usec = round(modf(val, &ipart) * 1000000);
tv.tv_sec = ipart;