summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/builtin.c12
-rw-r--r--py/builtin.h3
-rw-r--r--py/builtinmath.c81
-rw-r--r--py/builtinmp.c47
-rw-r--r--py/mpconfig.h20
-rw-r--r--py/obj.c8
-rw-r--r--py/obj.h21
-rw-r--r--py/objcomplex.c12
-rw-r--r--py/objfloat.c15
-rw-r--r--py/objfun.c2
-rw-r--r--py/objmodule.c42
-rw-r--r--py/py.mk1
-rw-r--r--py/qstrdefs.h29
-rw-r--r--py/runtime.c12
-rw-r--r--stm/Makefile1
-rw-r--r--stm/main.c25
-rw-r--r--stm/math.c48
-rw-r--r--stm/mpconfigport.h5
-rw-r--r--unix/main.c6
-rw-r--r--unix/mpconfigport.h5
-rw-r--r--unix/time.c2
21 files changed, 280 insertions, 117 deletions
diff --git a/py/builtin.c b/py/builtin.c
index ef9e70c940..df488e054a 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -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);
diff --git a/py/builtin.h b/py/builtin.h
index 85ceeafdf4..d9414045de 100644
--- a/py/builtin.h
+++ b/py/builtin.h
@@ -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;
diff --git a/py/builtinmath.c b/py/builtinmath.c
new file mode 100644
index 0000000000..cccda9d486
--- /dev/null
+++ b/py/builtinmath.c
@@ -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
diff --git a/py/builtinmp.c b/py/builtinmp.c
index 28bea3b840..22091f4ea5 100644
--- a/py/builtinmp.c
+++ b/py/builtinmp.c
@@ -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,
+};
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 34c83d3245..5b13c46480 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -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
diff --git a/py/obj.c b/py/obj.c
index 0068af4c43..0c97ee5aa3 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -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)));
diff --git a/py/obj.h b/py/obj.h
index 2ccda66ee7..4d93c7afad 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -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);
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 188c334132..bba89daf00 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -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;
diff --git a/py/objfloat.c b/py/objfloat.c
index 268bc2bde5..8ba9946b7e 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -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;
}
diff --git a/py/objfun.c b/py/objfun.c
index 80cee1643b..361df19145 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -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
diff --git a/py/objmodule.c b/py/objmodule.c
index ab460fbd39..791932dc7f 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -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;
}
diff --git a/py/py.mk b/py/py.mk
index 72ac785b56..579375e7d2 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -73,6 +73,7 @@ PY_O_BASENAME = \
builtinimport.o \
builtinevex.o \
builtinmp.o \
+ builtinmath.o \
vm.o \
showbc.o \
repl.o \
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index f1ba14ae60..8025b9bccc 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -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>)
diff --git a/py/runtime.c b/py/runtime.c
index 9d41f059f5..7034ce13c0 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -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
}
diff --git a/stm/Makefile b/stm/Makefile
index cc16eda437..1675c22aba 100644
--- a/stm/Makefile
+++ b/stm/Makefile
@@ -47,6 +47,7 @@ LIBS =
SRC_C = \
main.c \
printf.c \
+ math.c \
system_stm32f4xx.c \
stm32fxxx_it.c \
string0.c \
diff --git a/stm/main.c b/stm/main.c
index e5f5d4e763..bab8933b1e 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -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;
-}
diff --git a/stm/math.c b/stm/math.c
new file mode 100644
index 0000000000..ac680f6b7b
--- /dev/null
+++ b/stm/math.c
@@ -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; }
diff --git a/stm/mpconfigport.h b/stm/mpconfigport.h
index 9cbda9c6c2..3f48c43f04 100644
--- a/stm/mpconfigport.h
+++ b/stm/mpconfigport.h
@@ -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
diff --git a/unix/main.c b/unix/main.c
index fb0a6ecf07..481b815810 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -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) {
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index 99c13a7dc6..8950337d4a 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -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;
diff --git a/unix/time.c b/unix/time.c
index 6dba9f0d09..1abd7cff39 100644
--- a/unix/time.c
+++ b/unix/time.c
@@ -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;