diff options
author | Damien George <damien.p.george@gmail.com> | 2014-03-08 15:24:39 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-03-08 15:24:39 +0000 |
commit | 0c36da0b59bd3d5aeb6f7bd7f75913695a1dd366 (patch) | |
tree | eb1d8e50037139646f935df99da56764fcafb4f1 /py | |
parent | 8fd7d7e102372a3fe067030aa0f2049f744b1567 (diff) | |
download | micropython-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.c | 12 | ||||
-rw-r--r-- | py/builtin.h | 3 | ||||
-rw-r--r-- | py/builtinmath.c | 81 | ||||
-rw-r--r-- | py/builtinmp.c | 47 | ||||
-rw-r--r-- | py/mpconfig.h | 20 | ||||
-rw-r--r-- | py/obj.c | 8 | ||||
-rw-r--r-- | py/obj.h | 21 | ||||
-rw-r--r-- | py/objcomplex.c | 12 | ||||
-rw-r--r-- | py/objfloat.c | 15 | ||||
-rw-r--r-- | py/objfun.c | 2 | ||||
-rw-r--r-- | py/objmodule.c | 42 | ||||
-rw-r--r-- | py/py.mk | 1 | ||||
-rw-r--r-- | py/qstrdefs.h | 29 | ||||
-rw-r--r-- | py/runtime.c | 12 |
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 @@ -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))); @@ -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; } @@ -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 } |