Skip to content

Commit 0c36da0

Browse files
committed
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).
1 parent 8fd7d7e commit 0c36da0

File tree

21 files changed

+280
-117
lines changed

21 files changed

+280
-117
lines changed

py/builtin.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#include "map.h"
1616
#include "builtin.h"
1717

18+
#if MICROPY_ENABLE_FLOAT
19+
#include <math.h>
20+
#endif
21+
1822
// args[0] is function from class body
1923
// args[1] is class name
2024
// args[2:] are base objects
@@ -79,18 +83,18 @@ mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
7983
}
8084
return MP_OBJ_NEW_SMALL_INT(val);
8185
#if MICROPY_ENABLE_FLOAT
82-
} else if (MP_OBJ_IS_TYPE(o_in, &float_type)) {
86+
} else if (MP_OBJ_IS_TYPE(o_in, &mp_type_float)) {
8387
mp_float_t value = mp_obj_float_get(o_in);
8488
// TODO check for NaN etc
8589
if (value < 0) {
8690
return mp_obj_new_float(-value);
8791
} else {
8892
return o_in;
8993
}
90-
} else if (MP_OBJ_IS_TYPE(o_in, &complex_type)) {
94+
} else if (MP_OBJ_IS_TYPE(o_in, &mp_type_complex)) {
9195
mp_float_t real, imag;
9296
mp_obj_complex_get(o_in, &real, &imag);
93-
return mp_obj_new_float(machine_sqrt(real*real + imag*imag));
97+
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag));
9498
#endif
9599
} else {
96100
assert(0);
@@ -158,7 +162,7 @@ STATIC mp_obj_t mp_builtin_dir(uint n_args, const mp_obj_t *args) {
158162
} else { // n_args == 1
159163
// make a list of names in the given object
160164
mp_obj_type_t *type = mp_obj_get_type(args[0]);
161-
if (type == &module_type) {
165+
if (type == &mp_type_module) {
162166
map = mp_obj_module_get_globals(args[0]);
163167
} else if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &dict_type)) {
164168
map = mp_obj_dict_get_map(type->locals_dict);

py/builtin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_str_obj);
3434

3535
MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj);
3636

37-
void mp_module_micropython_init(void);
37+
extern const mp_obj_module_t mp_module_math;
38+
extern const mp_obj_module_t mp_module_micropython;

py/builtinmath.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include <stdint.h>
2+
#include <math.h>
3+
4+
#include "misc.h"
5+
#include "mpconfig.h"
6+
#include "qstr.h"
7+
#include "obj.h"
8+
#include "map.h"
9+
#include "builtin.h"
10+
11+
#if MICROPY_ENABLE_FLOAT
12+
13+
#define MATH_FUN_1(py_name, c_name) \
14+
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))); } \
15+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
16+
17+
#define MATH_FUN_2(py_name, c_name) \
18+
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))); } \
19+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
20+
21+
STATIC const mp_obj_float_t mp_math_pi_obj = {{&mp_type_float}, M_PI};
22+
23+
MATH_FUN_1(sqrt, sqrt)
24+
MATH_FUN_2(pow, pow)
25+
MATH_FUN_1(exp, exp)
26+
MATH_FUN_1(log, log)
27+
MATH_FUN_1(log2, log2)
28+
MATH_FUN_1(log10, log10)
29+
MATH_FUN_1(cosh, cosh)
30+
MATH_FUN_1(sinh, sinh)
31+
MATH_FUN_1(tanh, tanh)
32+
MATH_FUN_1(acosh, acosh)
33+
MATH_FUN_1(asinh, asinh)
34+
MATH_FUN_1(atanh, atanh)
35+
MATH_FUN_1(cos, cos)
36+
MATH_FUN_1(sin, sin)
37+
MATH_FUN_1(tan, tan)
38+
MATH_FUN_1(acos, acos)
39+
MATH_FUN_1(asin, asin)
40+
MATH_FUN_1(atan, atan)
41+
MATH_FUN_2(atan2, atan2)
42+
43+
STATIC const mp_map_elem_t mp_module_math_globals_table[] = {
44+
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_math) },
45+
{ MP_OBJ_NEW_QSTR(MP_QSTR_pi), (mp_obj_t)&mp_math_pi_obj },
46+
{ MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&mp_math_sqrt_obj },
47+
{ MP_OBJ_NEW_QSTR(MP_QSTR_pow), (mp_obj_t)&mp_math_pow_obj },
48+
{ MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&mp_math_exp_obj },
49+
{ MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&mp_math_log_obj },
50+
{ MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&mp_math_log2_obj },
51+
{ MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&mp_math_log10_obj },
52+
{ MP_OBJ_NEW_QSTR(MP_QSTR_cosh), (mp_obj_t)&mp_math_cosh_obj },
53+
{ MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&mp_math_sinh_obj },
54+
{ MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&mp_math_tanh_obj },
55+
{ MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&mp_math_acosh_obj },
56+
{ MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&mp_math_asinh_obj },
57+
{ MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&mp_math_atanh_obj },
58+
{ MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&mp_math_cos_obj },
59+
{ MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&mp_math_sin_obj },
60+
{ MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&mp_math_tan_obj },
61+
{ MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&mp_math_acos_obj },
62+
{ MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&mp_math_asin_obj },
63+
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&mp_math_atan_obj },
64+
{ MP_OBJ_NEW_QSTR(MP_QSTR_atan2), (mp_obj_t)&mp_math_atan2_obj },
65+
};
66+
67+
STATIC const mp_map_t mp_module_math_globals = {
68+
.all_keys_are_qstrs = 1,
69+
.table_is_fixed_array = 1,
70+
.used = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t),
71+
.alloc = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t),
72+
.table = (mp_map_elem_t*)mp_module_math_globals_table,
73+
};
74+
75+
const mp_obj_module_t mp_module_math = {
76+
.base = { &mp_type_module },
77+
.name = MP_QSTR_math,
78+
.globals = (mp_map_t*)&mp_module_math_globals,
79+
};
80+
81+
#endif // MICROPY_ENABLE_FLOAT

py/builtinmp.c

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,52 @@
11
#include <stdint.h>
2-
#include <stdlib.h>
3-
#include <stdio.h>
4-
#include <stdarg.h>
5-
#include <string.h>
6-
#include <assert.h>
72

83
#include "misc.h"
94
#include "mpconfig.h"
105
#include "qstr.h"
116
#include "obj.h"
12-
#include "runtime.h"
7+
#include "map.h"
138
#include "builtin.h"
149

1510
// Various builtins specific to MicroPython runtime,
1611
// living in micropython module
1712

1813
#if MICROPY_MEM_STATS
19-
STATIC mp_obj_t mem_total() {
14+
STATIC mp_obj_t mp_micropython_mem_total() {
2015
return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_total_bytes_allocated());
2116
}
2217

23-
STATIC mp_obj_t mem_current() {
18+
STATIC mp_obj_t mp_micropython_mem_current() {
2419
return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_current_bytes_allocated());
2520
}
2621

27-
STATIC mp_obj_t mem_peak() {
22+
STATIC mp_obj_t mp_micropython_mem_peak() {
2823
return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_peak_bytes_allocated());
2924
}
3025

31-
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_mem_total_obj, mem_total);
32-
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_mem_current_obj, mem_current);
33-
MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_mem_peak_obj, mem_peak);
26+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_total_obj, mp_micropython_mem_total);
27+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_current_obj, mp_micropython_mem_current);
28+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_peak_obj, mp_micropython_mem_peak);
3429
#endif
3530

36-
void mp_module_micropython_init(void) {
37-
mp_obj_t m_mp = mp_obj_new_module(MP_QSTR_micropython);
38-
rt_store_name(MP_QSTR_micropython, m_mp);
39-
31+
STATIC const mp_map_elem_t mp_module_micropython_globals_table[] = {
32+
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_micropython) },
4033
#if MICROPY_MEM_STATS
41-
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_total"), (mp_obj_t)&mp_builtin_mem_total_obj);
42-
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_current"), (mp_obj_t)&mp_builtin_mem_current_obj);
43-
rt_store_attr(m_mp, QSTR_FROM_STR_STATIC("mem_peak"), (mp_obj_t)&mp_builtin_mem_peak_obj);
34+
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_total), (mp_obj_t)&mp_micropython_mem_total_obj },
35+
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_current), (mp_obj_t)&mp_micropython_mem_current_obj },
36+
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_peak), (mp_obj_t)&mp_micropython_mem_peak_obj },
4437
#endif
45-
}
38+
};
39+
40+
STATIC const mp_map_t mp_module_micropython_globals = {
41+
.all_keys_are_qstrs = 1,
42+
.table_is_fixed_array = 1,
43+
.used = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t),
44+
.alloc = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t),
45+
.table = (mp_map_elem_t*)mp_module_micropython_globals_table,
46+
};
47+
48+
const mp_obj_module_t mp_module_micropython = {
49+
.base = { &mp_type_module },
50+
.name = MP_QSTR_micropython,
51+
.globals = (mp_map_t*)&mp_module_micropython_globals,
52+
};

py/mpconfig.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,24 @@ typedef long long mp_longint_impl_t;
8484
#define MICROPY_ENABLE_SOURCE_LINE (0)
8585
#endif
8686

87-
// Whether to support float and complex types
88-
#ifndef MICROPY_ENABLE_FLOAT
87+
// Float and complex implementation
88+
#define MICROPY_FLOAT_IMPL_NONE (0)
89+
#define MICROPY_FLOAT_IMPL_FLOAT (1)
90+
#define MICROPY_FLOAT_IMPL_DOUBLE (2)
91+
92+
#ifndef MICROPY_FLOAT_IMPL
93+
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
94+
#endif
95+
96+
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
97+
#define MICROPY_ENABLE_FLOAT (1)
98+
#define MICROPY_FLOAT_C_FUN(fun) fun##f
99+
typedef float mp_float_t;
100+
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
101+
#define MICROPY_ENABLE_FLOAT (1)
102+
#define MICROPY_FLOAT_C_FUN(fun) fun
103+
typedef double mp_float_t;
104+
#else
89105
#define MICROPY_ENABLE_FLOAT (0)
90106
#endif
91107

py/obj.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,14 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) {
165165
}
166166

167167
#if MICROPY_ENABLE_FLOAT
168-
machine_float_t mp_obj_get_float(mp_obj_t arg) {
168+
mp_float_t mp_obj_get_float(mp_obj_t arg) {
169169
if (arg == mp_const_false) {
170170
return 0;
171171
} else if (arg == mp_const_true) {
172172
return 1;
173173
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
174174
return MP_OBJ_SMALL_INT_VALUE(arg);
175-
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
175+
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
176176
return mp_obj_float_get(arg);
177177
} else {
178178
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) {
189189
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
190190
*real = MP_OBJ_SMALL_INT_VALUE(arg);
191191
*imag = 0;
192-
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
192+
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
193193
*real = mp_obj_float_get(arg);
194194
*imag = 0;
195-
} else if (MP_OBJ_IS_TYPE(arg, &complex_type)) {
195+
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) {
196196
mp_obj_complex_get(arg, real, imag);
197197
} else {
198198
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));

py/obj.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ typedef machine_const_ptr_t mp_const_obj_t;
99

1010
typedef machine_int_t mp_small_int_t;
1111

12-
// The machine floating-point type used for float and complex numbers
13-
14-
#if MICROPY_ENABLE_FLOAT
15-
typedef machine_float_t mp_float_t;
16-
#endif
17-
1812
// Anything that wants to be a Micro Python object must have
1913
// mp_obj_base_t as its first member (except NULL and small ints)
2014

@@ -318,12 +312,16 @@ extern const mp_obj_type_t bytes_type;
318312

319313
#if MICROPY_ENABLE_FLOAT
320314
// float
321-
extern const mp_obj_type_t float_type;
315+
typedef struct _mp_obj_float_t {
316+
mp_obj_base_t base;
317+
mp_float_t value;
318+
} mp_obj_float_t;
319+
extern const mp_obj_type_t mp_type_float;
322320
mp_float_t mp_obj_float_get(mp_obj_t self_in);
323321
mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs);
324322

325323
// complex
326-
extern const mp_obj_type_t complex_type;
324+
extern const mp_obj_type_t mp_type_complex;
327325
void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
328326
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);
329327
#endif
@@ -398,7 +396,12 @@ extern const mp_obj_type_t super_type;
398396
extern const mp_obj_type_t gen_instance_type;
399397

400398
// module
401-
extern const mp_obj_type_t module_type;
399+
typedef struct _mp_obj_module_t {
400+
mp_obj_base_t base;
401+
qstr name;
402+
struct _mp_map_t *globals;
403+
} mp_obj_module_t;
404+
extern const mp_obj_type_t mp_type_module;
402405
mp_obj_t mp_obj_new_module(qstr module_name);
403406
mp_obj_t mp_obj_module_get(qstr module_name);
404407
struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);

py/objcomplex.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
3939

4040
case 1:
4141
// TODO allow string as first arg and parse it
42-
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
42+
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
4343
return args[0];
4444
} else {
4545
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
4848
case 2:
4949
{
5050
mp_float_t real, imag;
51-
if (MP_OBJ_IS_TYPE(args[0], &complex_type)) {
51+
if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
5252
mp_obj_complex_get(args[0], &real, &imag);
5353
} else {
5454
real = mp_obj_get_float(args[0]);
5555
imag = 0;
5656
}
57-
if (MP_OBJ_IS_TYPE(args[1], &complex_type)) {
57+
if (MP_OBJ_IS_TYPE(args[1], &mp_type_complex)) {
5858
mp_float_t real2, imag2;
5959
mp_obj_complex_get(args[1], &real2, &imag2);
6060
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) {
8585
return mp_obj_complex_binary_op(op, lhs->real, lhs->imag, rhs_in);
8686
}
8787

88-
const mp_obj_type_t complex_type = {
88+
const mp_obj_type_t mp_type_complex = {
8989
{ &mp_type_type },
9090
.name = MP_QSTR_complex,
9191
.print = complex_print,
@@ -96,14 +96,14 @@ const mp_obj_type_t complex_type = {
9696

9797
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) {
9898
mp_obj_complex_t *o = m_new_obj(mp_obj_complex_t);
99-
o->base.type = &complex_type;
99+
o->base.type = &mp_type_complex;
100100
o->real = real;
101101
o->imag = imag;
102102
return o;
103103
}
104104

105105
void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) {
106-
assert(MP_OBJ_IS_TYPE(self_in, &complex_type));
106+
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_complex));
107107
mp_obj_complex_t *self = self_in;
108108
*real = self->real;
109109
*imag = self->imag;

0 commit comments

Comments
 (0)