summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-03-08 15:24:39 +0000
committerDamien George <damien.p.george@gmail.com>2014-03-08 15:24:39 +0000
commit0c36da0b59bd3d5aeb6f7bd7f75913695a1dd366 (patch)
treeeb1d8e50037139646f935df99da56764fcafb4f1 /py
parent8fd7d7e102372a3fe067030aa0f2049f744b1567 (diff)
downloadmicropython-0c36da0b59bd3d5aeb6f7bd7f75913695a1dd366.tar.gz
micropython-0c36da0b59bd3d5aeb6f7bd7f75913695a1dd366.zip
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).
Diffstat (limited to 'py')
-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
14 files changed, 228 insertions, 77 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
}