diff --git a/py/asmthumb.c b/py/asmthumb.c index 602caeb2d65e5e00902626296d9bd1972b9f3ec1..a6fe4be809b2bdbc97677a0f62bd9acab5d66220 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -4,7 +4,7 @@ #include <string.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "asmthumb.h" #define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0) diff --git a/py/bc.h b/py/bc.h index 6dc1dbbd4ee31d34cd963d316ec5da7cb4f1a38d..35847f458944ede0b6e1371cc4a7e9558ba0e0e2 100644 --- a/py/bc.h +++ b/py/bc.h @@ -1,101 +1,2 @@ -#define PYBC_LOAD_CONST_FALSE (0x10) -#define PYBC_LOAD_CONST_NONE (0x11) -#define PYBC_LOAD_CONST_TRUE (0x12) -#define PYBC_LOAD_CONST_SMALL_INT (0x13) // 24-bit, in excess -#define PYBC_LOAD_CONST_INT (0x14) // qstr -#define PYBC_LOAD_CONST_DEC (0x15) // qstr -#define PYBC_LOAD_CONST_ID (0x16) // qstr -#define PYBC_LOAD_CONST_BYTES (0x17) // qstr -#define PYBC_LOAD_CONST_STRING (0x18) // qstr - -#define PYBC_LOAD_FAST_0 (0x20) -#define PYBC_LOAD_FAST_1 (0x21) -#define PYBC_LOAD_FAST_2 (0x22) -#define PYBC_LOAD_FAST_N (0x23) // uint -#define PYBC_LOAD_DEREF (0x24) // uint -#define PYBC_LOAD_CLOSURE (0x25) // uint -#define PYBC_LOAD_NAME (0x26) // qstr -#define PYBC_LOAD_GLOBAL (0x27) // qstr -#define PYBC_LOAD_ATTR (0x28) // qstr -#define PYBC_LOAD_METHOD (0x29) // qstr -#define PYBC_LOAD_BUILD_CLASS (0x2a) - -#define PYBC_STORE_FAST_0 (0x30) -#define PYBC_STORE_FAST_1 (0x31) -#define PYBC_STORE_FAST_2 (0x32) -#define PYBC_STORE_FAST_N (0x33) // uint -#define PYBC_STORE_DEREF (0x34) // uint -#define PYBC_STORE_NAME (0x35) // qstr -#define PYBC_STORE_GLOBAL (0x36) // qstr -#define PYBC_STORE_ATTR (0x37) // qstr -#define PYBC_STORE_SUBSCR (0x38) - -#define PYBC_DELETE_FAST_N (0x39) // uint -#define PYBC_DELETE_DEREF (0x3a) // uint -#define PYBC_DELETE_NAME (0x3b) // qstr -#define PYBC_DELETE_GLOBAL (0x3c) // qstr -#define PYBC_DELETE_ATTR (0x3d) // qstr -#define PYBC_DELETE_SUBSCR (0x3e) - -#define PYBC_DUP_TOP (0x40) -#define PYBC_DUP_TOP_TWO (0x41) -#define PYBC_POP_TOP (0x42) -#define PYBC_ROT_TWO (0x43) -#define PYBC_ROT_THREE (0x44) - -#define PYBC_JUMP (0x45) // rel byte code offset, 16-bit signed, in excess -#define PYBC_POP_JUMP_IF_TRUE (0x46) // rel byte code offset, 16-bit signed, in excess -#define PYBC_POP_JUMP_IF_FALSE (0x47) // rel byte code offset, 16-bit signed, in excess -#define PYBC_JUMP_IF_TRUE_OR_POP (0x48) // rel byte code offset, 16-bit signed, in excess -#define PYBC_JUMP_IF_FALSE_OR_POP (0x49) // rel byte code offset, 16-bit signed, in excess -#define PYBC_SETUP_LOOP (0x4a) // rel byte code offset, 16-bit unsigned -#define PYBC_BREAK_LOOP (0x4b) // rel byte code offset, 16-bit unsigned -#define PYBC_CONTINUE_LOOP (0x4c) // rel byte code offset, 16-bit unsigned -#define PYBC_SETUP_WITH (0x4d) // rel byte code offset, 16-bit unsigned -#define PYBC_WITH_CLEANUP (0x4e) -#define PYBC_SETUP_EXCEPT (0x4f) // rel byte code offset, 16-bit unsigned -#define PYBC_SETUP_FINALLY (0x50) // rel byte code offset, 16-bit unsigned -#define PYBC_END_FINALLY (0x51) -#define PYBC_GET_ITER (0x52) -#define PYBC_FOR_ITER (0x53) // rel byte code offset, 16-bit unsigned -#define PYBC_POP_BLOCK (0x54) -#define PYBC_POP_EXCEPT (0x55) - -#define PYBC_UNARY_OP (0x60) // byte -#define PYBC_BINARY_OP (0x61) // byte -#define PYBC_COMPARE_OP (0x62) // byte - -#define PYBC_BUILD_TUPLE (0x70) // uint -#define PYBC_BUILD_LIST (0x71) // uint -#define PYBC_LIST_APPEND (0x72) // uint -#define PYBC_BUILD_MAP (0x73) // uint -#define PYBC_STORE_MAP (0x74) -#define PYBC_MAP_ADD (0x75) // uint -#define PYBC_BUILD_SET (0x76) // uint -#define PYBC_SET_ADD (0x77) // uint -#define PYBC_BUILD_SLICE (0x78) // uint -#define PYBC_UNPACK_SEQUENCE (0x79) // uint -#define PYBC_UNPACK_EX (0x7a) // uint - -#define PYBC_RETURN_VALUE (0x80) -#define PYBC_RAISE_VARARGS (0x81) // uint -#define PYBC_YIELD_VALUE (0x82) -#define PYBC_YIELD_FROM (0x83) - -#define PYBC_MAKE_FUNCTION (0x90) // uint -#define PYBC_MAKE_CLOSURE (0x91) // uint -#define PYBC_CALL_FUNCTION (0x92) // uint -#define PYBC_CALL_FUNCTION_VAR (0x93) // uint -#define PYBC_CALL_FUNCTION_KW (0x94) // uint -#define PYBC_CALL_FUNCTION_VAR_KW (0x95) // uint -#define PYBC_CALL_METHOD (0x96) // uint -#define PYBC_CALL_METHOD_VAR (0x97) // uint -#define PYBC_CALL_METHOD_KW (0x98) // uint -#define PYBC_CALL_METHOD_VAR_KW (0x99) // uint - -#define PYBC_IMPORT_NAME (0xe0) // qstr -#define PYBC_IMPORT_FROM (0xe1) // qstr -#define PYBC_IMPORT_STAR (0xe2) - -py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_args, uint n_state); -bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **sp_in_out); +mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state); +bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out); diff --git a/py/bc0.h b/py/bc0.h new file mode 100644 index 0000000000000000000000000000000000000000..e6dc84277a71aa34be6f541090da0a3fffca8508 --- /dev/null +++ b/py/bc0.h @@ -0,0 +1,98 @@ +#define MP_BC_LOAD_CONST_FALSE (0x10) +#define MP_BC_LOAD_CONST_NONE (0x11) +#define MP_BC_LOAD_CONST_TRUE (0x12) +#define MP_BC_LOAD_CONST_SMALL_INT (0x13) // 24-bit, in excess +#define MP_BC_LOAD_CONST_INT (0x14) // qstr +#define MP_BC_LOAD_CONST_DEC (0x15) // qstr +#define MP_BC_LOAD_CONST_ID (0x16) // qstr +#define MP_BC_LOAD_CONST_BYTES (0x17) // qstr +#define MP_BC_LOAD_CONST_STRING (0x18) // qstr + +#define MP_BC_LOAD_FAST_0 (0x20) +#define MP_BC_LOAD_FAST_1 (0x21) +#define MP_BC_LOAD_FAST_2 (0x22) +#define MP_BC_LOAD_FAST_N (0x23) // uint +#define MP_BC_LOAD_DEREF (0x24) // uint +#define MP_BC_LOAD_CLOSURE (0x25) // uint +#define MP_BC_LOAD_NAME (0x26) // qstr +#define MP_BC_LOAD_GLOBAL (0x27) // qstr +#define MP_BC_LOAD_ATTR (0x28) // qstr +#define MP_BC_LOAD_METHOD (0x29) // qstr +#define MP_BC_LOAD_BUILD_CLASS (0x2a) + +#define MP_BC_STORE_FAST_0 (0x30) +#define MP_BC_STORE_FAST_1 (0x31) +#define MP_BC_STORE_FAST_2 (0x32) +#define MP_BC_STORE_FAST_N (0x33) // uint +#define MP_BC_STORE_DEREF (0x34) // uint +#define MP_BC_STORE_NAME (0x35) // qstr +#define MP_BC_STORE_GLOBAL (0x36) // qstr +#define MP_BC_STORE_ATTR (0x37) // qstr +#define MP_BC_STORE_SUBSCR (0x38) + +#define MP_BC_DELETE_FAST_N (0x39) // uint +#define MP_BC_DELETE_DEREF (0x3a) // uint +#define MP_BC_DELETE_NAME (0x3b) // qstr +#define MP_BC_DELETE_GLOBAL (0x3c) // qstr +#define MP_BC_DELETE_ATTR (0x3d) // qstr +#define MP_BC_DELETE_SUBSCR (0x3e) + +#define MP_BC_DUP_TOP (0x40) +#define MP_BC_DUP_TOP_TWO (0x41) +#define MP_BC_POP_TOP (0x42) +#define MP_BC_ROT_TWO (0x43) +#define MP_BC_ROT_THREE (0x44) + +#define MP_BC_JUMP (0x45) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_POP_JUMP_IF_TRUE (0x46) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_POP_JUMP_IF_FALSE (0x47) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_JUMP_IF_TRUE_OR_POP (0x48) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_JUMP_IF_FALSE_OR_POP (0x49) // rel byte code offset, 16-bit signed, in excess +#define MP_BC_SETUP_LOOP (0x4a) // rel byte code offset, 16-bit unsigned +#define MP_BC_BREAK_LOOP (0x4b) // rel byte code offset, 16-bit unsigned +#define MP_BC_CONTINUE_LOOP (0x4c) // rel byte code offset, 16-bit unsigned +#define MP_BC_SETUP_WITH (0x4d) // rel byte code offset, 16-bit unsigned +#define MP_BC_WITH_CLEANUP (0x4e) +#define MP_BC_SETUP_EXCEPT (0x4f) // rel byte code offset, 16-bit unsigned +#define MP_BC_SETUP_FINALLY (0x50) // rel byte code offset, 16-bit unsigned +#define MP_BC_END_FINALLY (0x51) +#define MP_BC_GET_ITER (0x52) +#define MP_BC_FOR_ITER (0x53) // rel byte code offset, 16-bit unsigned +#define MP_BC_POP_BLOCK (0x54) +#define MP_BC_POP_EXCEPT (0x55) + +#define MP_BC_UNARY_OP (0x60) // byte +#define MP_BC_BINARY_OP (0x61) // byte +#define MP_BC_COMPARE_OP (0x62) // byte + +#define MP_BC_BUILD_TUPLE (0x70) // uint +#define MP_BC_BUILD_LIST (0x71) // uint +#define MP_BC_LIST_APPEND (0x72) // uint +#define MP_BC_BUILD_MAP (0x73) // uint +#define MP_BC_STORE_MAP (0x74) +#define MP_BC_MAP_ADD (0x75) // uint +#define MP_BC_BUILD_SET (0x76) // uint +#define MP_BC_SET_ADD (0x77) // uint +#define MP_BC_BUILD_SLICE (0x78) // uint +#define MP_BC_UNPACK_SEQUENCE (0x79) // uint +#define MP_BC_UNPACK_EX (0x7a) // uint + +#define MP_BC_RETURN_VALUE (0x80) +#define MP_BC_RAISE_VARARGS (0x81) // uint +#define MP_BC_YIELD_VALUE (0x82) +#define MP_BC_YIELD_FROM (0x83) + +#define MP_BC_MAKE_FUNCTION (0x90) // uint +#define MP_BC_MAKE_CLOSURE (0x91) // uint +#define MP_BC_CALL_FUNCTION (0x92) // uint +#define MP_BC_CALL_FUNCTION_VAR (0x93) // uint +#define MP_BC_CALL_FUNCTION_KW (0x94) // uint +#define MP_BC_CALL_FUNCTION_VAR_KW (0x95) // uint +#define MP_BC_CALL_METHOD (0x96) // uint +#define MP_BC_CALL_METHOD_VAR (0x97) // uint +#define MP_BC_CALL_METHOD_KW (0x98) // uint +#define MP_BC_CALL_METHOD_VAR_KW (0x99) // uint + +#define MP_BC_IMPORT_NAME (0xe0) // qstr +#define MP_BC_IMPORT_FROM (0xe1) // qstr +#define MP_BC_IMPORT_STAR (0xe2) diff --git a/py/builtin.c b/py/builtin.c index e45cdc98bc861c827bd3b806d554aa6e7236b01b..11e19fdea94c0bfe8b697bd2e0d4a35b5175d986 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -7,253 +7,258 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" #include "runtime.h" -#include "bc.h" - +//#include "bc.h" #include "map.h" -#include "obj.h" -#include "objprivate.h" #include "builtin.h" -py_obj_t py_builtin___build_class__(py_obj_t o_class_fun, py_obj_t o_class_name) { +mp_obj_t mp_builtin___build_class__(mp_obj_t o_class_fun, mp_obj_t o_class_name) { // we differ from CPython: we set the new __locals__ object here - py_map_t *old_locals = rt_get_map_locals(); - py_map_t *class_locals = py_map_new(MAP_QSTR, 0); + mp_map_t *old_locals = rt_get_map_locals(); + mp_map_t *class_locals = mp_map_new(MP_MAP_QSTR, 0); rt_set_map_locals(class_locals); // call the class code - rt_call_function_1(o_class_fun, (py_obj_t)0xdeadbeef); + rt_call_function_1(o_class_fun, (mp_obj_t)0xdeadbeef); // restore old __locals__ object rt_set_map_locals(old_locals); // create and return the new class - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_CLASS; - o->u_class.locals = class_locals; - return o; + return mp_obj_new_class(class_locals); } -py_obj_t py_builtin___import__(int n, py_obj_t *args) { +mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) { printf("import:\n"); for (int i = 0; i < n; i++) { printf(" "); - py_obj_print(args[i]); + mp_obj_print(args[i]); printf("\n"); } - return py_const_none; + return mp_const_none; } -py_obj_t py_builtin___repl_print__(py_obj_t o) { - if (o != py_const_none) { - py_obj_print(o); +mp_obj_t mp_builtin___repl_print__(mp_obj_t o) { + if (o != mp_const_none) { + mp_obj_print(o); printf("\n"); } - return py_const_none; + return mp_const_none; } -py_obj_t py_builtin_abs(py_obj_t o_in) { - if (IS_SMALL_INT(o_in)) { - py_small_int_t val = FROM_SMALL_INT(o_in); +mp_obj_t mp_builtin_abs(mp_obj_t o_in) { + if (MP_OBJ_IS_SMALL_INT(o_in)) { + mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o_in); if (val < 0) { val = -val; } - return TO_SMALL_INT(val); + return MP_OBJ_NEW_SMALL_INT(val); #if MICROPY_ENABLE_FLOAT - } else if (IS_O(o_in, O_FLOAT)) { - py_obj_base_t *o = o_in; + } else if (MP_OBJ_IS_TYPE(o_in, &float_type)) { + mp_float_t value = mp_obj_float_get(o_in); // TODO check for NaN etc - if (o->u_float < 0) { - return py_obj_new_float(-o->u_float); + if (value < 0) { + return mp_obj_new_float(-value); } else { return o_in; } - } else if (IS_O(o_in, O_COMPLEX)) { - py_obj_base_t *o = o_in; - return py_obj_new_float(machine_sqrt(o->u_complex.real*o->u_complex.real + o->u_complex.imag*o->u_complex.imag)); + } else if (MP_OBJ_IS_TYPE(o_in, &complex_type)) { + mp_float_t real, imag; + mp_obj_complex_get(o_in, &real, &imag); + return mp_obj_new_float(machine_sqrt(real*real + imag*imag)); #endif } else { assert(0); - return py_const_none; + return mp_const_none; } } -py_obj_t py_builtin_all(py_obj_t o_in) { - py_obj_t iterable = rt_getiter(o_in); - py_obj_t item; - while ((item = rt_iternext(iterable)) != py_const_stop_iteration) { +mp_obj_t mp_builtin_all(mp_obj_t o_in) { + mp_obj_t iterable = rt_getiter(o_in); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { if (!rt_is_true(item)) { - return py_const_false; + return mp_const_false; } } - return py_const_true; + return mp_const_true; } -py_obj_t py_builtin_any(py_obj_t o_in) { - py_obj_t iterable = rt_getiter(o_in); - py_obj_t item; - while ((item = rt_iternext(iterable)) != py_const_stop_iteration) { +mp_obj_t mp_builtin_any(mp_obj_t o_in) { + mp_obj_t iterable = rt_getiter(o_in); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { if (rt_is_true(item)) { - return py_const_true; + return mp_const_true; } } - return py_const_false; + return mp_const_false; } -py_obj_t py_builtin_bool(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_bool(int n_args, const mp_obj_t *args) { switch (n_args) { - case 0: return py_const_false; - case 1: if (rt_is_true(args[0])) { return py_const_true; } else { return py_const_false; } - default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "bool() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args, NULL)); + case 0: return mp_const_false; + case 1: if (rt_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; } + default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "bool() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args)); } } -py_obj_t py_builtin_callable(py_obj_t o_in) { - if (py_obj_is_callable(o_in)) { - return py_const_true; +mp_obj_t mp_builtin_callable(mp_obj_t o_in) { + if (mp_obj_is_callable(o_in)) { + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } #if MICROPY_ENABLE_FLOAT -py_obj_t py_builtin_complex(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_complex(int n_args, const mp_obj_t *args) { switch (n_args) { case 0: - return py_obj_new_complex(0, 0); + return mp_obj_new_complex(0, 0); case 1: // TODO allow string as first arg - if (IS_O(args[0], O_COMPLEX)) { + if (MP_OBJ_IS_TYPE(args[0], &complex_type)) { return args[0]; } else { - return py_obj_new_complex(py_obj_get_float(args[0]), 0); + return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } case 2: { - py_float_t real, imag; - if (IS_O(args[0], O_COMPLEX)) { - py_obj_get_complex(args[0], &real, &imag); + mp_float_t real, imag; + if (MP_OBJ_IS_TYPE(args[0], &complex_type)) { + mp_obj_get_complex(args[0], &real, &imag); } else { - real = py_obj_get_float(args[0]); + real = mp_obj_get_float(args[0]); imag = 0; } - if (IS_O(args[1], O_COMPLEX)) { - py_float_t real2, imag2; - py_obj_get_complex(args[1], &real2, &imag2); + if (MP_OBJ_IS_TYPE(args[1], &complex_type)) { + mp_float_t real2, imag2; + mp_obj_get_complex(args[1], &real2, &imag2); real -= imag2; imag += real2; } else { - imag += py_obj_get_float(args[1]); + imag += mp_obj_get_float(args[1]); } - return py_obj_new_complex(real, imag); + return mp_obj_new_complex(real, imag); } - default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "comlpex() takes at most 2 arguments (%d given)", (void*)(machine_int_t)n_args, NULL)); + default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "comlpex() takes at most 2 arguments (%d given)", (void*)(machine_int_t)n_args)); } } #endif -py_obj_t py_builtin_chr(py_obj_t o_in) { - int ord = py_obj_get_int(o_in); +mp_obj_t mp_builtin_chr(mp_obj_t o_in) { + int ord = mp_obj_get_int(o_in); if (0 <= ord && ord <= 0x10ffff) { char *str = m_new(char, 2); str[0] = ord; str[1] = '\0'; - return py_obj_new_str(qstr_from_str_take(str)); + return mp_obj_new_str(qstr_from_str_take(str)); } else { - nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "chr() arg not in range(0x110000)", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "chr() arg not in range(0x110000)")); } } -py_obj_t py_builtin_dict(void) { +mp_obj_t mp_builtin_dict(void) { // TODO create from an iterable! return rt_build_map(0); } -py_obj_t py_builtin_divmod(py_obj_t o1_in, py_obj_t o2_in) { - if (IS_SMALL_INT(o1_in) && IS_SMALL_INT(o2_in)) { - py_small_int_t i1 = FROM_SMALL_INT(o1_in); - py_small_int_t i2 = FROM_SMALL_INT(o2_in); - py_obj_t revs_args[2]; - revs_args[1] = TO_SMALL_INT(i1 / i2); - revs_args[0] = TO_SMALL_INT(i1 % i2); +mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) { + if (MP_OBJ_IS_SMALL_INT(o1_in) && MP_OBJ_IS_SMALL_INT(o2_in)) { + mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in); + mp_small_int_t i2 = MP_OBJ_SMALL_INT_VALUE(o2_in); + mp_obj_t revs_args[2]; + revs_args[1] = MP_OBJ_NEW_SMALL_INT(i1 / i2); + revs_args[0] = MP_OBJ_NEW_SMALL_INT(i1 % i2); return rt_build_tuple(2, revs_args); } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", py_obj_get_type_str(o1_in), py_obj_get_type_str(o2_in))); + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in))); } } -py_obj_t py_builtin_hash(py_obj_t o_in) { +static mp_obj_t mp_builtin_hash(mp_obj_t o_in) { // TODO hash will generally overflow small integer; can we safely truncate it? - return py_obj_new_int(py_obj_hash(o_in)); + return mp_obj_new_int(mp_obj_hash(o_in)); } -py_obj_t py_builtin_iter(py_obj_t o_in) { - return rt_getiter(o_in); -} +MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hash_obj, mp_builtin_hash); -py_obj_t py_builtin_next(py_obj_t o_in) { - return rt_gen_instance_next(o_in); +static mp_obj_t mp_builtin_iter(mp_obj_t o_in) { + return rt_getiter(o_in); } -py_obj_t py_builtin_len(py_obj_t o_in) { - py_small_int_t len = 0; - if (IS_O(o_in, O_STR)) { - py_obj_base_t *o = o_in; - len = strlen(qstr_str(o->u_str)); - } else if (IS_O(o_in, O_TUPLE) || IS_O(o_in, O_LIST)) { - py_obj_base_t *o = o_in; - len = o->u_tuple_list.len; - } else if (IS_O(o_in, O_MAP)) { - py_obj_base_t *o = o_in; +MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_iter_obj, mp_builtin_iter); + +mp_obj_t mp_builtin_len(mp_obj_t o_in) { + mp_small_int_t len = 0; + if (MP_OBJ_IS_TYPE(o_in, &str_type)) { + len = strlen(qstr_str(mp_obj_str_get(o_in))); + } else if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) { + uint seq_len; + mp_obj_t *seq_items; + mp_obj_tuple_get(o_in, &seq_len, &seq_items); + len = seq_len; + } else if (MP_OBJ_IS_TYPE(o_in, &list_type)) { + uint seq_len; + mp_obj_t *seq_items; + mp_obj_list_get(o_in, &seq_len, &seq_items); + len = seq_len; + /* TODO + } else if (MP_OBJ_IS_TYPE(o_in, &dict_type)) { + mp_obj_base_t *o = o_in; len = o->u_map.used; + */ } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "object of type '%s' has no len()", py_obj_get_type_str(o_in), NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in))); } - return TO_SMALL_INT(len); + return MP_OBJ_NEW_SMALL_INT(len); } -py_obj_t py_builtin_list(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args) { switch (n_args) { case 0: return rt_build_list(0, NULL); case 1: { // make list from iterable - py_obj_t iterable = rt_getiter(args[0]); - py_obj_t list = rt_build_list(0, NULL); - py_obj_t item; - while ((item = rt_iternext(iterable)) != py_const_stop_iteration) { + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t list = rt_build_list(0, NULL); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { rt_list_append(list, item); } return list; } - default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "list() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args, NULL)); + default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "list() takes at most 1 argument (%d given)", (void*)(machine_int_t)n_args)); } } -py_obj_t py_builtin_max(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) { if (n_args == 1) { // given an iterable - py_obj_t iterable = rt_getiter(args[0]); - py_obj_t max_obj = NULL; - py_obj_t item; - while ((item = rt_iternext(iterable)) != py_const_stop_iteration) { - if (max_obj == NULL || py_obj_less(max_obj, item)) { + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t max_obj = NULL; + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { + if (max_obj == NULL || mp_obj_less(max_obj, item)) { max_obj = item; } } if (max_obj == NULL) { - nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "max() arg is an empty sequence", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "max() arg is an empty sequence")); } return max_obj; } else { // given many args - py_obj_t max_obj = args[0]; + mp_obj_t max_obj = args[0]; for (int i = 1; i < n_args; i++) { - if (py_obj_less(max_obj, args[i])) { + if (mp_obj_less(max_obj, args[i])) { max_obj = args[i]; } } @@ -261,26 +266,26 @@ py_obj_t py_builtin_max(int n_args, const py_obj_t *args) { } } -py_obj_t py_builtin_min(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) { if (n_args == 1) { // given an iterable - py_obj_t iterable = rt_getiter(args[0]); - py_obj_t min_obj = NULL; - py_obj_t item; - while ((item = rt_iternext(iterable)) != py_const_stop_iteration) { - if (min_obj == NULL || py_obj_less(item, min_obj)) { + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t min_obj = NULL; + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { + if (min_obj == NULL || mp_obj_less(item, min_obj)) { min_obj = item; } } if (min_obj == NULL) { - nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "min() arg is an empty sequence", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(rt_q_ValueError, "min() arg is an empty sequence")); } return min_obj; } else { // given many args - py_obj_t min_obj = args[0]; + mp_obj_t min_obj = args[0]; for (int i = 1; i < n_args; i++) { - if (py_obj_less(args[i], min_obj)) { + if (mp_obj_less(args[i], min_obj)) { min_obj = args[i]; } } @@ -288,59 +293,85 @@ py_obj_t py_builtin_min(int n_args, const py_obj_t *args) { } } -py_obj_t py_builtin_ord(py_obj_t o_in) { - const char *str = qstr_str(py_obj_get_qstr(o_in)); +static mp_obj_t mp_builtin_next(mp_obj_t o_in) { + return mp_obj_gen_instance_next(o_in); +} + +MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next); + +mp_obj_t mp_builtin_ord(mp_obj_t o_in) { + const char *str = qstr_str(mp_obj_get_qstr(o_in)); if (strlen(str) == 1) { - return py_obj_new_int(str[0]); + return mp_obj_new_int(str[0]); } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "ord() expected a character, but string of length %d found", (void*)(machine_int_t)strlen(str), NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "ord() expected a character, but string of length %d found", (void*)(machine_int_t)strlen(str))); } } -py_obj_t py_builtin_pow(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args) { switch (n_args) { case 2: return rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]); case 3: return rt_binary_op(RT_BINARY_OP_MODULO, rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]), args[2]); // TODO optimise... - default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "pow expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args, NULL)); + default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "pow expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args)); } } -py_obj_t py_builtin_print(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args) { for (int i = 0; i < n_args; i++) { if (i > 0) { printf(" "); } - if (IS_O(args[i], O_STR)) { + if (MP_OBJ_IS_TYPE(args[i], &str_type)) { // special case, print string raw - printf("%s", qstr_str(((py_obj_base_t*)args[i])->u_str)); + printf("%s", qstr_str(mp_obj_str_get(args[i]))); } else { // print the object Python style - py_obj_print(args[i]); + mp_obj_print(args[i]); } } printf("\n"); - return py_const_none; + return mp_const_none; } -py_obj_t py_builtin_range(int n_args, const py_obj_t *args) { +mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args) { switch (n_args) { - case 1: return py_obj_new_range(0, py_obj_get_int(args[0]), 1); - case 2: return py_obj_new_range(py_obj_get_int(args[0]), py_obj_get_int(args[1]), 1); - case 3: return py_obj_new_range(py_obj_get_int(args[0]), py_obj_get_int(args[1]), py_obj_get_int(args[2])); - default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args, NULL)); + case 1: return mp_obj_new_range(0, mp_obj_get_int(args[0]), 1); + case 2: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), 1); + case 3: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2])); + default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "range expected at most 3 arguments, got %d", (void*)(machine_int_t)n_args)); + } +} + +static mp_obj_t mp_builtin_set(int n_args, const mp_obj_t *args) { + assert(0 <= n_args && n_args <= 1); + + if (n_args == 0) { + // return a new, empty set + return mp_obj_new_set(0, NULL); + } else { + // 1 argument, an iterable from which we make a new set + mp_obj_t set = mp_obj_new_set(0, NULL); + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { + mp_obj_set_store(set, item); + } + return set; } } -py_obj_t py_builtin_sum(int n_args, const py_obj_t *args) { - py_obj_t value; +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_set_obj, 0, 1, mp_builtin_set); + +mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) { + mp_obj_t value; switch (n_args) { - case 1: value = py_obj_new_int(0); break; + case 1: value = mp_obj_new_int(0); break; case 2: value = args[1]; break; - default: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "sum expected at most 2 arguments, got %d", (void*)(machine_int_t)n_args, NULL)); + default: nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "sum expected at most 2 arguments, got %d", (void*)(machine_int_t)n_args)); } - py_obj_t iterable = rt_getiter(args[0]); - py_obj_t item; - while ((item = rt_iternext(iterable)) != py_const_stop_iteration) { + mp_obj_t iterable = rt_getiter(args[0]); + mp_obj_t item; + while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) { value = rt_binary_op(RT_BINARY_OP_ADD, value, item); } return value; diff --git a/py/builtin.h b/py/builtin.h index 0a0470a842de74ff79aebb3edc161dfd9637d9a2..c164a76611054500eb3a0749dbf92b3e1bbd17e8 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -1,24 +1,27 @@ -py_obj_t py_builtin___build_class__(py_obj_t o_class_fun, py_obj_t o_class_name); -py_obj_t py_builtin___import__(int n, py_obj_t *args); -py_obj_t py_builtin___repl_print__(py_obj_t o); -py_obj_t py_builtin_abs(py_obj_t o_in); -py_obj_t py_builtin_all(py_obj_t o_in); -py_obj_t py_builtin_any(py_obj_t o_in); -py_obj_t py_builtin_bool(int n_args, const py_obj_t *args); -py_obj_t py_builtin_callable(py_obj_t o_in); -py_obj_t py_builtin_complex(int n_args, const py_obj_t *args); -py_obj_t py_builtin_chr(py_obj_t o_in); -py_obj_t py_builtin_dict(void); -py_obj_t py_builtin_divmod(py_obj_t o1_in, py_obj_t o2_in); -py_obj_t py_builtin_hash(py_obj_t o_in); -py_obj_t py_builtin_iter(py_obj_t o_in); -py_obj_t py_builtin_len(py_obj_t o_in); -py_obj_t py_builtin_list(int n_args, const py_obj_t *args); -py_obj_t py_builtin_max(int n_args, const py_obj_t *args); -py_obj_t py_builtin_min(int n_args, const py_obj_t *args); -py_obj_t py_builtin_next(py_obj_t o_in); -py_obj_t py_builtin_ord(py_obj_t o_in); -py_obj_t py_builtin_pow(int n_args, const py_obj_t *args); -py_obj_t py_builtin_print(int n_args, const py_obj_t *args); -py_obj_t py_builtin_range(int n_args, const py_obj_t *args); -py_obj_t py_builtin_sum(int n_args, const py_obj_t *args); +// TODO convert all these to objects using MP_DECLARE and MP_DEFINE + +mp_obj_t mp_builtin___build_class__(mp_obj_t o_class_fun, mp_obj_t o_class_name); +mp_obj_t mp_builtin___import__(int n, mp_obj_t *args); +mp_obj_t mp_builtin___repl_print__(mp_obj_t o); +mp_obj_t mp_builtin_abs(mp_obj_t o_in); +mp_obj_t mp_builtin_all(mp_obj_t o_in); +mp_obj_t mp_builtin_any(mp_obj_t o_in); +mp_obj_t mp_builtin_bool(int n_args, const mp_obj_t *args); +mp_obj_t mp_builtin_callable(mp_obj_t o_in); +mp_obj_t mp_builtin_complex(int n_args, const mp_obj_t *args); +mp_obj_t mp_builtin_chr(mp_obj_t o_in); +mp_obj_t mp_builtin_dict(void); +mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_iter_obj); +mp_obj_t mp_builtin_len(mp_obj_t o_in); +mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args); +mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args); +mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_next_obj); +mp_obj_t mp_builtin_ord(mp_obj_t o_in); +mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args); +mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args); +mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_set_obj); +mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args); diff --git a/py/compile.c b/py/compile.c index 42bac7d28acaea7d7472e46dd3eb97b59b11dd4a..38f14155db484ffc55399123a5e78140d39dce06 100644 --- a/py/compile.c +++ b/py/compile.c @@ -6,12 +6,12 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "scope.h" #include "compile.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" // TODO need to mangle __attr names @@ -78,28 +78,28 @@ typedef struct _compiler_t { const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm } compiler_t; -py_parse_node_t fold_constants(py_parse_node_t pn) { - if (PY_PARSE_NODE_IS_STRUCT(pn)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +mp_parse_node_t fold_constants(mp_parse_node_t pn) { + if (MP_PARSE_NODE_IS_STRUCT(pn)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); // fold arguments first for (int i = 0; i < n; i++) { pns->nodes[i] = fold_constants(pns->nodes[i]); } - switch (PY_PARSE_NODE_STRUCT_KIND(pns)) { + switch (MP_PARSE_NODE_STRUCT_KIND(pns)) { case PN_shift_expr: - if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { - int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_LESS)) { + if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { + int arg0 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + int arg1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[2]); + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_LESS)) { #if MICROPY_EMIT_CPYTHON // can overflow; enabled only to compare with CPython - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 << arg1); #endif - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1); + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_MORE)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 >> arg1); } else { // shouldn't happen assert(0); @@ -109,42 +109,42 @@ py_parse_node_t fold_constants(py_parse_node_t pn) { case PN_arith_expr: // overflow checking here relies on SMALL_INT being strictly smaller than machine_int_t - if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { - machine_int_t arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - machine_int_t arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]); + if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { + machine_int_t arg0 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + machine_int_t arg1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[2]); machine_int_t res; - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PLUS)) { res = arg0 + arg1; - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_MINUS)) { res = arg0 - arg1; } else { // shouldn't happen assert(0); res = 0; } - if (PY_FIT_SMALL_INT(res)) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, res); + if (MP_FIT_SMALL_INT(res)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, res); } } break; case PN_term: - if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { - int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) { + if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { + int arg0 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + int arg1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[2]); + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) { #if MICROPY_EMIT_CPYTHON // can overflow; enabled only to compare with CPython - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 * arg1); #endif - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_SLASH)) { ; // pass - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PERCENT)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PERCENT)) { // XXX implement this properly as Python's % operator acts differently to C's - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 % arg1); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_SLASH)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 % arg1); + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_SLASH)) { // XXX implement this properly as Python's // operator acts differently to C's - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 / arg1); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 / arg1); } else { // shouldn't happen assert(0); @@ -153,14 +153,14 @@ py_parse_node_t fold_constants(py_parse_node_t pn) { break; case PN_factor_2: - if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) { - machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, -arg); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg); + if (MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) { + machine_int_t arg = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]); + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_PLUS)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg); + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_MINUS)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, -arg); + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_TILDE)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, ~arg); } else { // shouldn't happen assert(0); @@ -171,17 +171,17 @@ py_parse_node_t fold_constants(py_parse_node_t pn) { #if MICROPY_EMIT_CPYTHON case PN_power: // can overflow; enabled only to compare with CPython - if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_NULL(pns->nodes[1]) && !PY_PARSE_NODE_IS_NULL(pns->nodes[2])) { - py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2]; - if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) { - int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]); + if (MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_NULL(pns->nodes[1]) && !MP_PARSE_NODE_IS_NULL(pns->nodes[2])) { + mp_parse_node_struct_t* pns2 = (mp_parse_node_struct_t*)pns->nodes[2]; + if (MP_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) { + int power = MP_PARSE_NODE_LEAF_ARG(pns2->nodes[0]); if (power >= 0) { int ans = 1; - int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + int base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); for (; power > 0; power--) { ans *= base; } - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, ans); } } } @@ -193,13 +193,13 @@ py_parse_node_t fold_constants(py_parse_node_t pn) { return pn; } -void compile_node(compiler_t *comp, py_parse_node_t pn); +void compile_node(compiler_t *comp, mp_parse_node_t pn); static int comp_next_label(compiler_t *comp) { return comp->next_label++; } -static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse_node_t pn, uint emit_options) { +static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) { scope_t *scope = scope_new(kind, pn, rt_get_unique_code_id(kind == SCOPE_MODULE), emit_options); scope->parent = comp->scope_cur; scope->next = NULL; @@ -215,68 +215,68 @@ static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse return scope; } -static int list_len(py_parse_node_t pn, int pn_kind) { - if (PY_PARSE_NODE_IS_NULL(pn)) { +static int list_len(mp_parse_node_t pn, int pn_kind) { + if (MP_PARSE_NODE_IS_NULL(pn)) { return 0; - } else if (PY_PARSE_NODE_IS_LEAF(pn)) { + } else if (MP_PARSE_NODE_IS_LEAF(pn)) { return 1; } else { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) { return 1; } else { - return PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + return MP_PARSE_NODE_STRUCT_NUM_NODES(pns); } } } -static void apply_to_single_or_list(compiler_t *comp, py_parse_node_t pn, int pn_list_kind, void (*f)(compiler_t*, py_parse_node_t)) { - if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +static void apply_to_single_or_list(compiler_t *comp, mp_parse_node_t pn, int pn_list_kind, void (*f)(compiler_t*, mp_parse_node_t)) { + if (MP_PARSE_NODE_IS_STRUCT(pn) && MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)pn) == pn_list_kind) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < num_nodes; i++) { f(comp, pns->nodes[i]); } - } else if (!PY_PARSE_NODE_IS_NULL(pn)) { + } else if (!MP_PARSE_NODE_IS_NULL(pn)) { f(comp, pn); } } -static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) { - if (PY_PARSE_NODE_IS_NULL(*pn)) { +static int list_get(mp_parse_node_t *pn, int pn_kind, mp_parse_node_t **nodes) { + if (MP_PARSE_NODE_IS_NULL(*pn)) { *nodes = NULL; return 0; - } else if (PY_PARSE_NODE_IS_LEAF(*pn)) { + } else if (MP_PARSE_NODE_IS_LEAF(*pn)) { *nodes = pn; return 1; } else { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn); - if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)(*pn); + if (MP_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) { *nodes = pn; return 1; } else { *nodes = pns->nodes; - return PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + return MP_PARSE_NODE_STRUCT_NUM_NODES(pns); } } } -void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_do_nothing(compiler_t *comp, mp_parse_node_struct_t *pns) { } -void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) { - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +void compile_generic_all_nodes(compiler_t *comp, mp_parse_node_struct_t *pns) { + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < num_nodes; i++) { compile_node(comp, pns->nodes[i]); } } #if MICROPY_EMIT_CPYTHON -static bool cpython_c_tuple_is_const(py_parse_node_t pn) { - if (!PY_PARSE_NODE_IS_LEAF(pn)) { +static bool cpython_c_tuple_is_const(mp_parse_node_t pn) { + if (!MP_PARSE_NODE_IS_LEAF(pn)) { return false; } - if (PY_PARSE_NODE_IS_ID(pn)) { + if (MP_PARSE_NODE_IS_ID(pn)) { return false; } return true; @@ -322,21 +322,21 @@ static void cpython_c_print_quoted_str(vstr_t *vstr, qstr qstr, bool bytes) { } } -static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn, vstr_t *vstr) { - assert(PY_PARSE_NODE_IS_LEAF(pn)); - int arg = PY_PARSE_NODE_LEAF_ARG(pn); - switch (PY_PARSE_NODE_LEAF_KIND(pn)) { - case PY_PARSE_NODE_ID: assert(0); - case PY_PARSE_NODE_SMALL_INT: vstr_printf(vstr, "%d", arg); break; - case PY_PARSE_NODE_INTEGER: vstr_printf(vstr, "%s", qstr_str(arg)); break; - case PY_PARSE_NODE_DECIMAL: vstr_printf(vstr, "%s", qstr_str(arg)); break; - case PY_PARSE_NODE_STRING: cpython_c_print_quoted_str(vstr, arg, false); break; - case PY_PARSE_NODE_BYTES: cpython_c_print_quoted_str(vstr, arg, true); break; - case PY_PARSE_NODE_TOKEN: +static void cpython_c_tuple_emit_const(compiler_t *comp, mp_parse_node_t pn, vstr_t *vstr) { + assert(MP_PARSE_NODE_IS_LEAF(pn)); + int arg = MP_PARSE_NODE_LEAF_ARG(pn); + switch (MP_PARSE_NODE_LEAF_KIND(pn)) { + case MP_PARSE_NODE_ID: assert(0); + case MP_PARSE_NODE_SMALL_INT: vstr_printf(vstr, "%d", arg); break; + case MP_PARSE_NODE_INTEGER: vstr_printf(vstr, "%s", qstr_str(arg)); break; + case MP_PARSE_NODE_DECIMAL: vstr_printf(vstr, "%s", qstr_str(arg)); break; + case MP_PARSE_NODE_STRING: cpython_c_print_quoted_str(vstr, arg, false); break; + case MP_PARSE_NODE_BYTES: cpython_c_print_quoted_str(vstr, arg, true); break; + case MP_PARSE_NODE_TOKEN: switch (arg) { - case PY_TOKEN_KW_FALSE: vstr_printf(vstr, "False"); break; - case PY_TOKEN_KW_NONE: vstr_printf(vstr, "None"); break; - case PY_TOKEN_KW_TRUE: vstr_printf(vstr, "True"); break; + case MP_TOKEN_KW_FALSE: vstr_printf(vstr, "False"); break; + case MP_TOKEN_KW_NONE: vstr_printf(vstr, "None"); break; + case MP_TOKEN_KW_TRUE: vstr_printf(vstr, "True"); break; default: assert(0); } break; @@ -344,14 +344,14 @@ static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn, vst } } -static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) { +static void cpython_c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_struct_t *pns_list) { int n = 0; if (pns_list != NULL) { - n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list); + n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns_list); } int total = n; bool is_const = true; - if (!PY_PARSE_NODE_IS_NULL(pn)) { + if (!MP_PARSE_NODE_IS_NULL(pn)) { total += 1; if (!cpython_c_tuple_is_const(pn)) { is_const = false; @@ -367,7 +367,7 @@ static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_ bool need_comma = false; vstr_t *vstr = vstr_new(); vstr_printf(vstr, "("); - if (!PY_PARSE_NODE_IS_NULL(pn)) { + if (!MP_PARSE_NODE_IS_NULL(pn)) { cpython_c_tuple_emit_const(comp, pn, vstr); need_comma = true; } @@ -386,7 +386,7 @@ static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_ EMIT(load_const_verbatim_str, vstr_str(vstr)); vstr_free(vstr); } else { - if (!PY_PARSE_NODE_IS_NULL(pn)) { + if (!MP_PARSE_NODE_IS_NULL(pn)) { compile_node(comp, pn); } for (int i = 0; i < n; i++) { @@ -398,17 +398,17 @@ static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_ #endif // funnelling all tuple creations through this function is purely so we can optionally agree with CPython -void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) { +void c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_struct_t *pns_list) { #if MICROPY_EMIT_CPYTHON cpython_c_tuple(comp, pn, pns_list); #else int total = 0; - if (!PY_PARSE_NODE_IS_NULL(pn)) { + if (!MP_PARSE_NODE_IS_NULL(pn)) { compile_node(comp, pn); total += 1; } if (pns_list != NULL) { - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns_list); for (int i = 0; i < n; i++) { compile_node(comp, pns_list->nodes[i]); } @@ -418,23 +418,23 @@ void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_l #endif } -void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_generic_tuple(compiler_t *comp, mp_parse_node_struct_t *pns) { // a simple tuple expression - c_tuple(comp, PY_PARSE_NODE_NULL, pns); + c_tuple(comp, MP_PARSE_NODE_NULL, pns); } -static bool node_is_const_false(py_parse_node_t pn) { - return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE); - // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1); +static bool node_is_const_false(mp_parse_node_t pn) { + return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_FALSE); + // untested: || (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_ARG(pn) == 1); } -static bool node_is_const_true(py_parse_node_t pn) { - return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_TRUE) || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1); +static bool node_is_const_true(mp_parse_node_t pn) { + return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_TRUE) || (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_ARG(pn) == 1); } #if MICROPY_EMIT_CPYTHON // the is_nested variable is purely to match with CPython, which doesn't fully optimise not's -static void cpython_c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label, bool is_nested) { +static void cpython_c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int label, bool is_nested) { if (node_is_const_false(pn)) { if (jump_if == false) { EMIT(jump, label); @@ -445,10 +445,10 @@ static void cpython_c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if EMIT(jump, label); } return; - } else if (PY_PARSE_NODE_IS_STRUCT(pn)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); - if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) { + } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); + if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) { if (jump_if == false) { int label2 = comp_next_label(comp); for (int i = 0; i < n - 1; i++) { @@ -462,7 +462,7 @@ static void cpython_c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if } } return; - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) { if (jump_if == false) { for (int i = 0; i < n; i++) { cpython_c_if_cond(comp, pns->nodes[i], false, label, true); @@ -476,7 +476,7 @@ static void cpython_c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if EMIT(label_assign, label2); } return; - } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) { + } else if (!is_nested && MP_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) { cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true); return; } @@ -492,7 +492,7 @@ static void cpython_c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if } #endif -static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) { +static void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int label) { #if MICROPY_EMIT_CPYTHON cpython_c_if_cond(comp, pn, jump_if, label, false); #else @@ -506,10 +506,10 @@ static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int la EMIT(jump, label); } return; - } else if (PY_PARSE_NODE_IS_STRUCT(pn)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); - if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) { + } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); + if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) { if (jump_if == false) { int label2 = comp_next_label(comp); for (int i = 0; i < n - 1; i++) { @@ -523,7 +523,7 @@ static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int la } } return; - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) { if (jump_if == false) { for (int i = 0; i < n; i++) { c_if_cond(comp, pns->nodes[i], false, label); @@ -537,7 +537,7 @@ static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int la EMIT(label_assign, label2); } return; - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) { c_if_cond(comp, pns->nodes[0], !jump_if, label); return; } @@ -554,29 +554,29 @@ static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int la } typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t; -void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind); +void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t kind); -void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) { +void c_assign_power(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t assign_kind) { if (assign_kind != ASSIGN_AUG_STORE) { compile_node(comp, pns->nodes[0]); } - if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) { - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1); + if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { + mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) { + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1); if (assign_kind != ASSIGN_AUG_STORE) { for (int i = 0; i < n - 1; i++) { compile_node(comp, pns1->nodes[i]); } } - assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1])); - pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1]; + assert(MP_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1])); + pns1 = (mp_parse_node_struct_t*)pns1->nodes[n - 1]; } - if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) { + if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) { printf("SyntaxError: can't assign to function call\n"); return; - } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) { if (assign_kind == ASSIGN_AUG_STORE) { EMIT(rot_three); EMIT(store_subscr); @@ -589,16 +589,16 @@ void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t EMIT(store_subscr); } } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) { - assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0])); + } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) { + assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0])); if (assign_kind == ASSIGN_AUG_LOAD) { EMIT(dup_top); - EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); + EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); } else { if (assign_kind == ASSIGN_AUG_STORE) { EMIT(rot_two); } - EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); + EMIT(store_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); } } else { // shouldn't happen @@ -609,17 +609,17 @@ void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assert(0); } - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) { + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) { // SyntaxError, cannot assign assert(0); } } -void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) { +void c_assign_tuple(compiler_t *comp, int n, mp_parse_node_t *nodes) { assert(n >= 0); int have_star_index = -1; for (int i = 0; i < n; i++) { - if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) { if (have_star_index < 0) { EMIT(unpack_ex, i, n - i - 1); have_star_index = i; @@ -634,7 +634,7 @@ void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) { } for (int i = 0; i < n; i++) { if (i == have_star_index) { - c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE); + c_assign(comp, ((mp_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE); } else { c_assign(comp, nodes[i], ASSIGN_STORE); } @@ -642,13 +642,13 @@ void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) { } // assigns top of stack to pn -void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) { +void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) { tail_recursion: - if (PY_PARSE_NODE_IS_NULL(pn)) { + if (MP_PARSE_NODE_IS_NULL(pn)) { assert(0); - } else if (PY_PARSE_NODE_IS_LEAF(pn)) { - if (PY_PARSE_NODE_IS_ID(pn)) { - int arg = PY_PARSE_NODE_LEAF_ARG(pn); + } else if (MP_PARSE_NODE_IS_LEAF(pn)) { + if (MP_PARSE_NODE_IS_ID(pn)) { + int arg = MP_PARSE_NODE_LEAF_ARG(pn); switch (assign_kind) { case ASSIGN_STORE: case ASSIGN_AUG_STORE: @@ -663,8 +663,8 @@ void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) { return; } } else { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - switch (PY_PARSE_NODE_STRUCT_KIND(pns)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + switch (MP_PARSE_NODE_STRUCT_KIND(pns)) { case PN_power: // lhs is an index or attribute c_assign_power(comp, pns, assign_kind); @@ -676,17 +676,17 @@ void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) { if (assign_kind != ASSIGN_STORE) { goto bad_aug; } - c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes); + c_assign_tuple(comp, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes); break; case PN_atom_paren: // lhs is something in parenthesis - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // empty tuple printf("SyntaxError: can't assign to ()\n"); return; - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { - pns = (py_parse_node_struct_t*)pns->nodes[0]; + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + pns = (mp_parse_node_struct_t*)pns->nodes[0]; goto testlist_comp; } else { // parenthesis around 1 item, is just that item @@ -700,11 +700,11 @@ void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) { if (assign_kind != ASSIGN_STORE) { goto bad_aug; } - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // empty list, assignment allowed c_assign_tuple(comp, 0, NULL); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { - pns = (py_parse_node_struct_t*)pns->nodes[0]; + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + pns = (mp_parse_node_struct_t*)pns->nodes[0]; goto testlist_comp; } else { // brackets around 1 item @@ -713,29 +713,29 @@ void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) { break; default: - printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns)); + printf("unknown assign, %u\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns)); assert(0); } return; testlist_comp: // lhs is a sequence - if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) { + if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) { // sequence of one item, with trailing comma - assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0])); + assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[0])); c_assign_tuple(comp, 1, &pns->nodes[0]); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) { // sequence of many items // TODO call c_assign_tuple instead - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns2); EMIT(unpack_sequence, 1 + n); c_assign(comp, pns->nodes[0], ASSIGN_STORE); for (int i = 0; i < n; i++) { c_assign(comp, pns2->nodes[i], ASSIGN_STORE); } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) { // TODO not implemented assert(0); } else { @@ -786,16 +786,16 @@ void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_ } } -void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) { - if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) { +void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) { // this parameter has a default value // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why if (comp->have_bare_star) { comp->param_pass_num_dict_params += 1; if (comp->param_pass == 1) { - EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); + EMIT(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); compile_node(comp, pns->nodes[2]); } } else { @@ -805,9 +805,9 @@ void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) { } } } - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // bare star comp->have_bare_star = true; } @@ -816,12 +816,12 @@ void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) { // leaves function object on stack // returns function name -qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) { +qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) { if (comp->pass == PASS_1) { // create a new scope for this function - scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options); + scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options); // store the function scope so the compiling function can use it at each pass - pns->nodes[4] = (py_parse_node_t)s; + pns->nodes[4] = (mp_parse_node_t)s; } // save variables (probably don't need to do this, since we can't have nested definitions..?) @@ -860,12 +860,12 @@ qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint // leaves class object on stack // returns class name -qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) { +qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) { if (comp->pass == PASS_1) { // create a new scope for this class - scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options); + scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (mp_parse_node_t)pns, emit_options); // store the class scope so the compiling function can use it at each pass - pns->nodes[3] = (py_parse_node_t)s; + pns->nodes[3] = (mp_parse_node_t)s; } EMIT(load_build_class); @@ -880,7 +880,7 @@ qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint EMIT(load_const_id, cscope->simple_name); // nodes[1] has parent classes, if any - if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { // no parent classes EMIT(call_function, 2, 0, false, false); } else { @@ -895,8 +895,8 @@ qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint } // returns true if it was a built-in decorator (even if the built-in had an error) -static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) { - if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) { +static bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_node_t *name_nodes, uint *emit_options) { + if (MP_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) { return false; } @@ -905,7 +905,7 @@ static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_ return true; } - qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]); + qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]); if (attr == comp->qstr_byte_code) { *emit_options = EMIT_OPT_BYTE_CODE; #if MICROPY_EMIT_NATIVE @@ -925,9 +925,9 @@ static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_ return true; } -void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) { // get the list of decorators - py_parse_node_t *nodes; + mp_parse_node_t *nodes; int n = list_get(&pns->nodes[0], PN_decorators, &nodes); // inherit emit options for this function/class definition @@ -936,11 +936,11 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) { // compile each decorator int num_built_in_decorators = 0; for (int i = 0; i < n; i++) { - assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be - py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i]; + assert(MP_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be + mp_parse_node_struct_t *pns_decorator = (mp_parse_node_struct_t*)nodes[i]; // nodes[0] contains the decorator function, which is a dotted name - py_parse_node_t *name_nodes; + mp_parse_node_t *name_nodes; int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes); // check for built-in decorators @@ -954,12 +954,12 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) { // compile the decorator function compile_node(comp, name_nodes[0]); for (int i = 1; i < name_len; i++) { - assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be - EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i])); + assert(MP_PARSE_NODE_IS_ID(name_nodes[i])); // should be + EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(name_nodes[i])); } // nodes[1] contains arguments to the decorator function, if any - if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) { + if (!MP_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) { // call the decorator function with the arguments in nodes[1] compile_node(comp, pns_decorator->nodes[1]); } @@ -967,11 +967,11 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) { } // compile the body (funcdef or classdef) and get its name - py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1]; + mp_parse_node_struct_t *pns_body = (mp_parse_node_struct_t*)pns->nodes[1]; qstr body_name = 0; - if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) { + if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) { body_name = compile_funcdef_helper(comp, pns_body, emit_options); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) { body_name = compile_classdef_helper(comp, pns_body, emit_options); } else { // shouldn't happen @@ -987,39 +987,39 @@ void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(store_id, body_name); } -void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_funcdef(compiler_t *comp, mp_parse_node_struct_t *pns) { qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options); // store function object into function name EMIT(store_id, fname); } -void c_del_stmt(compiler_t *comp, py_parse_node_t pn) { - if (PY_PARSE_NODE_IS_ID(pn)) { - EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn)); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; +void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) { + if (MP_PARSE_NODE_IS_ID(pn)) { + EMIT(delete_id, MP_PARSE_NODE_LEAF_ARG(pn)); + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; compile_node(comp, pns->nodes[0]); // base of the power node - if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) { - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1); + if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { + mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) { + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1); for (int i = 0; i < n - 1; i++) { compile_node(comp, pns1->nodes[i]); } - assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1])); - pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1]; + assert(MP_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1])); + pns1 = (mp_parse_node_struct_t*)pns1->nodes[n - 1]; } - if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) { + if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) { // SyntaxError: can't delete a function call assert(0); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) { compile_node(comp, pns1->nodes[0]); EMIT(delete_subscr); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) { - assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0])); - EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); + } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) { + assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0])); + EMIT(delete_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); } else { // shouldn't happen assert(0); @@ -1029,30 +1029,30 @@ void c_del_stmt(compiler_t *comp, py_parse_node_t pn) { assert(0); } - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) { + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) { // SyntaxError, cannot delete assert(0); } - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) { - pn = ((py_parse_node_struct_t*)pn)->nodes[0]; - if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) { + pn = ((mp_parse_node_struct_t*)pn)->nodes[0]; + if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp - if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) { + if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { + mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) { // sequence of one item, with trailing comma - assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0])); + assert(MP_PARSE_NODE_IS_NULL(pns1->nodes[0])); c_del_stmt(comp, pns->nodes[0]); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) { // sequence of many items - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1); c_del_stmt(comp, pns->nodes[0]); for (int i = 0; i < n; i++) { c_del_stmt(comp, pns1->nodes[i]); } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) { // TODO not implemented; can't del comprehension? assert(0); } else { @@ -1075,18 +1075,18 @@ void c_del_stmt(compiler_t *comp, py_parse_node_t pn) { } } -void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt); } -void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_break_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->break_label == 0) { printf("ERROR: cannot break from here\n"); } EMIT(break_loop, comp->break_label); } -void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_continue_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->continue_label == 0) { printf("ERROR: cannot continue from here\n"); } @@ -1097,19 +1097,19 @@ void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->scope_cur->kind != SCOPE_FUNCTION) { printf("SyntaxError: 'return' outside function\n"); comp->had_error = true; return; } - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // no argument to 'return', so return None - EMIT(load_const_tok, PY_TOKEN_KW_NONE); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) { + EMIT(load_const_tok, MP_TOKEN_KW_NONE); + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) { // special case when returning an if-expression; to match CPython optimisation - py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0]; - py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1]; + mp_parse_node_struct_t *pns_test_if_expr = (mp_parse_node_struct_t*)pns->nodes[0]; + mp_parse_node_struct_t *pns_test_if_else = (mp_parse_node_struct_t*)pns_test_if_expr->nodes[1]; int l_fail = comp_next_label(comp); c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition @@ -1123,18 +1123,18 @@ void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(return_value); } -void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_yield_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[0]); EMIT(pop_top); } -void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { +void compile_raise_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // raise EMIT(raise_varargs, 0); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) { // raise x from y - pns = (py_parse_node_struct_t*)pns->nodes[0]; + pns = (mp_parse_node_struct_t*)pns->nodes[0]; compile_node(comp, pns->nodes[0]); compile_node(comp, pns->nodes[1]); EMIT(raise_varargs, 2); @@ -1148,33 +1148,33 @@ void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { // q1 holds the base, q2 the full name // eg a -> q1=q2=a // a.b.c -> q1=a, q2=a.b.c -void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) { +void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q1, qstr *q2) { bool is_as = false; - if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; // a name of the form x as y; unwrap it - *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]); + *q1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]); pn = pns->nodes[0]; is_as = true; } - if (PY_PARSE_NODE_IS_ID(pn)) { + if (MP_PARSE_NODE_IS_ID(pn)) { // just a simple name - *q2 = PY_PARSE_NODE_LEAF_ARG(pn); + *q2 = MP_PARSE_NODE_LEAF_ARG(pn); if (!is_as) { *q1 = *q2; } EMIT(import_name, *q2); - } else if (PY_PARSE_NODE_IS_STRUCT(pn)) { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) { + } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) { // a name of the form a.b.c if (!is_as) { - *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + *q1 = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); } - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); int len = n - 1; for (int i = 0; i < n; i++) { - len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]))); + len += strlen(qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]))); } char *str = m_new(char, len + 1); str[0] = 0; @@ -1182,13 +1182,13 @@ void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) { if (i > 0) { strcat(str, "."); } - strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]))); + strcat(str, qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]))); } *q2 = qstr_from_str_take(str); EMIT(import_name, *q2); if (is_as) { for (int i = 1; i < n; i++) { - EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])); + EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); } } } else { @@ -1201,20 +1201,20 @@ void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) { } } -void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) { +void compile_dotted_as_name(compiler_t *comp, mp_parse_node_t pn) { EMIT(load_const_small_int, 0); // ?? - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); qstr q1, q2; do_import_name(comp, pn, &q1, &q2); EMIT(store_id, q1); } -void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) { apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name); } -void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) { - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) { +void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) { EMIT(load_const_small_int, 0); // level 0 for __import__ // build the "fromlist" tuple @@ -1234,16 +1234,16 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(load_const_small_int, 0); // level 0 for __import__ // build the "fromlist" tuple - py_parse_node_t *pn_nodes; + mp_parse_node_t *pn_nodes; int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes); #if MICROPY_EMIT_CPYTHON { vstr_t *vstr = vstr_new(); vstr_printf(vstr, "("); for (int i = 0; i < n; i++) { - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name)); - py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i]; - qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name)); + mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pn_nodes[i]; + qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id if (i > 0) { vstr_printf(vstr, ", "); } @@ -1260,9 +1260,9 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) { } #else for (int i = 0; i < n; i++) { - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name)); - py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i]; - qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name)); + mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pn_nodes[i]; + qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id EMIT(load_const_str, id2, false); } EMIT(build_tuple, n); @@ -1272,53 +1272,53 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) { qstr dummy_q, id1; do_import_name(comp, pns->nodes[0], &dummy_q, &id1); for (int i = 0; i < n; i++) { - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name)); - py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i]; - qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name)); + mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pn_nodes[i]; + qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id EMIT(import_from, id2); - if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) { + if (MP_PARSE_NODE_IS_NULL(pns3->nodes[1])) { EMIT(store_id, id2); } else { - EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1])); + EMIT(store_id, MP_PARSE_NODE_LEAF_ARG(pns3->nodes[1])); } } EMIT(pop_top); } } -void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->pass == PASS_1) { - if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) { - scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); + if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { + scope_declare_global(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); } else { - pns = (py_parse_node_struct_t*)pns->nodes[0]; - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + pns = (mp_parse_node_struct_t*)pns->nodes[0]; + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < num_nodes; i++) { - scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])); + scope_declare_global(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); } } } } -void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->pass == PASS_1) { - if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) { - scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); + if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { + scope_declare_nonlocal(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); } else { - pns = (py_parse_node_struct_t*)pns->nodes[0]; - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + pns = (mp_parse_node_struct_t*)pns->nodes[0]; + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < num_nodes; i++) { - scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])); + scope_declare_nonlocal(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); } } } } -void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { int l_end = comp_next_label(comp); c_if_cond(comp, pns->nodes[0], true, l_end); EMIT(load_id, comp->qstr_assertion_error); - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) { + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { // assertion message compile_node(comp, pns->nodes[1]); EMIT(call_function, 1, 0, false, false); @@ -1327,7 +1327,7 @@ void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(label_assign, l_end); } -void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { // TODO proper and/or short circuiting int l_end = comp_next_label(comp); @@ -1336,7 +1336,7 @@ void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition compile_node(comp, pns->nodes[1]); // if block - //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython + //if (!(MP_PARSE_NODE_IS_NULL(pns->nodes[2]) && MP_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython // jump over elif/else blocks if they exist if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython EMIT(jump, l_end); @@ -1344,17 +1344,17 @@ void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { //} EMIT(label_assign, l_fail); - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) { + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[2])) { // compile elif blocks - py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2]; + mp_parse_node_struct_t *pns_elif = (mp_parse_node_struct_t*)pns->nodes[2]; - if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) { + if (MP_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) { // multiple elif blocks - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns_elif); for (int i = 0; i < n; i++) { - py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i]; + mp_parse_node_struct_t *pns_elif2 = (mp_parse_node_struct_t*)pns_elif->nodes[i]; l_fail = comp_next_label(comp); c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition @@ -1385,7 +1385,7 @@ void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(label_assign, l_end); } -void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { int old_break_label = comp->break_label; int old_continue_label = comp->continue_label; @@ -1431,7 +1431,7 @@ void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { // TODO preload end and step onto stack if they are not constants // TODO check if step is negative and do opposite test -void compile_for_stmt_optimised_range(compiler_t *comp, py_parse_node_t pn_var, py_parse_node_t pn_start, py_parse_node_t pn_end, py_parse_node_t pn_step, py_parse_node_t pn_body, py_parse_node_t pn_else) { +void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, mp_parse_node_t pn_start, mp_parse_node_t pn_end, mp_parse_node_t pn_step, mp_parse_node_t pn_body, mp_parse_node_t pn_else) { int old_break_label = comp->break_label; int old_continue_label = comp->continue_label; @@ -1476,29 +1476,29 @@ void compile_for_stmt_optimised_range(compiler_t *comp, py_parse_node_t pn_var, EMIT(label_assign, break_label); } -void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { #if !MICROPY_EMIT_CPYTHON // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable // this is actually slower, but uses no heap memory // for viper it will be much, much faster - if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ PY_PARSE_NODE_IS_ID(pns->nodes[0]) && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) { - py_parse_node_struct_t *pns_it = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_IS_ID(pns_it->nodes[0]) && PY_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == comp->qstr_range && PY_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren) && PY_PARSE_NODE_IS_NULL(pns_it->nodes[2])) { - py_parse_node_t pn_range_args = ((py_parse_node_struct_t*)pns_it->nodes[1])->nodes[0]; - py_parse_node_t *args; + if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) { + mp_parse_node_struct_t *pns_it = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0]) && MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == comp->qstr_range && MP_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren) && MP_PARSE_NODE_IS_NULL(pns_it->nodes[2])) { + mp_parse_node_t pn_range_args = ((mp_parse_node_struct_t*)pns_it->nodes[1])->nodes[0]; + mp_parse_node_t *args; int n_args = list_get(&pn_range_args, PN_arglist, &args); if (1 <= n_args && n_args <= 3) { - py_parse_node_t pn_range_start; - py_parse_node_t pn_range_end; - py_parse_node_t pn_range_step; + mp_parse_node_t pn_range_start; + mp_parse_node_t pn_range_end; + mp_parse_node_t pn_range_step; if (n_args == 1) { - pn_range_start = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 0); + pn_range_start = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, 0); pn_range_end = args[0]; - pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1); + pn_range_step = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, 1); } else if (n_args == 2) { pn_range_start = args[0]; pn_range_end = args[1]; - pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1); + pn_range_step = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, 1); } else { pn_range_start = args[0]; pn_range_end = args[1]; @@ -1554,7 +1554,7 @@ void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(label_assign, end_label); } -void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except, py_parse_node_t *pn_excepts, py_parse_node_t pn_else) { +void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_excepts, mp_parse_node_t pn_else) { // this function is a bit of a hack at the moment // don't understand how the stack works with exceptions, so we force it to return to the correct value @@ -1571,13 +1571,13 @@ void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except, int l2 = comp_next_label(comp); for (int i = 0; i < n_except; i++) { - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be - py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i]; + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be + mp_parse_node_struct_t *pns_except = (mp_parse_node_struct_t*)pn_excepts[i]; qstr qstr_exception_local = 0; int end_finally_label = comp_next_label(comp); - if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) { + if (MP_PARSE_NODE_IS_NULL(pns_except->nodes[0])) { // this is a catch all exception handler if (i + 1 != n_except) { printf("SyntaxError: default 'except:' must be last\n"); @@ -1585,13 +1585,13 @@ void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except, } } else { // this exception handler requires a match to a certain type of exception - py_parse_node_t pns_exception_expr = pns_except->nodes[0]; - if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) { - py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr; - if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) { + mp_parse_node_t pns_exception_expr = pns_except->nodes[0]; + if (MP_PARSE_NODE_IS_STRUCT(pns_exception_expr)) { + mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pns_exception_expr; + if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) { // handler binds the exception to a local pns_exception_expr = pns3->nodes[0]; - qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]); + qstr_exception_local = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[1]); } } EMIT(dup_top); @@ -1621,9 +1621,9 @@ void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except, } EMIT(pop_except); if (qstr_exception_local != 0) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(label_assign, l3); - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(store_id, qstr_exception_local); EMIT(delete_id, qstr_exception_local); EMIT(end_finally); @@ -1640,47 +1640,47 @@ void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except, EMIT(set_stack_size, stack_size); } -void compile_try_finally(compiler_t *comp, py_parse_node_t pn_body, int n_except, py_parse_node_t *pn_except, py_parse_node_t pn_else, py_parse_node_t pn_finally) { +void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_except, mp_parse_node_t pn_else, mp_parse_node_t pn_finally) { // don't understand how the stack works with exceptions, so we force it to return to the correct value int stack_size = EMIT(get_stack_size); int l_finally_block = comp_next_label(comp); EMIT(setup_finally, l_finally_block); if (n_except == 0) { - assert(PY_PARSE_NODE_IS_NULL(pn_else)); + assert(MP_PARSE_NODE_IS_NULL(pn_else)); compile_node(comp, pn_body); } else { compile_try_except(comp, pn_body, n_except, pn_except, pn_else); } EMIT(pop_block); - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(label_assign, l_finally_block); compile_node(comp, pn_finally); EMIT(end_finally); EMIT(set_stack_size, stack_size); } -void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { - if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) { +void compile_try_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { + if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) { // just try-finally - compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) { + compile_try_finally(comp, pns->nodes[0], 0, NULL, MP_PARSE_NODE_NULL, pns2->nodes[0]); + } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) { // try-except and possibly else and/or finally - py_parse_node_t *pn_excepts; + mp_parse_node_t *pn_excepts; int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts); - if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) { + if (MP_PARSE_NODE_IS_NULL(pns2->nodes[2])) { // no finally compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]); } else { // have finally - compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]); + compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((mp_parse_node_struct_t*)pns2->nodes[2])->nodes[0]); } } else { // just try-except - py_parse_node_t *pn_excepts; + mp_parse_node_t *pn_excepts; int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts); - compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL); + compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, MP_PARSE_NODE_NULL); } } else { // shouldn't happen @@ -1688,15 +1688,15 @@ void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) { +void compile_with_stmt_helper(compiler_t *comp, int n, mp_parse_node_t *nodes, mp_parse_node_t body) { if (n == 0) { // no more pre-bits, compile the body of the with compile_node(comp, body); } else { int l_end = comp_next_label(comp); - if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) { // this pre-bit is of the form "a as b" - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0]; + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)nodes[0]; compile_node(comp, pns->nodes[0]); EMIT(setup_with, l_end); c_assign(comp, pns->nodes[1], ASSIGN_STORE); @@ -1710,16 +1710,16 @@ void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, p compile_with_stmt_helper(comp, n - 1, nodes + 1, body); // finish this with block EMIT(pop_block); - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(label_assign, l_end); EMIT(with_cleanup); EMIT(end_finally); } } -void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit) - py_parse_node_t *nodes; + mp_parse_node_t *nodes; int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes); assert(n > 0); @@ -1727,8 +1727,8 @@ void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]); } -void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { - if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) { +void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) { // for REPL, evaluate then print the expression EMIT(load_id, qstr_from_str_static("__repl_print__")); @@ -1738,7 +1738,7 @@ void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { } else { // for non-REPL, evaluate then discard the expression - if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) { + if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !MP_PARSE_NODE_IS_ID(pns->nodes[0])) { // do nothing with a lonely constant } else { compile_node(comp, pns->nodes[0]); // just an expression @@ -1746,32 +1746,32 @@ void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { } } } else { - py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1]; - int kind = PY_PARSE_NODE_STRUCT_KIND(pns1); + mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1]; + int kind = MP_PARSE_NODE_STRUCT_KIND(pns1); if (kind == PN_expr_stmt_augassign) { c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign compile_node(comp, pns1->nodes[1]); // rhs - assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0])); + assert(MP_PARSE_NODE_IS_TOKEN(pns1->nodes[0])); // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice - switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) { - case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break; - case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break; - case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break; - case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break; - case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break; - case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break; - case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break; - case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break; - case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break; - case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break; - case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break; - case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break; + switch (MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) { + case MP_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break; + case MP_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break; + case MP_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break; + case MP_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break; + case MP_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break; + case MP_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break; + case MP_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break; + case MP_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break; + case MP_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break; + case MP_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break; + case MP_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break; + case MP_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break; default: assert(0); // shouldn't happen } c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign } else if (kind == PN_expr_stmt_assign_list) { - int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1; - compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs + int rhs = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1; + compile_node(comp, ((mp_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs // following CPython, we store left-most first if (rhs > 0) { EMIT(dup_top); @@ -1781,28 +1781,28 @@ void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { if (i + 1 < rhs) { EMIT(dup_top); } - c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store + c_assign(comp, ((mp_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store } } else if (kind == PN_expr_stmt_assign) { - if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr) - && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr) - && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2 - && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr) + && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr) + && MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns1->nodes[0]) == 2 + && MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 2) { // optimisation for a, b = c, d; to match CPython's optimisation - py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0]; - py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0]; + mp_parse_node_struct_t* pns10 = (mp_parse_node_struct_t*)pns1->nodes[0]; + mp_parse_node_struct_t* pns0 = (mp_parse_node_struct_t*)pns->nodes[0]; compile_node(comp, pns10->nodes[0]); // rhs compile_node(comp, pns10->nodes[1]); // rhs EMIT(rot_two); c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr) - && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr) - && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3 - && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr) + && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr) + && MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns1->nodes[0]) == 3 + && MP_PARSE_NODE_STRUCT_NUM_NODES((mp_parse_node_struct_t*)pns->nodes[0]) == 3) { // optimisation for a, b, c = d, e, f; to match CPython's optimisation - py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0]; - py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0]; + mp_parse_node_struct_t* pns10 = (mp_parse_node_struct_t*)pns1->nodes[0]; + mp_parse_node_struct_t* pns0 = (mp_parse_node_struct_t*)pns->nodes[0]; compile_node(comp, pns10->nodes[0]); // rhs compile_node(comp, pns10->nodes[1]); // rhs compile_node(comp, pns10->nodes[2]); // rhs @@ -1822,8 +1822,8 @@ void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) { - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +void c_binary_op(compiler_t *comp, mp_parse_node_struct_t *pns, rt_binary_op_t binary_op) { + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); compile_node(comp, pns->nodes[0]); for (int i = 1; i < num_nodes; i += 1) { compile_node(comp, pns->nodes[i]); @@ -1831,9 +1831,9 @@ void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t b } } -void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) { - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else)); - py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1]; +void compile_test_if_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else)); + mp_parse_node_struct_t *pns_test_if_else = (mp_parse_node_struct_t*)pns->nodes[1]; int stack_size = EMIT(get_stack_size); int l_fail = comp_next_label(comp); @@ -1847,16 +1847,16 @@ void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(label_assign, l_end); } -void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) { // TODO default params etc for lambda; possibly just use funcdef code - //py_parse_node_t pn_params = pns->nodes[0]; - //py_parse_node_t pn_body = pns->nodes[1]; + //mp_parse_node_t pn_params = pns->nodes[0]; + //mp_parse_node_t pn_body = pns->nodes[1]; if (comp->pass == PASS_1) { // create a new scope for this lambda - scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (py_parse_node_t)pns, comp->scope_cur->emit_options); + scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (mp_parse_node_t)pns, comp->scope_cur->emit_options); // store the lambda scope so the compiling function (this one) can use it at each pass - pns->nodes[2] = (py_parse_node_t)s; + pns->nodes[2] = (mp_parse_node_t)s; } // get the scope for this lambda @@ -1866,9 +1866,9 @@ void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) { close_over_variables_etc(comp, this_scope, 0, 0); } -void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_or_test(compiler_t *comp, mp_parse_node_struct_t *pns) { int l_end = comp_next_label(comp); - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < n; i += 1) { compile_node(comp, pns->nodes[i]); if (i + 1 < n) { @@ -1878,9 +1878,9 @@ void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(label_assign, l_end); } -void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_and_test(compiler_t *comp, mp_parse_node_struct_t *pns) { int l_end = comp_next_label(comp); - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < n; i += 1) { compile_node(comp, pns->nodes[i]); if (i + 1 < n) { @@ -1890,14 +1890,14 @@ void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(label_assign, l_end); } -void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_not_test_2(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[0]); EMIT(unary_op, RT_UNARY_OP_NOT); } -void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) { int stack_size = EMIT(get_stack_size); - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); compile_node(comp, pns->nodes[0]); bool multi = (num_nodes > 3); int l_fail = 0; @@ -1910,27 +1910,27 @@ void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) { EMIT(dup_top); EMIT(rot_three); } - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_LESS)) { EMIT(compare_op, RT_COMPARE_OP_LESS); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_MORE)) { EMIT(compare_op, RT_COMPARE_OP_MORE); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_DBL_EQUAL)) { EMIT(compare_op, RT_COMPARE_OP_EQUAL); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_LESS_EQUAL)) { EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_MORE_EQUAL)) { EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_NOT_EQUAL)) { EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_KW_IN)) { EMIT(compare_op, RT_COMPARE_OP_IN); - } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) { - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i]; - int kind = PY_PARSE_NODE_STRUCT_KIND(pns2); + } else if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[i])) { + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[i]; + int kind = MP_PARSE_NODE_STRUCT_KIND(pns2); if (kind == PN_comp_op_not_in) { EMIT(compare_op, RT_COMPARE_OP_NOT_IN); } else if (kind == PN_comp_op_is) { - if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) { + if (MP_PARSE_NODE_IS_NULL(pns2->nodes[0])) { EMIT(compare_op, RT_COMPARE_OP_IS); } else { EMIT(compare_op, RT_COMPARE_OP_IS_NOT); @@ -1958,33 +1958,33 @@ void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_star_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { // TODO assert(0); compile_node(comp, pns->nodes[0]); //EMIT(unary_op, "UNARY_STAR"); } -void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { c_binary_op(comp, pns, RT_BINARY_OP_OR); } -void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_xor_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { c_binary_op(comp, pns, RT_BINARY_OP_XOR); } -void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_and_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { c_binary_op(comp, pns, RT_BINARY_OP_AND); } -void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) { - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +void compile_shift_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); compile_node(comp, pns->nodes[0]); for (int i = 1; i + 1 < num_nodes; i += 2) { compile_node(comp, pns->nodes[i + 1]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_DBL_LESS)) { EMIT(binary_op, RT_BINARY_OP_LSHIFT); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_DBL_MORE)) { EMIT(binary_op, RT_BINARY_OP_RSHIFT); } else { // shouldn't happen @@ -1993,14 +1993,14 @@ void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) { - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +void compile_arith_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); compile_node(comp, pns->nodes[0]); for (int i = 1; i + 1 < num_nodes; i += 2) { compile_node(comp, pns->nodes[i + 1]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_PLUS)) { EMIT(binary_op, RT_BINARY_OP_ADD); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_MINUS)) { EMIT(binary_op, RT_BINARY_OP_SUBTRACT); } else { // shouldn't happen @@ -2009,18 +2009,18 @@ void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) { - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +void compile_term(compiler_t *comp, mp_parse_node_struct_t *pns) { + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); compile_node(comp, pns->nodes[0]); for (int i = 1; i + 1 < num_nodes; i += 2) { compile_node(comp, pns->nodes[i + 1]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_STAR)) { EMIT(binary_op, RT_BINARY_OP_MULTIPLY); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_DBL_SLASH)) { EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_SLASH)) { EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_PERCENT)) { EMIT(binary_op, RT_BINARY_OP_MODULO); } else { // shouldn't happen @@ -2029,13 +2029,13 @@ void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_factor_2(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[1]); - if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_PLUS)) { EMIT(unary_op, RT_UNARY_OP_POSITIVE); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_MINUS)) { EMIT(unary_op, RT_UNARY_OP_NEGATIVE); - } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) { + } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_TILDE)) { EMIT(unary_op, RT_UNARY_OP_INVERT); } else { // shouldn't happen @@ -2043,7 +2043,7 @@ void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) { +void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_struct_t *pns, bool is_method_call) { // function to call is on top of stack int old_n_arg_keyword = comp->n_arg_keyword; @@ -2075,14 +2075,14 @@ void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, comp->have_dbl_star_arg = old_have_dbl_star_arg; } -void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) { - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); +void compile_power_trailers(compiler_t *comp, mp_parse_node_struct_t *pns) { + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < num_nodes; i++) { - if (i + 1 < num_nodes && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i], PN_trailer_period) && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i + 1], PN_trailer_paren)) { + if (i + 1 < num_nodes && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i], PN_trailer_period) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i + 1], PN_trailer_paren)) { // optimisation for method calls a.f(...), following PyPy - py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i]; - py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1]; - EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method + mp_parse_node_struct_t *pns_period = (mp_parse_node_struct_t*)pns->nodes[i]; + mp_parse_node_struct_t *pns_paren = (mp_parse_node_struct_t*)pns->nodes[i + 1]; + EMIT(load_method, MP_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method compile_trailer_paren_helper(comp, pns_paren, true); i += 1; } else { @@ -2091,29 +2091,29 @@ void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_power_dbl_star(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[0]); EMIT(binary_op, RT_BINARY_OP_POWER); } -void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_atom_string(compiler_t *comp, mp_parse_node_struct_t *pns) { // a list of strings // check type of list (string or bytes) and count total number of bytes - int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); int n_bytes = 0; - int string_kind = PY_PARSE_NODE_NULL; + int string_kind = MP_PARSE_NODE_NULL; for (int i = 0; i < n; i++) { - assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i])); - int pn_kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]); - assert(pn_kind == PY_PARSE_NODE_STRING || pn_kind == PY_PARSE_NODE_BYTES); + assert(MP_PARSE_NODE_IS_LEAF(pns->nodes[i])); + int pn_kind = MP_PARSE_NODE_LEAF_KIND(pns->nodes[i]); + assert(pn_kind == MP_PARSE_NODE_STRING || pn_kind == MP_PARSE_NODE_BYTES); if (i == 0) { string_kind = pn_kind; } else if (pn_kind != string_kind) { printf("SyntaxError: cannot mix bytes and nonbytes literals\n"); return; } - const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])); + const char *str = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); n_bytes += strlen(str); } @@ -2123,24 +2123,24 @@ void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) { // concatenate string/bytes for (int i = 0; i < n; i++) { - const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])); + const char *str = qstr_str(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); strcat(cat_str, str); } - EMIT(load_const_str, qstr_from_str_take(cat_str), string_kind == PY_PARSE_NODE_BYTES); + EMIT(load_const_str, qstr_from_str_take(cat_str), string_kind == MP_PARSE_NODE_BYTES); } // pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node -void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) { - assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2); - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)); - py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1]; +void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_kind_t kind) { + assert(MP_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2); + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)); + mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1]; if (comp->pass == PASS_1) { // create a new scope for this comprehension - scope_t *s = scope_new_and_link(comp, kind, (py_parse_node_t)pns, comp->scope_cur->emit_options); + scope_t *s = scope_new_and_link(comp, kind, (mp_parse_node_t)pns, comp->scope_cur->emit_options); // store the comprehension scope so the compiling function (this one) can use it at each pass - pns_comp_for->nodes[3] = (py_parse_node_t)s; + pns_comp_for->nodes[3] = (mp_parse_node_t)s; } // get the scope for this comprehension @@ -2154,23 +2154,23 @@ void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_ EMIT(call_function, 1, 0, false, false); } -void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) { - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { +void compile_atom_paren(compiler_t *comp, mp_parse_node_struct_t *pns) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // an empty tuple - c_tuple(comp, PY_PARSE_NODE_NULL, NULL); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { - pns = (py_parse_node_struct_t*)pns->nodes[0]; - assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1])); - if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) { + c_tuple(comp, MP_PARSE_NODE_NULL, NULL); + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + pns = (mp_parse_node_struct_t*)pns->nodes[0]; + assert(!MP_PARSE_NODE_IS_NULL(pns->nodes[1])); + if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) { + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) { // tuple of one item, with trailing comma - assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0])); + assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[0])); c_tuple(comp, pns->nodes[0], NULL); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) { // tuple of many items c_tuple(comp, pns->nodes[0], pns2); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) { // generator expression compile_comprehension(comp, pns, SCOPE_GEN_EXPR); } else { @@ -2180,7 +2180,7 @@ void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) { } else { // tuple with 2 items tuple_with_2_items: - c_tuple(comp, PY_PARSE_NODE_NULL, pns); + c_tuple(comp, MP_PARSE_NODE_NULL, pns); } } else { // parenthesis around a single item, is just that item @@ -2188,25 +2188,25 @@ void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) { - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { +void compile_atom_bracket(compiler_t *comp, mp_parse_node_struct_t *pns) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // empty list EMIT(build_list, 0); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0]; - if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) { - py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) { + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[0]; + if (MP_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) { + mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pns2->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) { // list of one item, with trailing comma - assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0])); + assert(MP_PARSE_NODE_IS_NULL(pns3->nodes[0])); compile_node(comp, pns2->nodes[0]); EMIT(build_list, 1); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) { // list of many items compile_node(comp, pns2->nodes[0]); compile_generic_all_nodes(comp, pns3); - EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3)); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) { + EMIT(build_list, 1 + MP_PARSE_NODE_STRUCT_NUM_NODES(pns3)); + } else if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) { // list comprehension compile_comprehension(comp, pns2, SCOPE_LIST_COMP); } else { @@ -2227,31 +2227,31 @@ void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) { - py_parse_node_t pn = pns->nodes[0]; - if (PY_PARSE_NODE_IS_NULL(pn)) { +void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { + mp_parse_node_t pn = pns->nodes[0]; + if (MP_PARSE_NODE_IS_NULL(pn)) { // empty dict EMIT(build_map, 0); - } else if (PY_PARSE_NODE_IS_STRUCT(pn)) { - pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) { + } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { + pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) { // dict with one element EMIT(build_map, 1); compile_node(comp, pn); EMIT(store_map); - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) { - assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed - py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) { + assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed + mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) { // dict/set with multiple elements // get tail elements (2nd, 3rd, ...) - py_parse_node_t *nodes; + mp_parse_node_t *nodes; int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes); // first element sets whether it's a dict or set bool is_dict; - if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { // a dictionary EMIT(build_map, 1 + n); compile_node(comp, pns->nodes[0]); @@ -2265,8 +2265,8 @@ void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) { // process rest of elements for (int i = 0; i < n; i++) { - py_parse_node_t pn = nodes[i]; - bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item); + mp_parse_node_t pn = nodes[i]; + bool is_key_value = MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item); compile_node(comp, pn); if (is_dict) { if (!is_key_value) { @@ -2286,9 +2286,9 @@ void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) { if (!is_dict) { EMIT(build_set, 1 + n); } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) { // dict/set comprehension - if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { // a dictionary comprehension compile_comprehension(comp, pns, SCOPE_DICT_COMP); } else { @@ -2311,34 +2311,34 @@ void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_trailer_paren(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_trailer_paren_helper(comp, pns, false); } -void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_trailer_bracket(compiler_t *comp, mp_parse_node_struct_t *pns) { // object who's index we want is on top of stack compile_node(comp, pns->nodes[0]); // the index EMIT(binary_op, RT_BINARY_OP_SUBSCR); } -void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_trailer_period(compiler_t *comp, mp_parse_node_struct_t *pns) { // object who's attribute we want is on top of stack - EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get + EMIT(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get } -void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) { - assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be - py_parse_node_t pn = pns->nodes[0]; - if (PY_PARSE_NODE_IS_NULL(pn)) { +void compile_subscript_3_helper(compiler_t *comp, mp_parse_node_struct_t *pns) { + assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be + mp_parse_node_t pn = pns->nodes[0]; + if (MP_PARSE_NODE_IS_NULL(pn)) { // [?:] - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(build_slice, 2); - } else if (PY_PARSE_NODE_IS_STRUCT(pn)) { - pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { + pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) { + EMIT(load_const_tok, MP_TOKEN_KW_NONE); pn = pns->nodes[0]; - if (PY_PARSE_NODE_IS_NULL(pn)) { + if (MP_PARSE_NODE_IS_NULL(pn)) { // [?::] EMIT(build_slice, 2); } else { @@ -2346,12 +2346,12 @@ void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) { compile_node(comp, pn); EMIT(build_slice, 3); } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) { compile_node(comp, pns->nodes[0]); - assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be - pns = (py_parse_node_struct_t*)pns->nodes[1]; - assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { + assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be + pns = (mp_parse_node_struct_t*)pns->nodes[1]; + assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // [?:x:] EMIT(build_slice, 2); } else { @@ -2371,30 +2371,30 @@ void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_subscript_2(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[0]); // start of slice - assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be - compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]); + assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be + compile_subscript_3_helper(comp, (mp_parse_node_struct_t*)pns->nodes[1]); } -void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); +void compile_subscript_3(compiler_t *comp, mp_parse_node_struct_t *pns) { + EMIT(load_const_tok, MP_TOKEN_KW_NONE); compile_subscript_3_helper(comp, pns); } -void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_dictorsetmaker_item(compiler_t *comp, mp_parse_node_struct_t *pns) { // if this is called then we are compiling a dict key:value pair compile_node(comp, pns->nodes[1]); // value compile_node(comp, pns->nodes[0]); // key } -void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_classdef(compiler_t *comp, mp_parse_node_struct_t *pns) { qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options); // store class object into class name EMIT(store_id, cname); } -void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_arglist_star(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->have_star_arg) { printf("SyntaxError?: can't have multiple *x\n"); return; @@ -2403,7 +2403,7 @@ void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[0]); } -void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_arglist_dbl_star(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->have_dbl_star_arg) { printf("SyntaxError?: can't have multiple **x\n"); return; @@ -2412,18 +2412,18 @@ void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) { compile_node(comp, pns->nodes[0]); } -void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) { - assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1]; - if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) { - if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) { +void compile_argument(compiler_t *comp, mp_parse_node_struct_t *pns) { + assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[1]; + if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) { + if (!MP_PARSE_NODE_IS_ID(pns->nodes[0])) { printf("SyntaxError?: lhs of keyword argument must be an id\n"); return; } - EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); + EMIT(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); compile_node(comp, pns2->nodes[0]); comp->n_arg_keyword += 1; - } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) { compile_comprehension(comp, pns, SCOPE_GEN_EXPR); } else { // shouldn't happen @@ -2431,19 +2431,19 @@ void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) { } } -void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) { +void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { if (comp->scope_cur->kind != SCOPE_FUNCTION) { printf("SyntaxError: 'yield' outside function\n"); return; } - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(yield_value); - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) { - pns = (py_parse_node_struct_t*)pns->nodes[0]; + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) { + pns = (mp_parse_node_struct_t*)pns->nodes[0]; compile_node(comp, pns->nodes[0]); EMIT(get_iter); - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(yield_from); } else { compile_node(comp, pns->nodes[0]); @@ -2451,7 +2451,7 @@ void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) { } } -typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*); +typedef void (*compile_function_t)(compiler_t*, mp_parse_node_struct_t*); static compile_function_t compile_function[] = { NULL, #define nc NULL @@ -2463,20 +2463,20 @@ static compile_function_t compile_function[] = { #undef DEF_RULE }; -void compile_node(compiler_t *comp, py_parse_node_t pn) { - if (PY_PARSE_NODE_IS_NULL(pn)) { +void compile_node(compiler_t *comp, mp_parse_node_t pn) { + if (MP_PARSE_NODE_IS_NULL(pn)) { // pass - } else if (PY_PARSE_NODE_IS_LEAF(pn)) { - int arg = PY_PARSE_NODE_LEAF_ARG(pn); - switch (PY_PARSE_NODE_LEAF_KIND(pn)) { - case PY_PARSE_NODE_ID: EMIT(load_id, arg); break; - case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break; - case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break; - case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break; - case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break; - case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break; - case PY_PARSE_NODE_TOKEN: - if (arg == PY_TOKEN_NEWLINE) { + } else if (MP_PARSE_NODE_IS_LEAF(pn)) { + int arg = MP_PARSE_NODE_LEAF_ARG(pn); + switch (MP_PARSE_NODE_LEAF_KIND(pn)) { + case MP_PARSE_NODE_ID: EMIT(load_id, arg); break; + case MP_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break; + case MP_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break; + case MP_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break; + case MP_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break; + case MP_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break; + case MP_PARSE_NODE_TOKEN: + if (arg == MP_TOKEN_NEWLINE) { // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline) // or when single_input lets through a NEWLINE (user enters a blank line) // do nothing @@ -2487,11 +2487,11 @@ void compile_node(compiler_t *comp, py_parse_node_t pn) { default: assert(0); } } else { - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)]; + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)]; if (f == NULL) { - printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns)); - py_parse_node_show(pn, 0); + printf("node %u cannot be compiled\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns)); + mp_parse_node_show(pn, 0); assert(0); } else { f(comp, pns); @@ -2499,32 +2499,32 @@ void compile_node(compiler_t *comp, py_parse_node_t pn) { } } -void compile_scope_func_lambda_param(compiler_t *comp, py_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star, bool allow_annotations) { +void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star, bool allow_annotations) { // TODO verify that *k and **k are last etc qstr param_name = 0; - py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL; - if (PY_PARSE_NODE_IS_ID(pn)) { - param_name = PY_PARSE_NODE_LEAF_ARG(pn); + mp_parse_node_t pn_annotation = MP_PARSE_NODE_NULL; + if (MP_PARSE_NODE_IS_ID(pn)) { + param_name = MP_PARSE_NODE_LEAF_ARG(pn); if (comp->have_bare_star) { // comes after a bare star, so doesn't count as a parameter } else { comp->scope_cur->num_params += 1; } } else { - assert(PY_PARSE_NODE_IS_STRUCT(pn)); - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) { - param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + assert(MP_PARSE_NODE_IS_STRUCT(pn)); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_name) { + param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); //int node_index = 1; unused if (allow_annotations) { - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) { + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { // this parameter has an annotation pn_annotation = pns->nodes[1]; } //node_index = 2; unused } /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param - if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) { + if (!MP_PARSE_NODE_IS_NULL(pns->nodes[node_index])) { // this parameter has a default value if (comp->have_bare_star) { comp->scope_cur->num_dict_params += 1; @@ -2538,29 +2538,29 @@ void compile_scope_func_lambda_param(compiler_t *comp, py_parse_node_t pn, pn_ki } else { comp->scope_cur->num_params += 1; } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) { - if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_star) { + if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // bare star // TODO see http://www.python.org/dev/peps/pep-3102/ comp->have_bare_star = true; //assert(comp->scope_cur->num_dict_params == 0); - } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) { + } else if (MP_PARSE_NODE_IS_ID(pns->nodes[0])) { // named star comp->scope_cur->flags |= SCOPE_FLAG_VARARGS; - param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) { + param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + } else if (allow_annotations && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) { // named star with annotation comp->scope_cur->flags |= SCOPE_FLAG_VARARGS; - pns = (py_parse_node_struct_t*)pns->nodes[0]; - param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + pns = (mp_parse_node_struct_t*)pns->nodes[0]; + param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); pn_annotation = pns->nodes[1]; } else { // shouldn't happen assert(0); } - } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) { - param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); - if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) { + } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) { + param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); + if (allow_annotations && !MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { // this parameter has an annotation pn_annotation = pns->nodes[1]; } @@ -2572,7 +2572,7 @@ void compile_scope_func_lambda_param(compiler_t *comp, py_parse_node_t pn, pn_ki } if (param_name != 0) { - if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) { + if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) { // TODO this parameter has an annotation } bool added; @@ -2586,17 +2586,17 @@ void compile_scope_func_lambda_param(compiler_t *comp, py_parse_node_t pn, pn_ki } } -void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) { +void compile_scope_func_param(compiler_t *comp, mp_parse_node_t pn) { compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true); } -void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) { +void compile_scope_lambda_param(compiler_t *comp, mp_parse_node_t pn) { compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false); } -void compile_scope_comp_iter(compiler_t *comp, py_parse_node_t pn_iter, py_parse_node_t pn_inner_expr, int l_top, int for_depth) { +void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_t pn_iter, mp_parse_node_t pn_inner_expr, int l_top, int for_depth) { tail_recursion: - if (PY_PARSE_NODE_IS_NULL(pn_iter)) { + if (MP_PARSE_NODE_IS_NULL(pn_iter)) { // no more nested if/for; compile inner expression compile_node(comp, pn_inner_expr); if (comp->scope_cur->kind == SCOPE_LIST_COMP) { @@ -2609,15 +2609,15 @@ void compile_scope_comp_iter(compiler_t *comp, py_parse_node_t pn_iter, py_parse EMIT(yield_value); EMIT(pop_top); } - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) { // if condition - py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter; + mp_parse_node_struct_t *pns_comp_if = (mp_parse_node_struct_t*)pn_iter; c_if_cond(comp, pns_comp_if->nodes[0], false, l_top); pn_iter = pns_comp_if->nodes[1]; goto tail_recursion; - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) { // for loop - py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter; + mp_parse_node_struct_t *pns_comp_for2 = (mp_parse_node_struct_t*)pn_iter; compile_node(comp, pns_comp_for2->nodes[1]); int l_end2 = comp_next_label(comp); int l_top2 = comp_next_label(comp); @@ -2635,37 +2635,37 @@ void compile_scope_comp_iter(compiler_t *comp, py_parse_node_t pn_iter, py_parse } } -void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) { +void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) { // see http://www.python.org/dev/peps/pep-0257/ // look for the first statement - if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) { // a statement; fall through - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) { // file input; find the first non-newline node - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn; - int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; + int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); for (int i = 0; i < num_nodes; i++) { pn = pns->nodes[i]; - if (!(PY_PARSE_NODE_IS_LEAF(pn) && PY_PARSE_NODE_LEAF_KIND(pn) == PY_PARSE_NODE_TOKEN && PY_PARSE_NODE_LEAF_ARG(pn) == PY_TOKEN_NEWLINE)) { + if (!(MP_PARSE_NODE_IS_LEAF(pn) && MP_PARSE_NODE_LEAF_KIND(pn) == MP_PARSE_NODE_TOKEN && MP_PARSE_NODE_LEAF_ARG(pn) == MP_TOKEN_NEWLINE)) { // not a newline, so this is the first statement; finish search break; } } // if we didn't find a non-newline then it's okay to fall through; pn will be a newline and so doc-string test below will fail gracefully - } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) { + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) { // a list of statements; get the first one - pn = ((py_parse_node_struct_t*)pn)->nodes[0]; + pn = ((mp_parse_node_struct_t*)pn)->nodes[0]; } else { return; } // check the first statement for a doc string - if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) { - py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn; - if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) { - int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]); - if (kind == PY_PARSE_NODE_STRING) { + if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) { + mp_parse_node_struct_t* pns = (mp_parse_node_struct_t*)pn; + if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { + int kind = MP_PARSE_NODE_LEAF_KIND(pns->nodes[0]); + if (kind == MP_PARSE_NODE_STRING) { compile_node(comp, pns->nodes[0]); // a doc string // store doc string EMIT(store_id, comp->qstr___doc__); @@ -2696,12 +2696,12 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { check_for_doc_string(comp, scope->pn); } compile_node(comp, scope->pn); - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(return_value); } else if (scope->kind == SCOPE_FUNCTION) { - assert(PY_PARSE_NODE_IS_STRUCT(scope->pn)); - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn; - assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef); + assert(MP_PARSE_NODE_IS_STRUCT(scope->pn)); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; + assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef); // work out number of parameters, keywords and default parameters, and add them to the id_info array // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc) @@ -2710,18 +2710,18 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param); } - assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something... + assert(MP_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something... compile_node(comp, pns->nodes[3]); // 3 is function body // emit return if it wasn't the last opcode if (!EMIT(last_emit_was_return_value)) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); EMIT(return_value); } } else if (scope->kind == SCOPE_LAMBDA) { - assert(PY_PARSE_NODE_IS_STRUCT(scope->pn)); - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn; - assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3); + assert(MP_PARSE_NODE_IS_STRUCT(scope->pn)); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; + assert(MP_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3); // work out number of parameters, keywords and default parameters, and add them to the id_info array // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc) @@ -2735,11 +2735,11 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) { // a bit of a hack at the moment - assert(PY_PARSE_NODE_IS_STRUCT(scope->pn)); - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn; - assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2); - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)); - py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1]; + assert(MP_PARSE_NODE_IS_STRUCT(scope->pn)); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; + assert(MP_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2); + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)); + mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1]; qstr qstr_arg = qstr_from_str_static(".0"); if (comp->pass == PASS_1) { @@ -2770,14 +2770,14 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { EMIT(for_iter_end); if (scope->kind == SCOPE_GEN_EXPR) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); } EMIT(return_value); } else { assert(scope->kind == SCOPE_CLASS); - assert(PY_PARSE_NODE_IS_STRUCT(scope->pn)); - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn; - assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef); + assert(MP_PARSE_NODE_IS_STRUCT(scope->pn)); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; + assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef); if (comp->pass == PASS_1) { bool added; @@ -2795,7 +2795,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { EMIT(store_locals); EMIT(load_id, comp->qstr___name__); EMIT(store_id, comp->qstr___module__); - EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name + EMIT(load_const_id, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name EMIT(store_id, comp->qstr___qualname__); check_for_doc_string(comp, pns->nodes[2]); @@ -2804,7 +2804,7 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { id_info_t *id = scope_find(scope, comp->qstr___class__); assert(id != NULL); if (id->kind == ID_INFO_KIND_LOCAL) { - EMIT(load_const_tok, PY_TOKEN_KW_NONE); + EMIT(load_const_tok, MP_TOKEN_KW_NONE); } else { EMIT(load_closure, comp->qstr___class__, 0); // XXX check this is the correct local num } @@ -2830,23 +2830,23 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass } // get the function definition parse node - assert(PY_PARSE_NODE_IS_STRUCT(scope->pn)); - py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn; - assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef); + assert(MP_PARSE_NODE_IS_STRUCT(scope->pn)); + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; + assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef); - //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name + //qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name // parameters are in pns->nodes[1] if (comp->pass == PASS_2) { - py_parse_node_t *pn_params; + mp_parse_node_t *pn_params; int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params); scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params); } - assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type + assert(MP_PARSE_NODE_IS_NULL(pns->nodes[2])); // type - py_parse_node_t pn_body = pns->nodes[3]; // body - py_parse_node_t *nodes; + mp_parse_node_t pn_body = pns->nodes[3]; // body + mp_parse_node_t *nodes; int num = list_get(&pn_body, PN_suite_block_stmts, &nodes); if (comp->pass == PASS_3) { @@ -2855,30 +2855,30 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass } for (int i = 0; i < num; i++) { - assert(PY_PARSE_NODE_IS_STRUCT(nodes[i])); - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i]; - assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt); - assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0])); - assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1])); - pns2 = (py_parse_node_struct_t*)pns2->nodes[0]; - assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power); - assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0])); - assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)); - assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2])); - qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]); - pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren - py_parse_node_t *pn_arg; + assert(MP_PARSE_NODE_IS_STRUCT(nodes[i])); + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)nodes[i]; + assert(MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt); + assert(MP_PARSE_NODE_IS_STRUCT(pns2->nodes[0])); + assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[1])); + pns2 = (mp_parse_node_struct_t*)pns2->nodes[0]; + assert(MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_power); + assert(MP_PARSE_NODE_IS_ID(pns2->nodes[0])); + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)); + assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[2])); + qstr op = MP_PARSE_NODE_LEAF_ARG(pns2->nodes[0]); + pns2 = (mp_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren + mp_parse_node_t *pn_arg; int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg); // emit instructions if (strcmp(qstr_str(op), "label") == 0) { - if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) { + if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) { printf("SyntaxError: inline assembler 'label' requires 1 argument\n"); return; } int lab = comp_next_label(comp); if (pass > PASS_1) { - EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0])); + EMIT_INLINE_ASM(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0])); } } else { if (pass > PASS_1) { @@ -2975,7 +2975,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) { } } -bool py_compile(py_parse_node_t pn, bool is_repl) { +bool mp_compile(mp_parse_node_t pn, bool is_repl) { compiler_t *comp = m_new(compiler_t, 1); comp->qstr___class__ = qstr_from_str_static("__class__"); diff --git a/py/compile.h b/py/compile.h index c15b40aa67ee5253160a3a66a646c6948dc3a06c..e283442bb066d465ead0c6bc4a410c58f6b47e71 100644 --- a/py/compile.h +++ b/py/compile.h @@ -1 +1 @@ -bool py_compile(py_parse_node_t pn, bool is_repl); +bool mp_compile(mp_parse_node_t pn, bool is_repl); diff --git a/py/emit.h b/py/emit.h index 62a149e10c3b419bd2f08c8b2c8d1f1ee2e18aaa..ea65731038676ddd2fc51cdf61c77f2a1e4f3741 100644 --- a/py/emit.h +++ b/py/emit.h @@ -32,7 +32,7 @@ typedef struct _emit_method_table_t { void (*import_name)(emit_t *emit, qstr qstr); void (*import_from)(emit_t *emit, qstr qstr); void (*import_star)(emit_t *emit); - void (*load_const_tok)(emit_t *emit, py_token_kind_t tok); + void (*load_const_tok)(emit_t *emit, mp_token_kind_t tok); void (*load_const_small_int)(emit_t *emit, int arg); void (*load_const_int)(emit_t *emit, qstr qstr); void (*load_const_dec)(emit_t *emit, qstr qstr); @@ -129,9 +129,9 @@ typedef struct _emit_inline_asm_t emit_inline_asm_t; typedef struct _emit_inline_asm_method_table_t { void (*start_pass)(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope); void (*end_pass)(emit_inline_asm_t *emit); - int (*count_params)(emit_inline_asm_t *emit, int n_params, py_parse_node_t *pn_params); + int (*count_params)(emit_inline_asm_t *emit, int n_params, mp_parse_node_t *pn_params); void (*label)(emit_inline_asm_t *emit, int label_num, qstr label_id); - void (*op)(emit_inline_asm_t *emit, qstr op, int n_args, py_parse_node_t *pn_args); + void (*op)(emit_inline_asm_t *emit, qstr op, int n_args, mp_parse_node_t *pn_args); } emit_inline_asm_method_table_t; extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table; diff --git a/py/emitbc.c b/py/emitbc.c index e1632f37f206ec1a06732148fa56c2589cf9889c..a10a3b96ebdca29385d6d2f5f924165d8c713ae5 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -6,14 +6,14 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "compile.h" #include "scope.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" -#include "bc.h" +#include "bc0.h" struct _emit_t { pass_kind_t pass; @@ -214,55 +214,55 @@ static void emit_bc_label_assign(emit_t *emit, int l) { static void emit_bc_import_name(emit_t *emit, qstr qstr) { emit_pre(emit, -1); - emit_write_byte_1_qstr(emit, PYBC_IMPORT_NAME, qstr); + emit_write_byte_1_qstr(emit, MP_BC_IMPORT_NAME, qstr); } static void emit_bc_import_from(emit_t *emit, qstr qstr) { emit_pre(emit, 1); - emit_write_byte_1_qstr(emit, PYBC_IMPORT_FROM, qstr); + emit_write_byte_1_qstr(emit, MP_BC_IMPORT_FROM, qstr); } static void emit_bc_import_star(emit_t *emit) { emit_pre(emit, -1); - emit_write_byte_1(emit, PYBC_IMPORT_STAR); + emit_write_byte_1(emit, MP_BC_IMPORT_STAR); } -static void emit_bc_load_const_tok(emit_t *emit, py_token_kind_t tok) { +static void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) { emit_pre(emit, 1); switch (tok) { - case PY_TOKEN_KW_FALSE: emit_write_byte_1(emit, PYBC_LOAD_CONST_FALSE); break; - case PY_TOKEN_KW_NONE: emit_write_byte_1(emit, PYBC_LOAD_CONST_NONE); break; - case PY_TOKEN_KW_TRUE: emit_write_byte_1(emit, PYBC_LOAD_CONST_TRUE); break; + case MP_TOKEN_KW_FALSE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_FALSE); break; + case MP_TOKEN_KW_NONE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_NONE); break; + case MP_TOKEN_KW_TRUE: emit_write_byte_1(emit, MP_BC_LOAD_CONST_TRUE); break; default: assert(0); } } static void emit_bc_load_const_small_int(emit_t *emit, int arg) { emit_pre(emit, 1); - emit_write_byte_1_int(emit, PYBC_LOAD_CONST_SMALL_INT, arg); + emit_write_byte_1_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg); } static void emit_bc_load_const_int(emit_t *emit, qstr qstr) { emit_pre(emit, 1); - emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_INT, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_INT, qstr); } static void emit_bc_load_const_dec(emit_t *emit, qstr qstr) { emit_pre(emit, 1); - emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_DEC, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_DEC, qstr); } static void emit_bc_load_const_id(emit_t *emit, qstr qstr) { emit_pre(emit, 1); - emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_ID, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_ID, qstr); } static void emit_bc_load_const_str(emit_t *emit, qstr qstr, bool bytes) { emit_pre(emit, 1); if (bytes) { - emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_BYTES, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_BYTES, qstr); } else { - emit_write_byte_1_qstr(emit, PYBC_LOAD_CONST_STRING, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_CONST_STRING, qstr); } } @@ -275,219 +275,219 @@ static void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) { assert(local_num >= 0); emit_pre(emit, 1); switch (local_num) { - case 0: emit_write_byte_1(emit, PYBC_LOAD_FAST_0); break; - case 1: emit_write_byte_1(emit, PYBC_LOAD_FAST_1); break; - case 2: emit_write_byte_1(emit, PYBC_LOAD_FAST_2); break; - default: emit_write_byte_1_uint(emit, PYBC_LOAD_FAST_N, local_num); break; + case 0: emit_write_byte_1(emit, MP_BC_LOAD_FAST_0); break; + case 1: emit_write_byte_1(emit, MP_BC_LOAD_FAST_1); break; + case 2: emit_write_byte_1(emit, MP_BC_LOAD_FAST_2); break; + default: emit_write_byte_1_uint(emit, MP_BC_LOAD_FAST_N, local_num); break; } } static void emit_bc_load_deref(emit_t *emit, qstr qstr, int local_num) { emit_pre(emit, 1); - emit_write_byte_1_uint(emit, PYBC_LOAD_DEREF, local_num); + emit_write_byte_1_uint(emit, MP_BC_LOAD_DEREF, local_num); } static void emit_bc_load_closure(emit_t *emit, qstr qstr, int local_num) { emit_pre(emit, 1); - emit_write_byte_1_uint(emit, PYBC_LOAD_CLOSURE, local_num); + emit_write_byte_1_uint(emit, MP_BC_LOAD_CLOSURE, local_num); } static void emit_bc_load_name(emit_t *emit, qstr qstr) { emit_pre(emit, 1); - emit_write_byte_1_qstr(emit, PYBC_LOAD_NAME, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_NAME, qstr); } static void emit_bc_load_global(emit_t *emit, qstr qstr) { emit_pre(emit, 1); - emit_write_byte_1_qstr(emit, PYBC_LOAD_GLOBAL, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_GLOBAL, qstr); } static void emit_bc_load_attr(emit_t *emit, qstr qstr) { emit_pre(emit, 0); - emit_write_byte_1_qstr(emit, PYBC_LOAD_ATTR, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_ATTR, qstr); } static void emit_bc_load_method(emit_t *emit, qstr qstr) { emit_pre(emit, 0); - emit_write_byte_1_qstr(emit, PYBC_LOAD_METHOD, qstr); + emit_write_byte_1_qstr(emit, MP_BC_LOAD_METHOD, qstr); } static void emit_bc_load_build_class(emit_t *emit) { emit_pre(emit, 1); - emit_write_byte_1(emit, PYBC_LOAD_BUILD_CLASS); + emit_write_byte_1(emit, MP_BC_LOAD_BUILD_CLASS); } static void emit_bc_store_fast(emit_t *emit, qstr qstr, int local_num) { assert(local_num >= 0); emit_pre(emit, -1); switch (local_num) { - case 0: emit_write_byte_1(emit, PYBC_STORE_FAST_0); break; - case 1: emit_write_byte_1(emit, PYBC_STORE_FAST_1); break; - case 2: emit_write_byte_1(emit, PYBC_STORE_FAST_2); break; - default: emit_write_byte_1_uint(emit, PYBC_STORE_FAST_N, local_num); break; + case 0: emit_write_byte_1(emit, MP_BC_STORE_FAST_0); break; + case 1: emit_write_byte_1(emit, MP_BC_STORE_FAST_1); break; + case 2: emit_write_byte_1(emit, MP_BC_STORE_FAST_2); break; + default: emit_write_byte_1_uint(emit, MP_BC_STORE_FAST_N, local_num); break; } } static void emit_bc_store_deref(emit_t *emit, qstr qstr, int local_num) { emit_pre(emit, -1); - emit_write_byte_1_uint(emit, PYBC_STORE_DEREF, local_num); + emit_write_byte_1_uint(emit, MP_BC_STORE_DEREF, local_num); } static void emit_bc_store_name(emit_t *emit, qstr qstr) { emit_pre(emit, -1); - emit_write_byte_1_qstr(emit, PYBC_STORE_NAME, qstr); + emit_write_byte_1_qstr(emit, MP_BC_STORE_NAME, qstr); } static void emit_bc_store_global(emit_t *emit, qstr qstr) { emit_pre(emit, -1); - emit_write_byte_1_qstr(emit, PYBC_STORE_GLOBAL, qstr); + emit_write_byte_1_qstr(emit, MP_BC_STORE_GLOBAL, qstr); } static void emit_bc_store_attr(emit_t *emit, qstr qstr) { emit_pre(emit, -2); - emit_write_byte_1_qstr(emit, PYBC_STORE_ATTR, qstr); + emit_write_byte_1_qstr(emit, MP_BC_STORE_ATTR, qstr); } static void emit_bc_store_subscr(emit_t *emit) { emit_pre(emit, -3); - emit_write_byte_1(emit, PYBC_STORE_SUBSCR); + emit_write_byte_1(emit, MP_BC_STORE_SUBSCR); } static void emit_bc_store_locals(emit_t *emit) { // not needed emit_pre(emit, -1); - emit_write_byte_1(emit, PYBC_POP_TOP); + emit_write_byte_1(emit, MP_BC_POP_TOP); } static void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) { assert(local_num >= 0); emit_pre(emit, 0); - emit_write_byte_1_uint(emit, PYBC_DELETE_FAST_N, local_num); + emit_write_byte_1_uint(emit, MP_BC_DELETE_FAST_N, local_num); } static void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) { emit_pre(emit, 0); - emit_write_byte_1_qstr(emit, PYBC_DELETE_DEREF, local_num); + emit_write_byte_1_qstr(emit, MP_BC_DELETE_DEREF, local_num); } static void emit_bc_delete_name(emit_t *emit, qstr qstr) { emit_pre(emit, 0); - emit_write_byte_1_qstr(emit, PYBC_DELETE_NAME, qstr); + emit_write_byte_1_qstr(emit, MP_BC_DELETE_NAME, qstr); } static void emit_bc_delete_global(emit_t *emit, qstr qstr) { emit_pre(emit, 0); - emit_write_byte_1_qstr(emit, PYBC_DELETE_GLOBAL, qstr); + emit_write_byte_1_qstr(emit, MP_BC_DELETE_GLOBAL, qstr); } static void emit_bc_delete_attr(emit_t *emit, qstr qstr) { emit_pre(emit, -1); - emit_write_byte_1_qstr(emit, PYBC_DELETE_ATTR, qstr); + emit_write_byte_1_qstr(emit, MP_BC_DELETE_ATTR, qstr); } static void emit_bc_delete_subscr(emit_t *emit) { emit_pre(emit, -2); - emit_write_byte_1(emit, PYBC_DELETE_SUBSCR); + emit_write_byte_1(emit, MP_BC_DELETE_SUBSCR); } static void emit_bc_dup_top(emit_t *emit) { emit_pre(emit, 1); - emit_write_byte_1(emit, PYBC_DUP_TOP); + emit_write_byte_1(emit, MP_BC_DUP_TOP); } static void emit_bc_dup_top_two(emit_t *emit) { emit_pre(emit, 2); - emit_write_byte_1(emit, PYBC_DUP_TOP_TWO); + emit_write_byte_1(emit, MP_BC_DUP_TOP_TWO); } static void emit_bc_pop_top(emit_t *emit) { emit_pre(emit, -1); - emit_write_byte_1(emit, PYBC_POP_TOP); + emit_write_byte_1(emit, MP_BC_POP_TOP); } static void emit_bc_rot_two(emit_t *emit) { emit_pre(emit, 0); - emit_write_byte_1(emit, PYBC_ROT_TWO); + emit_write_byte_1(emit, MP_BC_ROT_TWO); } static void emit_bc_rot_three(emit_t *emit) { emit_pre(emit, 0); - emit_write_byte_1(emit, PYBC_ROT_THREE); + emit_write_byte_1(emit, MP_BC_ROT_THREE); } static void emit_bc_jump(emit_t *emit, int label) { emit_pre(emit, 0); - emit_write_byte_1_signed_label(emit, PYBC_JUMP, label); + emit_write_byte_1_signed_label(emit, MP_BC_JUMP, label); } static void emit_bc_pop_jump_if_true(emit_t *emit, int label) { emit_pre(emit, -1); - emit_write_byte_1_signed_label(emit, PYBC_POP_JUMP_IF_TRUE, label); + emit_write_byte_1_signed_label(emit, MP_BC_POP_JUMP_IF_TRUE, label); } static void emit_bc_pop_jump_if_false(emit_t *emit, int label) { emit_pre(emit, -1); - emit_write_byte_1_signed_label(emit, PYBC_POP_JUMP_IF_FALSE, label); + emit_write_byte_1_signed_label(emit, MP_BC_POP_JUMP_IF_FALSE, label); } static void emit_bc_jump_if_true_or_pop(emit_t *emit, int label) { emit_pre(emit, -1); - emit_write_byte_1_signed_label(emit, PYBC_JUMP_IF_TRUE_OR_POP, label); + emit_write_byte_1_signed_label(emit, MP_BC_JUMP_IF_TRUE_OR_POP, label); } static void emit_bc_jump_if_false_or_pop(emit_t *emit, int label) { emit_pre(emit, -1); - emit_write_byte_1_signed_label(emit, PYBC_JUMP_IF_FALSE_OR_POP, label); + emit_write_byte_1_signed_label(emit, MP_BC_JUMP_IF_FALSE_OR_POP, label); } static void emit_bc_setup_loop(emit_t *emit, int label) { emit_pre(emit, 0); - emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_LOOP, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_LOOP, label); } static void emit_bc_break_loop(emit_t *emit, int label) { emit_pre(emit, 0); - emit_write_byte_1_unsigned_label(emit, PYBC_BREAK_LOOP, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_BREAK_LOOP, label); } static void emit_bc_continue_loop(emit_t *emit, int label) { emit_pre(emit, 0); - emit_write_byte_1_unsigned_label(emit, PYBC_CONTINUE_LOOP, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_CONTINUE_LOOP, label); } static void emit_bc_setup_with(emit_t *emit, int label) { emit_pre(emit, 7); - emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_WITH, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_WITH, label); } static void emit_bc_with_cleanup(emit_t *emit) { emit_pre(emit, -7); - emit_write_byte_1(emit, PYBC_WITH_CLEANUP); + emit_write_byte_1(emit, MP_BC_WITH_CLEANUP); } static void emit_bc_setup_except(emit_t *emit, int label) { emit_pre(emit, 6); - emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_EXCEPT, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label); } static void emit_bc_setup_finally(emit_t *emit, int label) { emit_pre(emit, 6); - emit_write_byte_1_unsigned_label(emit, PYBC_SETUP_FINALLY, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_SETUP_FINALLY, label); } static void emit_bc_end_finally(emit_t *emit) { emit_pre(emit, -1); - emit_write_byte_1(emit, PYBC_END_FINALLY); + emit_write_byte_1(emit, MP_BC_END_FINALLY); } static void emit_bc_get_iter(emit_t *emit) { emit_pre(emit, 0); - emit_write_byte_1(emit, PYBC_GET_ITER); + emit_write_byte_1(emit, MP_BC_GET_ITER); } static void emit_bc_for_iter(emit_t *emit, int label) { emit_pre(emit, 1); - emit_write_byte_1_unsigned_label(emit, PYBC_FOR_ITER, label); + emit_write_byte_1_unsigned_label(emit, MP_BC_FOR_ITER, label); } static void emit_bc_for_iter_end(emit_t *emit) { @@ -496,104 +496,104 @@ static void emit_bc_for_iter_end(emit_t *emit) { static void emit_bc_pop_block(emit_t *emit) { emit_pre(emit, 0); - emit_write_byte_1(emit, PYBC_POP_BLOCK); + emit_write_byte_1(emit, MP_BC_POP_BLOCK); } static void emit_bc_pop_except(emit_t *emit) { emit_pre(emit, 0); - emit_write_byte_1(emit, PYBC_POP_EXCEPT); + emit_write_byte_1(emit, MP_BC_POP_EXCEPT); } static void emit_bc_unary_op(emit_t *emit, rt_unary_op_t op) { emit_pre(emit, 0); - emit_write_byte_1_byte(emit, PYBC_UNARY_OP, op); + emit_write_byte_1_byte(emit, MP_BC_UNARY_OP, op); } static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) { emit_pre(emit, -1); - emit_write_byte_1_byte(emit, PYBC_BINARY_OP, op); + emit_write_byte_1_byte(emit, MP_BC_BINARY_OP, op); } static void emit_bc_compare_op(emit_t *emit, rt_compare_op_t op) { emit_pre(emit, -1); - emit_write_byte_1_byte(emit, PYBC_COMPARE_OP, op); + emit_write_byte_1_byte(emit, MP_BC_COMPARE_OP, op); } static void emit_bc_build_tuple(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, 1 - n_args); - emit_write_byte_1_uint(emit, PYBC_BUILD_TUPLE, n_args); + emit_write_byte_1_uint(emit, MP_BC_BUILD_TUPLE, n_args); } static void emit_bc_build_list(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, 1 - n_args); - emit_write_byte_1_uint(emit, PYBC_BUILD_LIST, n_args); + emit_write_byte_1_uint(emit, MP_BC_BUILD_LIST, n_args); } static void emit_bc_list_append(emit_t *emit, int list_stack_index) { assert(list_stack_index >= 0); emit_pre(emit, -1); - emit_write_byte_1_uint(emit, PYBC_LIST_APPEND, list_stack_index); + emit_write_byte_1_uint(emit, MP_BC_LIST_APPEND, list_stack_index); } static void emit_bc_build_map(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, 1); - emit_write_byte_1_uint(emit, PYBC_BUILD_MAP, n_args); + emit_write_byte_1_uint(emit, MP_BC_BUILD_MAP, n_args); } static void emit_bc_store_map(emit_t *emit) { emit_pre(emit, -2); - emit_write_byte_1(emit, PYBC_STORE_MAP); + emit_write_byte_1(emit, MP_BC_STORE_MAP); } static void emit_bc_map_add(emit_t *emit, int map_stack_index) { assert(map_stack_index >= 0); emit_pre(emit, -2); - emit_write_byte_1_uint(emit, PYBC_MAP_ADD, map_stack_index); + emit_write_byte_1_uint(emit, MP_BC_MAP_ADD, map_stack_index); } static void emit_bc_build_set(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, 1 - n_args); - emit_write_byte_1_uint(emit, PYBC_BUILD_SET, n_args); + emit_write_byte_1_uint(emit, MP_BC_BUILD_SET, n_args); } static void emit_bc_set_add(emit_t *emit, int set_stack_index) { assert(set_stack_index >= 0); emit_pre(emit, -1); - emit_write_byte_1_uint(emit, PYBC_SET_ADD, set_stack_index); + emit_write_byte_1_uint(emit, MP_BC_SET_ADD, set_stack_index); } static void emit_bc_build_slice(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, 1 - n_args); - emit_write_byte_1_uint(emit, PYBC_BUILD_SLICE, n_args); + emit_write_byte_1_uint(emit, MP_BC_BUILD_SLICE, n_args); } static void emit_bc_unpack_sequence(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, -1 + n_args); - emit_write_byte_1_uint(emit, PYBC_UNPACK_SEQUENCE, n_args); + emit_write_byte_1_uint(emit, MP_BC_UNPACK_SEQUENCE, n_args); } static void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) { assert(n_left >=0 && n_right >= 0); emit_pre(emit, -1 + n_left + n_right + 1); - emit_write_byte_1_uint(emit, PYBC_UNPACK_EX, n_left | (n_right << 8)); + emit_write_byte_1_uint(emit, MP_BC_UNPACK_EX, n_left | (n_right << 8)); } static void emit_bc_make_function(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) { assert(n_default_params == 0 && n_dict_params == 0); emit_pre(emit, 1); - emit_write_byte_1_uint(emit, PYBC_MAKE_FUNCTION, scope->unique_code_id); + emit_write_byte_1_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id); } static void emit_bc_make_closure(emit_t *emit, scope_t *scope, int n_dict_params, int n_default_params) { assert(n_default_params == 0 && n_dict_params == 0); emit_pre(emit, 0); - emit_write_byte_1_uint(emit, PYBC_MAKE_CLOSURE, scope->unique_code_id); + emit_write_byte_1_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id); } static void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) { @@ -608,15 +608,15 @@ static void emit_bc_call_function(emit_t *emit, int n_positional, int n_keyword, int op; if (have_star_arg) { if (have_dbl_star_arg) { - op = PYBC_CALL_FUNCTION_VAR_KW; + op = MP_BC_CALL_FUNCTION_VAR_KW; } else { - op = PYBC_CALL_FUNCTION_VAR; + op = MP_BC_CALL_FUNCTION_VAR; } } else { if (have_dbl_star_arg) { - op = PYBC_CALL_FUNCTION_KW; + op = MP_BC_CALL_FUNCTION_KW; } else { - op = PYBC_CALL_FUNCTION; + op = MP_BC_CALL_FUNCTION; } } emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints @@ -634,15 +634,15 @@ static void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, b int op; if (have_star_arg) { if (have_dbl_star_arg) { - op = PYBC_CALL_METHOD_VAR_KW; + op = MP_BC_CALL_METHOD_VAR_KW; } else { - op = PYBC_CALL_METHOD_VAR; + op = MP_BC_CALL_METHOD_VAR; } } else { if (have_dbl_star_arg) { - op = PYBC_CALL_METHOD_KW; + op = MP_BC_CALL_METHOD_KW; } else { - op = PYBC_CALL_METHOD; + op = MP_BC_CALL_METHOD; } } emit_write_byte_1_uint(emit, op, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints @@ -651,13 +651,13 @@ static void emit_bc_call_method(emit_t *emit, int n_positional, int n_keyword, b static void emit_bc_return_value(emit_t *emit) { emit_pre(emit, -1); emit->last_emit_was_return_value = true; - emit_write_byte_1(emit, PYBC_RETURN_VALUE); + emit_write_byte_1(emit, MP_BC_RETURN_VALUE); } static void emit_bc_raise_varargs(emit_t *emit, int n_args) { assert(n_args >= 0); emit_pre(emit, -n_args); - emit_write_byte_1_uint(emit, PYBC_RAISE_VARARGS, n_args); + emit_write_byte_1_uint(emit, MP_BC_RAISE_VARARGS, n_args); } static void emit_bc_yield_value(emit_t *emit) { @@ -665,7 +665,7 @@ static void emit_bc_yield_value(emit_t *emit) { if (emit->pass == PASS_2) { emit->scope->flags |= SCOPE_FLAG_GENERATOR; } - emit_write_byte_1(emit, PYBC_YIELD_VALUE); + emit_write_byte_1(emit, MP_BC_YIELD_VALUE); } static void emit_bc_yield_from(emit_t *emit) { @@ -673,7 +673,7 @@ static void emit_bc_yield_from(emit_t *emit) { if (emit->pass == PASS_2) { emit->scope->flags |= SCOPE_FLAG_GENERATOR; } - emit_write_byte_1(emit, PYBC_YIELD_FROM); + emit_write_byte_1(emit, MP_BC_YIELD_FROM); } const emit_method_table_t emit_bc_method_table = { diff --git a/py/emitcommon.c b/py/emitcommon.c index 0dfe96d891b068864e9bf7972aeed9e06a6033cc..e30cad74963843a0d48cbc6df5dfc3868dc10a2d 100644 --- a/py/emitcommon.c +++ b/py/emitcommon.c @@ -5,11 +5,11 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "scope.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" #define EMIT(fun, arg...) (emit_method_table->fun(emit, ##arg)) diff --git a/py/emitcpy.c b/py/emitcpy.c index cb8bef47946ecc51427d2af08fbe134381d68da1..52f804925c8a49604915234cd5bb439644df18c7 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -6,12 +6,12 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "compile.h" #include "scope.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" #if MICROPY_EMIT_CPYTHON @@ -136,9 +136,9 @@ static void emit_cpy_load_const_tok(emit_t *emit, py_token_kind_t tok) { if (emit->pass == PASS_3) { printf("LOAD_CONST "); switch (tok) { - case PY_TOKEN_KW_FALSE: printf("False"); break; - case PY_TOKEN_KW_NONE: printf("None"); break; - case PY_TOKEN_KW_TRUE: printf("True"); break; + case MP_TOKEN_KW_FALSE: printf("False"); break; + case MP_TOKEN_KW_NONE: printf("None"); break; + case MP_TOKEN_KW_TRUE: printf("True"); break; default: printf("?=%d\n", tok); return; assert(0); } printf("\n"); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 4a57235da7615217667d515a94ae317b24c881c7..073dfa06040c2a117e18a72384cf3043eca26b76 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -6,11 +6,11 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "scope.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" #include "asmthumb.h" @@ -45,22 +45,22 @@ static void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) { asm_thumb_end_pass(emit->as); if (emit->pass == PASS_3) { - py_fun_t f = asm_thumb_get_code(emit->as); + void *f = asm_thumb_get_code(emit->as); rt_assign_inline_asm_code(emit->scope->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params); } } -static int emit_inline_thumb_count_params(emit_inline_asm_t *emit, int n_params, py_parse_node_t *pn_params) { +static int emit_inline_thumb_count_params(emit_inline_asm_t *emit, int n_params, mp_parse_node_t *pn_params) { if (n_params > 4) { printf("SyntaxError: can only have up to 4 parameters to inline thumb assembly\n"); return 0; } for (int i = 0; i < n_params; i++) { - if (!PY_PARSE_NODE_IS_ID(pn_params[i])) { + if (!MP_PARSE_NODE_IS_ID(pn_params[i])) { printf("SyntaxError: parameter to inline assembler must be an identifier\n"); return 0; } - const char *p = qstr_str(PY_PARSE_NODE_LEAF_ARG(pn_params[i])); + const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i])); if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) { printf("SyntaxError: parameter %d to inline assembler must be r%d\n", i + 1, i); return 0; @@ -84,12 +84,12 @@ static bool check_n_arg(qstr op, int n_args, int wanted_n_args) { } } -static uint get_arg_rlo(qstr op, py_parse_node_t *pn_args, int wanted_arg_num) { - if (!PY_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) { +static uint get_arg_rlo(qstr op, mp_parse_node_t *pn_args, int wanted_arg_num) { + if (!MP_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) { printf("SyntaxError: '%s' expects a register in position %d\n", qstr_str(op), wanted_arg_num); return 0; } - qstr reg_qstr = PY_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); + qstr reg_qstr = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); const char *reg_str = qstr_str(reg_qstr); if (!(strlen(reg_str) == 2 && reg_str[0] == 'r' && ('0' <= reg_str[1] && reg_str[1] <= '7'))) { printf("SyntaxError: '%s' expects a register in position %d\n", qstr_str(op), wanted_arg_num); @@ -98,12 +98,12 @@ static uint get_arg_rlo(qstr op, py_parse_node_t *pn_args, int wanted_arg_num) { return reg_str[1] - '0'; } -static int get_arg_i(qstr op, py_parse_node_t *pn_args, int wanted_arg_num, int fit_mask) { - if (!PY_PARSE_NODE_IS_SMALL_INT(pn_args[wanted_arg_num])) { +static int get_arg_i(qstr op, mp_parse_node_t *pn_args, int wanted_arg_num, int fit_mask) { + if (!MP_PARSE_NODE_IS_SMALL_INT(pn_args[wanted_arg_num])) { printf("SyntaxError: '%s' expects an integer in position %d\n", qstr_str(op), wanted_arg_num); return 0; } - int i = PY_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); + int i = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); if ((i & (~fit_mask)) != 0) { printf("SyntaxError: '%s' integer 0x%x does not fit in mask 0x%x\n", qstr_str(op), i, fit_mask); return 0; @@ -111,12 +111,12 @@ static int get_arg_i(qstr op, py_parse_node_t *pn_args, int wanted_arg_num, int return i; } -static int get_arg_label(emit_inline_asm_t *emit, qstr op, py_parse_node_t *pn_args, int wanted_arg_num) { - if (!PY_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) { +static int get_arg_label(emit_inline_asm_t *emit, qstr op, mp_parse_node_t *pn_args, int wanted_arg_num) { + if (!MP_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) { printf("SyntaxError: '%s' expects a label in position %d\n", qstr_str(op), wanted_arg_num); return 0; } - qstr label_qstr = PY_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); + qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); for (int i = 0; i < emit->max_num_labels; i++) { if (emit->label_lookup[i] == label_qstr) { return i; @@ -129,7 +129,7 @@ static int get_arg_label(emit_inline_asm_t *emit, qstr op, py_parse_node_t *pn_a return 0; } -static void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, py_parse_node_t *pn_args) { +static void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, mp_parse_node_t *pn_args) { // TODO perhaps make two tables: // one_args = // "b", LAB, asm_thumb_b_n, diff --git a/py/emitnative.c b/py/emitnative.c index 17d217c9731af49f29c65c8b4f9805a36cb45401..a29922d96cbdbb1a388daee9bf0b736a96a2123c 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -24,12 +24,14 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "scope.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" +#include "obj.h" +#include "runtime.h" // wrapper around everything in this file #if N_X64 || N_THUMB @@ -258,10 +260,10 @@ static void emit_native_end_pass(emit_t *emit) { if (emit->pass == PASS_3) { #if N_X64 - py_fun_t f = asm_x64_get_code(emit->as); + void *f = asm_x64_get_code(emit->as); rt_assign_native_code(emit->scope->unique_code_id, f, asm_x64_get_code_size(emit->as), emit->scope->num_params); #elif N_THUMB - py_fun_t f = asm_thumb_get_code(emit->as); + void *f = asm_thumb_get_code(emit->as); rt_assign_native_code(emit->scope->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params); #endif } @@ -460,9 +462,9 @@ static void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, int reg_dest, in case VTYPE_BOOL: si->vtype = VTYPE_PYOBJ; if (si->u_imm == 0) { - ASM_MOV_IMM_TO_LOCAL_USING((machine_uint_t)py_const_false, emit->stack_start + emit->stack_size - 1 - i, reg_dest); + ASM_MOV_IMM_TO_LOCAL_USING((machine_uint_t)mp_const_false, emit->stack_start + emit->stack_size - 1 - i, reg_dest); } else { - ASM_MOV_IMM_TO_LOCAL_USING((machine_uint_t)py_const_true, emit->stack_start + emit->stack_size - 1 - i, reg_dest); + ASM_MOV_IMM_TO_LOCAL_USING((machine_uint_t)mp_const_true, emit->stack_start + emit->stack_size - 1 - i, reg_dest); } break; case VTYPE_INT: @@ -561,23 +563,23 @@ static void emit_native_import_star(emit_t *emit) { assert(0); } -static void emit_native_load_const_tok(emit_t *emit, py_token_kind_t tok) { +static void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) { emit_pre(emit); int vtype; machine_uint_t val; if (emit->do_viper_types) { switch (tok) { - case PY_TOKEN_KW_NONE: vtype = VTYPE_PTR_NONE; val = 0; break; - case PY_TOKEN_KW_FALSE: vtype = VTYPE_BOOL; val = 0; break; - case PY_TOKEN_KW_TRUE: vtype = VTYPE_BOOL; val = 1; break; + case MP_TOKEN_KW_NONE: vtype = VTYPE_PTR_NONE; val = 0; break; + case MP_TOKEN_KW_FALSE: vtype = VTYPE_BOOL; val = 0; break; + case MP_TOKEN_KW_TRUE: vtype = VTYPE_BOOL; val = 1; break; default: assert(0); vtype = 0; val = 0; // shouldn't happen } } else { vtype = VTYPE_PYOBJ; switch (tok) { - case PY_TOKEN_KW_NONE: val = (machine_uint_t)py_const_none; break; - case PY_TOKEN_KW_FALSE: val = (machine_uint_t)py_const_false; break; - case PY_TOKEN_KW_TRUE: val = (machine_uint_t)py_const_true; break; + case MP_TOKEN_KW_NONE: val = (machine_uint_t)mp_const_none; break; + case MP_TOKEN_KW_FALSE: val = (machine_uint_t)mp_const_false; break; + case MP_TOKEN_KW_TRUE: val = (machine_uint_t)mp_const_true; break; default: assert(0); vtype = 0; val = 0; // shouldn't happen } } @@ -956,7 +958,7 @@ static void emit_native_for_iter(emit_t *emit, int label) { emit_access_stack(emit, 1, &vtype, REG_ARG_1); assert(vtype == VTYPE_PYOBJ); emit_call(emit, RT_F_ITERNEXT, rt_iternext); - ASM_MOV_IMM_TO_REG((machine_uint_t)py_const_stop_iteration, REG_TEMP1); + ASM_MOV_IMM_TO_REG((machine_uint_t)mp_const_stop_iteration, REG_TEMP1); #if N_X64 asm_x64_cmp_r64_with_r64(emit->as, REG_RET, REG_TEMP1); asm_x64_jcc_label(emit->as, JCC_JE, label); diff --git a/py/emitpass1.c b/py/emitpass1.c index 5526c2d5d84c43f5d08d6833907c124a721ae804..551f30eb4c9cf46b4f1e6c15a65ed6ad01cf7e5f 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -6,12 +6,12 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" #include "compile.h" #include "scope.h" -#include "runtime.h" +#include "runtime0.h" #include "emit.h" struct _emit_t { diff --git a/py/gc.c b/py/gc.c index 690503d92c443e503ceb76d3ba0f82094d21195e..7d4cac6e74df3dee6958778ad9c9c4d198bb3d9a 100644 --- a/py/gc.c +++ b/py/gc.c @@ -3,7 +3,7 @@ #include <stdint.h> #include <string.h> -#include "mpyconfig.h" +#include "mpconfig.h" #include "gc.h" // a machine word is big enough to hold a pointer diff --git a/py/lexer.c b/py/lexer.c index cd2e05ece01d4432e51bda6e264be4596185b664..cf9eae5531fe2829f096301cab21fe8609c3d97d 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -13,11 +13,11 @@ // TODO seems that CPython allows NULL byte in the input stream // don't know if that's intentional or not, but we don't allow it -struct _py_lexer_t { +struct _mp_lexer_t { const char *name; // name of source void *stream_data; // data for stream - py_lexer_stream_next_char_t stream_next_char; // stream callback to get next char - py_lexer_stream_close_t stream_close; // stream callback to free + mp_lexer_stream_next_char_t stream_next_char; // stream callback to get next char + mp_lexer_stream_close_t stream_close; // stream callback to free unichar chr0, chr1, chr2; // current cached characters from source @@ -32,7 +32,7 @@ struct _py_lexer_t { uint16_t *indent_level; vstr_t vstr; - py_token_t tok_cur; + mp_token_t tok_cur; }; bool str_strn_equal(const char *str, const char *strn, int len) { @@ -47,7 +47,7 @@ bool str_strn_equal(const char *str, const char *strn, int len) { return i == len && *str == 0; } -void py_token_show(const py_token_t *tok) { +void mp_token_show(const mp_token_t *tok) { printf("(%s:%d:%d) kind:%d str:%p len:%d", tok->src_name, tok->src_line, tok->src_column, tok->kind, tok->str, tok->len); if (tok->str != NULL && tok->len > 0) { const char *i = tok->str; @@ -66,83 +66,83 @@ void py_token_show(const py_token_t *tok) { printf("\n"); } -void py_token_show_error_prefix(const py_token_t *tok) { +void mp_token_show_error_prefix(const mp_token_t *tok) { printf("(%s:%d:%d) ", tok->src_name, tok->src_line, tok->src_column); } -bool py_token_show_error(const py_token_t *tok, const char *msg) { +bool mp_token_show_error(const mp_token_t *tok, const char *msg) { printf("(%s:%d:%d) %s\n", tok->src_name, tok->src_line, tok->src_column, msg); return false; } #define CUR_CHAR(lex) ((lex)->chr0) -static bool is_end(py_lexer_t *lex) { - return lex->chr0 == PY_LEXER_CHAR_EOF; +static bool is_end(mp_lexer_t *lex) { + return lex->chr0 == MP_LEXER_CHAR_EOF; } -static bool is_physical_newline(py_lexer_t *lex) { +static bool is_physical_newline(mp_lexer_t *lex) { return lex->chr0 == '\n' || lex->chr0 == '\r'; } -static bool is_char(py_lexer_t *lex, char c) { +static bool is_char(mp_lexer_t *lex, char c) { return lex->chr0 == c; } -static bool is_char_or(py_lexer_t *lex, char c1, char c2) { +static bool is_char_or(mp_lexer_t *lex, char c1, char c2) { return lex->chr0 == c1 || lex->chr0 == c2; } -static bool is_char_or3(py_lexer_t *lex, char c1, char c2, char c3) { +static bool is_char_or3(mp_lexer_t *lex, char c1, char c2, char c3) { return lex->chr0 == c1 || lex->chr0 == c2 || lex->chr0 == c3; } /* -static bool is_char_following(py_lexer_t *lex, char c) { +static bool is_char_following(mp_lexer_t *lex, char c) { return lex->chr1 == c; } */ -static bool is_char_following_or(py_lexer_t *lex, char c1, char c2) { +static bool is_char_following_or(mp_lexer_t *lex, char c1, char c2) { return lex->chr1 == c1 || lex->chr1 == c2; } -static bool is_char_following_following_or(py_lexer_t *lex, char c1, char c2) { +static bool is_char_following_following_or(mp_lexer_t *lex, char c1, char c2) { return lex->chr2 == c1 || lex->chr2 == c2; } -static bool is_char_and(py_lexer_t *lex, char c1, char c2) { +static bool is_char_and(mp_lexer_t *lex, char c1, char c2) { return lex->chr0 == c1 && lex->chr1 == c2; } -static bool is_whitespace(py_lexer_t *lex) { +static bool is_whitespace(mp_lexer_t *lex) { return g_unichar_isspace(lex->chr0); } -static bool is_letter(py_lexer_t *lex) { +static bool is_letter(mp_lexer_t *lex) { return g_unichar_isalpha(lex->chr0); } -static bool is_digit(py_lexer_t *lex) { +static bool is_digit(mp_lexer_t *lex) { return g_unichar_isdigit(lex->chr0); } -static bool is_following_digit(py_lexer_t *lex) { +static bool is_following_digit(mp_lexer_t *lex) { return g_unichar_isdigit(lex->chr1); } // TODO UNICODE include unicode characters in definition of identifiers -static bool is_head_of_identifier(py_lexer_t *lex) { +static bool is_head_of_identifier(mp_lexer_t *lex) { return is_letter(lex) || lex->chr0 == '_'; } // TODO UNICODE include unicode characters in definition of identifiers -static bool is_tail_of_identifier(py_lexer_t *lex) { +static bool is_tail_of_identifier(mp_lexer_t *lex) { return is_head_of_identifier(lex) || is_digit(lex); } -static void next_char(py_lexer_t *lex) { - if (lex->chr0 == PY_LEXER_CHAR_EOF) { +static void next_char(mp_lexer_t *lex) { + if (lex->chr0 == MP_LEXER_CHAR_EOF) { return; } @@ -172,16 +172,16 @@ static void next_char(py_lexer_t *lex) { lex->chr0 = lex->chr1; lex->chr1 = lex->chr2; lex->chr2 = lex->stream_next_char(lex->stream_data); - if (lex->chr2 == PY_LEXER_CHAR_EOF) { + if (lex->chr2 == MP_LEXER_CHAR_EOF) { // EOF - if (lex->chr1 != PY_LEXER_CHAR_EOF && lex->chr1 != '\n' && lex->chr1 != '\r') { + if (lex->chr1 != MP_LEXER_CHAR_EOF && lex->chr1 != '\n' && lex->chr1 != '\r') { lex->chr2 = '\n'; // insert newline at end of file } } } } -void indent_push(py_lexer_t *lex, uint indent) { +void indent_push(mp_lexer_t *lex, uint indent) { if (lex->num_indent_level >= lex->alloc_indent_level) { lex->alloc_indent_level *= 2; lex->indent_level = m_renew(uint16_t, lex->indent_level, lex->alloc_indent_level); @@ -189,11 +189,11 @@ void indent_push(py_lexer_t *lex, uint indent) { lex->indent_level[lex->num_indent_level++] = indent; } -uint indent_top(py_lexer_t *lex) { +uint indent_top(mp_lexer_t *lex) { return lex->indent_level[lex->num_indent_level - 1]; } -void indent_pop(py_lexer_t *lex) { +void indent_pop(mp_lexer_t *lex) { lex->num_indent_level -= 1; } @@ -222,24 +222,24 @@ static const char *tok_enc = // TODO static assert that number of tokens is less than 256 so we can safely make this table with byte sized entries static const uint8_t tok_enc_kind[] = { - PY_TOKEN_DEL_PAREN_OPEN, PY_TOKEN_DEL_PAREN_CLOSE, - PY_TOKEN_DEL_BRACKET_OPEN, PY_TOKEN_DEL_BRACKET_CLOSE, - PY_TOKEN_DEL_BRACE_OPEN, PY_TOKEN_DEL_BRACE_CLOSE, - PY_TOKEN_DEL_COMMA, PY_TOKEN_DEL_COLON, PY_TOKEN_DEL_SEMICOLON, PY_TOKEN_DEL_AT, PY_TOKEN_OP_TILDE, - - PY_TOKEN_OP_LESS, PY_TOKEN_OP_LESS_EQUAL, PY_TOKEN_OP_DBL_LESS, PY_TOKEN_DEL_DBL_LESS_EQUAL, - PY_TOKEN_OP_MORE, PY_TOKEN_OP_MORE_EQUAL, PY_TOKEN_OP_DBL_MORE, PY_TOKEN_DEL_DBL_MORE_EQUAL, - PY_TOKEN_OP_STAR, PY_TOKEN_DEL_STAR_EQUAL, PY_TOKEN_OP_DBL_STAR, PY_TOKEN_DEL_DBL_STAR_EQUAL, - PY_TOKEN_OP_PLUS, PY_TOKEN_DEL_PLUS_EQUAL, - PY_TOKEN_OP_MINUS, PY_TOKEN_DEL_MINUS_EQUAL, PY_TOKEN_DEL_MINUS_MORE, - PY_TOKEN_OP_AMPERSAND, PY_TOKEN_DEL_AMPERSAND_EQUAL, - PY_TOKEN_OP_PIPE, PY_TOKEN_DEL_PIPE_EQUAL, - PY_TOKEN_OP_SLASH, PY_TOKEN_DEL_SLASH_EQUAL, PY_TOKEN_OP_DBL_SLASH, PY_TOKEN_DEL_DBL_SLASH_EQUAL, - PY_TOKEN_OP_PERCENT, PY_TOKEN_DEL_PERCENT_EQUAL, - PY_TOKEN_OP_CARET, PY_TOKEN_DEL_CARET_EQUAL, - PY_TOKEN_DEL_EQUAL, PY_TOKEN_OP_DBL_EQUAL, - PY_TOKEN_OP_NOT_EQUAL, - PY_TOKEN_DEL_PERIOD, PY_TOKEN_ELLIPSES, + MP_TOKEN_DEL_PAREN_OPEN, MP_TOKEN_DEL_PAREN_CLOSE, + MP_TOKEN_DEL_BRACKET_OPEN, MP_TOKEN_DEL_BRACKET_CLOSE, + MP_TOKEN_DEL_BRACE_OPEN, MP_TOKEN_DEL_BRACE_CLOSE, + MP_TOKEN_DEL_COMMA, MP_TOKEN_DEL_COLON, MP_TOKEN_DEL_SEMICOLON, MP_TOKEN_DEL_AT, MP_TOKEN_OP_TILDE, + + MP_TOKEN_OP_LESS, MP_TOKEN_OP_LESS_EQUAL, MP_TOKEN_OP_DBL_LESS, MP_TOKEN_DEL_DBL_LESS_EQUAL, + MP_TOKEN_OP_MORE, MP_TOKEN_OP_MORE_EQUAL, MP_TOKEN_OP_DBL_MORE, MP_TOKEN_DEL_DBL_MORE_EQUAL, + MP_TOKEN_OP_STAR, MP_TOKEN_DEL_STAR_EQUAL, MP_TOKEN_OP_DBL_STAR, MP_TOKEN_DEL_DBL_STAR_EQUAL, + MP_TOKEN_OP_PLUS, MP_TOKEN_DEL_PLUS_EQUAL, + MP_TOKEN_OP_MINUS, MP_TOKEN_DEL_MINUS_EQUAL, MP_TOKEN_DEL_MINUS_MORE, + MP_TOKEN_OP_AMPERSAND, MP_TOKEN_DEL_AMPERSAND_EQUAL, + MP_TOKEN_OP_PIPE, MP_TOKEN_DEL_PIPE_EQUAL, + MP_TOKEN_OP_SLASH, MP_TOKEN_DEL_SLASH_EQUAL, MP_TOKEN_OP_DBL_SLASH, MP_TOKEN_DEL_DBL_SLASH_EQUAL, + MP_TOKEN_OP_PERCENT, MP_TOKEN_DEL_PERCENT_EQUAL, + MP_TOKEN_OP_CARET, MP_TOKEN_DEL_CARET_EQUAL, + MP_TOKEN_DEL_EQUAL, MP_TOKEN_OP_DBL_EQUAL, + MP_TOKEN_OP_NOT_EQUAL, + MP_TOKEN_DEL_PERIOD, MP_TOKEN_ELLIPSES, }; // must have the same order as enum in lexer.h @@ -280,7 +280,7 @@ static const char *tok_kw[] = { NULL, }; -static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool first_token) { +static void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool first_token) { // skip white space and comments bool had_physical_newline = false; while (!is_end(lex)) { @@ -322,18 +322,18 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs // if first token is not on first line, we get a physical newline and // this check is done as part of normal indent/dedent checking below // (done to get equivalence with CPython) - tok->kind = PY_TOKEN_INDENT; + tok->kind = MP_TOKEN_INDENT; } else if (lex->emit_dent < 0) { - tok->kind = PY_TOKEN_DEDENT; + tok->kind = MP_TOKEN_DEDENT; lex->emit_dent += 1; } else if (lex->emit_dent > 0) { - tok->kind = PY_TOKEN_INDENT; + tok->kind = MP_TOKEN_INDENT; lex->emit_dent -= 1; } else if (had_physical_newline && lex->nested_bracket_level == 0) { - tok->kind = PY_TOKEN_NEWLINE; + tok->kind = MP_TOKEN_NEWLINE; uint num_spaces = lex->column - 1; lex->emit_dent = 0; @@ -347,20 +347,20 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs lex->emit_dent -= 1; } if (num_spaces != indent_top(lex)) { - tok->kind = PY_TOKEN_DEDENT_MISMATCH; + tok->kind = MP_TOKEN_DEDENT_MISMATCH; } } } else if (is_end(lex)) { if (indent_top(lex) > 0) { - tok->kind = PY_TOKEN_NEWLINE; + tok->kind = MP_TOKEN_NEWLINE; lex->emit_dent = 0; while (indent_top(lex) > 0) { indent_pop(lex); lex->emit_dent -= 1; } } else { - tok->kind = PY_TOKEN_END; + tok->kind = MP_TOKEN_END; } } else if (is_char_or(lex, '\'', '\"') @@ -391,9 +391,9 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs // set token kind if (is_bytes) { - tok->kind = PY_TOKEN_BYTES; + tok->kind = MP_TOKEN_BYTES; } else { - tok->kind = PY_TOKEN_STRING; + tok->kind = MP_TOKEN_STRING; } // get first quoting character @@ -427,8 +427,8 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs next_char(lex); unichar c = CUR_CHAR(lex); switch (c) { - case PY_LEXER_CHAR_EOF: break; // TODO a proper error message? - case '\n': c = PY_LEXER_CHAR_EOF; break; // TODO check this works correctly (we are supposed to ignore it + case MP_LEXER_CHAR_EOF: break; // TODO a proper error message? + case '\n': c = MP_LEXER_CHAR_EOF; break; // TODO check this works correctly (we are supposed to ignore it case '\\': break; case '\'': break; case '"': break; @@ -446,7 +446,7 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs case 'U': // TODO \Uxxxxxxxx only in strings default: break; // TODO error message } - if (c != PY_LEXER_CHAR_EOF) { + if (c != MP_LEXER_CHAR_EOF) { vstr_add_char(&lex->vstr, c); } } else { @@ -458,14 +458,14 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs // check we got the required end quotes if (n_closing < num_quotes) { - tok->kind = PY_TOKEN_LONELY_STRING_OPEN; + tok->kind = MP_TOKEN_LONELY_STRING_OPEN; } // cut off the end quotes from the token text vstr_cut_tail(&lex->vstr, n_closing); } else if (is_head_of_identifier(lex)) { - tok->kind = PY_TOKEN_NAME; + tok->kind = MP_TOKEN_NAME; // get first char vstr_add_char(&lex->vstr, CUR_CHAR(lex)); @@ -478,7 +478,7 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs } } else if (is_digit(lex) || (is_char(lex, '.') && is_following_digit(lex))) { - tok->kind = PY_TOKEN_NUMBER; + tok->kind = MP_TOKEN_NUMBER; // get first char vstr_add_char(&lex->vstr, CUR_CHAR(lex)); @@ -520,7 +520,7 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs if (*t == 0) { // didn't match any delimiter or operator characters - tok->kind = PY_TOKEN_INVALID; + tok->kind = MP_TOKEN_INVALID; } else { // matched a delimiter or operator character @@ -545,7 +545,7 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs next_char(lex); tok_enc_index = t_index; } else { - tok->kind = PY_TOKEN_INVALID; + tok->kind = MP_TOKEN_INVALID; } break; } @@ -569,9 +569,9 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs tok->kind = tok_enc_kind[tok_enc_index]; // compute bracket level for implicit line joining - if (tok->kind == PY_TOKEN_DEL_PAREN_OPEN || tok->kind == PY_TOKEN_DEL_BRACKET_OPEN || tok->kind == PY_TOKEN_DEL_BRACE_OPEN) { + if (tok->kind == MP_TOKEN_DEL_PAREN_OPEN || tok->kind == MP_TOKEN_DEL_BRACKET_OPEN || tok->kind == MP_TOKEN_DEL_BRACE_OPEN) { lex->nested_bracket_level += 1; - } else if (tok->kind == PY_TOKEN_DEL_PAREN_CLOSE || tok->kind == PY_TOKEN_DEL_BRACKET_CLOSE || tok->kind == PY_TOKEN_DEL_BRACE_CLOSE) { + } else if (tok->kind == MP_TOKEN_DEL_PAREN_CLOSE || tok->kind == MP_TOKEN_DEL_BRACKET_CLOSE || tok->kind == MP_TOKEN_DEL_BRACE_CLOSE) { lex->nested_bracket_level -= 1; } } @@ -582,18 +582,18 @@ static void py_lexer_next_token_into(py_lexer_t *lex, py_token_t *tok, bool firs tok->len = vstr_len(&lex->vstr); // check for keywords - if (tok->kind == PY_TOKEN_NAME) { + if (tok->kind == MP_TOKEN_NAME) { for (int i = 0; tok_kw[i] != NULL; i++) { if (str_strn_equal(tok_kw[i], tok->str, tok->len)) { - tok->kind = PY_TOKEN_KW_FALSE + i; + tok->kind = MP_TOKEN_KW_FALSE + i; break; } } } } -py_lexer_t *py_lexer_new(const char *src_name, void *stream_data, py_lexer_stream_next_char_t stream_next_char, py_lexer_stream_close_t stream_close) { - py_lexer_t *lex = m_new(py_lexer_t, 1); +mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close) { + mp_lexer_t *lex = m_new(mp_lexer_t, 1); lex->name = src_name; // TODO do we need to strdup this? lex->stream_data = stream_data; @@ -615,25 +615,25 @@ py_lexer_t *py_lexer_new(const char *src_name, void *stream_data, py_lexer_strea lex->chr2 = stream_next_char(stream_data); // if input stream is 0, 1 or 2 characters long and doesn't end in a newline, then insert a newline at the end - if (lex->chr0 == PY_LEXER_CHAR_EOF) { + if (lex->chr0 == MP_LEXER_CHAR_EOF) { lex->chr0 = '\n'; - } else if (lex->chr1 == PY_LEXER_CHAR_EOF) { + } else if (lex->chr1 == MP_LEXER_CHAR_EOF) { if (lex->chr0 != '\n' && lex->chr0 != '\r') { lex->chr1 = '\n'; } - } else if (lex->chr2 == PY_LEXER_CHAR_EOF) { + } else if (lex->chr2 == MP_LEXER_CHAR_EOF) { if (lex->chr1 != '\n' && lex->chr1 != '\r') { lex->chr2 = '\n'; } } // preload first token - py_lexer_next_token_into(lex, &lex->tok_cur, true); + mp_lexer_next_token_into(lex, &lex->tok_cur, true); return lex; } -void py_lexer_free(py_lexer_t *lex) { +void mp_lexer_free(mp_lexer_t *lex) { if (lex) { if (lex->stream_close) { lex->stream_close(lex->stream_data); @@ -643,45 +643,45 @@ void py_lexer_free(py_lexer_t *lex) { } } -void py_lexer_to_next(py_lexer_t *lex) { - py_lexer_next_token_into(lex, &lex->tok_cur, false); +void mp_lexer_to_next(mp_lexer_t *lex) { + mp_lexer_next_token_into(lex, &lex->tok_cur, false); } -const py_token_t *py_lexer_cur(const py_lexer_t *lex) { +const mp_token_t *mp_lexer_cur(const mp_lexer_t *lex) { return &lex->tok_cur; } -bool py_lexer_is_kind(py_lexer_t *lex, py_token_kind_t kind) { +bool mp_lexer_is_kind(mp_lexer_t *lex, mp_token_kind_t kind) { return lex->tok_cur.kind == kind; } /* -bool py_lexer_is_str(py_lexer_t *lex, const char *str) { - return py_token_is_str(&lex->tok_cur, str); +bool mp_lexer_is_str(mp_lexer_t *lex, const char *str) { + return mp_token_is_str(&lex->tok_cur, str); } -bool py_lexer_opt_kind(py_lexer_t *lex, py_token_kind_t kind) { - if (py_lexer_is_kind(lex, kind)) { - py_lexer_to_next(lex); +bool mp_lexer_opt_kind(mp_lexer_t *lex, mp_token_kind_t kind) { + if (mp_lexer_is_kind(lex, kind)) { + mp_lexer_to_next(lex); return true; } return false; } -bool py_lexer_opt_str(py_lexer_t *lex, const char *str) { - if (py_lexer_is_str(lex, str)) { - py_lexer_to_next(lex); +bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str) { + if (mp_lexer_is_str(lex, str)) { + mp_lexer_to_next(lex); return true; } return false; } */ -bool py_lexer_show_error(py_lexer_t *lex, const char *msg) { - return py_token_show_error(&lex->tok_cur, msg); +bool mp_lexer_show_error(mp_lexer_t *lex, const char *msg) { + return mp_token_show_error(&lex->tok_cur, msg); } -bool py_lexer_show_error_pythonic(py_lexer_t *lex, const char *msg) { +bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg) { printf(" File \"%s\", line %d column %d\n%s\n", lex->tok_cur.src_name, lex->tok_cur.src_line, lex->tok_cur.src_column, msg); return false; } diff --git a/py/lexer.h b/py/lexer.h index 3472370604638302a59d969d7ec72fd350901853..f58a38e92b7c0f88aab0947c5f85bf96cb642fa0 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -1,146 +1,140 @@ -/* lexer.h -- simple tokeniser for Python implementation +/* lexer.h -- simple tokeniser for Micro Python + * + * Uses (byte) length instead of null termination. + * Tokens are the same - UTF-8 with (byte) length. */ -#ifndef INCLUDED_LEXER_H -#define INCLUDED_LEXER_H - -/* uses (byte) length instead of null termination - * tokens are the same - UTF-8 with (byte) length - */ - -typedef enum _py_token_kind_t { - PY_TOKEN_END, // 0 - - PY_TOKEN_INVALID, - PY_TOKEN_DEDENT_MISMATCH, - PY_TOKEN_LONELY_STRING_OPEN, - - PY_TOKEN_NEWLINE, // 4 - PY_TOKEN_INDENT, // 5 - PY_TOKEN_DEDENT, // 6 - - PY_TOKEN_NAME, // 7 - PY_TOKEN_NUMBER, - PY_TOKEN_STRING, - PY_TOKEN_BYTES, - - PY_TOKEN_ELLIPSES, - - PY_TOKEN_KW_FALSE, // 12 - PY_TOKEN_KW_NONE, - PY_TOKEN_KW_TRUE, - PY_TOKEN_KW_AND, - PY_TOKEN_KW_AS, - PY_TOKEN_KW_ASSERT, - PY_TOKEN_KW_BREAK, - PY_TOKEN_KW_CLASS, - PY_TOKEN_KW_CONTINUE, - PY_TOKEN_KW_DEF, // 21 - PY_TOKEN_KW_DEL, - PY_TOKEN_KW_ELIF, - PY_TOKEN_KW_ELSE, - PY_TOKEN_KW_EXCEPT, - PY_TOKEN_KW_FINALLY, - PY_TOKEN_KW_FOR, - PY_TOKEN_KW_FROM, - PY_TOKEN_KW_GLOBAL, - PY_TOKEN_KW_IF, - PY_TOKEN_KW_IMPORT, // 31 - PY_TOKEN_KW_IN, - PY_TOKEN_KW_IS, - PY_TOKEN_KW_LAMBDA, - PY_TOKEN_KW_NONLOCAL, - PY_TOKEN_KW_NOT, - PY_TOKEN_KW_OR, - PY_TOKEN_KW_PASS, - PY_TOKEN_KW_RAISE, - PY_TOKEN_KW_RETURN, - PY_TOKEN_KW_TRY, // 41 - PY_TOKEN_KW_WHILE, - PY_TOKEN_KW_WITH, - PY_TOKEN_KW_YIELD, - - PY_TOKEN_OP_PLUS, // 45 - PY_TOKEN_OP_MINUS, - PY_TOKEN_OP_STAR, - PY_TOKEN_OP_DBL_STAR, - PY_TOKEN_OP_SLASH, - PY_TOKEN_OP_DBL_SLASH, - PY_TOKEN_OP_PERCENT, - PY_TOKEN_OP_LESS, - PY_TOKEN_OP_DBL_LESS, - PY_TOKEN_OP_MORE, - PY_TOKEN_OP_DBL_MORE, // 55 - PY_TOKEN_OP_AMPERSAND, - PY_TOKEN_OP_PIPE, - PY_TOKEN_OP_CARET, - PY_TOKEN_OP_TILDE, - PY_TOKEN_OP_LESS_EQUAL, - PY_TOKEN_OP_MORE_EQUAL, - PY_TOKEN_OP_DBL_EQUAL, - PY_TOKEN_OP_NOT_EQUAL, - - PY_TOKEN_DEL_PAREN_OPEN, // 64 - PY_TOKEN_DEL_PAREN_CLOSE, - PY_TOKEN_DEL_BRACKET_OPEN, - PY_TOKEN_DEL_BRACKET_CLOSE, - PY_TOKEN_DEL_BRACE_OPEN, - PY_TOKEN_DEL_BRACE_CLOSE, - PY_TOKEN_DEL_COMMA, - PY_TOKEN_DEL_COLON, - PY_TOKEN_DEL_PERIOD, - PY_TOKEN_DEL_SEMICOLON, - PY_TOKEN_DEL_AT, // 74 - PY_TOKEN_DEL_EQUAL, - PY_TOKEN_DEL_PLUS_EQUAL, - PY_TOKEN_DEL_MINUS_EQUAL, - PY_TOKEN_DEL_STAR_EQUAL, - PY_TOKEN_DEL_SLASH_EQUAL, - PY_TOKEN_DEL_DBL_SLASH_EQUAL, - PY_TOKEN_DEL_PERCENT_EQUAL, - PY_TOKEN_DEL_AMPERSAND_EQUAL, - PY_TOKEN_DEL_PIPE_EQUAL, - PY_TOKEN_DEL_CARET_EQUAL, // 84 - PY_TOKEN_DEL_DBL_MORE_EQUAL, - PY_TOKEN_DEL_DBL_LESS_EQUAL, - PY_TOKEN_DEL_DBL_STAR_EQUAL, - PY_TOKEN_DEL_MINUS_MORE, -} py_token_kind_t; - -typedef struct _py_token_t { +typedef enum _mp_token_kind_t { + MP_TOKEN_END, // 0 + + MP_TOKEN_INVALID, + MP_TOKEN_DEDENT_MISMATCH, + MP_TOKEN_LONELY_STRING_OPEN, + + MP_TOKEN_NEWLINE, // 4 + MP_TOKEN_INDENT, // 5 + MP_TOKEN_DEDENT, // 6 + + MP_TOKEN_NAME, // 7 + MP_TOKEN_NUMBER, + MP_TOKEN_STRING, + MP_TOKEN_BYTES, + + MP_TOKEN_ELLIPSES, + + MP_TOKEN_KW_FALSE, // 12 + MP_TOKEN_KW_NONE, + MP_TOKEN_KW_TRUE, + MP_TOKEN_KW_AND, + MP_TOKEN_KW_AS, + MP_TOKEN_KW_ASSERT, + MP_TOKEN_KW_BREAK, + MP_TOKEN_KW_CLASS, + MP_TOKEN_KW_CONTINUE, + MP_TOKEN_KW_DEF, // 21 + MP_TOKEN_KW_DEL, + MP_TOKEN_KW_ELIF, + MP_TOKEN_KW_ELSE, + MP_TOKEN_KW_EXCEPT, + MP_TOKEN_KW_FINALLY, + MP_TOKEN_KW_FOR, + MP_TOKEN_KW_FROM, + MP_TOKEN_KW_GLOBAL, + MP_TOKEN_KW_IF, + MP_TOKEN_KW_IMPORT, // 31 + MP_TOKEN_KW_IN, + MP_TOKEN_KW_IS, + MP_TOKEN_KW_LAMBDA, + MP_TOKEN_KW_NONLOCAL, + MP_TOKEN_KW_NOT, + MP_TOKEN_KW_OR, + MP_TOKEN_KW_PASS, + MP_TOKEN_KW_RAISE, + MP_TOKEN_KW_RETURN, + MP_TOKEN_KW_TRY, // 41 + MP_TOKEN_KW_WHILE, + MP_TOKEN_KW_WITH, + MP_TOKEN_KW_YIELD, + + MP_TOKEN_OP_PLUS, // 45 + MP_TOKEN_OP_MINUS, + MP_TOKEN_OP_STAR, + MP_TOKEN_OP_DBL_STAR, + MP_TOKEN_OP_SLASH, + MP_TOKEN_OP_DBL_SLASH, + MP_TOKEN_OP_PERCENT, + MP_TOKEN_OP_LESS, + MP_TOKEN_OP_DBL_LESS, + MP_TOKEN_OP_MORE, + MP_TOKEN_OP_DBL_MORE, // 55 + MP_TOKEN_OP_AMPERSAND, + MP_TOKEN_OP_PIPE, + MP_TOKEN_OP_CARET, + MP_TOKEN_OP_TILDE, + MP_TOKEN_OP_LESS_EQUAL, + MP_TOKEN_OP_MORE_EQUAL, + MP_TOKEN_OP_DBL_EQUAL, + MP_TOKEN_OP_NOT_EQUAL, + + MP_TOKEN_DEL_PAREN_OPEN, // 64 + MP_TOKEN_DEL_PAREN_CLOSE, + MP_TOKEN_DEL_BRACKET_OPEN, + MP_TOKEN_DEL_BRACKET_CLOSE, + MP_TOKEN_DEL_BRACE_OPEN, + MP_TOKEN_DEL_BRACE_CLOSE, + MP_TOKEN_DEL_COMMA, + MP_TOKEN_DEL_COLON, + MP_TOKEN_DEL_PERIOD, + MP_TOKEN_DEL_SEMICOLON, + MP_TOKEN_DEL_AT, // 74 + MP_TOKEN_DEL_EQUAL, + MP_TOKEN_DEL_PLUS_EQUAL, + MP_TOKEN_DEL_MINUS_EQUAL, + MP_TOKEN_DEL_STAR_EQUAL, + MP_TOKEN_DEL_SLASH_EQUAL, + MP_TOKEN_DEL_DBL_SLASH_EQUAL, + MP_TOKEN_DEL_PERCENT_EQUAL, + MP_TOKEN_DEL_AMPERSAND_EQUAL, + MP_TOKEN_DEL_PIPE_EQUAL, + MP_TOKEN_DEL_CARET_EQUAL, // 84 + MP_TOKEN_DEL_DBL_MORE_EQUAL, + MP_TOKEN_DEL_DBL_LESS_EQUAL, + MP_TOKEN_DEL_DBL_STAR_EQUAL, + MP_TOKEN_DEL_MINUS_MORE, +} mp_token_kind_t; + +typedef struct _mp_token_t { const char *src_name; // name of source uint src_line; // source line uint src_column; // source column - py_token_kind_t kind; // kind of token + mp_token_kind_t kind; // kind of token const char *str; // string of token (valid only while this token is current token) uint len; // (byte) length of string of token -} py_token_t; +} mp_token_t; // the next-char function must return the next character in the stream -// it must return PY_LEXER_CHAR_EOF if end of stream -// it can be called again after returning PY_LEXER_CHAR_EOF, and in that case must return PY_LEXER_CHAR_EOF -#define PY_LEXER_CHAR_EOF (-1) -typedef unichar (*py_lexer_stream_next_char_t)(void*); -typedef void (*py_lexer_stream_close_t)(void*); - -typedef struct _py_lexer_t py_lexer_t; - -void py_token_show(const py_token_t *tok); -void py_token_show_error_prefix(const py_token_t *tok); -bool py_token_show_error(const py_token_t *tok, const char *msg); - -py_lexer_t *py_lexer_new(const char *src_name, void *stream_data, py_lexer_stream_next_char_t stream_next_char, py_lexer_stream_close_t stream_close); -void py_lexer_free(py_lexer_t *lex); -void py_lexer_to_next(py_lexer_t *lex); -const py_token_t *py_lexer_cur(const py_lexer_t *lex); -bool py_lexer_is_kind(py_lexer_t *lex, py_token_kind_t kind); +// it must return MP_LEXER_CHAR_EOF if end of stream +// it can be called again after returning MP_LEXER_CHAR_EOF, and in that case must return MP_LEXER_CHAR_EOF +#define MP_LEXER_CHAR_EOF (-1) +typedef unichar (*mp_lexer_stream_next_char_t)(void*); +typedef void (*mp_lexer_stream_close_t)(void*); + +typedef struct _mp_lexer_t mp_lexer_t; + +void mp_token_show(const mp_token_t *tok); +void mp_token_show_error_prefix(const mp_token_t *tok); +bool mp_token_show_error(const mp_token_t *tok, const char *msg); + +mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close); +void mp_lexer_free(mp_lexer_t *lex); +void mp_lexer_to_next(mp_lexer_t *lex); +const mp_token_t *mp_lexer_cur(const mp_lexer_t *lex); +bool mp_lexer_is_kind(mp_lexer_t *lex, mp_token_kind_t kind); /* unused -bool py_lexer_is_str(py_lexer_t *lex, const char *str); -bool py_lexer_opt_kind(py_lexer_t *lex, py_token_kind_t kind); -bool py_lexer_opt_str(py_lexer_t *lex, const char *str); +bool mp_lexer_is_str(mp_lexer_t *lex, const char *str); +bool mp_lexer_opt_kind(mp_lexer_t *lex, mp_token_kind_t kind); +bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str); */ -bool py_lexer_show_error(py_lexer_t *lex, const char *msg); -bool py_lexer_show_error_pythonic(py_lexer_t *lex, const char *msg); - -#endif /* INCLUDED_LEXER_H */ +bool mp_lexer_show_error(mp_lexer_t *lex, const char *msg); +bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg); diff --git a/py/map.c b/py/map.c index 12753af9f9f99300402073b514f9d1f60437c99d..3c2d1fbb5511174ec5eb9d103646fd775b06566b 100644 --- a/py/map.c +++ b/py/map.c @@ -3,12 +3,10 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" -#include "runtime.h" - -#include "map.h" +#include "mpconfig.h" #include "obj.h" -#include "objprivate.h" +#include "runtime0.h" +#include "map.h" // approximatelly doubling primes; made with Mathematica command: Table[Prime[Floor[(1.7)^n]], {n, 3, 24}] static int doubling_primes[] = {7, 19, 43, 89, 179, 347, 647, 1229, 2297, 4243, 7829, 14347, 26017, 47149, 84947, 152443, 273253, 488399, 869927, 1547173, 2745121, 4861607}; @@ -24,43 +22,46 @@ int get_doubling_prime_greater_or_equal_to(int x) { return x | 1; } -void py_map_init(py_map_t *map, py_map_kind_t kind, int n) { +/******************************************************************************/ +/* map */ + +void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n) { map->kind = kind; map->used = 0; map->alloc = get_doubling_prime_greater_or_equal_to(n + 1); - map->table = m_new0(py_map_elem_t, map->alloc); + map->table = m_new0(mp_map_elem_t, map->alloc); } -py_map_t *py_map_new(py_map_kind_t kind, int n) { - py_map_t *map = m_new(py_map_t, 1); - py_map_init(map, kind, n); +mp_map_t *mp_map_new(mp_map_kind_t kind, int n) { + mp_map_t *map = m_new(mp_map_t, 1); + mp_map_init(map, kind, n); return map; } -py_map_elem_t* py_map_lookup_helper(py_map_t *map, py_obj_t index, bool add_if_not_found) { - bool is_map_py_obj = (map->kind == MAP_PY_OBJ); +mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_not_found) { + bool is_map_mp_obj = (map->kind == MP_MAP_OBJ); machine_uint_t hash; - if (is_map_py_obj) { - hash = py_obj_hash(index); + if (is_map_mp_obj) { + hash = mp_obj_hash(index); } else { hash = (machine_uint_t)index; } uint pos = hash % map->alloc; for (;;) { - py_map_elem_t *elem = &map->table[pos]; + mp_map_elem_t *elem = &map->table[pos]; if (elem->key == NULL) { // not in table if (add_if_not_found) { if (map->used + 1 >= map->alloc) { // not enough room in table, rehash it int old_alloc = map->alloc; - py_map_elem_t *old_table = map->table; + mp_map_elem_t *old_table = map->table; map->alloc = get_doubling_prime_greater_or_equal_to(map->alloc + 1); map->used = 0; - map->table = m_new0(py_map_elem_t, map->alloc); + map->table = m_new0(mp_map_elem_t, map->alloc); for (int i = 0; i < old_alloc; i++) { if (old_table[i].key != NULL) { - py_map_lookup_helper(map, old_table[i].key, true)->value = old_table[i].value; + mp_map_lookup_helper(map, old_table[i].key, true)->value = old_table[i].value; } } m_free(old_table); @@ -74,7 +75,7 @@ py_map_elem_t* py_map_lookup_helper(py_map_t *map, py_obj_t index, bool add_if_n } else { return NULL; } - } else if (elem->key == index || (is_map_py_obj && py_obj_equal(elem->key, index))) { + } else if (elem->key == index || (is_map_mp_obj && mp_obj_equal(elem->key, index))) { // found it /* it seems CPython does not replace the index; try x={True:'true'};x[1]='one';x if (add_if_not_found) { @@ -89,55 +90,57 @@ py_map_elem_t* py_map_lookup_helper(py_map_t *map, py_obj_t index, bool add_if_n } } -py_map_elem_t* py_qstr_map_lookup(py_map_t *map, qstr index, bool add_if_not_found) { - py_obj_t o = (py_obj_t)(machine_uint_t)index; - return py_map_lookup_helper(map, o, add_if_not_found); +mp_map_elem_t* mp_qstr_map_lookup(mp_map_t *map, qstr index, bool add_if_not_found) { + mp_obj_t o = (mp_obj_t)(machine_uint_t)index; + return mp_map_lookup_helper(map, o, add_if_not_found); } -py_map_elem_t* py_map_lookup(py_obj_t o, py_obj_t index, bool add_if_not_found) { - assert(IS_O(o, O_MAP)); - return py_map_lookup_helper(&((py_obj_base_t *)o)->u_map, index, add_if_not_found); +/******************************************************************************/ +/* set */ + +void mp_set_init(mp_set_t *set, int n) { + set->alloc = get_doubling_prime_greater_or_equal_to(n + 1); + set->used = 0; + set->table = m_new0(mp_obj_t, set->alloc); } -py_obj_t py_set_lookup(py_obj_t o_in, py_obj_t index, bool add_if_not_found) { - assert(IS_O(o_in, O_SET)); - py_obj_base_t *o = o_in; - int hash = py_obj_hash(index); - int pos = hash % o->u_set.alloc; +mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) { + int hash = mp_obj_hash(index); + int pos = hash % set->alloc; for (;;) { - py_obj_t elem = o->u_set.table[pos]; - if (elem == NULL) { + mp_obj_t elem = set->table[pos]; + if (elem == MP_OBJ_NULL) { // not in table if (add_if_not_found) { - if (o->u_set.used + 1 >= o->u_set.alloc) { + if (set->used + 1 >= set->alloc) { // not enough room in table, rehash it - int old_alloc = o->u_set.alloc; - py_obj_t *old_table = o->u_set.table; - o->u_set.alloc = get_doubling_prime_greater_or_equal_to(o->u_set.alloc + 1); - o->u_set.used = 0; - o->u_set.table = m_new(py_obj_t, o->u_set.alloc); + int old_alloc = set->alloc; + mp_obj_t *old_table = set->table; + set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1); + set->used = 0; + set->table = m_new(mp_obj_t, set->alloc); for (int i = 0; i < old_alloc; i++) { if (old_table[i] != NULL) { - py_set_lookup(o, old_table[i], true); + mp_set_lookup(set, old_table[i], true); } } m_free(old_table); // restart the search for the new element - pos = hash % o->u_set.alloc; + pos = hash % set->alloc; } else { - o->u_set.used += 1; - o->u_set.table[pos] = index; + set->used += 1; + set->table[pos] = index; return index; } } else { - return NULL; + return MP_OBJ_NULL; } - } else if (py_obj_equal(elem, index)) { + } else if (mp_obj_equal(elem, index)) { // found it return elem; } else { // not yet found, keep searching in this table - pos = (pos + 1) % o->u_set.alloc; + pos = (pos + 1) % set->alloc; } } } diff --git a/py/map.h b/py/map.h index 6c9df9ece09ecb49be01f8964412f38523522786..8ee8429b5271ff4bf3584b8696f5682a580f110c 100644 --- a/py/map.h +++ b/py/map.h @@ -1,30 +1,37 @@ typedef enum { - MAP_QSTR, - MAP_PY_OBJ, -} py_map_kind_t; + MP_MAP_QSTR, + MP_MAP_OBJ, +} mp_map_kind_t; -typedef struct _py_map_elem_t { - py_obj_t key; - py_obj_t value; -} py_map_elem_t; +typedef struct _mp_map_elem_t { + mp_obj_t key; + mp_obj_t value; +} mp_map_elem_t; -typedef struct _py_map_t { +typedef struct _mp_map_t { struct { - py_map_kind_t kind : 1; + mp_map_kind_t kind : 1; machine_uint_t used : (8 * BYTES_PER_WORD - 1); }; machine_uint_t alloc; - py_map_elem_t *table; -} py_map_t; + mp_map_elem_t *table; +} mp_map_t; + +typedef struct _mp_set_t { + machine_uint_t alloc; + machine_uint_t used; + mp_obj_t *table; +} mp_set_t; // these are defined in runtime.c -py_map_t *rt_get_map_locals(void); -void rt_set_map_locals(py_map_t *m); +mp_map_t *rt_get_map_locals(void); +void rt_set_map_locals(mp_map_t *m); int get_doubling_prime_greater_or_equal_to(int x); -void py_map_init(py_map_t *map, py_map_kind_t kind, int n); -py_map_t *py_map_new(py_map_kind_t kind, int n); -py_map_elem_t* py_map_lookup_helper(py_map_t *map, py_obj_t index, bool add_if_not_found); -py_map_elem_t* py_qstr_map_lookup(py_map_t *map, qstr index, bool add_if_not_found); -py_map_elem_t* py_map_lookup(py_obj_t o, py_obj_t index, bool add_if_not_found); -py_obj_t py_set_lookup(py_obj_t o_in, py_obj_t index, bool add_if_not_found); +void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n); +mp_map_t *mp_map_new(mp_map_kind_t kind, int n); +mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_not_found); +mp_map_elem_t* mp_qstr_map_lookup(mp_map_t *map, qstr index, bool add_if_not_found); + +void mp_set_init(mp_set_t *set, int n); +mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found); diff --git a/py/misc.h b/py/misc.h index 4a100af29d0797cffe5d456302c038fc2e433494..6c0e18ca0f8e23b87f41325e711fbdedce342591 100644 --- a/py/misc.h +++ b/py/misc.h @@ -19,6 +19,8 @@ typedef unsigned int uint; #define m_new(type, num) ((type*)(m_malloc(sizeof(type) * (num)))) #define m_new0(type, num) ((type*)(m_malloc0(sizeof(type) * (num)))) #define m_renew(type, ptr, num) ((type*)(m_realloc((ptr), sizeof(type) * (num)))) +#define m_new_obj(type) (m_new(type, 1)) +#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type*)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num))) void m_free(void *ptr); void *m_malloc(int num_bytes); diff --git a/py/obj.c b/py/obj.c index 0699d4cde7cc7935a8f7029f8c5a36ee01c0d89e..ff49492bf8e1e40fda87ff04cda91d95a314f966 100644 --- a/py/obj.c +++ b/py/obj.c @@ -6,166 +6,22 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" #include "runtime.h" - #include "map.h" -#include "obj.h" -#include "objprivate.h" - -py_obj_t py_obj_new_int(machine_int_t value) { - return TO_SMALL_INT(value); -} - -py_obj_t py_obj_new_const(const char *id) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_CONST; - o->id = id; - return (py_obj_t)o; -} - -py_obj_t py_obj_new_str(qstr qstr) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_STR; - o->u_str = qstr; - return (py_obj_t)o; -} - -#if MICROPY_ENABLE_FLOAT -py_obj_t py_obj_new_float(py_float_t val) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_FLOAT; - o->u_float = val; - return (py_obj_t)o; -} - -py_obj_t py_obj_new_complex(py_float_t real, py_float_t imag) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_COMPLEX; - o->u_complex.real = real; - o->u_complex.imag = imag; - return (py_obj_t)o; -} -#endif - -py_obj_t py_obj_new_exception_0(qstr id) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_EXCEPTION_0; - o->u_exc0.id = id; - return (py_obj_t)o; -} - -py_obj_t py_obj_new_exception_2(qstr id, const char *fmt, const char *s1, const char *s2) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_EXCEPTION_N; - o->u_exc_n.id = id; - o->u_exc_n.n_args = 3; - o->u_exc_n.args = m_new(const void*, 3); - o->u_exc_n.args[0] = fmt; - o->u_exc_n.args[1] = s1; - o->u_exc_n.args[2] = s2; - return (py_obj_t)o; -} - -// range is a class and instances are immutable sequence objects -py_obj_t py_obj_new_range(int start, int stop, int step) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_RANGE; - o->u_range.start = start; - o->u_range.stop = stop; - o->u_range.step = step; - return o; -} - -py_obj_t py_obj_new_range_iterator(int cur, int stop, int step) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_RANGE_IT; - o->u_range_it.cur = cur; - o->u_range_it.stop = stop; - o->u_range_it.step = step; - return o; -} - -py_obj_t py_obj_new_tuple_iterator(py_obj_base_t *tuple, int cur) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_TUPLE_IT; - o->u_tuple_list_it.obj = tuple; - o->u_tuple_list_it.cur = cur; - return o; -} -py_obj_t py_obj_new_list_iterator(py_obj_base_t *list, int cur) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_LIST_IT; - o->u_tuple_list_it.obj = list; - o->u_tuple_list_it.cur = cur; - return o; +mp_obj_t mp_obj_new_int(machine_int_t value) { + return MP_OBJ_NEW_SMALL_INT(value); } -py_obj_t py_obj_new_user(const py_user_info_t *info, machine_uint_t data1, machine_uint_t data2) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_USER; - // TODO should probably parse the info to turn strings to qstr's, and wrap functions in O_FUN_N objects - // that'll take up some memory. maybe we can lazily do the O_FUN_N: leave it a ptr to a C function, and - // only when the method is looked-up do we change that to the O_FUN_N object. - o->u_user.info = info; - o->u_user.data1 = data1; - o->u_user.data2 = data2; - return o; -} - -const char *py_obj_get_type_str(py_obj_t o_in) { - if (IS_SMALL_INT(o_in)) { +const char *mp_obj_get_type_str(mp_obj_t o_in) { + if (MP_OBJ_IS_SMALL_INT(o_in)) { return "int"; } else { - py_obj_base_t *o = o_in; - switch (o->kind) { - case O_CONST: - if (o == py_const_none) { - return "NoneType"; - } else { - return "bool"; - } - case O_STR: - return "str"; -#if MICROPY_ENABLE_FLOAT - case O_FLOAT: - return "float"; -#endif - case O_FUN_0: - case O_FUN_1: - case O_FUN_2: - case O_FUN_N: - case O_FUN_VAR: - case O_FUN_BC: - return "function"; - case O_GEN_INSTANCE: - return "generator"; - case O_TUPLE: - return "tuple"; - case O_LIST: - return "list"; - case O_TUPLE_IT: - return "tuple_iterator"; - case O_LIST_IT: - return "list_iterator"; - case O_SET: - return "set"; - case O_MAP: - return "dict"; - case O_OBJ: - { - py_map_elem_t *qn = py_qstr_map_lookup(o->u_obj.class->u_class.locals, qstr_from_str_static("__qualname__"), false); - assert(qn != NULL); - assert(IS_O(qn->value, O_STR)); - return qstr_str(((py_obj_base_t*)qn->value)->u_str); - } - case O_USER: - return o->u_user.info->type_name; - default: - assert(0); - return "UnknownType"; - } + mp_obj_base_t *o = o_in; + return o->type->name; } } @@ -176,148 +32,43 @@ void printf_wrapper(void *env, const char *fmt, ...) { va_end(args); } -void py_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, py_obj_t o_in) { - if (IS_SMALL_INT(o_in)) { - print(env, "%d", (int)FROM_SMALL_INT(o_in)); +void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { + if (MP_OBJ_IS_SMALL_INT(o_in)) { + print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(o_in)); } else { - py_obj_base_t *o = o_in; - switch (o->kind) { - case O_CONST: - print(env, "%s", o->id); - break; - case O_STR: - // TODO need to escape chars etc - print(env, "'%s'", qstr_str(o->u_str)); - break; -#if MICROPY_ENABLE_FLOAT - case O_FLOAT: - print(env, "%.8g", o->u_float); - break; - case O_COMPLEX: - if (o->u_complex.real == 0) { - print(env, "%.8gj", o->u_complex.imag); - } else { - print(env, "(%.8g+%.8gj)", o->u_complex.real, o->u_complex.imag); - } - break; -#endif - case O_EXCEPTION_0: - print(env, "%s", qstr_str(o->u_exc0.id)); - break; - case O_EXCEPTION_N: - print(env, "%s: ", qstr_str(o->u_exc_n.id)); - print(env, o->u_exc_n.args[0], o->u_exc_n.args[1], o->u_exc_n.args[2]); - break; - case O_GEN_INSTANCE: - print(env, "<generator object 'fun-name' at %p>", o); - break; - case O_TUPLE: - print(env, "("); - for (int i = 0; i < o->u_tuple_list.len; i++) { - if (i > 0) { - print(env, ", "); - } - py_obj_print_helper(print, env, o->u_tuple_list.items[i]); - } - if (o->u_tuple_list.len == 1) { - print(env, ","); - } - print(env, ")"); - break; - case O_LIST: - print(env, "["); - for (int i = 0; i < o->u_tuple_list.len; i++) { - if (i > 0) { - print(env, ", "); - } - py_obj_print_helper(print, env, o->u_tuple_list.items[i]); - } - print(env, "]"); - break; - case O_SET: - { - bool first = true; - print(env, "{"); - for (int i = 0; i < o->u_set.alloc; i++) { - if (o->u_set.table[i] != NULL) { - if (!first) { - print(env, ", "); - } - first = false; - py_obj_print_helper(print, env, o->u_set.table[i]); - } - } - print(env, "}"); - break; - } - case O_MAP: - { - bool first = true; - print(env, "{"); - for (int i = 0; i < o->u_map.alloc; i++) { - if (o->u_map.table[i].key != NULL) { - if (!first) { - print(env, ", "); - } - first = false; - py_obj_print_helper(print, env, o->u_map.table[i].key); - print(env, ": "); - py_obj_print_helper(print, env, o->u_map.table[i].value); - } - } - print(env, "}"); - break; - } - case O_USER: - if (o->u_user.info->print == NULL) { - print(env, "<unknown user object>"); - } else { - o->u_user.info->print(o_in); - } - break; - default: - print(env, "<? %d>", o->kind); - assert(0); + mp_obj_base_t *o = o_in; + if (o->type->print != NULL) { + o->type->print(print, env, o_in); + } else { + print(env, "<%s>", o->type->name); } } } -void py_obj_print(py_obj_t o_in) { - py_obj_print_helper(printf_wrapper, NULL, o_in); +void mp_obj_print(mp_obj_t o_in) { + mp_obj_print_helper(printf_wrapper, NULL, o_in); } -bool py_obj_is_callable(py_obj_t o_in) { - if (IS_SMALL_INT(o_in)) { +bool mp_obj_is_callable(mp_obj_t o_in) { + if (MP_OBJ_IS_SMALL_INT(o_in)) { return false; } else { - py_obj_base_t *o = o_in; - switch (o->kind) { - case O_FUN_0: - case O_FUN_1: - case O_FUN_2: - case O_FUN_VAR: - case O_FUN_N: - case O_FUN_BC: - case O_FUN_ASM: - // what about O_CLASS, and an O_OBJ that has a __call__ method? - return true; - default: - return false; - } + mp_obj_base_t *o = o_in; + return o->type->call_n != NULL; } } -machine_int_t py_obj_hash(py_obj_t o_in) { - if (o_in == py_const_false) { +machine_int_t mp_obj_hash(mp_obj_t o_in) { + if (o_in == mp_const_false) { return 0; // needs to hash to same as the integer 0, since False==0 - } else if (o_in == py_const_true) { + } else if (o_in == mp_const_true) { return 1; // needs to hash to same as the integer 1, since True==1 - } else if (IS_SMALL_INT(o_in)) { - return FROM_SMALL_INT(o_in); - } else if (IS_O(o_in, O_CONST)) { + } else if (MP_OBJ_IS_SMALL_INT(o_in)) { + return MP_OBJ_SMALL_INT_VALUE(o_in); + } else if (MP_OBJ_IS_TYPE(o_in, &none_type)) { return (machine_int_t)o_in; - } else if (IS_O(o_in, O_STR)) { - return ((py_obj_base_t*)o_in)->u_str; + } else if (MP_OBJ_IS_TYPE(o_in, &str_type)) { + return mp_obj_str_get(o_in); } else { assert(0); return 0; @@ -330,38 +81,38 @@ machine_int_t py_obj_hash(py_obj_t o_in) { // to a common type. Otherwise, the == and != operators always consider objects of // different types to be unequal." // note also that False==0 and True==1 are true expressions -bool py_obj_equal(py_obj_t o1, py_obj_t o2) { +bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { if (o1 == o2) { return true; - } else if (IS_SMALL_INT(o1) || IS_SMALL_INT(o2)) { - if (IS_SMALL_INT(o1) && IS_SMALL_INT(o2)) { + } else if (MP_OBJ_IS_SMALL_INT(o1) || MP_OBJ_IS_SMALL_INT(o2)) { + if (MP_OBJ_IS_SMALL_INT(o1) && MP_OBJ_IS_SMALL_INT(o2)) { return false; } else { - if (IS_SMALL_INT(o2)) { - py_obj_t temp = o1; o1 = o2; o2 = temp; + if (MP_OBJ_IS_SMALL_INT(o2)) { + mp_obj_t temp = o1; o1 = o2; o2 = temp; } // o1 is the SMALL_INT, o2 is not - py_small_int_t val = FROM_SMALL_INT(o1); - if (o2 == py_const_false) { + mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o1); + if (o2 == mp_const_false) { return val == 0; - } else if (o2 == py_const_true) { + } else if (o2 == mp_const_true) { return val == 1; } else { return false; } } - } else if (IS_O(o1, O_STR) && IS_O(o2, O_STR)) { - return ((py_obj_base_t*)o1)->u_str == ((py_obj_base_t*)o2)->u_str; + } else if (MP_OBJ_IS_TYPE(o1, &str_type) && MP_OBJ_IS_TYPE(o2, &str_type)) { + return mp_obj_str_get(o1) == mp_obj_str_get(o2); } else { assert(0); return false; } } -bool py_obj_less(py_obj_t o1, py_obj_t o2) { - if (IS_SMALL_INT(o1) && IS_SMALL_INT(o2)) { - py_small_int_t i1 = FROM_SMALL_INT(o1); - py_small_int_t i2 = FROM_SMALL_INT(o2); +bool mp_obj_less(mp_obj_t o1, mp_obj_t o2) { + if (MP_OBJ_IS_SMALL_INT(o1) && MP_OBJ_IS_SMALL_INT(o2)) { + mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1); + mp_small_int_t i2 = MP_OBJ_SMALL_INT_VALUE(o2); return i1 < i2; } else { assert(0); @@ -369,13 +120,13 @@ bool py_obj_less(py_obj_t o1, py_obj_t o2) { } } -machine_int_t py_obj_get_int(py_obj_t arg) { - if (arg == py_const_false) { +machine_int_t mp_obj_get_int(mp_obj_t arg) { + if (arg == mp_const_false) { return 0; - } else if (arg == py_const_true) { + } else if (arg == mp_const_true) { return 1; - } else if (IS_SMALL_INT(arg)) { - return FROM_SMALL_INT(arg); + } else if (MP_OBJ_IS_SMALL_INT(arg)) { + return MP_OBJ_SMALL_INT_VALUE(arg); } else { assert(0); return 0; @@ -383,37 +134,36 @@ machine_int_t py_obj_get_int(py_obj_t arg) { } #if MICROPY_ENABLE_FLOAT -machine_float_t py_obj_get_float(py_obj_t arg) { - if (arg == py_const_false) { +machine_float_t mp_obj_get_float(mp_obj_t arg) { + if (arg == mp_const_false) { return 0; - } else if (arg == py_const_true) { + } else if (arg == mp_const_true) { return 1; - } else if (IS_SMALL_INT(arg)) { - return FROM_SMALL_INT(arg); - } else if (IS_O(arg, O_FLOAT)) { - return ((py_obj_base_t*)arg)->u_float; + } else if (MP_OBJ_IS_SMALL_INT(arg)) { + return MP_OBJ_SMALL_INT_VALUE(arg); + } else if (MP_OBJ_IS_TYPE(arg, &float_type)) { + return mp_obj_float_get(arg); } else { assert(0); return 0; } } -void py_obj_get_complex(py_obj_t arg, py_float_t *real, py_float_t *imag) { - if (arg == py_const_false) { +void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { + if (arg == mp_const_false) { *real = 0; *imag = 0; - } else if (arg == py_const_true) { + } else if (arg == mp_const_true) { *real = 1; *imag = 0; - } else if (IS_SMALL_INT(arg)) { - *real = FROM_SMALL_INT(arg); + } else if (MP_OBJ_IS_SMALL_INT(arg)) { + *real = MP_OBJ_SMALL_INT_VALUE(arg); *imag = 0; - } else if (IS_O(arg, O_FLOAT)) { - *real = ((py_obj_base_t*)arg)->u_float; + } else if (MP_OBJ_IS_TYPE(arg, &float_type)) { + *real = mp_obj_float_get(arg); *imag = 0; - } else if (IS_O(arg, O_COMPLEX)) { - *real = ((py_obj_base_t*)arg)->u_complex.real; - *imag = ((py_obj_base_t*)arg)->u_complex.imag; + } else if (MP_OBJ_IS_TYPE(arg, &complex_type)) { + mp_obj_complex_get(arg, real, imag); } else { assert(0); *real = 0; @@ -422,49 +172,45 @@ void py_obj_get_complex(py_obj_t arg, py_float_t *real, py_float_t *imag) { } #endif -qstr py_obj_get_qstr(py_obj_t arg) { - if (IS_O(arg, O_STR)) { - return ((py_obj_base_t*)arg)->u_str; +qstr mp_obj_get_qstr(mp_obj_t arg) { + if (MP_OBJ_IS_TYPE(arg, &str_type)) { + return mp_obj_str_get(arg); } else { assert(0); return 0; } } -py_obj_t *py_obj_get_array_fixed_n(py_obj_t o_in, machine_int_t n) { - if (IS_O(o_in, O_TUPLE) || IS_O(o_in, O_LIST)) { - py_obj_base_t *o = o_in; - if (o->u_tuple_list.len != n) { - nlr_jump(py_obj_new_exception_2(rt_q_IndexError, "requested length %d but object has length %d", (void*)n, (void*)o->u_tuple_list.len)); +mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o_in, machine_int_t n) { + if (MP_OBJ_IS_TYPE(o_in, &tuple_type) || MP_OBJ_IS_TYPE(o_in, &list_type)) { + uint seq_len; + mp_obj_t *seq_items; + if (MP_OBJ_IS_TYPE(o_in, &tuple_type)) { + mp_obj_tuple_get(o_in, &seq_len, &seq_items); + } else { + mp_obj_list_get(o_in, &seq_len, &seq_items); + } + if (seq_len != n) { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_IndexError, "requested length %d but object has length %d", (void*)n, (void*)(machine_uint_t)seq_len)); } - return o->u_tuple_list.items; + return seq_items; } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "object '%s' is not a tuple or list", py_obj_get_type_str(o_in), NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o_in))); } } -void py_user_get_data(py_obj_t o, machine_uint_t *data1, machine_uint_t *data2) { - assert(IS_O(o, O_USER)); - if (data1 != NULL) { - *data1 = ((py_obj_base_t*)o)->u_user.data1; - } - if (data2 != NULL) { - *data2 = ((py_obj_base_t*)o)->u_user.data2; +uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index) { + // TODO False and True are considered 0 and 1 for indexing purposes + if (MP_OBJ_IS_SMALL_INT(index)) { + int i = MP_OBJ_SMALL_INT_VALUE(index); + if (i < 0) { + i += len; + } + if (i < 0 || i >= len) { + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_IndexError, "%s index out of range", type->name)); + } + return i; + } else { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "%s indices must be integers, not %s", type->name, mp_obj_get_type_str(index))); } } - -void py_user_set_data(py_obj_t o, machine_uint_t data1, machine_uint_t data2) { - assert(IS_O(o, O_USER)); - ((py_obj_base_t*)o)->u_user.data1 = data1; - ((py_obj_base_t*)o)->u_user.data2 = data2; -} - -// temporary way of making C modules -// hack: use class to mimic a module - -py_obj_t py_module_new(void) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_CLASS; - o->u_class.locals = py_map_new(MAP_QSTR, 0); - return o; -} diff --git a/py/obj.h b/py/obj.h index 746c92bbadc0b0cd1f2f20eb5f238a0cd989e943..7d58371dbb5c2f7755127653b2788f4d1110939a 100644 --- a/py/obj.h +++ b/py/obj.h @@ -1,56 +1,238 @@ -typedef machine_int_t py_small_int_t; // do we need to expose this in the public API? +// All Micro Python objects are at least this type +// It must be of pointer size + +typedef machine_ptr_t mp_obj_t; +typedef machine_const_ptr_t mp_const_obj_t; + +// Integers that fit in a pointer have this type +// (do we need to expose this in the public API?) + +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 py_float_t; +typedef machine_float_t mp_float_t; #endif -// user defined objects +// Anything that wants to be a Micro Python object must +// have mp_obj_base_t as its first member (except NULL and small ints) + +typedef struct _mp_obj_base_t mp_obj_base_t; +typedef struct _mp_obj_type_t mp_obj_type_t; + +struct _mp_obj_base_t { + const mp_obj_type_t *type; +}; + +// The NULL object is used to indicate the absence of an object +// It *cannot* be used when an mp_obj_t is expected, except where explicitly allowed + +#define MP_OBJ_NULL ((mp_obj_t)NULL) + +// These macros check for small int or object, and access small int values + +#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 1) == 0) +#define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0) +#define MP_OBJ_IS_TYPE(o, t) (((((mp_small_int_t)(o)) & 1) == 0) && (((mp_obj_base_t*)(o))->type == (t))) +#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1) +#define MP_OBJ_NEW_SMALL_INT(o) ((mp_obj_t)(((o) << 1) | 1)) + +// These macros are used to declare and define constant function objects +// You can put "static" in front of the definitions to make them local + +#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_native_t obj_name -typedef struct _py_user_method_t { +#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 0, 0, fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 1, 1, fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 2, 2, fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, (~((machine_uint_t)0)), fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, n_args_max, fun_name} + +// Type definitions for methods + +typedef mp_obj_t (*mp_fun_0_t)(void); +typedef mp_obj_t (*mp_fun_1_t)(mp_obj_t); +typedef mp_obj_t (*mp_fun_2_t)(mp_obj_t, mp_obj_t); +typedef mp_obj_t (*mp_fun_t)(void); +typedef mp_obj_t (*mp_fun_var_t)(int n, const mp_obj_t *); + +typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o); +typedef mp_obj_t (*mp_call_n_fun_t)(mp_obj_t fun, int n_args, const mp_obj_t *args); // args are in reverse order in the array +typedef mp_obj_t (*mp_unary_op_fun_t)(int op, mp_obj_t); +typedef mp_obj_t (*mp_binary_op_fun_t)(int op, mp_obj_t, mp_obj_t); + +typedef struct _mp_method_t { const char *name; - machine_uint_t kind; - void *fun; -} py_user_method_t; + mp_const_obj_t fun; +} mp_method_t; + +struct _mp_obj_type_t { + mp_obj_base_t base; + const char *name; + mp_print_fun_t print; + + mp_call_n_fun_t call_n; + mp_unary_op_fun_t unary_op; // can return NULL if op not supported + mp_binary_op_fun_t binary_op; // can return NULL if op not supported + + mp_fun_1_t getiter; + mp_fun_1_t iternext; + + const mp_method_t methods[]; + + /* + What we might need to add here: + + dynamic_type instance -typedef struct _py_user_info_t { - const char *type_name; - void (*print)(py_obj_t); - const py_user_method_t methods[]; -} py_user_info_t; + compare_op + load_attr instance class list + load_method instance str gen list user + store_attr instance class + store_subscr list dict -py_obj_t py_obj_new_int(machine_int_t value); -py_obj_t py_obj_new_const(const char *id); -py_obj_t py_obj_new_str(qstr qstr); + len str tuple list map + abs float complex + hash bool int none str + equal int str + less int + get_array_n tuple list + + unpack seq list tuple + __next__ gen-instance + */ +}; + +// Constant objects, globally accessible + +extern const mp_obj_type_t mp_const_type; +extern const mp_obj_t mp_const_none; +extern const mp_obj_t mp_const_false; +extern const mp_obj_t mp_const_true; +extern const mp_obj_t mp_const_stop_iteration; // special object indicating end of iteration (not StopIteration exception!) + +// Need to declare this here so we are not dependent on map.h + +typedef struct _mp_map_t mp_map_t; + +// General API for objects + +mp_obj_t mp_obj_new_none(void); +mp_obj_t mp_obj_new_bool(bool value); +mp_obj_t mp_obj_new_int(machine_int_t value); +mp_obj_t mp_obj_new_str(qstr qstr); #if MICROPY_ENABLE_FLOAT -py_obj_t py_obj_new_float(py_float_t val); -py_obj_t py_obj_new_complex(py_float_t real, py_float_t imag); +mp_obj_t mp_obj_new_float(mp_float_t val); +mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); #endif -py_obj_t py_obj_new_exception_0(qstr id); -py_obj_t py_obj_new_exception_2(qstr id, const char *fmt, const char *s1, const char *s2); -py_obj_t py_obj_new_range(int start, int stop, int step); -py_obj_t py_obj_new_range_iterator(int cur, int stop, int step); -py_obj_t py_obj_new_user(const py_user_info_t *info, machine_uint_t data1, machine_uint_t data2); +mp_obj_t mp_obj_new_exception(qstr id); +mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg); +mp_obj_t mp_obj_new_exception_msg_1_arg(qstr id, const char *fmt, const char *a1); +mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2); +mp_obj_t mp_obj_new_range(int start, int stop, int step); +mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step); +mp_obj_t mp_obj_new_fun_bc(int n_args, uint n_state, const byte *code); +mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun); +mp_obj_t mp_obj_new_gen_wrap(uint n_locals, uint n_cells, uint n_stack, mp_obj_t fun); +mp_obj_t mp_obj_new_gen_instance(mp_obj_t state, const byte *ip, mp_obj_t *sp); +mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple); +mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_list_reverse(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_dict(int n_args); +mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items); +mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth); +mp_obj_t mp_obj_new_class(mp_map_t *class_locals); +mp_obj_t mp_obj_new_instance(mp_obj_t clas); -const char *py_obj_get_type_str(py_obj_t o_in); +const char *mp_obj_get_type_str(mp_obj_t o_in); -void py_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, py_obj_t o_in); -void py_obj_print(py_obj_t o); +void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in); +void mp_obj_print(mp_obj_t o); -bool py_obj_is_callable(py_obj_t o_in); -machine_int_t py_obj_hash(py_obj_t o_in); -bool py_obj_equal(py_obj_t o1, py_obj_t o2); -bool py_obj_less(py_obj_t o1, py_obj_t o2); +bool mp_obj_is_callable(mp_obj_t o_in); +machine_int_t mp_obj_hash(mp_obj_t o_in); +bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2); +bool mp_obj_less(mp_obj_t o1, mp_obj_t o2); -machine_int_t py_obj_get_int(py_obj_t arg); +machine_int_t mp_obj_get_int(mp_obj_t arg); #if MICROPY_ENABLE_FLOAT -machine_float_t py_obj_get_float(py_obj_t arg); -void py_obj_get_complex(py_obj_t arg, py_float_t *real, py_float_t *imag); +mp_float_t mp_obj_get_float(mp_obj_t self_in); +void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); #endif -qstr py_obj_get_qstr(py_obj_t arg); -py_obj_t *py_obj_get_array_fixed_n(py_obj_t o, machine_int_t n); +qstr mp_obj_get_qstr(mp_obj_t arg); +mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o, machine_int_t n); +uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index); + +// none +extern const mp_obj_type_t none_type; + +// bool +extern const mp_obj_type_t bool_type; + +// cell +mp_obj_t mp_obj_cell_get(mp_obj_t self_in); +void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj); + +// str +extern const mp_obj_type_t str_type; +qstr mp_obj_str_get(mp_obj_t self_in); + +#if MICROPY_ENABLE_FLOAT +// float +extern const mp_obj_type_t float_type; +mp_float_t mp_obj_float_get(mp_obj_t self_in); + +// complex +extern const mp_obj_type_t complex_type; +void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); +#endif + +// tuple +extern const mp_obj_type_t tuple_type; +void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items); + +// list +extern const mp_obj_type_t list_type; +mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); +void mp_obj_list_get(mp_obj_t self_in, uint *len, mp_obj_t **items); +void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); + +// dict +extern const mp_obj_type_t dict_type; +mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); + +// set +void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item); + +// functions +typedef struct _mp_obj_fun_native_t { // need this so we can define static objects + mp_obj_base_t base; + machine_uint_t n_args_min; // inclusive + machine_uint_t n_args_max; // inclusive + void *fun; +} mp_obj_fun_native_t; +extern const mp_obj_type_t fun_native_type; +extern const mp_obj_type_t fun_bc_type; +void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code); + +// generator +extern const mp_obj_type_t gen_instance_type; +mp_obj_t mp_obj_gen_instance_next(mp_obj_t self_in); +MP_DECLARE_CONST_FUN_OBJ(mp_obj_gen_instance_next_obj); + +// class +extern const mp_obj_type_t class_type; +extern const mp_obj_t gen_instance_next_obj; +mp_map_t *mp_obj_class_get_locals(mp_obj_t self_in); -void py_user_get_data(py_obj_t o, machine_uint_t *data1, machine_uint_t *data2); -void py_user_set_data(py_obj_t o, machine_uint_t data1, machine_uint_t data2); +// instance +extern const mp_obj_type_t instance_type; +mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr); +void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest); +void mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value); // temporary way of making C modules -py_obj_t py_module_new(void); +mp_obj_t mp_module_new(void); diff --git a/py/objbool.c b/py/objbool.c new file mode 100644 index 0000000000000000000000000000000000000000..9b53ffae94f012f0e349c81b06e7ad7562ae2c07 --- /dev/null +++ b/py/objbool.c @@ -0,0 +1,39 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" + +typedef struct _mp_obj_bool_t { + mp_obj_base_t base; + bool value; +} mp_obj_bool_t; + +void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + mp_obj_bool_t *self = self_in; + if (self->value) { + print(env, "True"); + } else { + print(env, "False"); + } +} + +const mp_obj_type_t bool_type = { + { &mp_const_type }, + "bool", + bool_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +static const mp_obj_bool_t false_obj = {{&bool_type}, false}; +static const mp_obj_bool_t true_obj = {{&bool_type}, true}; + +const mp_obj_t mp_const_false = (mp_obj_t)&false_obj; +const mp_obj_t mp_const_true = (mp_obj_t)&true_obj; diff --git a/py/objboundmeth.c b/py/objboundmeth.c new file mode 100644 index 0000000000000000000000000000000000000000..8bd238c65ed63f86ccb4f7267df90903dfa7c1e2 --- /dev/null +++ b/py/objboundmeth.c @@ -0,0 +1,54 @@ +#include <stdlib.h> +#include <stdint.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" + +typedef struct _mp_obj_bound_meth_t { + mp_obj_base_t base; + mp_obj_t meth; + mp_obj_t self; +} mp_obj_bound_meth_t; + +// args are in reverse order in the array +mp_obj_t bound_meth_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + mp_obj_bound_meth_t *self = self_in; + + if (n_args == 0) { + return rt_call_function_n(self->meth, 1, &self->self); + } else if (n_args == 1) { + mp_obj_t args2[2]; + args2[1] = self->self; + args2[0] = args[0]; + return rt_call_function_n(self->meth, 2, args2); + } else { + // TODO not implemented + assert(0); + return mp_const_none; + //return rt_call_function_2(self->meth, n_args + 1, self->self + args); + } +} + +const mp_obj_type_t bound_meth_type = { + { &mp_const_type }, + "bound_method", + NULL, // print + bound_meth_call_n, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth) { + mp_obj_bound_meth_t *o = m_new_obj(mp_obj_bound_meth_t); + o->base.type = &bound_meth_type; + o->meth = meth; + o->self = self; + return o; +} diff --git a/py/objcell.c b/py/objcell.c new file mode 100644 index 0000000000000000000000000000000000000000..cba1980579acae2fb4aa0cc584ec9a9ff5f8def6 --- /dev/null +++ b/py/objcell.c @@ -0,0 +1,43 @@ +#include <stdlib.h> +#include <stdint.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" + +typedef struct _mp_obj_cell_t { + mp_obj_base_t base; + mp_obj_t obj; +} mp_obj_cell_t; + +mp_obj_t mp_obj_cell_get(mp_obj_t self_in) { + mp_obj_cell_t *self = self_in; + return self->obj; +} + +void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj) { + mp_obj_cell_t *self = self_in; + self->obj = obj; +} + +const mp_obj_type_t cell_type = { + { &mp_const_type }, + "cell", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_cell(mp_obj_t obj) { + mp_obj_cell_t *o = m_new_obj(mp_obj_cell_t); + o->base.type = &cell_type; + o->obj = obj; + return o; +} diff --git a/py/objclass.c b/py/objclass.c new file mode 100644 index 0000000000000000000000000000000000000000..52e43724f7cc34eda66ddeb58843309fd5bc0269 --- /dev/null +++ b/py/objclass.c @@ -0,0 +1,85 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" +#include "map.h" + +typedef struct _mp_obj_class_t { + mp_obj_base_t base; + mp_map_t *locals; +} mp_obj_class_t; + +// args are in reverse order in the array +mp_obj_t class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + // instantiate an instance of a class + + mp_obj_class_t *self = self_in; + + // make instance + mp_obj_t o = mp_obj_new_instance(self_in); + + // look for __init__ function + mp_map_elem_t *init_fn = mp_qstr_map_lookup(self->locals, qstr_from_str_static("__init__"), false); + + if (init_fn != NULL) { + // call __init__ function + mp_obj_t init_ret; + if (n_args == 0) { + init_ret = rt_call_function_n(init_fn->value, 1, (mp_obj_t*)&o); + } else { + mp_obj_t *args2 = m_new(mp_obj_t, n_args + 1); + memcpy(args2, args, n_args * sizeof(mp_obj_t)); + args2[n_args] = o; + init_ret = rt_call_function_n(init_fn->value, n_args + 1, args2); + m_free(args2); + } + if (init_ret != mp_const_none) { + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret))); + } + + } else { + // TODO + if (n_args != 0) { + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "function takes 0 positional arguments but %d were given", (void*)(machine_int_t)n_args)); + } + } + + return o; +} + +mp_map_t *mp_obj_class_get_locals(mp_obj_t self_in) { + assert(MP_OBJ_IS_TYPE(self_in, &class_type)); + mp_obj_class_t *self = self_in; + return self->locals; +} + +const mp_obj_type_t class_type = { + { &mp_const_type }, + "class", + NULL, // print + class_call_n, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_class(mp_map_t *class_locals) { + mp_obj_class_t *o = m_new_obj(mp_obj_class_t); + o->base.type = &class_type; + o->locals = class_locals; + return o; +} + +// temporary way of making C modules +// hack: use class to mimic a module +mp_obj_t mp_module_new(void) { + return mp_obj_new_class(mp_map_new(MP_MAP_QSTR, 0)); +} diff --git a/py/objclosure.c b/py/objclosure.c new file mode 100644 index 0000000000000000000000000000000000000000..e699c5daaa4d0e874560a4cd2fada6044b9d5c3c --- /dev/null +++ b/py/objclosure.c @@ -0,0 +1,35 @@ +#include <stdlib.h> +#include <stdint.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" + +typedef struct _mp_obj_closure_t { + mp_obj_base_t base; + mp_obj_t fun; + mp_obj_t vars; +} mp_obj_closure_t; + +const mp_obj_type_t closure_type = { + { &mp_const_type }, + "closure", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple) { + mp_obj_closure_t *o = m_new_obj(mp_obj_closure_t); + o->base.type = &closure_type; + o->fun = fun; + o->vars = closure_tuple; + return o; +} diff --git a/py/objcomplex.c b/py/objcomplex.c new file mode 100644 index 0000000000000000000000000000000000000000..ab9c146774493df2bad97a91db94ce370cfa0331 --- /dev/null +++ b/py/objcomplex.c @@ -0,0 +1,105 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" +#include "map.h" + +#if MICROPY_ENABLE_FLOAT + +typedef struct _mp_obj_complex_t { + mp_obj_base_t base; + mp_float_t real; + mp_float_t imag; +} mp_obj_complex_t; + +mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); + +void complex_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { + mp_obj_complex_t *o = o_in; + if (o->real == 0) { + print(env, "%.8gj", o->imag); + } else { + print(env, "(%.8g+%.8gj)", o->real, o->imag); + } +} + +mp_obj_t complex_unary_op(int op, mp_obj_t o_in) { + mp_obj_complex_t *o = o_in; + switch (op) { + case RT_UNARY_OP_NOT: if (o->real != 0 || o->imag != 0) { return mp_const_true;} else { return mp_const_false; } + case RT_UNARY_OP_POSITIVE: return o_in; + case RT_UNARY_OP_NEGATIVE: return mp_obj_new_complex(-o->real, -o->imag); + default: return MP_OBJ_NULL; // op not supported + } +} + +mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_float_t lhs_real, lhs_imag, rhs_real, rhs_imag; + mp_obj_complex_get(lhs_in, &lhs_real, &lhs_imag); + mp_obj_complex_get(rhs_in, &rhs_real, &rhs_imag); + switch (op) { + case RT_BINARY_OP_ADD: + case RT_BINARY_OP_INPLACE_ADD: + lhs_real += rhs_real; + lhs_imag += rhs_imag; + break; + case RT_BINARY_OP_SUBTRACT: + case RT_BINARY_OP_INPLACE_SUBTRACT: + lhs_real -= rhs_real; + lhs_imag -= rhs_imag; + break; + case RT_BINARY_OP_MULTIPLY: + case RT_BINARY_OP_INPLACE_MULTIPLY: + { + mp_float_t real = lhs_real * rhs_real - lhs_imag * rhs_imag; + lhs_imag = lhs_real * rhs_imag + lhs_imag * rhs_real; + lhs_real = real; + break; + } + /* TODO floor(?) the value + case RT_BINARY_OP_FLOOR_DIVIDE: + case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; + */ + /* TODO + case RT_BINARY_OP_TRUE_DIVIDE: + case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: val = lhs_val / rhs_val; break; + */ + return NULL; // op not supported + } + return mp_obj_new_complex(lhs_real, lhs_imag); +} + +const mp_obj_type_t complex_type = { + { &mp_const_type }, + "complex", + complex_print, // print + NULL, // call_n + complex_unary_op, // unary_op + complex_binary_op, // binary_op + NULL, // getiter + NULL, // iternext + { { NULL, NULL }, }, // method list +}; + +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->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)); + mp_obj_complex_t *self = self_in; + *real = self->real; + *imag = self->imag; +} + +#endif diff --git a/py/objdict.c b/py/objdict.c new file mode 100644 index 0000000000000000000000000000000000000000..02753e3817087f82dcdbd0192e41f18bd5e5a5a1 --- /dev/null +++ b/py/objdict.c @@ -0,0 +1,80 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" +#include "runtime.h" +#include "map.h" + +typedef struct _mp_obj_dict_t { + mp_obj_base_t base; + mp_map_t map; +} mp_obj_dict_t; + +void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + mp_obj_dict_t *self = self_in; + bool first = true; + print(env, "{"); + for (int i = 0; i < self->map.alloc; i++) { + if (self->map.table[i].key != NULL) { + if (!first) { + print(env, ", "); + } + first = false; + mp_obj_print_helper(print, env, self->map.table[i].key); + print(env, ": "); + mp_obj_print_helper(print, env, self->map.table[i].value); + } + } + print(env, "}"); +} + +mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_obj_dict_t *o = lhs_in; + switch (op) { + case RT_BINARY_OP_SUBSCR: + { + // dict load + mp_map_elem_t *elem = mp_map_lookup_helper(&o->map, rhs_in, false); + if (elem == NULL) { + nlr_jump(mp_obj_new_exception_msg(rt_q_KeyError, "<value>")); + } else { + return elem->value; + } + } + default: + // op not supported + return NULL; + } +} + +mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { + assert(MP_OBJ_IS_TYPE(self_in, &dict_type)); + mp_obj_dict_t *self = self_in; + mp_map_lookup_helper(&self->map, key, true)->value = value; + return self_in; +} + +const mp_obj_type_t dict_type = { + { &mp_const_type }, + "dict", + dict_print, // print + NULL, // call_n + NULL, // unary_op + dict_binary_op, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_dict(int n_args) { + mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t); + o->base.type = &dict_type; + mp_map_init(&o->map, MP_MAP_OBJ, n_args); + return o; +} diff --git a/py/objexcept.c b/py/objexcept.c new file mode 100644 index 0000000000000000000000000000000000000000..4abc6243760bf53cdeb08f6e0e24a22882ee3964 --- /dev/null +++ b/py/objexcept.c @@ -0,0 +1,86 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" + +typedef struct mp_obj_exception_t { + mp_obj_base_t base; + qstr id; + int n_args; + const void *args[]; +} mp_obj_exception_t; + +void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { + mp_obj_exception_t *o = o_in; + switch (o->n_args) { + case 0: + print(env, "%s", qstr_str(o->id)); + break; + case 1: + print(env, "%s: %s", qstr_str(o->id), (const char*)o->args[0]); + break; + case 2: + print(env, "%s: ", qstr_str(o->id)); + print(env, (const char*)o->args[0], o->args[1]); + break; + default: // here we just assume at least 3 args, but only use first 3 + print(env, "%s: ", qstr_str(o->id)); + print(env, (const char*)o->args[0], o->args[1], o->args[2]); + break; + } +} + +const mp_obj_type_t exception_type = { + { &mp_const_type }, + "exception", + exception_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_exception(qstr id) { + mp_obj_exception_t *o = m_new_obj(mp_obj_exception_t); + o->base.type = &exception_type; + o->id = id; + o->n_args = 0; + return o; +} + +mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg) { + mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, 1); + o->base.type = &exception_type; + o->id = id; + o->n_args = 1; + o->args[0] = msg; + return o; +} + +mp_obj_t mp_obj_new_exception_msg_1_arg(qstr id, const char *fmt, const char *a1) { + mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, 2); + o->base.type = &exception_type; + o->id = id; + o->n_args = 2; + o->args[0] = fmt; + o->args[1] = a1; + return o; +} + +mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2) { + mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, 3); + o->base.type = &exception_type; + o->id = id; + o->n_args = 3; + o->args[0] = fmt; + o->args[1] = a1; + o->args[2] = a2; + return o; +} diff --git a/py/objfloat.c b/py/objfloat.c new file mode 100644 index 0000000000000000000000000000000000000000..f151fe25a0aceed5d50a05b1900be6db20ee6923 --- /dev/null +++ b/py/objfloat.c @@ -0,0 +1,85 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" + +#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); + +void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { + mp_obj_float_t *o = o_in; + print(env, "%.8g", o->value); +} + +mp_obj_t float_unary_op(int op, mp_obj_t o_in) { + mp_obj_float_t *o = o_in; + switch (op) { + case RT_UNARY_OP_NOT: if (o->value != 0) { return mp_const_true;} else { return mp_const_false; } + case RT_UNARY_OP_POSITIVE: return o_in; + case RT_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value); + default: return NULL; // op not supported + } +} + +mp_obj_t float_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + if (MP_OBJ_IS_TYPE(rhs_in, &complex_type)) { + return complex_type.binary_op(op, lhs_in, rhs_in); + } + mp_float_t lhs_val = mp_obj_get_float(lhs_in); + mp_float_t rhs_val = mp_obj_get_float(rhs_in); + switch (op) { + case RT_BINARY_OP_ADD: + case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; + case RT_BINARY_OP_SUBTRACT: + case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; + case RT_BINARY_OP_MULTIPLY: + case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; + /* TODO floor(?) the value + case RT_BINARY_OP_FLOOR_DIVIDE: + case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; + */ + case RT_BINARY_OP_TRUE_DIVIDE: + case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break; + return NULL; // op not supported + } + return mp_obj_new_float(lhs_val); +} + +const mp_obj_type_t float_type = { + { &mp_const_type }, + "float", + float_print, + NULL, // call_n + float_unary_op, + float_binary_op, + NULL, // getiter + NULL, // iternext + { { NULL, NULL }, }, // method list +}; + +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->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)); + mp_obj_float_t *self = self_in; + return self->value; +} + +#endif diff --git a/py/objfun.c b/py/objfun.c new file mode 100644 index 0000000000000000000000000000000000000000..bf11b5e6ab71e696aa9eb9969c63d452fe62c10b --- /dev/null +++ b/py/objfun.c @@ -0,0 +1,280 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" +#include "bc.h" + +/******************************************************************************/ +/* native functions */ + +// mp_obj_fun_native_t defined in obj.h + +// args are in reverse order in the array +mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + mp_obj_fun_native_t *self = self_in; + if (self->n_args_min == self->n_args_max) { + // function requires a fixed number of arguments + + // check number of arguments + if (n_args != self->n_args_min) { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args_min, (const char*)(machine_int_t)n_args)); + } + + // dispatch function call + switch (self->n_args_min) { + case 0: + return ((mp_fun_0_t)self->fun)(); + + case 1: + return ((mp_fun_1_t)self->fun)(args[0]); + + case 2: + return ((mp_fun_2_t)self->fun)(args[1], args[0]); + + default: + assert(0); + return mp_const_none; + } + + } else { + // function takes a variable number of arguments + + if (n_args < self->n_args_min) { + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(self->n_args_min - n_args))); + } else if (n_args > self->n_args_max) { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "<fun name> expected at most %d arguments, got %d", (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args)); + } + + // TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args + mp_obj_t *args_ordered = m_new(mp_obj_t, n_args); + for (int i = 0; i < n_args; i++) { + args_ordered[i] = args[n_args - i - 1]; + } + + mp_obj_t res = ((mp_fun_var_t)self->fun)(n_args, args_ordered); + m_free(args_ordered); + + return res; + } +} + +const mp_obj_type_t fun_native_type = { + { &mp_const_type }, + "function", + NULL, // print + fun_native_call_n, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + {NULL, NULL}, // end-of-list sentinel + }, +}; + +mp_obj_t rt_make_function_0(mp_fun_0_t fun) { + mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t); + o->base.type = &fun_native_type; + o->n_args_min = 0; + o->n_args_max = 0; + o->fun = fun; + return o; +} + +mp_obj_t rt_make_function_1(mp_fun_1_t fun) { + mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t); + o->base.type = &fun_native_type; + o->n_args_min = 1; + o->n_args_max = 1; + o->fun = fun; + return o; +} + +mp_obj_t rt_make_function_2(mp_fun_2_t fun) { + mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t); + o->base.type = &fun_native_type; + o->n_args_min = 2; + o->n_args_max = 2; + o->fun = fun; + return o; +} + +mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t fun) { + mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t); + o->base.type = &fun_native_type; + o->n_args_min = n_args_min; + o->n_args_max = ~((machine_uint_t)0); + o->fun = fun; + return o; +} + +// min and max are inclusive +mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun) { + mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t); + o->base.type = &fun_native_type; + o->n_args_min = n_args_min; + o->n_args_max = n_args_max; + o->fun = fun; + return o; +} + +/******************************************************************************/ +/* byte code functions */ + +typedef struct _mp_obj_fun_bc_t { + mp_obj_base_t base; + int n_args; + uint n_state; + const byte *code; +} mp_obj_fun_bc_t; + +// args are in reverse order in the array +mp_obj_t fun_bc_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + mp_obj_fun_bc_t *self = self_in; + + if (n_args != self->n_args) { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args)); + } + + return mp_execute_byte_code(self->code, args, n_args, self->n_state); +} + +void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code) { + assert(MP_OBJ_IS_TYPE(self_in, &fun_bc_type)); + mp_obj_fun_bc_t *self = self_in; + *n_args = self->n_args; + *n_state = self->n_state; + *code = self->code; +} + +const mp_obj_type_t fun_bc_type = { + { &mp_const_type }, + "function", + NULL, // print + fun_bc_call_n, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + {NULL, NULL}, // end-of-list sentinel + }, +}; + +mp_obj_t mp_obj_new_fun_bc(int n_args, uint n_state, const byte *code) { + mp_obj_fun_bc_t *o = m_new_obj(mp_obj_fun_bc_t); + o->base.type = &fun_bc_type; + o->n_args = n_args; + o->n_state = n_state; + o->code = code; + return o; +} + +/******************************************************************************/ +/* inline assembler functions */ + +typedef struct _mp_obj_fun_asm_t { + mp_obj_base_t base; + int n_args; + void *fun; +} mp_obj_fun_asm_t; + +typedef machine_uint_t (*inline_asm_fun_0_t)(); +typedef machine_uint_t (*inline_asm_fun_1_t)(machine_uint_t); +typedef machine_uint_t (*inline_asm_fun_2_t)(machine_uint_t, machine_uint_t); +typedef machine_uint_t (*inline_asm_fun_3_t)(machine_uint_t, machine_uint_t, machine_uint_t); + +// convert a Micro Python object to a sensible value for inline asm +machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { + // TODO for byte_array, pass pointer to the array + if (MP_OBJ_IS_SMALL_INT(obj)) { + return MP_OBJ_SMALL_INT_VALUE(obj); + } else if (obj == mp_const_none) { + return 0; + } else if (obj == mp_const_false) { + return 0; + } else if (obj == mp_const_true) { + return 1; + } else if (MP_OBJ_IS_TYPE(obj, &str_type)) { + // pointer to the string (it's probably constant though!) + return (machine_uint_t)qstr_str(mp_obj_str_get(obj)); +#if MICROPY_ENABLE_FLOAT + } else if (MP_OBJ_IS_TYPE(obj, &float_type)) { + // convert float to int (could also pass in float registers) + return (machine_int_t)mp_obj_float_get(obj); +#endif + } else if (MP_OBJ_IS_TYPE(obj, &tuple_type)) { + // pointer to start of tuple (could pass length, but then could use len(x) for that) + uint len; + mp_obj_t *items; + mp_obj_tuple_get(obj, &len, &items); + return (machine_uint_t)items; + } else if (MP_OBJ_IS_TYPE(obj, &list_type)) { + // pointer to start of list (could pass length, but then could use len(x) for that) + uint len; + mp_obj_t *items; + mp_obj_list_get(obj, &len, &items); + return (machine_uint_t)items; + } else { + // just pass along a pointer to the object + return (machine_uint_t)obj; + } +} + +// convert a return value from inline asm to a sensible Micro Python object +mp_obj_t convert_val_from_inline_asm(machine_uint_t val) { + return MP_OBJ_NEW_SMALL_INT(val); +} + +// args are in reverse order in the array +mp_obj_t fun_asm_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + mp_obj_fun_asm_t *self = self_in; + + if (n_args != self->n_args) { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args, (const char*)(machine_int_t)n_args)); + } + + machine_uint_t ret; + if (n_args == 0) { + ret = ((inline_asm_fun_0_t)self->fun)(); + } else if (n_args == 1) { + ret = ((inline_asm_fun_1_t)self->fun)(convert_obj_for_inline_asm(args[0])); + } else if (n_args == 2) { + ret = ((inline_asm_fun_2_t)self->fun)(convert_obj_for_inline_asm(args[1]), convert_obj_for_inline_asm(args[0])); + } else if (n_args == 3) { + ret = ((inline_asm_fun_3_t)self->fun)(convert_obj_for_inline_asm(args[2]), convert_obj_for_inline_asm(args[1]), convert_obj_for_inline_asm(args[0])); + } else { + assert(0); + ret = 0; + } + + return convert_val_from_inline_asm(ret); +} + +static const mp_obj_type_t fun_asm_type = { + { &mp_const_type }, + "function", + NULL, // print + fun_asm_call_n, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + {NULL, NULL}, // end-of-list sentinel + }, +}; + +mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun) { + mp_obj_fun_asm_t *o = m_new_obj(mp_obj_fun_asm_t); + o->base.type = &fun_asm_type; + o->n_args = n_args; + o->fun = fun; + return o; +} diff --git a/py/objgenerator.c b/py/objgenerator.c new file mode 100644 index 0000000000000000000000000000000000000000..fdb642c1c49c872c87d5e5ea2442b3d6f043c39a --- /dev/null +++ b/py/objgenerator.c @@ -0,0 +1,130 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" +#include "bc.h" + +/******************************************************************************/ +/* generator wrapper */ + +typedef struct _mp_obj_gen_wrap_t { + mp_obj_base_t base; + int n_state; + mp_obj_t *fun; +} mp_obj_gen_wrap_t; + +// args are in reverse order in the array +mp_obj_t gen_wrap_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { + mp_obj_gen_wrap_t *self = self_in; + mp_obj_t self_fun = self->fun; + assert(MP_OBJ_IS_TYPE(self_fun, &fun_bc_type)); + int bc_n_args; + uint bc_n_state; + const byte *bc_code; + mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code); + if (n_args != bc_n_args) { + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)bc_n_args, (const char*)(machine_int_t)n_args)); + } + mp_obj_t *state = m_new(mp_obj_t, 1 + self->n_state); + // put function object at first slot in state (to keep u_gen_instance small) + state[0] = self_fun; + // init args + for (int i = 0; i < n_args; i++) { + state[1 + i] = args[n_args - 1 - i]; + } + return mp_obj_new_gen_instance(state, bc_code, state + self->n_state); +} + +const mp_obj_type_t gen_wrap_type = { + { &mp_const_type }, + "generator", + NULL, // print + gen_wrap_call_n, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_gen_wrap(uint n_locals, uint n_cells, uint n_stack, mp_obj_t fun) { + mp_obj_gen_wrap_t *o = m_new_obj(mp_obj_gen_wrap_t); + o->base.type = &gen_wrap_type; + // we have at least 3 locals so the bc can write back fast[0,1,2] safely; should improve how this is done + o->n_state = ((n_locals + n_cells) < 3 ? 3 : (n_locals + n_cells)) + n_stack; + o->fun = fun; + return o; +} + +/******************************************************************************/ +/* generator instance */ + +typedef struct _mp_obj_gen_instance_t { + mp_obj_base_t base; + mp_obj_t *state; + const byte *ip; + mp_obj_t *sp; +} mp_obj_gen_instance_t; + +void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + print(env, "<generator object 'fun-name' at %p>", self_in); +} + +mp_obj_t gen_instance_getiter(mp_obj_t self_in) { + return self_in; +} + +mp_obj_t gen_instance_iternext(mp_obj_t self_in) { + mp_obj_gen_instance_t *self = self_in; + //mp_obj_base_t *fun = self->u_gen_instance.state[0]; + //assert(fun->kind == O_FUN_BC); + bool yield = mp_execute_byte_code_2(&self->ip, &self->state[1], &self->sp); + if (yield) { + return *self->sp; + } else { + if (*self->sp == mp_const_none) { + return mp_const_stop_iteration; + } else { + // TODO return StopIteration with value *self->sp + return mp_const_stop_iteration; + } + } +} + +const mp_obj_type_t gen_instance_type = { + { &mp_const_type }, + "generator", + gen_instance_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + gen_instance_getiter, // getiter + gen_instance_iternext, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_gen_instance(mp_obj_t state, const byte *ip, mp_obj_t *sp) { + mp_obj_gen_instance_t *o = m_new_obj(mp_obj_gen_instance_t); + o->base.type = &gen_instance_type; + o->state = state; + o->ip = ip; + o->sp = sp; + return o; +} + +mp_obj_t mp_obj_gen_instance_next(mp_obj_t self_in) { + mp_obj_t ret = rt_iternext(self_in); + if (ret == mp_const_stop_iteration) { + nlr_jump(mp_obj_new_exception(qstr_from_str_static("StopIteration"))); + } else { + return ret; + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(mp_obj_gen_instance_next_obj, mp_obj_gen_instance_next); diff --git a/py/objinstance.c b/py/objinstance.c new file mode 100644 index 0000000000000000000000000000000000000000..e5d23af2d50b25cd75be5f1b3fd2a78c5a214240 --- /dev/null +++ b/py/objinstance.c @@ -0,0 +1,109 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime.h" +#include "map.h" + +typedef struct _mp_obj_instance_t { + mp_obj_base_t base; + mp_obj_base_t *class; // points to a "class" object + mp_map_t *members; +} mp_obj_instance_t; + +/* +type needs to be specified dynamically + case O_OBJ: + { + py_map_elem_t *qn = py_qstr_map_lookup(o->u_obj.class->u_class.locals, qstr_from_str_static("__qualname__"), false); assert(qn != NULL); + assert(IS_O(qn->value, O_STR)); + return qstr_str(((py_obj_base_t*)qn->value)->u_str); + } + */ + +mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr) { + // logic: look in obj members then class locals (TODO check this against CPython) + mp_obj_instance_t *self = self_in; + mp_map_elem_t *elem = mp_qstr_map_lookup(self->members, attr, false); + if (elem != NULL) { + // object member, always treated as a value + return elem->value; + } + elem = mp_qstr_map_lookup(mp_obj_class_get_locals(self->class), attr, false); + if (elem != NULL) { + if (mp_obj_is_callable(elem->value)) { + // class member is callable so build a bound method + return mp_obj_new_bound_meth(self_in, elem->value); + } else { + // class member is a value, so just return that value + return elem->value; + } + } + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(self_in), qstr_str(attr))); +} + +void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + // logic: look in obj members then class locals (TODO check this against CPython) + mp_obj_instance_t *self = self_in; + mp_map_elem_t *elem = mp_qstr_map_lookup(self->members, attr, false); + if (elem != NULL) { + // object member, always treated as a value + dest[1] = elem->value; + dest[0] = NULL; + return; + } + elem = mp_qstr_map_lookup(mp_obj_class_get_locals(self->class), attr, false); + if (elem != NULL) { + if (mp_obj_is_callable(elem->value)) { + // class member is callable so build a bound method + dest[1] = elem->value; + dest[0] = self_in; + return; + } else { + // class member is a value, so just return that value + dest[1] = elem->value; + dest[0] = NULL; + return; + } + } + + // no such method, so fall back to load attr + dest[1] = rt_load_attr(self_in, attr); + dest[0] = NULL; +} + +void mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) { + // logic: look in class locals (no add) then obj members (add) (TODO check this against CPython) + mp_obj_instance_t *self = self_in; + mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_class_get_locals(self->class), attr, false); + if (elem != NULL) { + elem->value = value; + } else { + mp_qstr_map_lookup(self->members, attr, true)->value = value; + } +} + +const mp_obj_type_t instance_type = { + { &mp_const_type }, + "instance", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_instance(mp_obj_t class) { + mp_obj_instance_t *o = m_new_obj(mp_obj_instance_t); + o->base.type = &instance_type; + o->class = class; + o->members = mp_map_new(MP_MAP_QSTR, 0); + return o; +} diff --git a/py/objlist.c b/py/objlist.c new file mode 100644 index 0000000000000000000000000000000000000000..4d70c37eb3ebab66003dc1c9dc94269635e79d98 --- /dev/null +++ b/py/objlist.c @@ -0,0 +1,204 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" +#include "runtime.h" + +typedef struct _mp_obj_list_t { + mp_obj_base_t base; + machine_uint_t alloc; + machine_uint_t len; + mp_obj_t *items; +} mp_obj_list_t; + +static mp_obj_t mp_obj_new_list_iterator(mp_obj_list_t *list, int cur); + +/******************************************************************************/ +/* list */ + +static void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { + mp_obj_list_t *o = o_in; + print(env, "["); + for (int i = 0; i < o->len; i++) { + if (i > 0) { + print(env, ", "); + } + mp_obj_print_helper(print, env, o->items[i]); + } + print(env, "]"); +} + +static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { + mp_obj_list_t *o = lhs; + switch (op) { + case RT_BINARY_OP_SUBSCR: + { + // list load + uint index = mp_get_index(o->base.type, o->len, rhs); + return o->items[index]; + } + default: + // op not supported + return NULL; + } +} + +static mp_obj_t list_getiter(mp_obj_t o_in) { + return mp_obj_new_list_iterator(o_in, 0); +} + +mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_TYPE(self_in, &list_type)); + mp_obj_list_t *self = self_in; + if (self->len >= self->alloc) { + self->alloc *= 2; + self->items = m_renew(mp_obj_t, self->items, self->alloc); + } + self->items[self->len++] = arg; + return mp_const_none; // return None, as per CPython +} + +static mp_obj_t list_pop(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_TYPE(self_in, &list_type)); + mp_obj_list_t *self = self_in; + uint index = mp_get_index(self->base.type, self->len, arg); + mp_obj_t ret = self->items[index]; + self->len -= 1; + memcpy(self->items + index, self->items + index + 1, (self->len - index) * sizeof(mp_obj_t)); + return ret; +} + +// TODO make this conform to CPython's definition of sort +static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn) { + while (head < tail) { + mp_obj_t *h = head - 1; + mp_obj_t *t = tail; + mp_obj_t v = rt_call_function_1(key_fn, tail[0]); // get pivot using key_fn + for (;;) { + do ++h; while (rt_compare_op(RT_COMPARE_OP_LESS, rt_call_function_1(key_fn, h[0]), v) == mp_const_true); + do --t; while (h < t && rt_compare_op(RT_COMPARE_OP_LESS, v, rt_call_function_1(key_fn, t[0])) == mp_const_true); + if (h >= t) break; + mp_obj_t x = h[0]; + h[0] = t[0]; + t[0] = x; + } + mp_obj_t x = h[0]; + h[0] = tail[0]; + tail[0] = x; + mp_quicksort(head, t, key_fn); + head = h + 1; + } +} + +static mp_obj_t list_sort(mp_obj_t self_in, mp_obj_t key_fn) { + assert(MP_OBJ_IS_TYPE(self_in, &list_type)); + mp_obj_list_t *self = self_in; + if (self->len > 1) { + mp_quicksort(self->items, self->items + self->len - 1, key_fn); + } + return mp_const_none; // return None, as per CPython +} + +static MP_DEFINE_CONST_FUN_OBJ_2(list_append_obj, mp_obj_list_append); +static MP_DEFINE_CONST_FUN_OBJ_2(list_pop_obj, list_pop); +static MP_DEFINE_CONST_FUN_OBJ_2(list_sort_obj, list_sort); + +const mp_obj_type_t list_type = { + { &mp_const_type }, + "list", + list_print, // print + NULL, // call_n + NULL, // unary_op + list_binary_op, // binary_op + list_getiter, // getiter + NULL, // iternext + { // method list + { "append", &list_append_obj }, + { "pop", &list_pop_obj }, + { "sort", &list_sort_obj }, + { NULL, NULL }, // end-of-list sentinel + }, +}; + +static mp_obj_list_t *list_new(uint n) { + mp_obj_list_t *o = m_new_obj(mp_obj_list_t); + o->base.type = &list_type; + o->alloc = n < 4 ? 4 : n; + o->len = n; + o->items = m_new(mp_obj_t, o->alloc); + return o; +} + +mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items) { + mp_obj_list_t *o = list_new(n); + for (int i = 0; i < n; i++) { + o->items[i] = items[i]; + } + return o; +} + +mp_obj_t mp_obj_new_list_reverse(uint n, mp_obj_t *items) { + mp_obj_list_t *o = list_new(n); + for (int i = 0; i < n; i++) { + o->items[i] = items[n - i - 1]; + } + return o; +} + +void mp_obj_list_get(mp_obj_t self_in, uint *len, mp_obj_t **items) { + mp_obj_list_t *self = self_in; + *len = self->len; + *items = self->items; +} + +void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { + mp_obj_list_t *self = self_in; + uint i = mp_get_index(self->base.type, self->len, index); + self->items[i] = value; +} + +/******************************************************************************/ +/* list iterator */ + +typedef struct _mp_obj_list_it_t { + mp_obj_base_t base; + mp_obj_list_t *list; + machine_uint_t cur; +} mp_obj_list_it_t; + +mp_obj_t list_it_iternext(mp_obj_t self_in) { + mp_obj_list_it_t *self = self_in; + if (self->cur < self->list->len) { + mp_obj_t o_out = self->list->items[self->cur]; + self->cur += 1; + return o_out; + } else { + return mp_const_stop_iteration; + } +} + +static const mp_obj_type_t list_it_type = { + { &mp_const_type }, + "list_iterator", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + list_it_iternext, // iternext + { { NULL, NULL }, }, // method list +}; + +mp_obj_t mp_obj_new_list_iterator(mp_obj_list_t *list, int cur) { + mp_obj_list_it_t *o = m_new_obj(mp_obj_list_it_t); + o->base.type = &list_it_type; + o->list = list; + o->cur = cur; + return o; +} diff --git a/py/objnone.c b/py/objnone.c new file mode 100644 index 0000000000000000000000000000000000000000..f7b665e9974ddaeaa4f80a6c70cee3f95dd9b8f3 --- /dev/null +++ b/py/objnone.c @@ -0,0 +1,35 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" + +typedef struct _mp_obj_none_t { + mp_obj_base_t base; +} mp_obj_none_t; + +void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + print(env, "None"); +} + +const mp_obj_type_t none_type = { + { &mp_const_type }, + "NoneType", + none_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +static const mp_obj_none_t none_obj = {{&none_type}}; +const mp_obj_t mp_const_none = (mp_obj_t)&none_obj; + +// the stop-iteration object just needs to be something unique +// it's not the StopIteration exception +static const mp_obj_none_t stop_it_obj = {{&none_type}}; +const mp_obj_t mp_const_stop_iteration = (mp_obj_t)&stop_it_obj; diff --git a/py/objprivate.h b/py/objprivate.h deleted file mode 100644 index 70ee6560da243dd5a3e0bd82e8e6992beaaada88..0000000000000000000000000000000000000000 --- a/py/objprivate.h +++ /dev/null @@ -1,140 +0,0 @@ -// internal py_obj_t representation -// not for general use, instead access using py_obj_xxx functions - -#define IS_O(o, k) (((((py_small_int_t)(o)) & 1) == 0) && (((py_obj_base_t*)(o))->kind == (k))) -#define IS_SMALL_INT(o) (((py_small_int_t)(o)) & 1) -#define FROM_SMALL_INT(o) (((py_small_int_t)(o)) >> 1) -#define TO_SMALL_INT(o) ((py_obj_t)(((o) << 1) | 1)) - -typedef enum { - O_CONST, - O_STR, -#if MICROPY_ENABLE_FLOAT - O_FLOAT, - O_COMPLEX, -#endif - O_CELL, - O_EXCEPTION_0, - O_EXCEPTION_N, - O_RANGE, - O_RANGE_IT, - O_FUN_0, - O_FUN_1, - O_FUN_2, - O_FUN_N, - O_FUN_VAR, - O_FUN_BC, - O_FUN_ASM, - O_GEN_WRAP, - O_GEN_INSTANCE, - O_BOUND_METH, - O_CLOSURE, - O_TUPLE, - O_LIST, - O_TUPLE_IT, - O_LIST_IT, - O_SET, - O_MAP, - O_CLASS, - O_OBJ, - O_USER, -} py_obj_kind_t; - -typedef struct _py_obj_base_t py_obj_base_t; - -struct _py_obj_base_t { - py_obj_kind_t kind; - union { - const char *id; - qstr u_str; -#if MICROPY_ENABLE_FLOAT - py_float_t u_float; // for O_FLOAT - struct { // for O_COMPLEX - py_float_t real; - py_float_t imag; - } u_complex; -#endif - py_obj_t u_cell; // for O_CELL - struct { // for O_EXCEPTION_0 - qstr id; - } u_exc0; - struct { // for O_EXCEPTION_N - // TODO make generic object or something - qstr id; - int n_args; - const void **args; - } u_exc_n; - struct { // for O_RANGE - // TODO make generic object or something - machine_int_t start; - machine_int_t stop; - machine_int_t step; - } u_range; - struct { // for O_RANGE_IT - // TODO make generic object or something - machine_int_t cur; - machine_int_t stop; - machine_int_t step; - } u_range_it; - struct { // for O_FUN_[012N], O_FUN_VAR - int n_args; - void *fun; - } u_fun; - struct { // for O_FUN_BC - int n_args; - uint n_state; - byte *code; - } u_fun_bc; - struct { // for O_FUN_ASM - int n_args; - void *fun; - } u_fun_asm; - struct { // for O_GEN_WRAP - int n_state; - py_obj_base_t *fun; - } u_gen_wrap; - struct { // for O_GEN_INSTANCE - py_obj_t *state; - const byte *ip; - py_obj_t *sp; - } u_gen_instance; - struct { // for O_BOUND_METH - py_obj_t meth; - py_obj_t self; - } u_bound_meth; - struct { // for O_CLOSURE - py_obj_t fun; - py_obj_t vars; - } u_closure; - struct { // for O_TUPLE, O_LIST - machine_uint_t alloc; - machine_uint_t len; - py_obj_t *items; - } u_tuple_list; - struct { // for O_TUPLE_IT, O_LIST_IT - py_obj_base_t *obj; - machine_uint_t cur; - } u_tuple_list_it; - struct { // for O_SET - machine_uint_t alloc; - machine_uint_t used; - py_obj_t *table; - } u_set; - py_map_t u_map; // for O_MAP - struct { // for O_CLASS - py_map_t *locals; - } u_class; - struct { // for O_OBJ - py_obj_base_t *class; // points to a O_CLASS object - py_map_t *members; - } u_obj; - struct { // for O_USER - const py_user_info_t *info; - machine_uint_t data1; - machine_uint_t data2; - } u_user; - }; -}; - -py_obj_t py_obj_new_tuple_iterator(py_obj_base_t *tuple, int cur); -py_obj_t py_obj_new_list_iterator(py_obj_base_t *list, int cur); diff --git a/py/objrange.c b/py/objrange.c new file mode 100644 index 0000000000000000000000000000000000000000..b7fd17fa0ada1fb5924317f862fadcea891357c3 --- /dev/null +++ b/py/objrange.c @@ -0,0 +1,88 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" + +/******************************************************************************/ +/* range */ + +typedef struct _mp_obj_range_t { + mp_obj_base_t base; + // TODO make these values generic objects or something + machine_int_t start; + machine_int_t stop; + machine_int_t step; +} mp_obj_range_t; + +mp_obj_t range_getiter(mp_obj_t o_in) { + mp_obj_range_t *o = o_in; + return mp_obj_new_range_iterator(o->start, o->stop, o->step); +} + +static const mp_obj_type_t range_type = { + { &mp_const_type} , + "range", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + range_getiter, + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +// range is a class and instances are immutable sequence objects +mp_obj_t mp_obj_new_range(int start, int stop, int step) { + mp_obj_range_t *o = m_new_obj(mp_obj_range_t); + o->base.type = &range_type; + o->start = start; + o->stop = stop; + o->step = step; + return o; +} + +/******************************************************************************/ +/* range iterator */ + +typedef struct _mp_obj_range_it_t { + mp_obj_base_t base; + // TODO make these values generic objects or something + machine_int_t cur; + machine_int_t stop; + machine_int_t step; +} mp_obj_range_it_t; + +mp_obj_t range_it_iternext(mp_obj_t o_in) { + mp_obj_range_it_t *o = o_in; + if ((o->step > 0 && o->cur < o->stop) || (o->step < 0 && o->cur > o->stop)) { + mp_obj_t o_out = MP_OBJ_NEW_SMALL_INT(o->cur); + o->cur += o->step; + return o_out; + } else { + return mp_const_stop_iteration; + } +} + +static const mp_obj_type_t range_it_type = { + { &mp_const_type }, + "range_iterator", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + range_it_iternext, + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step) { + mp_obj_range_it_t *o = m_new_obj(mp_obj_range_it_t); + o->base.type = &range_it_type; + o->cur = cur; + o->stop = stop; + o->step = step; + return o; +} diff --git a/py/objset.c b/py/objset.c new file mode 100644 index 0000000000000000000000000000000000000000..f225ca7f66efa52f5c9a92defff3b71c59b5cc0d --- /dev/null +++ b/py/objset.c @@ -0,0 +1,58 @@ +#include <stdlib.h> +#include <stdint.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "map.h" + +typedef struct _mp_obj_set_t { + mp_obj_base_t base; + mp_set_t set; +} mp_obj_set_t; + +void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + mp_obj_set_t *self = self_in; + bool first = true; + print(env, "{"); + for (int i = 0; i < self->set.alloc; i++) { + if (self->set.table[i] != MP_OBJ_NULL) { + if (!first) { + print(env, ", "); + } + first = false; + mp_obj_print_helper(print, env, self->set.table[i]); + } + } + print(env, "}"); +} + +static const mp_obj_type_t set_type = { + { &mp_const_type }, + "set", + set_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { { NULL, NULL }, }, // method list +}; + +mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) { + mp_obj_set_t *o = m_new_obj(mp_obj_set_t); + o->base.type = &set_type; + mp_set_init(&o->set, n_args); + for (int i = 0; i < n_args; i++) { + mp_set_lookup(&o->set, items[i], true); + } + return o; +} + +void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) { + assert(MP_OBJ_IS_TYPE(self_in, &set_type)); + mp_obj_set_t *self = self_in; + mp_set_lookup(&self->set, item, true); +} diff --git a/py/objstr.c b/py/objstr.c new file mode 100644 index 0000000000000000000000000000000000000000..d82ea3d3ce88a8b2ba01583ae18bc498a0671dea --- /dev/null +++ b/py/objstr.c @@ -0,0 +1,151 @@ +#include <stdlib.h> +#include <stdint.h> +#include <stdarg.h> +#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" +#include "runtime.h" + +typedef struct _mp_obj_str_t { + mp_obj_base_t base; + qstr qstr; +} mp_obj_str_t; + +void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + mp_obj_str_t *self = self_in; + // TODO need to escape chars etc + print(env, "'%s'", qstr_str(self->qstr)); +} + +mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_obj_str_t *lhs = lhs_in; + const char *lhs_str = qstr_str(lhs->qstr); + switch (op) { + case RT_BINARY_OP_SUBSCR: + // string access + // XXX a massive hack! + return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]); + + case RT_BINARY_OP_ADD: + case RT_BINARY_OP_INPLACE_ADD: + if (MP_OBJ_IS_TYPE(rhs_in, &str_type)) { + // add 2 strings + const char *rhs_str = qstr_str(((mp_obj_str_t*)rhs_in)->qstr); + char *val = m_new(char, strlen(lhs_str) + strlen(rhs_str) + 1); + stpcpy(stpcpy(val, lhs_str), rhs_str); + return mp_obj_new_str(qstr_from_str_take(val)); + } + break; + } + + return MP_OBJ_NULL; // op not supported +} + +mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { + assert(MP_OBJ_IS_TYPE(self_in, &str_type)); + mp_obj_str_t *self = self_in; + int required_len = strlen(qstr_str(self->qstr)); + + // process arg, count required chars + uint seq_len; + mp_obj_t *seq_items; + if (MP_OBJ_IS_TYPE(arg, &tuple_type)) { + mp_obj_tuple_get(arg, &seq_len, &seq_items); + } else if (MP_OBJ_IS_TYPE(arg, &list_type)) { + mp_obj_list_get(arg, &seq_len, &seq_items); + } else { + goto bad_arg; + } + for (int i = 0; i < seq_len; i++) { + if (!MP_OBJ_IS_TYPE(seq_items[i], &str_type)) { + goto bad_arg; + } + required_len += strlen(qstr_str(mp_obj_str_get(seq_items[i]))); + } + + // make joined string + char *joined_str = m_new(char, required_len + 1); + joined_str[0] = 0; + for (int i = 0; i < seq_len; i++) { + const char *s2 = qstr_str(mp_obj_str_get(seq_items[i])); + if (i > 0) { + strcat(joined_str, qstr_str(self->qstr)); + } + strcat(joined_str, s2); + } + return mp_obj_new_str(qstr_from_str_take(joined_str)); + +bad_arg: + nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "?str.join expecting a list of str's")); +} + +void vstr_printf_wrapper(void *env, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vstr_vprintf(env, fmt, args); + va_end(args); +} + +mp_obj_t str_format(int n_args, const mp_obj_t *args) { + assert(MP_OBJ_IS_TYPE(args[0], &str_type)); + mp_obj_str_t *self = args[0]; + + const char *str = qstr_str(self->qstr); + int arg_i = 1; + vstr_t *vstr = vstr_new(); + for (; *str; str++) { + if (*str == '{') { + str++; + if (*str == '{') { + vstr_add_char(vstr, '{'); + } else if (*str == '}') { + if (arg_i >= n_args) { + nlr_jump(mp_obj_new_exception_msg(rt_q_IndexError, "tuple index out of range")); + } + mp_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i]); + arg_i++; + } + } else { + vstr_add_char(vstr, *str); + } + } + + return mp_obj_new_str(qstr_from_str_take(vstr->buf)); +} + +static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join); +static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format); + +const mp_obj_type_t str_type = { + { &mp_const_type }, + "str", + str_print, // print + NULL, // call_n + NULL, // unary_op + str_binary_op, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "join", &str_join_obj }, + { "format", &str_format_obj }, + { NULL, NULL }, // end-of-list sentinel + }, +}; + +mp_obj_t mp_obj_new_str(qstr qstr) { + mp_obj_str_t *o = m_new_obj(mp_obj_str_t); + o->base.type = &str_type; + o->qstr = qstr; + return o; +} + +qstr mp_obj_str_get(mp_obj_t self_in) { + assert(MP_OBJ_IS_TYPE(self_in, &str_type)); + mp_obj_str_t *self = self_in; + return self->qstr; +} diff --git a/py/objtuple.c b/py/objtuple.c new file mode 100644 index 0000000000000000000000000000000000000000..b98d6ede7be40909927e416c1a3de35ed8fc6529 --- /dev/null +++ b/py/objtuple.c @@ -0,0 +1,133 @@ +#include <stdlib.h> +#include <stdint.h> +//#include <string.h> +#include <assert.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" + +typedef struct _mp_obj_tuple_t { + mp_obj_base_t base; + machine_uint_t len; + mp_obj_t items[]; +} mp_obj_tuple_t; + +static mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur); + +/******************************************************************************/ +/* tuple */ + +void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { + mp_obj_tuple_t *o = o_in; + print(env, "("); + for (int i = 0; i < o->len; i++) { + if (i > 0) { + print(env, ", "); + } + mp_obj_print_helper(print, env, o->items[i]); + } + if (o->len == 1) { + print(env, ","); + } + print(env, ")"); +} + +mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { + mp_obj_tuple_t *o = lhs; + switch (op) { + case RT_BINARY_OP_SUBSCR: + { + // tuple load + uint index = mp_get_index(o->base.type, o->len, rhs); + return o->items[index]; + } + default: + // op not supported + return NULL; + } +} + +mp_obj_t tuple_getiter(mp_obj_t o_in) { + return mp_obj_new_tuple_iterator(o_in, 0); +} + +void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items) { + mp_obj_tuple_t *self = self_in; + *len = self->len; + *items = &self->items[0]; +} + +const mp_obj_type_t tuple_type = { + { &mp_const_type }, + "tuple", + tuple_print, // print + NULL, // call_n + NULL, // unary_op + tuple_binary_op, // binary_op + tuple_getiter, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; + +mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items) { + mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n); + o->base.type = &tuple_type; + o->len = n; + for (int i = 0; i < n; i++) { + o->items[i] = items[i]; + } + return o; +} + +mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items) { + mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n); + o->base.type = &tuple_type; + o->len = n; + for (int i = 0; i < n; i++) { + o->items[i] = items[n - i - 1]; + } + return o; +} + +/******************************************************************************/ +/* tuple iterator */ + +typedef struct _mp_obj_tuple_it_t { + mp_obj_base_t base; + mp_obj_tuple_t *tuple; + machine_uint_t cur; +} mp_obj_tuple_it_t; + +mp_obj_t tuple_it_iternext(mp_obj_t self_in) { + mp_obj_tuple_it_t *self = self_in; + if (self->cur < self->tuple->len) { + mp_obj_t o_out = self->tuple->items[self->cur]; + self->cur += 1; + return o_out; + } else { + return mp_const_stop_iteration; + } +} + +static const mp_obj_type_t tuple_it_type = { + { &mp_const_type }, + "tuple_iterator", + NULL, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + tuple_it_iternext, + {{NULL, NULL},}, // method list +}; + +static mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur) { + mp_obj_tuple_it_t *o = m_new_obj(mp_obj_tuple_it_t); + o->base.type = &tuple_it_type; + o->tuple = tuple; + o->cur = cur; + return o; +} diff --git a/py/objtype.c b/py/objtype.c new file mode 100644 index 0000000000000000000000000000000000000000..4358148c04dca28c788c5db251435e41f74a748d --- /dev/null +++ b/py/objtype.c @@ -0,0 +1,23 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" + +void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + print(env, "type?"); +} + +const mp_obj_type_t mp_const_type = { + { &mp_const_type }, + "type?", + type_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + {{NULL, NULL},}, // method list +}; diff --git a/py/parse.c b/py/parse.c index 632ac4e4f50e2bf0ed6c2914fe8b33e172eedeca..48c30480568a951dbef8d4392acae978deae4ac8 100644 --- a/py/parse.c +++ b/py/parse.c @@ -7,7 +7,7 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "parse.h" @@ -50,9 +50,9 @@ enum { #define one_or_more (RULE_ACT_LIST | 2) #define list (RULE_ACT_LIST | 1) #define list_with_end (RULE_ACT_LIST | 3) -#define tok(t) (RULE_ARG_TOK | PY_TOKEN_##t) +#define tok(t) (RULE_ARG_TOK | MP_TOKEN_##t) #define rule(r) (RULE_ARG_RULE | RULE_##r) -#define opt_tok(t) (RULE_ARG_OPT_TOK | PY_TOKEN_##t) +#define opt_tok(t) (RULE_ARG_OPT_TOK | MP_TOKEN_##t) #define opt_rule(r) (RULE_ARG_OPT_RULE | RULE_##r) #ifdef USE_RULE_NAME #define DEF_RULE(rule, comp, kind, arg...) static const rule_t rule_##rule = { RULE_##rule, kind, #rule, { arg } }; @@ -89,7 +89,7 @@ typedef struct _parser_t { rule_stack_t *rule_stack; uint result_stack_top; - py_parse_node_t *result_stack; + mp_parse_node_t *result_stack; } parser_t; static void push_rule(parser_t *parser, const rule_t *rule, int arg_i) { @@ -115,47 +115,47 @@ static void pop_rule(parser_t *parser, const rule_t **rule, uint *arg_i) { *arg_i = parser->rule_stack[parser->rule_stack_top].arg_i; } -py_parse_node_t py_parse_node_new_leaf(machine_int_t kind, machine_int_t arg) { - return (py_parse_node_t)(kind | (arg << 4)); +mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg) { + return (mp_parse_node_t)(kind | (arg << 4)); } int num_parse_nodes_allocated = 0; -py_parse_node_struct_t *parse_node_new_struct(int rule_id, int num_args) { - py_parse_node_struct_t *pn = m_malloc(sizeof(py_parse_node_struct_t) + num_args * sizeof(py_parse_node_t)); +mp_parse_node_struct_t *parse_node_new_struct(int rule_id, int num_args) { + mp_parse_node_struct_t *pn = m_malloc(sizeof(mp_parse_node_struct_t) + num_args * sizeof(mp_parse_node_t)); pn->source = 0; // TODO pn->kind_num_nodes = (rule_id & 0xff) | (num_args << 8); num_parse_nodes_allocated += 1; return pn; } -void py_parse_node_show(py_parse_node_t pn, int indent) { +void mp_parse_node_show(mp_parse_node_t pn, int indent) { for (int i = 0; i < indent; i++) { printf(" "); } - if (PY_PARSE_NODE_IS_NULL(pn)) { + if (MP_PARSE_NODE_IS_NULL(pn)) { printf("NULL\n"); - } else if (PY_PARSE_NODE_IS_LEAF(pn)) { - int arg = PY_PARSE_NODE_LEAF_ARG(pn); - switch (PY_PARSE_NODE_LEAF_KIND(pn)) { - case PY_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break; - case PY_PARSE_NODE_SMALL_INT: printf("int(%d)\n", arg); break; - case PY_PARSE_NODE_INTEGER: printf("int(%s)\n", qstr_str(arg)); break; - case PY_PARSE_NODE_DECIMAL: printf("dec(%s)\n", qstr_str(arg)); break; - case PY_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break; - case PY_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break; - case PY_PARSE_NODE_TOKEN: printf("tok(%d)\n", arg); break; + } else if (MP_PARSE_NODE_IS_LEAF(pn)) { + int arg = MP_PARSE_NODE_LEAF_ARG(pn); + switch (MP_PARSE_NODE_LEAF_KIND(pn)) { + case MP_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break; + case MP_PARSE_NODE_SMALL_INT: printf("int(%d)\n", arg); break; + case MP_PARSE_NODE_INTEGER: printf("int(%s)\n", qstr_str(arg)); break; + case MP_PARSE_NODE_DECIMAL: printf("dec(%s)\n", qstr_str(arg)); break; + case MP_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break; + case MP_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break; + case MP_PARSE_NODE_TOKEN: printf("tok(%d)\n", arg); break; default: assert(0); } } else { - py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pn; + mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pn; int n = pns2->kind_num_nodes >> 8; #ifdef USE_RULE_NAME - printf("%s(%d) (n=%d)\n", rules[PY_PARSE_NODE_STRUCT_KIND(pns2)]->rule_name, PY_PARSE_NODE_STRUCT_KIND(pns2), n); + printf("%s(%d) (n=%d)\n", rules[MP_PARSE_NODE_STRUCT_KIND(pns2)]->rule_name, MP_PARSE_NODE_STRUCT_KIND(pns2), n); #else - printf("rule(%u) (n=%d)\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns2), n); + printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns2), n); #endif for (int i = 0; i < n; i++) { - py_parse_node_show(pns2->nodes[i], indent + 2); + mp_parse_node_show(pns2->nodes[i], indent + 2); } } } @@ -164,31 +164,31 @@ void py_parse_node_show(py_parse_node_t pn, int indent) { static void result_stack_show(parser_t *parser) { printf("result stack, most recent first\n"); for (int i = parser->result_stack_top - 1; i >= 0; i--) { - py_parse_node_show(parser->result_stack[i], 0); + mp_parse_node_show(parser->result_stack[i], 0); } } */ -static py_parse_node_t pop_result(parser_t *parser) { +static mp_parse_node_t pop_result(parser_t *parser) { assert(parser->result_stack_top > 0); return parser->result_stack[--parser->result_stack_top]; } -static py_parse_node_t peek_result(parser_t *parser, int pos) { +static mp_parse_node_t peek_result(parser_t *parser, int pos) { assert(parser->result_stack_top > pos); return parser->result_stack[parser->result_stack_top - 1 - pos]; } -static void push_result_node(parser_t *parser, py_parse_node_t pn) { +static void push_result_node(parser_t *parser, mp_parse_node_t pn) { parser->result_stack[parser->result_stack_top++] = pn; } -static void push_result_token(parser_t *parser, const py_lexer_t *lex) { - const py_token_t *tok = py_lexer_cur(lex); - py_parse_node_t pn; - if (tok->kind == PY_TOKEN_NAME) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_ID, qstr_from_strn_copy(tok->str, tok->len)); - } else if (tok->kind == PY_TOKEN_NUMBER) { +static void push_result_token(parser_t *parser, const mp_lexer_t *lex) { + const mp_token_t *tok = mp_lexer_cur(lex); + mp_parse_node_t pn; + if (tok->kind == MP_TOKEN_NAME) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_ID, qstr_from_strn_copy(tok->str, tok->len)); + } else if (tok->kind == MP_TOKEN_NUMBER) { bool dec = false; bool small_int = true; int int_val = 0; @@ -227,43 +227,43 @@ static void push_result_token(parser_t *parser, const py_lexer_t *lex) { } } if (dec) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_DECIMAL, qstr_from_strn_copy(str, len)); - } else if (small_int && PY_FIT_SMALL_INT(int_val)) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, int_val); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_DECIMAL, qstr_from_strn_copy(str, len)); + } else if (small_int && MP_FIT_SMALL_INT(int_val)) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, int_val); } else { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_INTEGER, qstr_from_strn_copy(str, len)); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_INTEGER, qstr_from_strn_copy(str, len)); } - } else if (tok->kind == PY_TOKEN_STRING) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_STRING, qstr_from_strn_copy(tok->str, tok->len)); - } else if (tok->kind == PY_TOKEN_BYTES) { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_BYTES, qstr_from_strn_copy(tok->str, tok->len)); + } else if (tok->kind == MP_TOKEN_STRING) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_STRING, qstr_from_strn_copy(tok->str, tok->len)); + } else if (tok->kind == MP_TOKEN_BYTES) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_BYTES, qstr_from_strn_copy(tok->str, tok->len)); } else { - pn = py_parse_node_new_leaf(PY_PARSE_NODE_TOKEN, tok->kind); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_TOKEN, tok->kind); } push_result_node(parser, pn); } static void push_result_rule(parser_t *parser, const rule_t *rule, int num_args) { - py_parse_node_struct_t *pn = parse_node_new_struct(rule->rule_id, num_args); + mp_parse_node_struct_t *pn = parse_node_new_struct(rule->rule_id, num_args); for (int i = num_args; i > 0; i--) { pn->nodes[i - 1] = pop_result(parser); } - push_result_node(parser, (py_parse_node_t)pn); + push_result_node(parser, (mp_parse_node_t)pn); } -py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { +mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { parser_t *parser = m_new(parser_t, 1); parser->rule_stack_alloc = 64; parser->rule_stack_top = 0; parser->rule_stack = m_new(rule_stack_t, parser->rule_stack_alloc); - parser->result_stack = m_new(py_parse_node_t, 1000); + parser->result_stack = m_new(mp_parse_node_t, 1000); parser->result_stack_top = 0; int top_level_rule; switch (input_kind) { - case PY_PARSE_SINGLE_INPUT: top_level_rule = RULE_single_input; break; - //case PY_PARSE_EVAL_INPUT: top_level_rule = RULE_eval_input; break; + case MP_PARSE_SINGLE_INPUT: top_level_rule = RULE_single_input; break; + //case MP_PARSE_EVAL_INPUT: top_level_rule = RULE_eval_input; break; default: top_level_rule = RULE_file_input; } push_rule(parser, rules[top_level_rule], 0); @@ -271,7 +271,7 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { uint n, i; bool backtrack = false; const rule_t *rule; - py_token_kind_t tok_kind; + mp_token_kind_t tok_kind; bool emit_rule; bool had_trailing_sep; @@ -303,9 +303,9 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { for (; i < n - 1; ++i) { switch (rule->arg[i] & RULE_ARG_KIND_MASK) { case RULE_ARG_TOK: - if (py_lexer_is_kind(lex, rule->arg[i] & RULE_ARG_ARG_MASK)) { + if (mp_lexer_is_kind(lex, rule->arg[i] & RULE_ARG_ARG_MASK)) { push_result_token(parser, lex); - py_lexer_to_next(lex); + mp_lexer_to_next(lex); goto next_rule; } break; @@ -318,9 +318,9 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { } } if ((rule->arg[i] & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) { - if (py_lexer_is_kind(lex, rule->arg[i] & RULE_ARG_ARG_MASK)) { + if (mp_lexer_is_kind(lex, rule->arg[i] & RULE_ARG_ARG_MASK)) { push_result_token(parser, lex); - py_lexer_to_next(lex); + mp_lexer_to_next(lex); } else { backtrack = true; goto next_rule; @@ -337,7 +337,7 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { assert(i > 0); if ((rule->arg[i - 1] & RULE_ARG_KIND_MASK) == RULE_ARG_OPT_RULE) { // an optional rule that failed, so continue with next arg - push_result_node(parser, PY_PARSE_NODE_NULL); + push_result_node(parser, MP_PARSE_NODE_NULL); backtrack = false; } else { // a mandatory rule that failed, so propagate backtrack @@ -356,12 +356,12 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { case RULE_ARG_TOK: // need to match a token tok_kind = rule->arg[i] & RULE_ARG_ARG_MASK; - if (py_lexer_is_kind(lex, tok_kind)) { + if (mp_lexer_is_kind(lex, tok_kind)) { // matched token - if (tok_kind == PY_TOKEN_NAME) { + if (tok_kind == MP_TOKEN_NAME) { push_result_token(parser, lex); } - py_lexer_to_next(lex); + mp_lexer_to_next(lex); } else { // failed to match token if (i > 0) { @@ -399,10 +399,10 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { for (int x = 0; x < n; ++x) { if ((rule->arg[x] & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) { tok_kind = rule->arg[x] & RULE_ARG_ARG_MASK; - if (tok_kind >= PY_TOKEN_NAME) { + if (tok_kind >= MP_TOKEN_NAME) { emit_rule = true; } - if (tok_kind == PY_TOKEN_NAME) { + if (tok_kind == MP_TOKEN_NAME) { // only tokens which were names are pushed to stack i += 1; } @@ -427,13 +427,13 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { // always emit these rules, and add an extra blank node at the end (to be used by the compiler to store data) if (rule->rule_id == RULE_funcdef || rule->rule_id == RULE_classdef || rule->rule_id == RULE_comp_for || rule->rule_id == RULE_lambdef || rule->rule_id == RULE_lambdef_nocond) { emit_rule = true; - push_result_node(parser, PY_PARSE_NODE_NULL); + push_result_node(parser, MP_PARSE_NODE_NULL); i += 1; } int num_not_nil = 0; for (int x = 0; x < i; ++x) { - if (peek_result(parser, x) != PY_PARSE_NODE_NULL) { + if (peek_result(parser, x) != MP_PARSE_NODE_NULL) { num_not_nil += 1; } } @@ -446,10 +446,10 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { //assert(0); } else if (num_not_nil == 1) { // single result, leave it on stack - py_parse_node_t pn = PY_PARSE_NODE_NULL; + mp_parse_node_t pn = MP_PARSE_NODE_NULL; for (int x = 0; x < i; ++x) { - py_parse_node_t pn2 = pop_result(parser); - if (pn2 != PY_PARSE_NODE_NULL) { + mp_parse_node_t pn2 = pop_result(parser); + if (pn2 != MP_PARSE_NODE_NULL) { pn = pn2; } } @@ -498,13 +498,13 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { uint arg = rule->arg[i & 1 & n]; switch (arg & RULE_ARG_KIND_MASK) { case RULE_ARG_TOK: - if (py_lexer_is_kind(lex, arg & RULE_ARG_ARG_MASK)) { + if (mp_lexer_is_kind(lex, arg & RULE_ARG_ARG_MASK)) { if (i & 1 & n) { // separators which are tokens are not pushed to result stack } else { push_result_token(parser, lex); } - py_lexer_to_next(lex); + mp_lexer_to_next(lex); // got element of list, so continue parsing list i += 1; } else { @@ -552,7 +552,7 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { } // check we are at the end of the token stream - if (!py_lexer_is_kind(lex, PY_TOKEN_END)) { + if (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { goto syntax_error; } @@ -564,16 +564,16 @@ py_parse_node_t py_parse(py_lexer_t *lex, py_parse_input_kind_t input_kind) { return parser->result_stack[0]; syntax_error: - if (py_lexer_is_kind(lex, PY_TOKEN_INDENT)) { - py_lexer_show_error_pythonic(lex, "IndentationError: unexpected indent"); - } else if (py_lexer_is_kind(lex, PY_TOKEN_DEDENT_MISMATCH)) { - py_lexer_show_error_pythonic(lex, "IndentationError: unindent does not match any outer indentation level"); + if (mp_lexer_is_kind(lex, MP_TOKEN_INDENT)) { + mp_lexer_show_error_pythonic(lex, "IndentationError: unexpected indent"); + } else if (mp_lexer_is_kind(lex, MP_TOKEN_DEDENT_MISMATCH)) { + mp_lexer_show_error_pythonic(lex, "IndentationError: unindent does not match any outer indentation level"); } else { - py_lexer_show_error_pythonic(lex, "syntax error:"); + mp_lexer_show_error_pythonic(lex, "syntax error:"); #ifdef USE_RULE_NAME - py_lexer_show_error(lex, rule->rule_name); + mp_lexer_show_error(lex, rule->rule_name); #endif - py_token_show(py_lexer_cur(lex)); + mp_token_show(mp_lexer_cur(lex)); } - return PY_PARSE_NODE_NULL; + return MP_PARSE_NODE_NULL; } diff --git a/py/parse.h b/py/parse.h index 722d9f6c20705b67bafa2687b091dd3f5d28daa6..7326243ea442ae49c21f2d3afed8daeb7013f020 100644 --- a/py/parse.h +++ b/py/parse.h @@ -1,6 +1,6 @@ -struct _py_lexer_t; +struct _mp_lexer_t; -// a py_parse_node_t is: +// a mp_parse_node_t is: // - 0000...0000: no node // - xxxx...0001: an identifier; bits 4 and above are the qstr // - xxxx...0011: a small integer; bits 4 and above are the signed value, 2's complement @@ -8,58 +8,58 @@ struct _py_lexer_t; // - xxxx...0111: a decimal; bits 4 and above are the qstr holding the value // - xxxx...1001: a string; bits 4 and above are the qstr holding the value // - xxxx...1011: a string with triple quotes; bits 4 and above are the qstr holding the value -// - xxxx...1101: a token; bits 4 and above are py_token_kind_t -// - xxxx...xxx0: pointer to py_parse_node_struct_t +// - xxxx...1101: a token; bits 4 and above are mp_token_kind_t +// - xxxx...xxx0: pointer to mp_parse_node_struct_t // makes sure the top 5 bits of x are all cleared (positive number) or all set (negavite number) // these macros can probably go somewhere else because they are used more than just in the parser -#define PY_UINT_HIGH_5_BITS (~((~((machine_uint_t)0)) >> 5)) -#define PY_FIT_SMALL_INT(x) (((((machine_uint_t)(x)) & PY_UINT_HIGH_5_BITS) == 0) || ((((machine_uint_t)(x)) & PY_UINT_HIGH_5_BITS) == PY_UINT_HIGH_5_BITS)) +#define MP_UINT_HIGH_5_BITS (~((~((machine_uint_t)0)) >> 5)) +#define MP_FIT_SMALL_INT(x) (((((machine_uint_t)(x)) & MP_UINT_HIGH_5_BITS) == 0) || ((((machine_uint_t)(x)) & MP_UINT_HIGH_5_BITS) == MP_UINT_HIGH_5_BITS)) -#define PY_PARSE_NODE_NULL (0) -#define PY_PARSE_NODE_ID (0x1) -#define PY_PARSE_NODE_SMALL_INT (0x3) -#define PY_PARSE_NODE_INTEGER (0x5) -#define PY_PARSE_NODE_DECIMAL (0x7) -#define PY_PARSE_NODE_STRING (0x9) -#define PY_PARSE_NODE_BYTES (0xb) -#define PY_PARSE_NODE_TOKEN (0xd) +#define MP_PARSE_NODE_NULL (0) +#define MP_PARSE_NODE_ID (0x1) +#define MP_PARSE_NODE_SMALL_INT (0x3) +#define MP_PARSE_NODE_INTEGER (0x5) +#define MP_PARSE_NODE_DECIMAL (0x7) +#define MP_PARSE_NODE_STRING (0x9) +#define MP_PARSE_NODE_BYTES (0xb) +#define MP_PARSE_NODE_TOKEN (0xd) -typedef machine_uint_t py_parse_node_t; // must be pointer size +typedef machine_uint_t mp_parse_node_t; // must be pointer size -typedef struct _py_parse_node_struct_t { +typedef struct _mp_parse_node_struct_t { uint32_t source; // file identifier, and line number uint32_t kind_num_nodes; // parse node kind, and number of nodes - py_parse_node_t nodes[]; // nodes -} py_parse_node_struct_t; + mp_parse_node_t nodes[]; // nodes +} mp_parse_node_struct_t; -// macros for py_parse_node_t usage +// macros for mp_parse_node_t usage // some of these evaluate their argument more than once -#define PY_PARSE_NODE_IS_NULL(pn) ((pn) == PY_PARSE_NODE_NULL) -#define PY_PARSE_NODE_IS_LEAF(pn) ((pn) & 1) -#define PY_PARSE_NODE_IS_STRUCT(pn) ((pn) != PY_PARSE_NODE_NULL && ((pn) & 1) == 0) -#define PY_PARSE_NODE_IS_STRUCT_KIND(pn, k) ((pn) != PY_PARSE_NODE_NULL && ((pn) & 1) == 0 && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)(pn)) == (k)) +#define MP_PARSE_NODE_IS_NULL(pn) ((pn) == MP_PARSE_NODE_NULL) +#define MP_PARSE_NODE_IS_LEAF(pn) ((pn) & 1) +#define MP_PARSE_NODE_IS_STRUCT(pn) ((pn) != MP_PARSE_NODE_NULL && ((pn) & 1) == 0) +#define MP_PARSE_NODE_IS_STRUCT_KIND(pn, k) ((pn) != MP_PARSE_NODE_NULL && ((pn) & 1) == 0 && MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)(pn)) == (k)) -#define PY_PARSE_NODE_IS_ID(pn) (((pn) & 0xf) == PY_PARSE_NODE_ID) -#define PY_PARSE_NODE_IS_SMALL_INT(pn) (((pn) & 0xf) == PY_PARSE_NODE_SMALL_INT) -#define PY_PARSE_NODE_IS_TOKEN(pn) (((pn) & 0xf) == PY_PARSE_NODE_TOKEN) -#define PY_PARSE_NODE_IS_TOKEN_KIND(pn, k) ((pn) == (PY_PARSE_NODE_TOKEN | (k << 4))) +#define MP_PARSE_NODE_IS_ID(pn) (((pn) & 0xf) == MP_PARSE_NODE_ID) +#define MP_PARSE_NODE_IS_SMALL_INT(pn) (((pn) & 0xf) == MP_PARSE_NODE_SMALL_INT) +#define MP_PARSE_NODE_IS_TOKEN(pn) (((pn) & 0xf) == MP_PARSE_NODE_TOKEN) +#define MP_PARSE_NODE_IS_TOKEN_KIND(pn, k) ((pn) == (MP_PARSE_NODE_TOKEN | (k << 4))) -#define PY_PARSE_NODE_LEAF_KIND(pn) ((pn) & 0xf) +#define MP_PARSE_NODE_LEAF_KIND(pn) ((pn) & 0xf) // TODO should probably have int and uint versions of this macro -#define PY_PARSE_NODE_LEAF_ARG(pn) (((machine_int_t)(pn)) >> 4) -#define PY_PARSE_NODE_STRUCT_KIND(pns) ((pns)->kind_num_nodes & 0xff) -#define PY_PARSE_NODE_STRUCT_NUM_NODES(pns) ((pns)->kind_num_nodes >> 8) +#define MP_PARSE_NODE_LEAF_ARG(pn) (((machine_int_t)(pn)) >> 4) +#define MP_PARSE_NODE_STRUCT_KIND(pns) ((pns)->kind_num_nodes & 0xff) +#define MP_PARSE_NODE_STRUCT_NUM_NODES(pns) ((pns)->kind_num_nodes >> 8) -py_parse_node_t py_parse_node_new_leaf(machine_int_t kind, machine_int_t arg); +mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg); -void py_parse_node_show(py_parse_node_t pn, int indent); +void mp_parse_node_show(mp_parse_node_t pn, int indent); typedef enum { - PY_PARSE_SINGLE_INPUT, - PY_PARSE_FILE_INPUT, - PY_PARSE_EVAL_INPUT, -} py_parse_input_kind_t; + MP_PARSE_SINGLE_INPUT, + MP_PARSE_FILE_INPUT, + MP_PARSE_EVAL_INPUT, +} mp_parse_input_kind_t; -py_parse_node_t py_parse(struct _py_lexer_t *lex, py_parse_input_kind_t input_kind); +mp_parse_node_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind); diff --git a/py/repl.c b/py/repl.c index f295aff23db50a43cfbee66fd83273d2e38b6ed4..ecf6e2d20b910b3effcef55ddc22ec15eabdfca7 100644 --- a/py/repl.c +++ b/py/repl.c @@ -11,7 +11,7 @@ bool str_startswith_word(const char *str, const char *head) { return head[i] == '\0' && (str[i] == '\0' || !g_unichar_isalpha(str[i])); } -bool py_repl_is_compound_stmt(const char *line) { +bool mp_repl_is_compound_stmt(const char *line) { // compound if line starts with a certain keyword if ( str_startswith_word(line, "if") diff --git a/py/repl.h b/py/repl.h index 014e8609b4edadff0bdfbe70dce42c5b79f5a8c8..02fe523ed431580d8ad3119847abdc504372610a 100644 --- a/py/repl.h +++ b/py/repl.h @@ -1 +1 @@ -bool py_repl_is_compound_stmt(const char *line); +bool mp_repl_is_compound_stmt(const char *line); diff --git a/py/runtime.c b/py/runtime.c index 35f4f2af29f133fd9774d59ecf71ea0ceb353e6c..a3d11f3c6ce58bec277d03e46303088fe30a7270 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1,23 +1,20 @@ // in principle, rt_xxx functions are called only by vm/native/viper and make assumptions about args -// py_xxx functions are safer and can be called by anyone +// mp_xxx functions are safer and can be called by anyone // note that rt_assign_xxx are called only from emit*, and maybe we can rename them to reflect this #include <stdint.h> #include <stdlib.h> #include <stdio.h> -#include <stdarg.h> #include <string.h> #include <assert.h> #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" +#include "obj.h" +#include "runtime0.h" #include "runtime.h" -#include "bc.h" - #include "map.h" -#include "obj.h" -#include "objprivate.h" #include "builtin.h" #if 0 // print debugging info @@ -46,203 +43,20 @@ qstr rt_q_TypeError; qstr rt_q_SyntaxError; qstr rt_q_ValueError; -py_obj_t py_const_none; -py_obj_t py_const_false; -py_obj_t py_const_true; -py_obj_t py_const_stop_iteration; - // locals and globals need to be pointers because they can be the same in outer module scope -static py_map_t *map_locals; -static py_map_t *map_globals; -static py_map_t map_builtins; - -py_map_t *rt_get_map_locals(void) { - return map_locals; -} - -void rt_set_map_locals(py_map_t *m) { - map_locals = m; -} - -static bool fit_small_int(py_small_int_t o) { - return true; -} - -int rt_is_true(py_obj_t arg) { - DEBUG_OP_printf("is true %p\n", arg); - if (IS_SMALL_INT(arg)) { - if (FROM_SMALL_INT(arg) == 0) { - return 0; - } else { - return 1; - } - } else if (arg == py_const_none) { - return 0; - } else if (arg == py_const_false) { - return 0; - } else if (arg == py_const_true) { - return 1; - } else { - assert(0); - return 0; - } -} - -void vstr_printf_wrapper(void *env, const char *fmt, ...) { - va_list args; - va_start(args, fmt); - vstr_vprintf(env, fmt, args); - va_end(args); -} - -py_obj_t rt_str_join(py_obj_t self_in, py_obj_t arg) { - assert(IS_O(self_in, O_STR)); - py_obj_base_t *self = self_in; - int required_len = strlen(qstr_str(self->u_str)); - - // process arg, count required chars - if (!IS_O(arg, O_TUPLE) && !IS_O(arg, O_LIST)) { - goto bad_arg; - } - py_obj_base_t *tuple_list = arg; - for (int i = 0; i < tuple_list->u_tuple_list.len; i++) { - if (!IS_O(tuple_list->u_tuple_list.items[i], O_STR)) { - goto bad_arg; - } - required_len += strlen(qstr_str(((py_obj_base_t*)tuple_list->u_tuple_list.items[i])->u_str)); - } - - // make joined string - char *joined_str = m_new(char, required_len + 1); - joined_str[0] = 0; - for (int i = 0; i < tuple_list->u_tuple_list.len; i++) { - const char *s2 = qstr_str(((py_obj_base_t*)tuple_list->u_tuple_list.items[i])->u_str); - if (i > 0) { - strcat(joined_str, qstr_str(self->u_str)); - } - strcat(joined_str, s2); - } - return py_obj_new_str(qstr_from_str_take(joined_str)); - -bad_arg: - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "?str.join expecting a list of str's", NULL, NULL)); -} - -py_obj_t rt_str_format(int n_args, const py_obj_t *args) { - assert(IS_O(args[0], O_STR)); - py_obj_base_t *self = args[0]; - - const char *str = qstr_str(self->u_str); - int arg_i = 1; - vstr_t *vstr = vstr_new(); - for (; *str; str++) { - if (*str == '{') { - str++; - if (*str == '{') { - vstr_add_char(vstr, '{'); - } else if (*str == '}') { - if (arg_i >= n_args) { - nlr_jump(py_obj_new_exception_2(rt_q_IndexError, "tuple index out of range", NULL, NULL)); - } - py_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i]); - arg_i++; - } - } else { - vstr_add_char(vstr, *str); - } - } - - return py_obj_new_str(qstr_from_str_take(vstr->buf)); -} - -uint get_index(py_obj_base_t *base, py_obj_t index) { - // assumes base is O_TUPLE or O_LIST - // TODO False and True are considered 0 and 1 for indexing purposes - int len = base->u_tuple_list.len; - if (IS_SMALL_INT(index)) { - int i = FROM_SMALL_INT(index); - if (i < 0) { - i += len; - } - if (i < 0 || i >= len) { - nlr_jump(py_obj_new_exception_2(rt_q_IndexError, "%s index out of range", py_obj_get_type_str(base), NULL)); - } - return i; - } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "%s indices must be integers, not %s", py_obj_get_type_str(base), py_obj_get_type_str(index))); - } -} - -py_obj_t rt_list_append(py_obj_t self_in, py_obj_t arg) { - assert(IS_O(self_in, O_LIST)); - py_obj_base_t *self = self_in; - if (self->u_tuple_list.len >= self->u_tuple_list.alloc) { - self->u_tuple_list.alloc *= 2; - self->u_tuple_list.items = m_renew(py_obj_t, self->u_tuple_list.items, self->u_tuple_list.alloc); - } - self->u_tuple_list.items[self->u_tuple_list.len++] = arg; - return py_const_none; // return None, as per CPython -} - -py_obj_t rt_list_pop(py_obj_t self_in, py_obj_t arg) { - assert(IS_O(self_in, O_LIST)); - py_obj_base_t *self = self_in; - uint index = get_index(self, arg); - py_obj_t ret = self->u_tuple_list.items[index]; - self->u_tuple_list.len -= 1; - memcpy(self->u_tuple_list.items + index, self->u_tuple_list.items + index + 1, (self->u_tuple_list.len - index) * sizeof(py_obj_t)); - return ret; -} - -// TODO make this conform to CPython's definition of sort -static void py_quicksort(py_obj_t *head, py_obj_t *tail, py_obj_t key_fn) { - while (head < tail) { - py_obj_t *h = head - 1; - py_obj_t *t = tail; - py_obj_t v = rt_call_function_1(key_fn, tail[0]); // get pivot using key_fn - for (;;) { - do ++h; while (rt_compare_op(RT_COMPARE_OP_LESS, rt_call_function_1(key_fn, h[0]), v) == py_const_true); - do --t; while (h < t && rt_compare_op(RT_COMPARE_OP_LESS, v, rt_call_function_1(key_fn, t[0])) == py_const_true); - if (h >= t) break; - py_obj_t x = h[0]; - h[0] = t[0]; - t[0] = x; - } - py_obj_t x = h[0]; - h[0] = tail[0]; - tail[0] = x; - py_quicksort(head, t, key_fn); - head = h + 1; - } -} - -py_obj_t rt_list_sort(py_obj_t self_in, py_obj_t key_fn) { - assert(IS_O(self_in, O_LIST)); - py_obj_base_t *self = self_in; - if (self->u_tuple_list.len > 1) { - py_quicksort(self->u_tuple_list.items, self->u_tuple_list.items + self->u_tuple_list.len - 1, key_fn); - } - return py_const_none; // return None, as per CPython -} - -py_obj_t rt_gen_instance_next(py_obj_t self_in) { - py_obj_t ret = rt_iternext(self_in); - if (ret == py_const_stop_iteration) { - nlr_jump(py_obj_new_exception_0(qstr_from_str_static("StopIteration"))); - } else { - return ret; - } -} +static mp_map_t *map_locals; +static mp_map_t *map_globals; +static mp_map_t map_builtins; typedef enum { - PY_CODE_NONE, - PY_CODE_BYTE, - PY_CODE_NATIVE, - PY_CODE_INLINE_ASM, -} py_code_kind_t; - -typedef struct _py_code_t { - py_code_kind_t kind; + MP_CODE_NONE, + MP_CODE_BYTE, + MP_CODE_NATIVE, + MP_CODE_INLINE_ASM, +} mp_code_kind_t; + +typedef struct _mp_code_t { + mp_code_kind_t kind; int n_args; int n_locals; int n_cells; @@ -254,23 +68,16 @@ typedef struct _py_code_t { uint len; } u_byte; struct { - py_fun_t fun; + mp_fun_t fun; } u_native; struct { void *fun; } u_inline_asm; }; -} py_code_t; +} mp_code_t; static int next_unique_code_id; -static py_code_t *unique_codes; - -py_obj_t fun_str_join; -py_obj_t fun_str_format; -py_obj_t fun_list_append; -py_obj_t fun_list_pop; -py_obj_t fun_list_sort; -py_obj_t fun_gen_instance_next; +static mp_code_t *unique_codes; #ifdef WRITE_CODE FILE *fp_write_code = NULL; @@ -292,50 +99,41 @@ void rt_init(void) { rt_q_SyntaxError = qstr_from_str_static("SyntaxError"); rt_q_ValueError = qstr_from_str_static("ValueError"); - py_const_none = py_obj_new_const("None"); - py_const_false = py_obj_new_const("False"); - py_const_true = py_obj_new_const("True"); - py_const_stop_iteration = py_obj_new_const("StopIteration"); - // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New()) - map_locals = map_globals = py_map_new(MAP_QSTR, 1); - py_qstr_map_lookup(map_globals, qstr_from_str_static("__name__"), true)->value = py_obj_new_str(qstr_from_str_static("__main__")); - - py_map_init(&map_builtins, MAP_QSTR, 3); - py_qstr_map_lookup(&map_builtins, rt_q___build_class__, true)->value = rt_make_function_2(py_builtin___build_class__); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("__repl_print__"), true)->value = rt_make_function_1(py_builtin___repl_print__); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("abs"), true)->value = rt_make_function_1(py_builtin_abs); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("all"), true)->value = rt_make_function_1(py_builtin_all); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("any"), true)->value = rt_make_function_1(py_builtin_any); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("bool"), true)->value = rt_make_function_var(0, py_builtin_bool); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("callable"), true)->value = rt_make_function_1(py_builtin_callable); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("complex"), true)->value = rt_make_function_var(0, py_builtin_complex); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("chr"), true)->value = rt_make_function_1(py_builtin_chr); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("dict"), true)->value = rt_make_function_0(py_builtin_dict); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("divmod"), true)->value = rt_make_function_2(py_builtin_divmod); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("hash"), true)->value = rt_make_function_1(py_builtin_hash); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("iter"), true)->value = rt_make_function_1(py_builtin_iter); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("len"), true)->value = rt_make_function_1(py_builtin_len); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("list"), true)->value = rt_make_function_var(0, py_builtin_list); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("max"), true)->value = rt_make_function_var(1, py_builtin_max); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("min"), true)->value = rt_make_function_var(1, py_builtin_min); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("next"), true)->value = rt_make_function_1(py_builtin_next); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("ord"), true)->value = rt_make_function_1(py_builtin_ord); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("pow"), true)->value = rt_make_function_var(2, py_builtin_pow); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("print"), true)->value = rt_make_function_var(0, py_builtin_print); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("range"), true)->value = rt_make_function_var(1, py_builtin_range); - py_qstr_map_lookup(&map_builtins, qstr_from_str_static("sum"), true)->value = rt_make_function_var(1, py_builtin_sum); + map_locals = map_globals = mp_map_new(MP_MAP_QSTR, 1); + mp_qstr_map_lookup(map_globals, qstr_from_str_static("__name__"), true)->value = mp_obj_new_str(qstr_from_str_static("__main__")); + + mp_map_init(&map_builtins, MP_MAP_QSTR, 3); + mp_qstr_map_lookup(&map_builtins, rt_q___build_class__, true)->value = rt_make_function_2(mp_builtin___build_class__); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("__repl_print__"), true)->value = rt_make_function_1(mp_builtin___repl_print__); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("abs"), true)->value = rt_make_function_1(mp_builtin_abs); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("all"), true)->value = rt_make_function_1(mp_builtin_all); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("any"), true)->value = rt_make_function_1(mp_builtin_any); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("bool"), true)->value = rt_make_function_var(0, mp_builtin_bool); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("callable"), true)->value = rt_make_function_1(mp_builtin_callable); +#if MICROPY_ENABLE_FLOAT + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("complex"), true)->value = rt_make_function_var(0, mp_builtin_complex); +#endif + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("chr"), true)->value = rt_make_function_1(mp_builtin_chr); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("dict"), true)->value = rt_make_function_0(mp_builtin_dict); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("divmod"), true)->value = rt_make_function_2(mp_builtin_divmod); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("hash"), true)->value = (mp_obj_t)&mp_builtin_hash_obj; + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("iter"), true)->value = (mp_obj_t)&mp_builtin_iter_obj; + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("len"), true)->value = rt_make_function_1(mp_builtin_len); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("list"), true)->value = rt_make_function_var(0, mp_builtin_list); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("max"), true)->value = rt_make_function_var(1, mp_builtin_max); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("min"), true)->value = rt_make_function_var(1, mp_builtin_min); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("next"), true)->value = (mp_obj_t)&mp_builtin_next_obj; + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("ord"), true)->value = rt_make_function_1(mp_builtin_ord); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("pow"), true)->value = rt_make_function_var(2, mp_builtin_pow); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("print"), true)->value = rt_make_function_var(0, mp_builtin_print); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("range"), true)->value = rt_make_function_var(1, mp_builtin_range); + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("set"), true)->value = (mp_obj_t)&mp_builtin_set_obj; + mp_qstr_map_lookup(&map_builtins, qstr_from_str_static("sum"), true)->value = rt_make_function_var(1, mp_builtin_sum); next_unique_code_id = 2; // 1 is reserved for the __main__ module scope unique_codes = NULL; - fun_str_join = rt_make_function_2(rt_str_join); - fun_str_format = rt_make_function_var(1, rt_str_format); - fun_list_append = rt_make_function_2(rt_list_append); - fun_list_pop = rt_make_function_2(rt_list_pop); - fun_list_sort = rt_make_function_2(rt_list_sort); - fun_gen_instance_next = rt_make_function_1(rt_gen_instance_next); - #ifdef WRITE_CODE fp_write_code = fopen("out-code", "wb"); #endif @@ -359,9 +157,9 @@ int rt_get_unique_code_id(bool is_main_module) { static void alloc_unique_codes(void) { if (unique_codes == NULL) { - unique_codes = m_new(py_code_t, next_unique_code_id + 10); // XXX hack until we fix the REPL allocation problem + unique_codes = m_new(mp_code_t, next_unique_code_id + 10); // XXX hack until we fix the REPL allocation problem for (int i = 0; i < next_unique_code_id; i++) { - unique_codes[i].kind = PY_CODE_NONE; + unique_codes[i].kind = MP_CODE_NONE; } } } @@ -370,7 +168,7 @@ void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, i alloc_unique_codes(); assert(unique_code_id < next_unique_code_id); - unique_codes[unique_code_id].kind = PY_CODE_BYTE; + unique_codes[unique_code_id].kind = MP_CODE_BYTE; unique_codes[unique_code_id].n_args = n_args; unique_codes[unique_code_id].n_locals = n_locals; unique_codes[unique_code_id].n_cells = n_cells; @@ -390,8 +188,8 @@ void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, i DEBUG_printf(" %02x", code[i]); } DEBUG_printf("\n"); - extern void py_show_byte_code(const byte *code, int len); - py_show_byte_code(code, len); + extern void mp_show_byte_code(const byte *code, int len); + mp_show_byte_code(code, len); #ifdef WRITE_CODE if (fp_write_code != NULL) { @@ -402,11 +200,11 @@ void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, i #endif } -void rt_assign_native_code(int unique_code_id, py_fun_t fun, uint len, int n_args) { +void rt_assign_native_code(int unique_code_id, void *fun, uint len, int n_args) { alloc_unique_codes(); assert(1 <= unique_code_id && unique_code_id < next_unique_code_id); - unique_codes[unique_code_id].kind = PY_CODE_NATIVE; + unique_codes[unique_code_id].kind = MP_CODE_NATIVE; unique_codes[unique_code_id].n_args = n_args; unique_codes[unique_code_id].n_locals = 0; unique_codes[unique_code_id].n_cells = 0; @@ -436,11 +234,11 @@ void rt_assign_native_code(int unique_code_id, py_fun_t fun, uint len, int n_arg #endif } -void rt_assign_inline_asm_code(int unique_code_id, py_fun_t fun, uint len, int n_args) { +void rt_assign_inline_asm_code(int unique_code_id, void *fun, uint len, int n_args) { alloc_unique_codes(); assert(1 <= unique_code_id && unique_code_id < next_unique_code_id); - unique_codes[unique_code_id].kind = PY_CODE_INLINE_ASM; + unique_codes[unique_code_id].kind = MP_CODE_INLINE_ASM; unique_codes[unique_code_id].n_args = n_args; unique_codes[unique_code_id].n_locals = 0; unique_codes[unique_code_id].n_cells = 0; @@ -467,16 +265,52 @@ void rt_assign_inline_asm_code(int unique_code_id, py_fun_t fun, uint len, int n #endif } +mp_map_t *rt_get_map_locals(void) { + return map_locals; +} + +void rt_set_map_locals(mp_map_t *m) { + map_locals = m; +} + +static bool fit_small_int(mp_small_int_t o) { + return true; +} + +int rt_is_true(mp_obj_t arg) { + DEBUG_OP_printf("is true %p\n", arg); + if (MP_OBJ_IS_SMALL_INT(arg)) { + if (MP_OBJ_SMALL_INT_VALUE(arg) == 0) { + return 0; + } else { + return 1; + } + } else if (arg == mp_const_none) { + return 0; + } else if (arg == mp_const_false) { + return 0; + } else if (arg == mp_const_true) { + return 1; + } else { + assert(0); + return 0; + } +} + +mp_obj_t rt_list_append(mp_obj_t self_in, mp_obj_t arg) { + return mp_obj_list_append(self_in, arg); +} + #define PARSE_DEC_IN_INTG (1) #define PARSE_DEC_IN_FRAC (2) #define PARSE_DEC_IN_EXP (3) -py_obj_t rt_load_const_dec(qstr qstr) { +mp_obj_t rt_load_const_dec(qstr qstr) { #if MICROPY_ENABLE_FLOAT DEBUG_OP_printf("load '%s'\n", qstr_str(qstr)); const char *s = qstr_str(qstr); int in = PARSE_DEC_IN_INTG; - py_float_t dec_val = 0; + mp_float_t dec_val = 0; bool exp_neg = false; int exp_val = 0; int exp_extra = 0; @@ -513,7 +347,7 @@ py_obj_t rt_load_const_dec(qstr qstr) { } } if (*s != 0) { - nlr_jump(py_obj_new_exception_2(rt_q_SyntaxError, "invalid syntax for number", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(rt_q_SyntaxError, "invalid syntax for number")); } if (exp_neg) { exp_val = -exp_val; @@ -526,52 +360,52 @@ py_obj_t rt_load_const_dec(qstr qstr) { dec_val *= 0.1; } if (imag) { - return py_obj_new_complex(0, dec_val); + return mp_obj_new_complex(0, dec_val); } else { - return py_obj_new_float(dec_val); + return mp_obj_new_float(dec_val); } #else - nlr_jump(py_obj_new_exception_2(rt_q_SyntaxError, "decimal numbers not supported", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(rt_q_SyntaxError, "decimal numbers not supported")); #endif } -py_obj_t rt_load_const_str(qstr qstr) { +mp_obj_t rt_load_const_str(qstr qstr) { DEBUG_OP_printf("load '%s'\n", qstr_str(qstr)); - return py_obj_new_str(qstr); + return mp_obj_new_str(qstr); } -py_obj_t rt_load_name(qstr qstr) { +mp_obj_t rt_load_name(qstr qstr) { // logic: search locals, globals, builtins DEBUG_OP_printf("load name %s\n", qstr_str(qstr)); - py_map_elem_t *elem = py_qstr_map_lookup(map_locals, qstr, false); + mp_map_elem_t *elem = mp_qstr_map_lookup(map_locals, qstr, false); if (elem == NULL) { - elem = py_qstr_map_lookup(map_globals, qstr, false); + elem = mp_qstr_map_lookup(map_globals, qstr, false); if (elem == NULL) { - elem = py_qstr_map_lookup(&map_builtins, qstr, false); + elem = mp_qstr_map_lookup(&map_builtins, qstr, false); if (elem == NULL) { - nlr_jump(py_obj_new_exception_2(rt_q_NameError, "name '%s' is not defined", qstr_str(qstr), NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_NameError, "name '%s' is not defined", qstr_str(qstr))); } } } return elem->value; } -py_obj_t rt_load_global(qstr qstr) { +mp_obj_t rt_load_global(qstr qstr) { // logic: search globals, builtins DEBUG_OP_printf("load global %s\n", qstr_str(qstr)); - py_map_elem_t *elem = py_qstr_map_lookup(map_globals, qstr, false); + mp_map_elem_t *elem = mp_qstr_map_lookup(map_globals, qstr, false); if (elem == NULL) { - elem = py_qstr_map_lookup(&map_builtins, qstr, false); + elem = mp_qstr_map_lookup(&map_builtins, qstr, false); if (elem == NULL) { - nlr_jump(py_obj_new_exception_2(rt_q_NameError, "name '%s' is not defined", qstr_str(qstr), NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_NameError, "name '%s' is not defined", qstr_str(qstr))); } } return elem->value; } -py_obj_t rt_load_build_class(void) { +mp_obj_t rt_load_build_class(void) { DEBUG_OP_printf("load_build_class\n"); - py_map_elem_t *elem = py_qstr_map_lookup(&map_builtins, rt_q___build_class__, false); + mp_map_elem_t *elem = mp_qstr_map_lookup(&map_builtins, rt_q___build_class__, false); if (elem == NULL) { printf("name doesn't exist: __build_class__\n"); assert(0); @@ -579,97 +413,60 @@ py_obj_t rt_load_build_class(void) { return elem->value; } -py_obj_t rt_new_cell(py_obj_t val) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_CELL; - o->u_cell = val; - return (py_obj_t)o; -} - -py_obj_t rt_get_cell(py_obj_t cell) { - if (IS_O(cell, O_CELL)) { - return ((py_obj_base_t*)cell)->u_cell; - } else { - assert(0); - return py_const_none; - } +mp_obj_t rt_get_cell(mp_obj_t cell) { + return mp_obj_cell_get(cell); } -void rt_set_cell(py_obj_t cell, py_obj_t val) { - if (IS_O(cell, O_CELL)) { - ((py_obj_base_t*)cell)->u_cell = val; - } else { - assert(0); - } +void rt_set_cell(mp_obj_t cell, mp_obj_t val) { + mp_obj_cell_set(cell, val); } -void rt_store_name(qstr qstr, py_obj_t obj) { +void rt_store_name(qstr qstr, mp_obj_t obj) { DEBUG_OP_printf("store name %s <- %p\n", qstr_str(qstr), obj); - py_qstr_map_lookup(map_locals, qstr, true)->value = obj; + mp_qstr_map_lookup(map_locals, qstr, true)->value = obj; } -void rt_store_global(qstr qstr, py_obj_t obj) { +void rt_store_global(qstr qstr, mp_obj_t obj) { DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qstr), obj); - py_qstr_map_lookup(map_globals, qstr, true)->value = obj; + mp_qstr_map_lookup(map_globals, qstr, true)->value = obj; } -py_obj_t rt_unary_op(int op, py_obj_t arg) { +mp_obj_t rt_unary_op(int op, mp_obj_t arg) { DEBUG_OP_printf("unary %d %p\n", op, arg); - if (IS_SMALL_INT(arg)) { - py_small_int_t val = FROM_SMALL_INT(arg); + if (MP_OBJ_IS_SMALL_INT(arg)) { + mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(arg); switch (op) { - case RT_UNARY_OP_NOT: if (val != 0) { return py_const_true;} else { return py_const_false; } + case RT_UNARY_OP_NOT: if (val != 0) { return mp_const_true;} else { return mp_const_false; } case RT_UNARY_OP_POSITIVE: break; case RT_UNARY_OP_NEGATIVE: val = -val; break; case RT_UNARY_OP_INVERT: val = ~val; break; default: assert(0); val = 0; } if (fit_small_int(val)) { - return TO_SMALL_INT(val); - } -#if MICROPY_ENABLE_FLOAT - } else if (IS_O(arg, O_FLOAT)) { - py_float_t val = py_obj_get_float(arg); - switch (op) { - case RT_UNARY_OP_NOT: if (val != 0) { return py_const_true;} else { return py_const_false; } - case RT_UNARY_OP_POSITIVE: break; - case RT_UNARY_OP_NEGATIVE: val = -val; break; - case RT_UNARY_OP_INVERT: nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "bad operand type for unary ~: 'float'", NULL, NULL)); - default: assert(0); val = 0; + return MP_OBJ_NEW_SMALL_INT(val); + } else { + // TODO make a bignum + assert(0); + return mp_const_none; + } + } else { // will be an object (small ints are caught in previous if) + mp_obj_base_t *o = arg; + if (o->type->unary_op != NULL) { + mp_obj_t result = o->type->unary_op(op, arg); + if (result != NULL) { + return result; + } } - return py_obj_new_float(val); -#endif + // TODO specify in error message what the operator is + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "bad operand type for unary operator: '%s'", o->type->name)); } - assert(0); - return py_const_none; } -py_obj_t rt_binary_op(int op, py_obj_t lhs, py_obj_t rhs) { +mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { DEBUG_OP_printf("binary %d %p %p\n", op, lhs, rhs); - if (op == RT_BINARY_OP_SUBSCR) { - if (IS_O(lhs, O_STR)) { - // string access - // XXX a hack! - const char *str = qstr_str(((py_obj_base_t*)lhs)->u_str); - return py_obj_new_int(str[FROM_SMALL_INT(rhs)]); - } else if ((IS_O(lhs, O_TUPLE) || IS_O(lhs, O_LIST))) { - // tuple/list load - uint index = get_index(lhs, rhs); - return ((py_obj_base_t*)lhs)->u_tuple_list.items[index]; - } else if (IS_O(lhs, O_MAP)) { - // map load - py_map_elem_t *elem = py_map_lookup(lhs, rhs, false); - if (elem == NULL) { - nlr_jump(py_obj_new_exception_2(rt_q_KeyError, "<value>", NULL, NULL)); - } else { - return elem->value; - } - } else { - assert(0); - } - } else if (IS_SMALL_INT(lhs) && IS_SMALL_INT(rhs)) { - py_small_int_t lhs_val = FROM_SMALL_INT(lhs); - py_small_int_t rhs_val = FROM_SMALL_INT(rhs); + if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) { + mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs); + mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs); switch (op) { case RT_BINARY_OP_OR: case RT_BINARY_OP_INPLACE_OR: lhs_val |= rhs_val; break; @@ -691,7 +488,7 @@ py_obj_t rt_binary_op(int op, py_obj_t lhs, py_obj_t rhs) { case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: lhs_val /= rhs_val; break; #if MICROPY_ENABLE_FLOAT case RT_BINARY_OP_TRUE_DIVIDE: - case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return py_obj_new_float((py_float_t)lhs_val / (py_float_t)rhs_val); + case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val); #endif // TODO implement modulo as specified by Python @@ -717,102 +514,46 @@ py_obj_t rt_binary_op(int op, py_obj_t lhs, py_obj_t rhs) { default: printf("%d\n", op); assert(0); } if (fit_small_int(lhs_val)) { - return TO_SMALL_INT(lhs_val); - } -#if MICROPY_ENABLE_FLOAT - } else if (IS_O(lhs, O_COMPLEX) || IS_O(rhs, O_COMPLEX)) { - py_float_t lhs_real, lhs_imag, rhs_real, rhs_imag; - py_obj_get_complex(lhs, &lhs_real, &lhs_imag); - py_obj_get_complex(rhs, &rhs_real, &rhs_imag); - switch (op) { - case RT_BINARY_OP_ADD: - case RT_BINARY_OP_INPLACE_ADD: - lhs_real += rhs_real; - lhs_imag += rhs_imag; - break; - case RT_BINARY_OP_SUBTRACT: - case RT_BINARY_OP_INPLACE_SUBTRACT: - lhs_real -= rhs_real; - lhs_imag -= rhs_imag; - break; - case RT_BINARY_OP_MULTIPLY: - case RT_BINARY_OP_INPLACE_MULTIPLY: - { - py_float_t real = lhs_real * rhs_real - lhs_imag * rhs_imag; - lhs_imag = lhs_real * rhs_imag + lhs_imag * rhs_real; - lhs_real = real; - break; + return MP_OBJ_NEW_SMALL_INT(lhs_val); + } + } else if (MP_OBJ_IS_OBJ(lhs)) { + mp_obj_base_t *o = lhs; + if (o->type->binary_op != NULL) { + mp_obj_t result = o->type->binary_op(op, lhs, rhs); + if (result != NULL) { + return result; } - /* TODO floor(?) the value - case RT_BINARY_OP_FLOOR_DIVIDE: - case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; - */ - /* TODO - case RT_BINARY_OP_TRUE_DIVIDE: - case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: val = lhs_val / rhs_val; break; - */ - default: printf("%d\n", op); assert(0); - } - return py_obj_new_complex(lhs_real, lhs_imag); - } else if (IS_O(lhs, O_FLOAT) || IS_O(rhs, O_FLOAT)) { - py_float_t lhs_val = py_obj_get_float(lhs); - py_float_t rhs_val = py_obj_get_float(rhs); - switch (op) { - case RT_BINARY_OP_ADD: - case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; - case RT_BINARY_OP_SUBTRACT: - case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; - case RT_BINARY_OP_MULTIPLY: - case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; - /* TODO floor(?) the value - case RT_BINARY_OP_FLOOR_DIVIDE: - case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; - */ - case RT_BINARY_OP_TRUE_DIVIDE: - case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break; - default: printf("%d\n", op); assert(0); - } - return py_obj_new_float(lhs_val); -#endif - } else if (IS_O(lhs, O_STR) && IS_O(rhs, O_STR)) { - const char *lhs_str = qstr_str(((py_obj_base_t*)lhs)->u_str); - const char *rhs_str = qstr_str(((py_obj_base_t*)rhs)->u_str); - char *val; - switch (op) { - case RT_BINARY_OP_ADD: - case RT_BINARY_OP_INPLACE_ADD: val = m_new(char, strlen(lhs_str) + strlen(rhs_str) + 1); strcpy(val, lhs_str); strcat(val, rhs_str); break; - default: printf("%d\n", op); assert(0); val = NULL; } - return py_obj_new_str(qstr_from_str_take(val)); } - assert(0); - return py_const_none; + + // TODO specify in error message what the operator is + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "unsupported operand type for binary operator: '%s'", mp_obj_get_type_str(lhs))); } -py_obj_t rt_compare_op(int op, py_obj_t lhs, py_obj_t rhs) { +mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs) { DEBUG_OP_printf("compare %d %p %p\n", op, lhs, rhs); // deal with == and != if (op == RT_COMPARE_OP_EQUAL || op == RT_COMPARE_OP_NOT_EQUAL) { - if (py_obj_equal(lhs, rhs)) { + if (mp_obj_equal(lhs, rhs)) { if (op == RT_COMPARE_OP_EQUAL) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } else { if (op == RT_COMPARE_OP_EQUAL) { - return py_const_false; + return mp_const_false; } else { - return py_const_true; + return mp_const_true; } } } // deal with small ints - if (IS_SMALL_INT(lhs) && IS_SMALL_INT(rhs)) { - py_small_int_t lhs_val = FROM_SMALL_INT(lhs); - py_small_int_t rhs_val = FROM_SMALL_INT(rhs); + if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) { + mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs); + mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs); int cmp; switch (op) { case RT_COMPARE_OP_LESS: cmp = lhs_val < rhs_val; break; @@ -822,17 +563,17 @@ py_obj_t rt_compare_op(int op, py_obj_t lhs, py_obj_t rhs) { default: assert(0); cmp = 0; } if (cmp) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } #if MICROPY_ENABLE_FLOAT // deal with floats - if (IS_O(lhs, O_FLOAT) || IS_O(rhs, O_FLOAT)) { - py_float_t lhs_val = py_obj_get_float(lhs); - py_float_t rhs_val = py_obj_get_float(rhs); + if (MP_OBJ_IS_TYPE(lhs, &float_type) || MP_OBJ_IS_TYPE(rhs, &float_type)) { + mp_float_t lhs_val = mp_obj_get_float(lhs); + mp_float_t rhs_val = mp_obj_get_float(rhs); int cmp; switch (op) { case RT_COMPARE_OP_LESS: cmp = lhs_val < rhs_val; break; @@ -842,666 +583,287 @@ py_obj_t rt_compare_op(int op, py_obj_t lhs, py_obj_t rhs) { default: assert(0); cmp = 0; } if (cmp) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } #endif // not implemented assert(0); - return py_const_none; + return mp_const_none; } -py_obj_t rt_make_function_from_id(int unique_code_id) { +mp_obj_t rt_make_function_from_id(int unique_code_id) { DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id); if (unique_code_id < 1 || unique_code_id >= next_unique_code_id) { // illegal code id - return py_const_none; + return mp_const_none; } - py_code_t *c = &unique_codes[unique_code_id]; - py_obj_base_t *o = m_new(py_obj_base_t, 1); + + // make the function, depending on the code kind + mp_code_t *c = &unique_codes[unique_code_id]; + mp_obj_t fun; switch (c->kind) { - case PY_CODE_BYTE: - o->kind = O_FUN_BC; - o->u_fun_bc.n_args = c->n_args; - o->u_fun_bc.n_state = c->n_locals + c->n_cells + c->n_stack; - o->u_fun_bc.code = c->u_byte.code; + case MP_CODE_BYTE: + fun = mp_obj_new_fun_bc(c->n_args, c->n_locals + c->n_cells + c->n_stack, c->u_byte.code); break; - case PY_CODE_NATIVE: + case MP_CODE_NATIVE: switch (c->n_args) { - case 0: o->kind = O_FUN_0; break; - case 1: o->kind = O_FUN_1; break; - case 2: o->kind = O_FUN_2; break; - default: assert(0); + case 0: fun = rt_make_function_0(c->u_native.fun); break; + case 1: fun = rt_make_function_1((mp_fun_1_t)c->u_native.fun); break; + case 2: fun = rt_make_function_2((mp_fun_2_t)c->u_native.fun); break; + default: assert(0); fun = mp_const_none; } - o->u_fun.fun = c->u_native.fun; break; - case PY_CODE_INLINE_ASM: - o->kind = O_FUN_ASM; - o->u_fun_asm.n_args = c->n_args; - o->u_fun_asm.fun = c->u_inline_asm.fun; + case MP_CODE_INLINE_ASM: + fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun); break; default: assert(0); + fun = mp_const_none; } // check for generator functions and if so wrap in generator object if (c->is_generator) { - py_obj_base_t *o2 = m_new(py_obj_base_t, 1); - o2->kind = O_GEN_WRAP; - // we have at least 3 locals so the bc can write back fast[0,1,2] safely; should improve how this is done - o2->u_gen_wrap.n_state = ((c->n_locals + c->n_cells) < 3 ? 3 : (c->n_locals + c->n_cells)) + c->n_stack; - o2->u_gen_wrap.fun = o; - o = o2; + fun = mp_obj_new_gen_wrap(c->n_locals, c->n_cells, c->n_stack, fun); } - return o; -} - -py_obj_t rt_make_function_0(py_fun_0_t fun) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_FUN_0; - o->u_fun.fun = fun; - return o; + return fun; } -py_obj_t rt_make_function_1(py_fun_1_t fun) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_FUN_1; - o->u_fun.fun = fun; - return o; -} - -py_obj_t rt_make_function_2(py_fun_2_t fun) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_FUN_2; - o->u_fun.fun = fun; - return o; -} - -py_obj_t rt_make_function(int n_args, py_fun_t code) { - // assumes code is a pointer to a py_fun_t (i think this is safe...) - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_FUN_N; - o->u_fun.n_args = n_args; - o->u_fun.fun = code; - return o; -} - -py_obj_t rt_make_function_var(int n_fixed_args, py_fun_var_t f) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_FUN_VAR; - o->u_fun.n_args = n_fixed_args; - o->u_fun.fun = f; - return o; -} - -py_obj_t rt_make_closure_from_id(int unique_code_id, py_obj_t closure_tuple) { - py_obj_t f = rt_make_function_from_id(unique_code_id); +mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple) { + // make function object + mp_obj_t ffun = rt_make_function_from_id(unique_code_id); // wrap function in closure object - py_obj_base_t *f2 = m_new(py_obj_base_t, 1); - f2->kind = O_CLOSURE; - f2->u_closure.fun = f; - f2->u_closure.vars = closure_tuple; - return f2; + return mp_obj_new_closure(ffun, closure_tuple); } -py_obj_t rt_call_function_0(py_obj_t fun) { +mp_obj_t rt_call_function_0(mp_obj_t fun) { return rt_call_function_n(fun, 0, NULL); } -py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg) { +mp_obj_t rt_call_function_1(mp_obj_t fun, mp_obj_t arg) { return rt_call_function_n(fun, 1, &arg); } -py_obj_t rt_call_function_2(py_obj_t fun, py_obj_t arg1, py_obj_t arg2) { - py_obj_t args[2]; +mp_obj_t rt_call_function_2(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2) { + mp_obj_t args[2]; args[1] = arg1; args[0] = arg2; return rt_call_function_n(fun, 2, args); } -typedef machine_uint_t (*inline_asm_fun_0_t)(); -typedef machine_uint_t (*inline_asm_fun_1_t)(machine_uint_t); -typedef machine_uint_t (*inline_asm_fun_2_t)(machine_uint_t, machine_uint_t); -typedef machine_uint_t (*inline_asm_fun_3_t)(machine_uint_t, machine_uint_t, machine_uint_t); - -// convert a Python object to a sensible value for inline asm -machine_uint_t rt_convert_obj_for_inline_asm(py_obj_t obj) { - // TODO for byte_array, pass pointer to the array - if (IS_SMALL_INT(obj)) { - return FROM_SMALL_INT(obj); - } else if (obj == py_const_none) { - return 0; - } else if (obj == py_const_false) { - return 0; - } else if (obj == py_const_true) { - return 1; - } else { - py_obj_base_t *o = obj; - switch (o->kind) { - case O_STR: - // pointer to the string (it's probably constant though!) - return (machine_uint_t)qstr_str(o->u_str); - -#if MICROPY_ENABLE_FLOAT - case O_FLOAT: - // convert float to int (could also pass in float registers) - return (machine_int_t)o->u_float; -#endif - - case O_TUPLE: - case O_LIST: - // pointer to start of tuple/list (could pass length, but then could use len(x) for that) - return (machine_uint_t)o->u_tuple_list.items; - - default: - // just pass along a pointer to the object - return (machine_uint_t)obj; - } - } -} - -// convert a return value from inline asm to a sensible Python object -py_obj_t rt_convert_val_from_inline_asm(machine_uint_t val) { - return TO_SMALL_INT(val); -} - // args are in reverse order in the array -py_obj_t rt_call_function_n(py_obj_t fun, int n_args, const py_obj_t *args) { - int n_args_fun = 0; - if (IS_O(fun, O_FUN_0)) { - py_obj_base_t *o = fun; - if (n_args != 0) { - n_args_fun = 0; - goto bad_n_args; - } - DEBUG_OP_printf("calling native %p()\n", o->u_fun.fun); - return ((py_fun_0_t)o->u_fun.fun)(); - - } else if (IS_O(fun, O_FUN_1)) { - py_obj_base_t *o = fun; - if (n_args != 1) { - n_args_fun = 1; - goto bad_n_args; - } - DEBUG_OP_printf("calling native %p(%p)\n", o->u_fun.fun, args[0]); - return ((py_fun_1_t)o->u_fun.fun)(args[0]); - - } else if (IS_O(fun, O_FUN_2)) { - py_obj_base_t *o = fun; - if (n_args != 2) { - n_args_fun = 2; - goto bad_n_args; - } - DEBUG_OP_printf("calling native %p(%p, %p)\n", o->u_fun.fun, args[1], args[0]); - return ((py_fun_2_t)o->u_fun.fun)(args[1], args[0]); - - // TODO O_FUN_N - - } else if (IS_O(fun, O_FUN_VAR)) { - py_obj_base_t *o = fun; - if (n_args < o->u_fun.n_args) { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(o->u_fun.n_args - n_args), NULL)); - } - // TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args - py_obj_t *args_ordered = m_new(py_obj_t, n_args); - for (int i = 0; i < n_args; i++) { - args_ordered[i] = args[n_args - i - 1]; - } - py_obj_t res = ((py_fun_var_t)o->u_fun.fun)(n_args, args_ordered); - m_free(args_ordered); - return res; - - } else if (IS_O(fun, O_FUN_BC)) { - py_obj_base_t *o = fun; - if (n_args != o->u_fun_bc.n_args) { - n_args_fun = o->u_fun_bc.n_args; - goto bad_n_args; - } - DEBUG_OP_printf("calling byte code %p(n_args=%d)\n", o->u_fun_bc.code, n_args); - return py_execute_byte_code(o->u_fun_bc.code, args, n_args, o->u_fun_bc.n_state); - - } else if (IS_O(fun, O_FUN_ASM)) { - py_obj_base_t *o = fun; - if (n_args != o->u_fun_asm.n_args) { - n_args_fun = o->u_fun_asm.n_args; - goto bad_n_args; - } - DEBUG_OP_printf("calling inline asm %p(n_args=%d)\n", o->u_fun_asm.fun, n_args); - machine_uint_t ret; - if (n_args == 0) { - ret = ((inline_asm_fun_0_t)o->u_fun_asm.fun)(); - } else if (n_args == 1) { - ret = ((inline_asm_fun_1_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(args[0])); - } else if (n_args == 2) { - ret = ((inline_asm_fun_2_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(args[1]), rt_convert_obj_for_inline_asm(args[0])); - } else if (n_args == 3) { - ret = ((inline_asm_fun_3_t)o->u_fun_asm.fun)(rt_convert_obj_for_inline_asm(args[2]), rt_convert_obj_for_inline_asm(args[1]), rt_convert_obj_for_inline_asm(args[0])); - } else { - assert(0); - ret = 0; - } - return rt_convert_val_from_inline_asm(ret); - - } else if (IS_O(fun, O_GEN_WRAP)) { - py_obj_base_t *o = fun; - py_obj_base_t *o_fun = o->u_gen_wrap.fun; - assert(o_fun->kind == O_FUN_BC); // TODO - if (n_args != o_fun->u_fun_bc.n_args) { - n_args_fun = o_fun->u_fun_bc.n_args; - goto bad_n_args; - } - py_obj_t *state = m_new(py_obj_t, 1 + o->u_gen_wrap.n_state); - // put function object at first slot in state (to keep u_gen_instance small) - state[0] = o_fun; - // init args - for (int i = 0; i < n_args; i++) { - state[1 + i] = args[n_args - 1 - i]; - } - py_obj_base_t *o2 = m_new(py_obj_base_t, 1); - o2->kind = O_GEN_INSTANCE; - o2->u_gen_instance.state = state; - o2->u_gen_instance.ip = o_fun->u_fun_bc.code; - o2->u_gen_instance.sp = state + o->u_gen_wrap.n_state; - return o2; - - } else if (IS_O(fun, O_BOUND_METH)) { - py_obj_base_t *o = fun; - DEBUG_OP_printf("calling bound method %p(self=%p, n_args=%d)\n", o->u_bound_meth.meth, o->u_bound_meth.self, n_args); - if (n_args == 0) { - return rt_call_function_n(o->u_bound_meth.meth, 1, &o->u_bound_meth.self); - } else if (n_args == 1) { - py_obj_t args2[2]; - args2[1] = o->u_bound_meth.self; - args2[0] = args[0]; - return rt_call_function_n(o->u_bound_meth.meth, 2, args2); - } else { - // TODO not implemented - assert(0); - return py_const_none; - //return rt_call_function_2(o->u_bound_meth.meth, n_args + 1, o->u_bound_meth.self + args); - } +mp_obj_t rt_call_function_n(mp_obj_t fun_in, int n_args, const mp_obj_t *args) { + // TODO improve this: fun object can specify its type and we parse here the arguments, + // passing to the function arrays of fixed and keyword arguments - } else if (IS_O(fun, O_CLASS)) { - // instantiate an instance of a class - - DEBUG_OP_printf("instantiate object of class %p with %d args\n", fun, n_args); - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_OBJ; - o->u_obj.class = fun; - o->u_obj.members = py_map_new(MAP_QSTR, 0); - - // look for __init__ function - py_obj_base_t *o_class = fun; - py_map_elem_t *init_fn = py_qstr_map_lookup(o_class->u_class.locals, qstr_from_str_static("__init__"), false); - - if (init_fn != NULL) { - // call __init__ function - py_obj_t init_ret; - if (n_args == 0) { - init_ret = rt_call_function_n(init_fn->value, 1, (py_obj_t*)&o); - } else { - py_obj_t *args2 = m_new(py_obj_t, n_args + 1); - memcpy(args2, args, n_args * sizeof(py_obj_t)); - args2[n_args] = o; - init_ret = rt_call_function_n(init_fn->value, n_args + 1, args2); - m_free(args2); - } - if (init_ret != py_const_none) { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "__init__() should return None, not '%s'", py_obj_get_type_str(init_ret), NULL)); - } + DEBUG_OP_printf("calling function %p(n_args=%d, args=%p)\n", fun_in, n_args, args); + if (MP_OBJ_IS_SMALL_INT(fun_in)) { + nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "'int' object is not callable")); + } else { + mp_obj_base_t *fun = fun_in; + if (fun->type->call_n != NULL) { + return fun->type->call_n(fun_in, n_args, args); } else { - // TODO - if (n_args != 0) { - n_args_fun = 0; - goto bad_n_args; - } + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "'%s' object is not callable", fun->type->name)); } - - return o; - - } else { - printf("fun %p %d\n", fun, ((py_obj_base_t*)fun)->kind); - assert(0); - return py_const_none; } - -bad_n_args: - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)n_args_fun, (const char*)(machine_int_t)n_args)); } // args are in reverse order in the array; keyword arguments come first, value then key // eg: (value1, key1, value0, key0, arg1, arg0) -py_obj_t rt_call_function_n_kw(py_obj_t fun, uint n_args, uint n_kw, const py_obj_t *args) { +mp_obj_t rt_call_function_n_kw(mp_obj_t fun, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO assert(0); - return py_const_none; + return mp_const_none; } // args contains: arg(n_args-1) arg(n_args-2) ... arg(0) self/NULL fun // if n_args==0 then there are only self/NULL and fun -py_obj_t rt_call_method_n(uint n_args, const py_obj_t *args) { +mp_obj_t rt_call_method_n(uint n_args, const mp_obj_t *args) { DEBUG_OP_printf("call method %p(self=%p, n_args=%u)\n", args[n_args + 1], args[n_args], n_args); return rt_call_function_n(args[n_args + 1], n_args + ((args[n_args] == NULL) ? 0 : 1), args); } // args contains: kw_val(n_kw-1) kw_key(n_kw-1) ... kw_val(0) kw_key(0) arg(n_args-1) arg(n_args-2) ... arg(0) self/NULL fun -py_obj_t rt_call_method_n_kw(uint n_args, uint n_kw, const py_obj_t *args) { +mp_obj_t rt_call_method_n_kw(uint n_args, uint n_kw, const mp_obj_t *args) { uint n = n_args + 2 * n_kw; DEBUG_OP_printf("call method %p(self=%p, n_args=%u, n_kw=%u)\n", args[n + 1], args[n], n_args, n_kw); return rt_call_function_n_kw(args[n + 1], n_args + ((args[n] == NULL) ? 0 : 1), n_kw, args); } // items are in reverse order -py_obj_t rt_build_tuple(int n_args, py_obj_t *items) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_TUPLE; - o->u_tuple_list.alloc = n_args < 4 ? 4 : n_args; - o->u_tuple_list.len = n_args; - o->u_tuple_list.items = m_new(py_obj_t, o->u_tuple_list.alloc); - for (int i = 0; i < n_args; i++) { - o->u_tuple_list.items[i] = items[n_args - i - 1]; - } - return o; +mp_obj_t rt_build_tuple(int n_args, mp_obj_t *items) { + return mp_obj_new_tuple_reverse(n_args, items); } // items are in reverse order -py_obj_t rt_build_list(int n_args, py_obj_t *items) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_LIST; - o->u_tuple_list.alloc = n_args < 4 ? 4 : n_args; - o->u_tuple_list.len = n_args; - o->u_tuple_list.items = m_new(py_obj_t, o->u_tuple_list.alloc); - for (int i = 0; i < n_args; i++) { - o->u_tuple_list.items[i] = items[n_args - i - 1]; - } - return o; +mp_obj_t rt_build_list(int n_args, mp_obj_t *items) { + return mp_obj_new_list_reverse(n_args, items); } -py_obj_t rt_build_set(int n_args, py_obj_t *items) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_SET; - o->u_set.alloc = get_doubling_prime_greater_or_equal_to(n_args + 1); - o->u_set.used = 0; - o->u_set.table = m_new(py_obj_t, o->u_set.alloc); - for (int i = 0; i < o->u_set.alloc; i++) { - o->u_set.table[i] = NULL; - } - for (int i = 0; i < n_args; i++) { - py_set_lookup(o, items[i], true); - } - return o; +mp_obj_t rt_build_set(int n_args, mp_obj_t *items) { + return mp_obj_new_set(n_args, items); } -py_obj_t rt_store_set(py_obj_t set, py_obj_t item) { - py_set_lookup(set, item, true); +mp_obj_t rt_store_set(mp_obj_t set, mp_obj_t item) { + mp_set_lookup(set, item, true); return set; } // unpacked items are stored in order into the array pointed to by items -void rt_unpack_sequence(py_obj_t seq_in, uint num, py_obj_t *items) { - if (IS_O(seq_in, O_TUPLE) || IS_O(seq_in, O_LIST)) { - py_obj_base_t *seq = seq_in; - if (seq->u_tuple_list.len < num) { - nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "need more than %d values to unpack", (void*)seq->u_tuple_list.len, NULL)); - } else if (seq->u_tuple_list.len > num) { - nlr_jump(py_obj_new_exception_2(rt_q_ValueError, "too many values to unpack (expected %d)", (void*)(machine_uint_t)num, NULL)); +void rt_unpack_sequence(mp_obj_t seq_in, uint num, mp_obj_t *items) { + if (MP_OBJ_IS_TYPE(seq_in, &tuple_type) || MP_OBJ_IS_TYPE(seq_in, &list_type)) { + uint seq_len; + mp_obj_t *seq_items; + if (MP_OBJ_IS_TYPE(seq_in, &tuple_type)) { + mp_obj_tuple_get(seq_in, &seq_len, &seq_items); + } else { + mp_obj_list_get(seq_in, &seq_len, &seq_items); } - memcpy(items, seq->u_tuple_list.items, num * sizeof(py_obj_t)); + if (seq_len < num) { + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_ValueError, "need more than %d values to unpack", (void*)(machine_uint_t)seq_len)); + } else if (seq_len > num) { + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_ValueError, "too many values to unpack (expected %d)", (void*)(machine_uint_t)num)); + } + memcpy(items, seq_items, num * sizeof(mp_obj_t)); } else { // TODO call rt_getiter and extract via rt_iternext - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "'%s' object is not iterable", py_obj_get_type_str(seq_in), NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(seq_in))); } } -py_obj_t rt_build_map(int n_args) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_MAP; - py_map_init(&o->u_map, MAP_PY_OBJ, n_args); - return o; -} - -py_obj_t rt_store_map(py_obj_t map, py_obj_t key, py_obj_t value) { - assert(IS_O(map, O_MAP)); // should always be - py_map_lookup(map, key, true)->value = value; - return map; +mp_obj_t rt_build_map(int n_args) { + return mp_obj_new_dict(n_args); } -py_obj_t build_bound_method(py_obj_t self, py_obj_t meth) { - py_obj_base_t *o = m_new(py_obj_base_t, 1); - o->kind = O_BOUND_METH; - o->u_bound_meth.meth = meth; - o->u_bound_meth.self = self; - return o; +mp_obj_t rt_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value) { + // map should always be a dict + return mp_obj_dict_store(map, key, value); } -py_obj_t rt_load_attr(py_obj_t base, qstr attr) { +mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) { DEBUG_OP_printf("load attr %s\n", qstr_str(attr)); - if (IS_O(base, O_LIST) && attr == rt_q_append) { - return build_bound_method(base, fun_list_append); - } else if (IS_O(base, O_LIST) && attr == rt_q_pop) { - return build_bound_method(base, fun_list_pop); - } else if (IS_O(base, O_LIST) && attr == rt_q_sort) { - return build_bound_method(base, fun_list_sort); - } else if (IS_O(base, O_CLASS)) { - py_obj_base_t *o = base; - py_map_elem_t *elem = py_qstr_map_lookup(o->u_class.locals, attr, false); + if (MP_OBJ_IS_TYPE(base, &class_type)) { + mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_class_get_locals(base), attr, false); if (elem == NULL) { - goto no_attr; + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr))); } return elem->value; - } else if (IS_O(base, O_OBJ)) { - // logic: look in obj members then class locals (TODO check this against CPython) - py_obj_base_t *o = base; - py_map_elem_t *elem = py_qstr_map_lookup(o->u_obj.members, attr, false); - if (elem != NULL) { - // object member, always treated as a value - return elem->value; - } - elem = py_qstr_map_lookup(o->u_obj.class->u_class.locals, attr, false); - if (elem != NULL) { - if (py_obj_is_callable(elem->value)) { - // class member is callable so build a bound method - return build_bound_method(base, elem->value); - } else { - // class member is a value, so just return that value - return elem->value; + } else if (MP_OBJ_IS_TYPE(base, &instance_type)) { + return mp_obj_instance_load_attr(base, attr); + } else if (MP_OBJ_IS_OBJ(base)) { + // generic method lookup + mp_obj_base_t *o = base; + const mp_method_t *meth = &o->type->methods[0]; + for (; meth->name != NULL; meth++) { + if (strcmp(meth->name, qstr_str(attr)) == 0) { + return mp_obj_new_bound_meth(base, (mp_obj_t)meth->fun); } } - goto no_attr; } - -no_attr: - nlr_jump(py_obj_new_exception_2(rt_q_AttributeError, "'%s' object has no attribute '%s'", py_obj_get_type_str(base), qstr_str(attr))); + nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr))); } -void rt_load_method(py_obj_t base, qstr attr, py_obj_t *dest) { +void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { DEBUG_OP_printf("load method %s\n", qstr_str(attr)); - if (IS_O(base, O_STR)) { - if (attr == rt_q_join) { - dest[1] = fun_str_join; - dest[0] = base; - return; - } else if (attr == rt_q_format) { - dest[1] = fun_str_format; - dest[0] = base; - return; - } - } else if (IS_O(base, O_GEN_INSTANCE) && attr == rt_q___next__) { - dest[1] = fun_gen_instance_next; - dest[0] = base; - return; - } else if (IS_O(base, O_LIST) && attr == rt_q_append) { - dest[1] = fun_list_append; - dest[0] = base; - return; - } else if (IS_O(base, O_LIST) && attr == rt_q_pop) { - dest[1] = fun_list_pop; + if (MP_OBJ_IS_TYPE(base, &gen_instance_type) && attr == rt_q___next__) { + dest[1] = (mp_obj_t)&mp_obj_gen_instance_next_obj; dest[0] = base; return; - } else if (IS_O(base, O_LIST) && attr == rt_q_sort) { - dest[1] = fun_list_sort; - dest[0] = base; + } else if (MP_OBJ_IS_TYPE(base, &instance_type)) { + mp_obj_instance_load_method(base, attr, dest); return; - } else if (IS_O(base, O_OBJ)) { - // logic: look in obj members then class locals (TODO check this against CPython) - py_obj_base_t *o = base; - py_map_elem_t *elem = py_qstr_map_lookup(o->u_obj.members, attr, false); - if (elem != NULL) { - // object member, always treated as a value - dest[1] = elem->value; - dest[0] = NULL; - return; - } - elem = py_qstr_map_lookup(o->u_obj.class->u_class.locals, attr, false); - if (elem != NULL) { - if (py_obj_is_callable(elem->value)) { - // class member is callable so build a bound method - dest[1] = elem->value; - dest[0] = base; - return; - } else { - // class member is a value, so just return that value - dest[1] = elem->value; - dest[0] = NULL; - return; - } - } - goto no_attr; - } else if (IS_O(base, O_USER)) { - py_obj_base_t *o = base; - const py_user_method_t *meth = &o->u_user.info->methods[0]; + } else if (MP_OBJ_IS_OBJ(base)) { + // generic method lookup + mp_obj_base_t *o = base; + const mp_method_t *meth = &o->type->methods[0]; for (; meth->name != NULL; meth++) { if (strcmp(meth->name, qstr_str(attr)) == 0) { - if (meth->kind == 0) { - dest[1] = rt_make_function_1(meth->fun); - } else if (meth->kind == 1) { - dest[1] = rt_make_function_2(meth->fun); - } else { - assert(0); - } + dest[1] = (mp_obj_t)meth->fun; dest[0] = base; return; } } } -no_attr: + // no method; fallback to load_attr dest[1] = rt_load_attr(base, attr); dest[0] = NULL; } -void rt_store_attr(py_obj_t base, qstr attr, py_obj_t value) { +void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { DEBUG_OP_printf("store attr %p.%s <- %p\n", base, qstr_str(attr), value); - if (IS_O(base, O_CLASS)) { + if (MP_OBJ_IS_TYPE(base, &class_type)) { // TODO CPython allows STORE_ATTR to a class, but is this the correct implementation? - py_obj_base_t *o = base; - py_qstr_map_lookup(o->u_class.locals, attr, true)->value = value; - } else if (IS_O(base, O_OBJ)) { - // logic: look in class locals (no add) then obj members (add) (TODO check this against CPython) - py_obj_base_t *o = base; - py_map_elem_t *elem = py_qstr_map_lookup(o->u_obj.class->u_class.locals, attr, false); - if (elem != NULL) { - elem->value = value; - } else { - py_qstr_map_lookup(o->u_obj.members, attr, true)->value = value; - } + mp_map_t *locals = mp_obj_class_get_locals(base); + mp_qstr_map_lookup(locals, attr, true)->value = value; + } else if (MP_OBJ_IS_TYPE(base, &instance_type)) { + mp_obj_instance_store_attr(base, attr, value); } else { - printf("?AttributeError: '%s' object has no attribute '%s'\n", py_obj_get_type_str(base), qstr_str(attr)); + printf("?AttributeError: '%s' object has no attribute '%s'\n", mp_obj_get_type_str(base), qstr_str(attr)); assert(0); } } -void rt_store_subscr(py_obj_t base, py_obj_t index, py_obj_t value) { +void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { DEBUG_OP_printf("store subscr %p[%p] <- %p\n", base, index, value); - if (IS_O(base, O_LIST)) { + if (MP_OBJ_IS_TYPE(base, &list_type)) { // list store - uint i = get_index(base, index); - ((py_obj_base_t*)base)->u_tuple_list.items[i] = value; - } else if (IS_O(base, O_MAP)) { - // map store - py_map_lookup(base, index, true)->value = value; + mp_obj_list_store(base, index, value); + } else if (MP_OBJ_IS_TYPE(base, &dict_type)) { + // dict store + mp_obj_dict_store(base, index, value); } else { assert(0); } } -py_obj_t rt_getiter(py_obj_t o_in) { - if (IS_O(o_in, O_GEN_INSTANCE)) { - return o_in; - } else if (IS_O(o_in, O_RANGE)) { - py_obj_base_t *o = o_in; - return py_obj_new_range_iterator(o->u_range.start, o->u_range.stop, o->u_range.step); - } else if (IS_O(o_in, O_TUPLE)) { - return py_obj_new_tuple_iterator(o_in, 0); - } else if (IS_O(o_in, O_LIST)) { - return py_obj_new_list_iterator(o_in, 0); +mp_obj_t rt_getiter(mp_obj_t o_in) { + if (MP_OBJ_IS_SMALL_INT(o_in)) { + nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "'int' object is not iterable")); } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "'%s' object is not iterable", py_obj_get_type_str(o_in), NULL)); - } -} - -py_obj_t rt_iternext(py_obj_t o_in) { - if (IS_O(o_in, O_GEN_INSTANCE)) { - py_obj_base_t *self = o_in; - //py_obj_base_t *fun = self->u_gen_instance.state[0]; - //assert(fun->kind == O_FUN_BC); - bool yield = py_execute_byte_code_2(&self->u_gen_instance.ip, &self->u_gen_instance.state[1], &self->u_gen_instance.sp); - if (yield) { - return *self->u_gen_instance.sp; + mp_obj_base_t *o = o_in; + if (o->type->getiter != NULL) { + return o->type->getiter(o_in); } else { - if (*self->u_gen_instance.sp == py_const_none) { - return py_const_stop_iteration; - } else { - // TODO return StopIteration with value *self->u_gen_instance.sp - return py_const_stop_iteration; - } - } - - } else if (IS_O(o_in, O_RANGE_IT)) { - py_obj_base_t *o = o_in; - if ((o->u_range_it.step > 0 && o->u_range_it.cur < o->u_range_it.stop) || (o->u_range_it.step < 0 && o->u_range_it.cur > o->u_range_it.stop)) { - py_obj_t o_out = TO_SMALL_INT(o->u_range_it.cur); - o->u_range_it.cur += o->u_range_it.step; - return o_out; - } else { - return py_const_stop_iteration; + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "'%s' object is not iterable", o->type->name)); } + } +} - } else if (IS_O(o_in, O_TUPLE_IT) || IS_O(o_in, O_LIST_IT)) { - py_obj_base_t *o = o_in; - if (o->u_tuple_list_it.cur < o->u_tuple_list_it.obj->u_tuple_list.len) { - py_obj_t o_out = o->u_tuple_list_it.obj->u_tuple_list.items[o->u_tuple_list_it.cur]; - o->u_tuple_list_it.cur += 1; - return o_out; +mp_obj_t rt_iternext(mp_obj_t o_in) { + if (MP_OBJ_IS_SMALL_INT(o_in)) { + nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "? 'int' object is not iterable")); + } else { + mp_obj_base_t *o = o_in; + if (o->type->iternext != NULL) { + return o->type->iternext(o_in); } else { - return py_const_stop_iteration; + nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_TypeError, "? '%s' object is not iterable", o->type->name)); } - - } else { - nlr_jump(py_obj_new_exception_2(rt_q_TypeError, "? '%s' object is not iterable", py_obj_get_type_str(o_in), NULL)); } } -py_obj_t rt_import_name(qstr name, py_obj_t fromlist, py_obj_t level) { +mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) { // build args array - py_obj_t args[5]; - args[0] = py_obj_new_str(name); - args[1] = py_const_none; // TODO should be globals - args[2] = py_const_none; // TODO should be locals + mp_obj_t args[5]; + args[0] = mp_obj_new_str(name); + args[1] = mp_const_none; // TODO should be globals + args[2] = mp_const_none; // TODO should be locals args[3] = fromlist; args[4] = level; // must be 0; we don't yet support other values // TODO lookup __import__ and call that instead of going straight to builtin implementation - return py_builtin___import__(5, args); + return mp_builtin___import__(5, args); } -py_obj_t rt_import_from(py_obj_t module, qstr name) { - py_obj_t x = rt_load_attr(module, name); +mp_obj_t rt_import_from(mp_obj_t module, qstr name) { + mp_obj_t x = rt_load_attr(module, name); /* TODO convert AttributeError to ImportError if (fail) { (ImportError, "cannot import name %s", qstr_str(name), NULL) diff --git a/py/runtime.h b/py/runtime.h index d5d160535f29ca4723c04012bed9324b33c0e096..37b036852fd49902192853731eaffa8cd3141039 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -1,91 +1,3 @@ -typedef enum { - RT_UNARY_OP_NOT, - RT_UNARY_OP_POSITIVE, - RT_UNARY_OP_NEGATIVE, - RT_UNARY_OP_INVERT, -} rt_unary_op_t; - -typedef enum { - RT_BINARY_OP_SUBSCR, - RT_BINARY_OP_OR, - RT_BINARY_OP_XOR, - RT_BINARY_OP_AND, - RT_BINARY_OP_LSHIFT, - RT_BINARY_OP_RSHIFT, - RT_BINARY_OP_ADD, - RT_BINARY_OP_SUBTRACT, - RT_BINARY_OP_MULTIPLY, - RT_BINARY_OP_FLOOR_DIVIDE, - RT_BINARY_OP_TRUE_DIVIDE, - RT_BINARY_OP_MODULO, - RT_BINARY_OP_POWER, - RT_BINARY_OP_INPLACE_OR, - RT_BINARY_OP_INPLACE_XOR, - RT_BINARY_OP_INPLACE_AND, - RT_BINARY_OP_INPLACE_LSHIFT, - RT_BINARY_OP_INPLACE_RSHIFT, - RT_BINARY_OP_INPLACE_ADD, - RT_BINARY_OP_INPLACE_SUBTRACT, - RT_BINARY_OP_INPLACE_MULTIPLY, - RT_BINARY_OP_INPLACE_FLOOR_DIVIDE, - RT_BINARY_OP_INPLACE_TRUE_DIVIDE, - RT_BINARY_OP_INPLACE_MODULO, - RT_BINARY_OP_INPLACE_POWER, -} rt_binary_op_t; - -typedef enum { - RT_COMPARE_OP_LESS, - RT_COMPARE_OP_MORE, - RT_COMPARE_OP_EQUAL, - RT_COMPARE_OP_LESS_EQUAL, - RT_COMPARE_OP_MORE_EQUAL, - RT_COMPARE_OP_NOT_EQUAL, - RT_COMPARE_OP_IN, - RT_COMPARE_OP_NOT_IN, - RT_COMPARE_OP_IS, - RT_COMPARE_OP_IS_NOT, - RT_COMPARE_OP_EXCEPTION_MATCH, -} rt_compare_op_t; - -typedef enum { - RT_F_LOAD_CONST_DEC = 0, - RT_F_LOAD_CONST_STR, - RT_F_LOAD_NAME, - RT_F_LOAD_GLOBAL, - RT_F_LOAD_BUILD_CLASS, - RT_F_LOAD_ATTR, - RT_F_LOAD_METHOD, - RT_F_STORE_NAME, - RT_F_STORE_ATTR, - RT_F_STORE_SUBSCR, - RT_F_IS_TRUE, - RT_F_UNARY_OP, - RT_F_BUILD_TUPLE, - RT_F_BUILD_LIST, - RT_F_LIST_APPEND, - RT_F_BUILD_MAP, - RT_F_STORE_MAP, - RT_F_BUILD_SET, - RT_F_STORE_SET, - RT_F_MAKE_FUNCTION_FROM_ID, - RT_F_CALL_FUNCTION_N, - RT_F_CALL_METHOD_N, - RT_F_BINARY_OP, - RT_F_COMPARE_OP, - RT_F_GETITER, - RT_F_ITERNEXT, - RT_F_NUMBER_OF, -} rt_fun_kind_t; - -extern void *const rt_fun_table[RT_F_NUMBER_OF]; - -typedef machine_ptr_t py_obj_t; // must be of pointer size -typedef py_obj_t (*py_fun_0_t)(void); -typedef py_obj_t (*py_fun_1_t)(py_obj_t); -typedef py_obj_t (*py_fun_2_t)(py_obj_t, py_obj_t); -typedef py_obj_t (*py_fun_t)(void); -typedef py_obj_t (*py_fun_var_t)(int n, const py_obj_t *); - extern qstr rt_q_append; extern qstr rt_q_pop; extern qstr rt_q_sort; @@ -101,61 +13,47 @@ extern qstr rt_q_TypeError; extern qstr rt_q_SyntaxError; extern qstr rt_q_ValueError; -extern py_obj_t py_const_none; -extern py_obj_t py_const_false; -extern py_obj_t py_const_true; -extern py_obj_t py_const_stop_iteration; // special object indicating end of iteration (not StopIteration exception!) - -void rt_init(void); -void rt_deinit(void); -int rt_get_unique_code_id(bool is_main_module); -void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_cells, int n_stack, bool is_generator); -void rt_assign_native_code(int unique_code_id, py_fun_t f, uint len, int n_args); -void rt_assign_inline_asm_code(int unique_code_id, py_fun_t f, uint len, int n_args); - -int rt_is_true(py_obj_t arg); - -py_obj_t rt_load_const_dec(qstr qstr); -py_obj_t rt_load_const_str(qstr qstr); -py_obj_t rt_load_name(qstr qstr); -py_obj_t rt_load_global(qstr qstr); -py_obj_t rt_load_build_class(void); -py_obj_t rt_get_cell(py_obj_t cell); -void rt_set_cell(py_obj_t cell, py_obj_t val); -void rt_store_name(qstr qstr, py_obj_t obj); -void rt_store_global(qstr qstr, py_obj_t obj); -py_obj_t rt_unary_op(int op, py_obj_t arg); -py_obj_t rt_binary_op(int op, py_obj_t lhs, py_obj_t rhs); -py_obj_t rt_compare_op(int op, py_obj_t lhs, py_obj_t rhs); -py_obj_t rt_make_function_from_id(int unique_code_id); -py_obj_t rt_make_function_0(py_fun_0_t f); -py_obj_t rt_make_function_1(py_fun_1_t f); -py_obj_t rt_make_function_2(py_fun_2_t f); -py_obj_t rt_make_function(int n_args, py_fun_t code); -py_obj_t rt_make_function_var(int n_fixed_args, py_fun_var_t f); -py_obj_t rt_make_closure_from_id(int unique_code_id, py_obj_t closure_tuple); -py_obj_t rt_call_function_0(py_obj_t fun); -py_obj_t rt_call_function_1(py_obj_t fun, py_obj_t arg); -py_obj_t rt_call_function_2(py_obj_t fun, py_obj_t arg1, py_obj_t arg2); -py_obj_t rt_call_function_n(py_obj_t fun, int n_args, const py_obj_t *args); -py_obj_t rt_call_function_n_kw(py_obj_t fun, uint n_args, uint n_kw, const py_obj_t *args); -py_obj_t rt_call_method_n(uint n_args, const py_obj_t *args); -py_obj_t rt_call_method_n_kw(uint n_args, uint n_kw, const py_obj_t *args); -py_obj_t rt_build_tuple(int n_args, py_obj_t *items); -py_obj_t rt_build_list(int n_args, py_obj_t *items); -py_obj_t rt_list_append(py_obj_t list, py_obj_t arg); -py_obj_t rt_build_set(int n_args, py_obj_t *items); -py_obj_t rt_store_set(py_obj_t set, py_obj_t item); -void rt_unpack_sequence(py_obj_t seq, uint num, py_obj_t *items); -py_obj_t rt_build_map(int n_args); -py_obj_t rt_store_map(py_obj_t map, py_obj_t key, py_obj_t value); -py_obj_t rt_load_attr(py_obj_t base, qstr attr); -void rt_load_method(py_obj_t base, qstr attr, py_obj_t *dest); -void rt_store_attr(py_obj_t base, qstr attr, py_obj_t val); -void rt_store_subscr(py_obj_t base, py_obj_t index, py_obj_t val); -py_obj_t rt_getiter(py_obj_t o); -py_obj_t rt_iternext(py_obj_t o); -py_obj_t rt_import_name(qstr name, py_obj_t fromlist, py_obj_t level); -py_obj_t rt_import_from(py_obj_t module, qstr name); - -py_obj_t rt_gen_instance_next(py_obj_t self_in); +int rt_is_true(mp_obj_t arg); + +mp_obj_t rt_load_const_dec(qstr qstr); +mp_obj_t rt_load_const_str(qstr qstr); +mp_obj_t rt_load_name(qstr qstr); +mp_obj_t rt_load_global(qstr qstr); +mp_obj_t rt_load_build_class(void); +mp_obj_t rt_get_cell(mp_obj_t cell); +void rt_set_cell(mp_obj_t cell, mp_obj_t val); +void rt_store_name(qstr qstr, mp_obj_t obj); +void rt_store_global(qstr qstr, mp_obj_t obj); +mp_obj_t rt_unary_op(int op, mp_obj_t arg); +mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs); +mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs); +mp_obj_t rt_make_function_from_id(int unique_code_id); +mp_obj_t rt_make_function_0(mp_fun_0_t f); +mp_obj_t rt_make_function_1(mp_fun_1_t f); +mp_obj_t rt_make_function_2(mp_fun_2_t f); +mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t f); +mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive +mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple); +mp_obj_t rt_call_function_0(mp_obj_t fun); +mp_obj_t rt_call_function_1(mp_obj_t fun, mp_obj_t arg); +mp_obj_t rt_call_function_2(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2); +mp_obj_t rt_call_function_n(mp_obj_t fun, int n_args, const mp_obj_t *args); +mp_obj_t rt_call_function_n_kw(mp_obj_t fun, uint n_args, uint n_kw, const mp_obj_t *args); +mp_obj_t rt_call_method_n(uint n_args, const mp_obj_t *args); +mp_obj_t rt_call_method_n_kw(uint n_args, uint n_kw, const mp_obj_t *args); +mp_obj_t rt_build_tuple(int n_args, mp_obj_t *items); +mp_obj_t rt_build_list(int n_args, mp_obj_t *items); +mp_obj_t rt_list_append(mp_obj_t list, mp_obj_t arg); +mp_obj_t rt_build_set(int n_args, mp_obj_t *items); +mp_obj_t rt_store_set(mp_obj_t set, mp_obj_t item); +void rt_unpack_sequence(mp_obj_t seq, uint num, mp_obj_t *items); +mp_obj_t rt_build_map(int n_args); +mp_obj_t rt_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value); +mp_obj_t rt_load_attr(mp_obj_t base, qstr attr); +void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest); +void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t val); +void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val); +mp_obj_t rt_getiter(mp_obj_t o); +mp_obj_t rt_iternext(mp_obj_t o); +mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level); +mp_obj_t rt_import_from(mp_obj_t module, qstr name); diff --git a/py/runtime0.h b/py/runtime0.h new file mode 100644 index 0000000000000000000000000000000000000000..f68b7b961b481850f248e369e3844a821910a3e0 --- /dev/null +++ b/py/runtime0.h @@ -0,0 +1,87 @@ +typedef enum { + RT_UNARY_OP_NOT, + RT_UNARY_OP_POSITIVE, + RT_UNARY_OP_NEGATIVE, + RT_UNARY_OP_INVERT, +} rt_unary_op_t; + +typedef enum { + RT_BINARY_OP_SUBSCR, + RT_BINARY_OP_OR, + RT_BINARY_OP_XOR, + RT_BINARY_OP_AND, + RT_BINARY_OP_LSHIFT, + RT_BINARY_OP_RSHIFT, + RT_BINARY_OP_ADD, + RT_BINARY_OP_SUBTRACT, + RT_BINARY_OP_MULTIPLY, + RT_BINARY_OP_FLOOR_DIVIDE, + RT_BINARY_OP_TRUE_DIVIDE, + RT_BINARY_OP_MODULO, + RT_BINARY_OP_POWER, + RT_BINARY_OP_INPLACE_OR, + RT_BINARY_OP_INPLACE_XOR, + RT_BINARY_OP_INPLACE_AND, + RT_BINARY_OP_INPLACE_LSHIFT, + RT_BINARY_OP_INPLACE_RSHIFT, + RT_BINARY_OP_INPLACE_ADD, + RT_BINARY_OP_INPLACE_SUBTRACT, + RT_BINARY_OP_INPLACE_MULTIPLY, + RT_BINARY_OP_INPLACE_FLOOR_DIVIDE, + RT_BINARY_OP_INPLACE_TRUE_DIVIDE, + RT_BINARY_OP_INPLACE_MODULO, + RT_BINARY_OP_INPLACE_POWER, +} rt_binary_op_t; + +typedef enum { + RT_COMPARE_OP_LESS, + RT_COMPARE_OP_MORE, + RT_COMPARE_OP_EQUAL, + RT_COMPARE_OP_LESS_EQUAL, + RT_COMPARE_OP_MORE_EQUAL, + RT_COMPARE_OP_NOT_EQUAL, + RT_COMPARE_OP_IN, + RT_COMPARE_OP_NOT_IN, + RT_COMPARE_OP_IS, + RT_COMPARE_OP_IS_NOT, + RT_COMPARE_OP_EXCEPTION_MATCH, +} rt_compare_op_t; + +typedef enum { + RT_F_LOAD_CONST_DEC = 0, + RT_F_LOAD_CONST_STR, + RT_F_LOAD_NAME, + RT_F_LOAD_GLOBAL, + RT_F_LOAD_BUILD_CLASS, + RT_F_LOAD_ATTR, + RT_F_LOAD_METHOD, + RT_F_STORE_NAME, + RT_F_STORE_ATTR, + RT_F_STORE_SUBSCR, + RT_F_IS_TRUE, + RT_F_UNARY_OP, + RT_F_BUILD_TUPLE, + RT_F_BUILD_LIST, + RT_F_LIST_APPEND, + RT_F_BUILD_MAP, + RT_F_STORE_MAP, + RT_F_BUILD_SET, + RT_F_STORE_SET, + RT_F_MAKE_FUNCTION_FROM_ID, + RT_F_CALL_FUNCTION_N, + RT_F_CALL_METHOD_N, + RT_F_BINARY_OP, + RT_F_COMPARE_OP, + RT_F_GETITER, + RT_F_ITERNEXT, + RT_F_NUMBER_OF, +} rt_fun_kind_t; + +extern void *const rt_fun_table[RT_F_NUMBER_OF]; + +void rt_init(void); +void rt_deinit(void); +int rt_get_unique_code_id(bool is_main_module); +void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, int n_locals, int n_cells, int n_stack, bool is_generator); +void rt_assign_native_code(int unique_code_id, void *f, uint len, int n_args); +void rt_assign_inline_asm_code(int unique_code_id, void *f, uint len, int n_args); diff --git a/py/scope.c b/py/scope.c index d72d130f28c05734d5ede4b81de62911b1c20caf..7d55d3923f002c5851af3213efb83646be99295c 100644 --- a/py/scope.c +++ b/py/scope.c @@ -4,11 +4,11 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "scope.h" -scope_t *scope_new(scope_kind_t kind, py_parse_node_t pn, uint unique_code_id, uint emit_options) { +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, uint unique_code_id, uint emit_options) { scope_t *scope = m_new(scope_t, 1); scope->kind = kind; scope->parent = NULL; @@ -20,8 +20,8 @@ scope_t *scope_new(scope_kind_t kind, py_parse_node_t pn, uint unique_code_id, u break; case SCOPE_FUNCTION: case SCOPE_CLASS: - assert(PY_PARSE_NODE_IS_STRUCT(pn)); - scope->simple_name = PY_PARSE_NODE_LEAF_ARG(((py_parse_node_struct_t*)pn)->nodes[0]); + assert(MP_PARSE_NODE_IS_STRUCT(pn)); + scope->simple_name = MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pn)->nodes[0]); break; case SCOPE_LAMBDA: scope->simple_name = qstr_from_str_static("<lambda>"); diff --git a/py/scope.h b/py/scope.h index f560e3d21abe3ede8331071b048f6ebc28a3c9fe..1231b3cc5e37a28af91d486567d1030dd5bae6f1 100644 --- a/py/scope.h +++ b/py/scope.h @@ -37,7 +37,7 @@ typedef struct _scope_t { scope_kind_t kind; struct _scope_t *parent; struct _scope_t *next; - py_parse_node_t pn; + mp_parse_node_t pn; qstr simple_name; int id_info_alloc; int id_info_len; @@ -55,7 +55,7 @@ typedef struct _scope_t { uint emit_options; } scope_t; -scope_t *scope_new(scope_kind_t kind, py_parse_node_t pn, uint unique_code_id, uint emit_options); +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, uint unique_code_id, uint emit_options); id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added); id_info_t *scope_find(scope_t *scope, qstr qstr); id_info_t *scope_find_global(scope_t *scope, qstr qstr); diff --git a/py/showbc.c b/py/showbc.c index bd8a50515515420876c2d3cdd77a1bdb0de43fa9..fd1d512031ddfb2e1056207f663417be5fe7c70b 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -5,16 +5,15 @@ #include <assert.h> #include "misc.h" -#include "mpyconfig.h" -#include "runtime.h" -#include "bc.h" +#include "mpconfig.h" +#include "bc0.h" #define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } while (0) #define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0) #define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0) #define DECODE_QSTR do { qstr = *ip++; if (qstr > 127) { qstr = ((qstr & 0x3f) << 8) | (*ip++); } } while (0) -void py_show_byte_code(const byte *ip, int len) { +void mp_show_byte_code(const byte *ip, int len) { const byte *ip_start = ip; machine_uint_t unum; qstr qstr; @@ -22,164 +21,164 @@ void py_show_byte_code(const byte *ip, int len) { printf("%02u ", (uint)(ip - ip_start)); int op = *ip++; switch (op) { - case PYBC_LOAD_CONST_FALSE: + case MP_BC_LOAD_CONST_FALSE: printf("LOAD_CONST_FALSE"); break; - case PYBC_LOAD_CONST_NONE: + case MP_BC_LOAD_CONST_NONE: printf("LOAD_CONST_NONE"); break; - case PYBC_LOAD_CONST_TRUE: + case MP_BC_LOAD_CONST_TRUE: printf("LOAD_CONST_TRUE"); break; - case PYBC_LOAD_CONST_SMALL_INT: + case MP_BC_LOAD_CONST_SMALL_INT: unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000; ip += 3; printf("LOAD_CONST_SMALL_INT %d", (int)unum); break; /* - case PYBC_LOAD_CONST_DEC: + case MP_BC_LOAD_CONST_DEC: DECODE_QSTR; PUSH(rt_load_const_dec(qstr)); break; */ - case PYBC_LOAD_CONST_ID: + case MP_BC_LOAD_CONST_ID: DECODE_QSTR; printf("LOAD_CONST_ID %s", qstr_str(qstr)); break; - case PYBC_LOAD_CONST_STRING: + case MP_BC_LOAD_CONST_STRING: DECODE_QSTR; printf("LOAD_CONST_STRING %s", qstr_str(qstr)); break; - case PYBC_LOAD_FAST_0: + case MP_BC_LOAD_FAST_0: printf("LOAD_FAST_0"); break; - case PYBC_LOAD_FAST_1: + case MP_BC_LOAD_FAST_1: printf("LOAD_FAST_1"); break; - case PYBC_LOAD_FAST_2: + case MP_BC_LOAD_FAST_2: printf("LOAD_FAST_2"); break; - case PYBC_LOAD_FAST_N: + case MP_BC_LOAD_FAST_N: DECODE_UINT; printf("LOAD_FAST_N %lu", unum); break; - case PYBC_LOAD_NAME: + case MP_BC_LOAD_NAME: DECODE_QSTR; printf("LOAD_NAME %s", qstr_str(qstr)); break; - case PYBC_LOAD_GLOBAL: + case MP_BC_LOAD_GLOBAL: DECODE_QSTR; printf("LOAD_GLOBAL %s", qstr_str(qstr)); break; - case PYBC_LOAD_ATTR: + case MP_BC_LOAD_ATTR: DECODE_QSTR; printf("LOAD_ATTR %s", qstr_str(qstr)); break; - case PYBC_LOAD_METHOD: + case MP_BC_LOAD_METHOD: DECODE_QSTR; printf("LOAD_METHOD %s", qstr_str(qstr)); break; - case PYBC_LOAD_BUILD_CLASS: + case MP_BC_LOAD_BUILD_CLASS: printf("LOAD_BUILD_CLASS"); break; - case PYBC_STORE_FAST_0: + case MP_BC_STORE_FAST_0: printf("STORE_FAST_0"); break; - case PYBC_STORE_FAST_1: + case MP_BC_STORE_FAST_1: printf("STORE_FAST_1"); break; - case PYBC_STORE_FAST_2: + case MP_BC_STORE_FAST_2: printf("STORE_FAST_2"); break; - case PYBC_STORE_FAST_N: + case MP_BC_STORE_FAST_N: DECODE_UINT; printf("STORE_FAST_N %lu", unum); break; - case PYBC_STORE_NAME: + case MP_BC_STORE_NAME: DECODE_QSTR; printf("STORE_NAME %s", qstr_str(qstr)); break; /* - case PYBC_STORE_GLOBAL: + case MP_BC_STORE_GLOBAL: DECODE_QSTR; rt_store_global(qstr, POP()); break; */ - case PYBC_STORE_ATTR: + case MP_BC_STORE_ATTR: DECODE_QSTR; printf("STORE_ATTR %s", qstr_str(qstr)); break; - case PYBC_STORE_SUBSCR: + case MP_BC_STORE_SUBSCR: printf("STORE_SUBSCR"); break; /* - case PYBC_DUP_TOP: + case MP_BC_DUP_TOP: obj1 = *sp; PUSH(obj1); break; */ - case PYBC_DUP_TOP_TWO: + case MP_BC_DUP_TOP_TWO: printf("DUP_TOP_TWO"); break; - case PYBC_POP_TOP: + case MP_BC_POP_TOP: printf("POP_TOP"); break; /* - case PYBC_ROT_TWO: + case MP_BC_ROT_TWO: obj1 = sp[0]; sp[0] = sp[1]; sp[1] = obj1; break; */ - case PYBC_ROT_THREE: + case MP_BC_ROT_THREE: printf("ROT_THREE"); break; - case PYBC_JUMP: + case MP_BC_JUMP: DECODE_SLABEL; printf("JUMP %lu", ip + unum - ip_start); break; - case PYBC_POP_JUMP_IF_TRUE: + case MP_BC_POP_JUMP_IF_TRUE: DECODE_SLABEL; printf("POP_JUMP_IF_TRUE %lu", ip + unum - ip_start); break; - case PYBC_POP_JUMP_IF_FALSE: + case MP_BC_POP_JUMP_IF_FALSE: DECODE_SLABEL; printf("POP_JUMP_IF_FALSE %lu", ip + unum - ip_start); break; /* - case PYBC_JUMP_IF_TRUE_OR_POP: + case MP_BC_JUMP_IF_TRUE_OR_POP: DECODE_SLABEL; if (rt_is_true(*sp)) { ip += unum; @@ -188,7 +187,7 @@ void py_show_byte_code(const byte *ip, int len) { } break; - case PYBC_JUMP_IF_FALSE_OR_POP: + case MP_BC_JUMP_IF_FALSE_OR_POP: DECODE_SLABEL; if (rt_is_true(*sp)) { sp++; @@ -197,13 +196,13 @@ void py_show_byte_code(const byte *ip, int len) { } break; - case PYBC_SETUP_EXCEPT: + case MP_BC_SETUP_EXCEPT: DECODE_ULABEL; // except labels are always forward *++exc_sp = (machine_uint_t)ip + unum; *++exc_sp = (machine_uint_t)sp; break; - case PYBC_END_FINALLY: + case MP_BC_END_FINALLY: // not implemented // if TOS is an exception, reraises the exception (3 values on TOS) // if TOS is an integer, does something else @@ -213,90 +212,90 @@ void py_show_byte_code(const byte *ip, int len) { break; */ - case PYBC_GET_ITER: + case MP_BC_GET_ITER: printf("GET_ITER"); break; - case PYBC_FOR_ITER: + case MP_BC_FOR_ITER: DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward printf("FOR_ITER %lu", ip + unum - ip_start); break; /* - case PYBC_POP_BLOCK: + case MP_BC_POP_BLOCK: // pops block and restores the stack assert(0); break; - case PYBC_POP_EXCEPT: + case MP_BC_POP_EXCEPT: // TODO need to work out how blocks work etc // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate assert(exc_sp >= &exc_stack[0]); - //sp = (py_obj_t*)(*exc_sp--); + //sp = (mp_obj_t*)(*exc_sp--); //exc_sp--; // discard ip exc_sp -= 2; //sp += 3; // pop 3 exception values break; - case PYBC_UNARY_OP: + case MP_BC_UNARY_OP: unum = *ip++; *sp = rt_unary_op(unum, *sp); break; */ - case PYBC_BINARY_OP: + case MP_BC_BINARY_OP: unum = *ip++; printf("BINARY_OP %lu", unum); break; - case PYBC_COMPARE_OP: + case MP_BC_COMPARE_OP: unum = *ip++; printf("COMPARE_OP %lu", unum); break; - case PYBC_BUILD_TUPLE: + case MP_BC_BUILD_TUPLE: DECODE_UINT; printf("BUILD_TUPLE %lu", unum); break; - case PYBC_BUILD_LIST: + case MP_BC_BUILD_LIST: DECODE_UINT; printf("BUILD_LIST %lu", unum); break; /* - case PYBC_LIST_APPEND: + case MP_BC_LIST_APPEND: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum] is a list rt_list_append(sp[unum], sp[0]); sp++; break; - case PYBC_BUILD_MAP: + case MP_BC_BUILD_MAP: DECODE_UINT; PUSH(rt_build_map(unum)); break; - case PYBC_STORE_MAP: + case MP_BC_STORE_MAP: sp += 2; rt_store_map(sp[0], sp[-2], sp[-1]); break; - case PYBC_MAP_ADD: + case MP_BC_MAP_ADD: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum + 1] is a map rt_store_map(sp[unum + 1], sp[0], sp[1]); sp += 2; break; - case PYBC_BUILD_SET: + case MP_BC_BUILD_SET: DECODE_UINT; obj1 = rt_build_set(unum, sp); sp += unum - 1; *sp = obj1; break; - case PYBC_SET_ADD: + case MP_BC_SET_ADD: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum] is a set rt_store_set(sp[unum], sp[0]); @@ -304,32 +303,32 @@ void py_show_byte_code(const byte *ip, int len) { break; */ - case PYBC_UNPACK_SEQUENCE: + case MP_BC_UNPACK_SEQUENCE: DECODE_UINT; printf("UNPACK_SEQUENCE %lu", unum); break; - case PYBC_MAKE_FUNCTION: + case MP_BC_MAKE_FUNCTION: DECODE_UINT; printf("MAKE_FUNCTION %lu", unum); break; - case PYBC_CALL_FUNCTION: + case MP_BC_CALL_FUNCTION: DECODE_UINT; printf("CALL_FUNCTION n=%lu nkw=%lu", unum & 0xff, (unum >> 8) & 0xff); break; - case PYBC_CALL_METHOD: + case MP_BC_CALL_METHOD: DECODE_UINT; printf("CALL_METHOD n=%lu nkw=%lu", unum & 0xff, (unum >> 8) & 0xff); break; - case PYBC_RETURN_VALUE: + case MP_BC_RETURN_VALUE: printf("RETURN_VALUE"); break; /* - case PYBC_YIELD_VALUE: + case MP_BC_YIELD_VALUE: nlr_pop(); *ip_in_out = ip; fastn[0] = fast0; diff --git a/py/vm.c b/py/vm.c index 7db6a7d9c406e7ff5d0ad13dcd9d624bc627bcde..b10d641ca16704e86f582660f2476264552dde62 100644 --- a/py/vm.c +++ b/py/vm.c @@ -6,8 +6,10 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" +#include "obj.h" #include "runtime.h" +#include "bc0.h" #include "bc.h" // (value) stack grows down (to be compatible with native code when passing pointers to the stack), top element is pointed to @@ -23,12 +25,12 @@ #define SET_TOP(val) *sp = (val) // args are in reverse order in array -py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_args, uint n_state) { - py_obj_t temp_state[10]; // TODO allocate properly - py_obj_t *state = &temp_state[0]; - py_obj_t *sp = &state[10]; +mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state) { + mp_obj_t temp_state[10]; // TODO allocate properly + mp_obj_t *state = &temp_state[0]; + mp_obj_t *sp = &state[10]; if (n_state > 10) { - state = m_new(py_obj_t, n_state); + state = m_new(mp_obj_t, n_state); sp = &state[n_state]; } // init args @@ -37,7 +39,7 @@ py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_arg state[i] = args[n_args - 1 - i]; } const byte *ip = code; - if (py_execute_byte_code_2(&ip, &state[0], &sp)) { + if (mp_execute_byte_code_2(&ip, &state[0], &sp)) { // it shouldn't yield assert(0); } @@ -48,15 +50,15 @@ py_obj_t py_execute_byte_code(const byte *code, const py_obj_t *args, uint n_arg // fastn has items in normal order // sp points to top of stack which grows down -bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t **sp_in_out) { +bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out) { // careful: be sure to declare volatile any variables read in the exception handler (written is ok, I think) const byte *ip = *ip_in_out; - py_obj_t *sp = *sp_in_out; + mp_obj_t *sp = *sp_in_out; machine_uint_t unum; qstr qstr; - py_obj_t obj1, obj2; - py_obj_t fast0 = fastn[0], fast1 = fastn[1], fast2 = fastn[2]; + mp_obj_t obj1, obj2; + mp_obj_t fast0 = fastn[0], fast1 = fastn[1], fast2 = fastn[2]; nlr_buf_t nlr; // on the exception stack we store (ip, sp) for each block @@ -70,182 +72,182 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** for (;;) { int op = *ip++; switch (op) { - case PYBC_LOAD_CONST_FALSE: - PUSH(py_const_false); + case MP_BC_LOAD_CONST_FALSE: + PUSH(mp_const_false); break; - case PYBC_LOAD_CONST_NONE: - PUSH(py_const_none); + case MP_BC_LOAD_CONST_NONE: + PUSH(mp_const_none); break; - case PYBC_LOAD_CONST_TRUE: - PUSH(py_const_true); + case MP_BC_LOAD_CONST_TRUE: + PUSH(mp_const_true); break; - case PYBC_LOAD_CONST_SMALL_INT: + case MP_BC_LOAD_CONST_SMALL_INT: unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000; ip += 3; - PUSH((py_obj_t)(unum << 1 | 1)); + PUSH((mp_obj_t)(unum << 1 | 1)); break; - case PYBC_LOAD_CONST_DEC: + case MP_BC_LOAD_CONST_DEC: DECODE_QSTR; PUSH(rt_load_const_dec(qstr)); break; - case PYBC_LOAD_CONST_ID: + case MP_BC_LOAD_CONST_ID: DECODE_QSTR; PUSH(rt_load_const_str(qstr)); // TODO break; - case PYBC_LOAD_CONST_STRING: + case MP_BC_LOAD_CONST_STRING: DECODE_QSTR; PUSH(rt_load_const_str(qstr)); break; - case PYBC_LOAD_FAST_0: + case MP_BC_LOAD_FAST_0: PUSH(fast0); break; - case PYBC_LOAD_FAST_1: + case MP_BC_LOAD_FAST_1: PUSH(fast1); break; - case PYBC_LOAD_FAST_2: + case MP_BC_LOAD_FAST_2: PUSH(fast2); break; - case PYBC_LOAD_FAST_N: + case MP_BC_LOAD_FAST_N: DECODE_UINT; PUSH(fastn[unum]); break; - case PYBC_LOAD_DEREF: + case MP_BC_LOAD_DEREF: DECODE_UINT; PUSH(rt_get_cell(fastn[unum])); break; - case PYBC_LOAD_CLOSURE: + case MP_BC_LOAD_CLOSURE: DECODE_UINT; PUSH(fastn[unum]); break; - case PYBC_LOAD_NAME: + case MP_BC_LOAD_NAME: DECODE_QSTR; PUSH(rt_load_name(qstr)); break; - case PYBC_LOAD_GLOBAL: + case MP_BC_LOAD_GLOBAL: DECODE_QSTR; PUSH(rt_load_global(qstr)); break; - case PYBC_LOAD_ATTR: + case MP_BC_LOAD_ATTR: DECODE_QSTR; SET_TOP(rt_load_attr(TOP(), qstr)); break; - case PYBC_LOAD_METHOD: + case MP_BC_LOAD_METHOD: DECODE_QSTR; sp -= 1; rt_load_method(sp[1], qstr, sp); break; - case PYBC_LOAD_BUILD_CLASS: + case MP_BC_LOAD_BUILD_CLASS: PUSH(rt_load_build_class()); break; - case PYBC_STORE_FAST_0: + case MP_BC_STORE_FAST_0: fast0 = POP(); break; - case PYBC_STORE_FAST_1: + case MP_BC_STORE_FAST_1: fast1 = POP(); break; - case PYBC_STORE_FAST_2: + case MP_BC_STORE_FAST_2: fast2 = POP(); break; - case PYBC_STORE_FAST_N: + case MP_BC_STORE_FAST_N: DECODE_UINT; fastn[unum] = POP(); break; - case PYBC_STORE_DEREF: + case MP_BC_STORE_DEREF: DECODE_UINT; rt_set_cell(fastn[unum], POP()); break; - case PYBC_STORE_NAME: + case MP_BC_STORE_NAME: DECODE_QSTR; rt_store_name(qstr, POP()); break; - case PYBC_STORE_GLOBAL: + case MP_BC_STORE_GLOBAL: DECODE_QSTR; rt_store_global(qstr, POP()); break; - case PYBC_STORE_ATTR: + case MP_BC_STORE_ATTR: DECODE_QSTR; rt_store_attr(sp[0], qstr, sp[1]); sp += 2; break; - case PYBC_STORE_SUBSCR: + case MP_BC_STORE_SUBSCR: rt_store_subscr(sp[1], sp[0], sp[2]); sp += 3; break; - case PYBC_DUP_TOP: + case MP_BC_DUP_TOP: obj1 = TOP(); PUSH(obj1); break; - case PYBC_DUP_TOP_TWO: + case MP_BC_DUP_TOP_TWO: sp -= 2; sp[0] = sp[2]; sp[1] = sp[3]; break; - case PYBC_POP_TOP: + case MP_BC_POP_TOP: ++sp; break; - case PYBC_ROT_TWO: + case MP_BC_ROT_TWO: obj1 = sp[0]; sp[0] = sp[1]; sp[1] = obj1; break; - case PYBC_ROT_THREE: + case MP_BC_ROT_THREE: obj1 = sp[0]; sp[0] = sp[1]; sp[1] = sp[2]; sp[2] = obj1; break; - case PYBC_JUMP: + case MP_BC_JUMP: DECODE_SLABEL; ip += unum; break; - case PYBC_POP_JUMP_IF_TRUE: + case MP_BC_POP_JUMP_IF_TRUE: DECODE_SLABEL; if (rt_is_true(POP())) { ip += unum; } break; - case PYBC_POP_JUMP_IF_FALSE: + case MP_BC_POP_JUMP_IF_FALSE: DECODE_SLABEL; if (!rt_is_true(POP())) { ip += unum; } break; - case PYBC_JUMP_IF_TRUE_OR_POP: + case MP_BC_JUMP_IF_TRUE_OR_POP: DECODE_SLABEL; if (rt_is_true(TOP())) { ip += unum; @@ -254,7 +256,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** } break; - case PYBC_JUMP_IF_FALSE_OR_POP: + case MP_BC_JUMP_IF_FALSE_OR_POP: DECODE_SLABEL; if (rt_is_true(TOP())) { sp++; @@ -264,19 +266,19 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** break; /* we are trying to get away without using this opcode - case PYBC_SETUP_LOOP: + case MP_BC_SETUP_LOOP: DECODE_UINT; - // push_block(PYBC_SETUP_LOOP, ip + unum, sp) + // push_block(MP_BC_SETUP_LOOP, ip + unum, sp) break; */ - case PYBC_SETUP_EXCEPT: + case MP_BC_SETUP_EXCEPT: DECODE_ULABEL; // except labels are always forward *++exc_sp = (machine_uint_t)ip + unum; *++exc_sp = (machine_uint_t)sp; break; - case PYBC_END_FINALLY: + case MP_BC_END_FINALLY: // not implemented // if TOS is an exception, reraises the exception (3 values on TOS) // if TOS is an integer, does something else @@ -285,14 +287,14 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** assert(0); break; - case PYBC_GET_ITER: + case MP_BC_GET_ITER: SET_TOP(rt_getiter(TOP())); break; - case PYBC_FOR_ITER: + case MP_BC_FOR_ITER: DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward obj1 = rt_iternext(TOP()); - if (obj1 == py_const_stop_iteration) { + if (obj1 == mp_const_stop_iteration) { ++sp; // pop the exhausted iterator ip += unum; // jump to after for-block } else { @@ -300,110 +302,110 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** } break; - case PYBC_POP_BLOCK: + case MP_BC_POP_BLOCK: // pops block and restores the stack assert(0); break; - case PYBC_POP_EXCEPT: + case MP_BC_POP_EXCEPT: // TODO need to work out how blocks work etc // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate assert(exc_sp >= &exc_stack[0]); - //sp = (py_obj_t*)(*exc_sp--); + //sp = (mp_obj_t*)(*exc_sp--); //exc_sp--; // discard ip exc_sp -= 2; //sp += 3; // pop 3 exception values break; - case PYBC_UNARY_OP: + case MP_BC_UNARY_OP: unum = *ip++; SET_TOP(rt_unary_op(unum, TOP())); break; - case PYBC_BINARY_OP: + case MP_BC_BINARY_OP: unum = *ip++; obj2 = POP(); obj1 = TOP(); SET_TOP(rt_binary_op(unum, obj1, obj2)); break; - case PYBC_COMPARE_OP: + case MP_BC_COMPARE_OP: unum = *ip++; obj2 = POP(); obj1 = TOP(); SET_TOP(rt_compare_op(unum, obj1, obj2)); break; - case PYBC_BUILD_TUPLE: + case MP_BC_BUILD_TUPLE: DECODE_UINT; obj1 = rt_build_tuple(unum, sp); sp += unum - 1; SET_TOP(obj1); break; - case PYBC_BUILD_LIST: + case MP_BC_BUILD_LIST: DECODE_UINT; obj1 = rt_build_list(unum, sp); sp += unum - 1; SET_TOP(obj1); break; - case PYBC_LIST_APPEND: + case MP_BC_LIST_APPEND: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum] is a list rt_list_append(sp[unum], sp[0]); sp++; break; - case PYBC_BUILD_MAP: + case MP_BC_BUILD_MAP: DECODE_UINT; PUSH(rt_build_map(unum)); break; - case PYBC_STORE_MAP: + case MP_BC_STORE_MAP: sp += 2; rt_store_map(sp[0], sp[-2], sp[-1]); break; - case PYBC_MAP_ADD: + case MP_BC_MAP_ADD: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum + 1] is a map rt_store_map(sp[unum + 1], sp[0], sp[1]); sp += 2; break; - case PYBC_BUILD_SET: + case MP_BC_BUILD_SET: DECODE_UINT; obj1 = rt_build_set(unum, sp); sp += unum - 1; SET_TOP(obj1); break; - case PYBC_SET_ADD: + case MP_BC_SET_ADD: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum] is a set rt_store_set(sp[unum], sp[0]); sp++; break; - case PYBC_UNPACK_SEQUENCE: + case MP_BC_UNPACK_SEQUENCE: DECODE_UINT; rt_unpack_sequence(sp[0], unum, sp - unum + 1); sp -= unum - 1; break; - case PYBC_MAKE_FUNCTION: + case MP_BC_MAKE_FUNCTION: DECODE_UINT; PUSH(rt_make_function_from_id(unum)); break; - case PYBC_MAKE_CLOSURE: + case MP_BC_MAKE_CLOSURE: DECODE_UINT; obj1 = POP(); PUSH(rt_make_closure_from_id(unum, obj1)); break; - case PYBC_CALL_FUNCTION: + case MP_BC_CALL_FUNCTION: DECODE_UINT; assert((unum & 0xff00) == 0); // n_keyword unum &= 0xff; // n_positional @@ -411,7 +413,7 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** *sp = rt_call_function_n(*sp, unum, sp - unum); break; - case PYBC_CALL_METHOD: + case MP_BC_CALL_METHOD: DECODE_UINT; if ((unum & 0xff00) == 0) { // no keywords @@ -426,13 +428,13 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** SET_TOP(obj1); break; - case PYBC_RETURN_VALUE: + case MP_BC_RETURN_VALUE: nlr_pop(); *sp_in_out = sp; assert(exc_sp == &exc_stack[-1]); return false; - case PYBC_YIELD_VALUE: + case MP_BC_YIELD_VALUE: nlr_pop(); *ip_in_out = ip; fastn[0] = fast0; @@ -441,13 +443,13 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** *sp_in_out = sp; return true; - case PYBC_IMPORT_NAME: + case MP_BC_IMPORT_NAME: DECODE_QSTR; obj1 = POP(); SET_TOP(rt_import_name(qstr, obj1, TOP())); break; - case PYBC_IMPORT_FROM: + case MP_BC_IMPORT_FROM: DECODE_QSTR; obj1 = rt_import_from(TOP(), qstr); PUSH(obj1); @@ -466,12 +468,12 @@ bool py_execute_byte_code_2(const byte **ip_in_out, py_obj_t *fastn, py_obj_t ** if (exc_sp >= &exc_stack[0]) { // catch exception and pass to byte code - sp = (py_obj_t*)(exc_sp[0]); + sp = (mp_obj_t*)(exc_sp[0]); ip = (const byte*)(exc_sp[-1]); // push(traceback, exc-val, exc-type) - PUSH(py_const_none); + PUSH(mp_const_none); PUSH(nlr.ret_val); - PUSH(py_const_none); + PUSH(mp_const_none); } else { // re-raise exception // TODO what to do if this is a generator?? diff --git a/stm/Makefile b/stm/Makefile index 8817717950989854af3217dcbdf310ec06f154fc..1e0831159e9417f9961a7fb13f0874cb32ed1e0b 100644 --- a/stm/Makefile +++ b/stm/Makefile @@ -23,6 +23,7 @@ SRC_C = \ lexerstm.c \ led.c \ lcd.c \ + servo.c \ flash.c \ storage.c \ mma.c \ @@ -57,6 +58,25 @@ PY_O = \ runtime.o \ map.o \ obj.o \ + objbool.o \ + objboundmeth.o \ + objcell.o \ + objclass.o \ + objclosure.o \ + objcomplex.o \ + objdict.o \ + objexcept.o \ + objfloat.o \ + objfun.o \ + objgenerator.o \ + objinstance.o \ + objlist.o \ + objnone.o \ + objrange.o \ + objset.o \ + objstr.o \ + objtuple.o \ + objtype.o \ builtin.o \ vm.o \ repl.o \ @@ -150,7 +170,7 @@ $(BUILD)/%.o: $(CC3KSRC)/%.c $(BUILD)/%.o: $(PYSRC)/%.s $(AS) -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h diff --git a/stm/audio.c b/stm/audio.c index 41614416e2c3b31f9de24f683430db48ed09f0ac..62d2ff2f861fc26da6c540847fdb0cfb89e62df1 100644 --- a/stm/audio.c +++ b/stm/audio.c @@ -6,9 +6,10 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "audio.h" @@ -44,22 +45,22 @@ void audio_drain(void) { } // direct access to DAC -py_obj_t pyb_audio_dac(py_obj_t val) { - DAC_SetChannel2Data(DAC_Align_8b_R, py_obj_get_int(val)); - return py_const_none; +mp_obj_t pyb_audio_dac(mp_obj_t val) { + DAC_SetChannel2Data(DAC_Align_8b_R, mp_obj_get_int(val)); + return mp_const_none; } -py_obj_t pyb_audio_is_full(void) { +mp_obj_t pyb_audio_is_full(void) { if (audio_is_full()) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } -py_obj_t pyb_audio_fill(py_obj_t val) { - audio_fill(py_obj_get_int(val)); - return py_const_none; +mp_obj_t pyb_audio_fill(mp_obj_t val) { + audio_fill(mp_obj_get_int(val)); + return mp_const_none; } void audio_init(void) { @@ -90,7 +91,7 @@ void audio_init(void) { // enable interrupt // Python interface - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("dac"), rt_make_function_1(pyb_audio_dac)); rt_store_attr(m, qstr_from_str_static("is_full"), rt_make_function_0(pyb_audio_is_full)); rt_store_attr(m, qstr_from_str_static("fill"), rt_make_function_1(pyb_audio_fill)); diff --git a/stm/lcd.c b/stm/lcd.c index 5d2c677349cd02e2af088323c42626b7aa7736d0..cec5bf548d426a23fb25a6faf4f83e51b456b01f 100644 --- a/stm/lcd.c +++ b/stm/lcd.c @@ -3,9 +3,10 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "systick.h" @@ -88,16 +89,16 @@ static void lcd_data_out(uint8_t i) { // writes 8 vertical pixels // pos 0 is upper left, pos 1 is 8 pixels to right of that, pos 128 is 8 pixels below that -py_obj_t lcd_draw_pixel_8(py_obj_t py_pos, py_obj_t py_val) { - int pos = py_obj_get_int(py_pos); - int val = py_obj_get_int(py_val); +mp_obj_t lcd_draw_pixel_8(mp_obj_t mp_pos, mp_obj_t mp_val) { + int pos = mp_obj_get_int(mp_pos); + int val = mp_obj_get_int(mp_val); int page = pos / 128; int offset = pos - (page * 128); lcd_out(LCD_INSTR, 0xb0 | page); // page address set lcd_out(LCD_INSTR, 0x10 | ((offset >> 4) & 0x0f)); // column address set upper lcd_out(LCD_INSTR, 0x00 | (offset & 0x0f)); // column address set lower lcd_out(LCD_DATA, val); // write data - return py_const_none; + return mp_const_none; } #define LCD_BUF_W (16) @@ -112,45 +113,45 @@ int lcd_next_line; byte lcd_pix_buf[LCD_PIX_BUF_SIZE]; byte lcd_pix_buf2[LCD_PIX_BUF_SIZE]; -py_obj_t lcd_pix_clear(void) { +mp_obj_t lcd_pix_clear(void) { memset(lcd_pix_buf, 0, LCD_PIX_BUF_SIZE); memset(lcd_pix_buf2, 0, LCD_PIX_BUF_SIZE); - return py_const_none; + return mp_const_none; } -py_obj_t lcd_pix_get(py_obj_t py_x, py_obj_t py_y) { - int x = py_obj_get_int(py_x); - int y = py_obj_get_int(py_y); +mp_obj_t lcd_pix_get(mp_obj_t mp_x, mp_obj_t mp_y) { + int x = mp_obj_get_int(mp_x); + int y = mp_obj_get_int(mp_y); if (0 <= x && x <= 127 && 0 <= y && y <= 31) { uint byte_pos = x + 128 * ((uint)y >> 3); if (lcd_pix_buf[byte_pos] & (1 << (y & 7))) { - return py_obj_new_int(1); + return mp_obj_new_int(1); } } - return py_obj_new_int(0); + return mp_obj_new_int(0); } -py_obj_t lcd_pix_set(py_obj_t py_x, py_obj_t py_y) { - int x = py_obj_get_int(py_x); - int y = py_obj_get_int(py_y); +mp_obj_t lcd_pix_set(mp_obj_t mp_x, mp_obj_t mp_y) { + int x = mp_obj_get_int(mp_x); + int y = mp_obj_get_int(mp_y); if (0 <= x && x <= 127 && 0 <= y && y <= 31) { uint byte_pos = x + 128 * ((uint)y >> 3); lcd_pix_buf2[byte_pos] |= 1 << (y & 7); } - return py_const_none; + return mp_const_none; } -py_obj_t lcd_pix_reset(py_obj_t py_x, py_obj_t py_y) { - int x = py_obj_get_int(py_x); - int y = py_obj_get_int(py_y); +mp_obj_t lcd_pix_reset(mp_obj_t mp_x, mp_obj_t mp_y) { + int x = mp_obj_get_int(mp_x); + int y = mp_obj_get_int(mp_y); if (0 <= x && x <= 127 && 0 <= y && y <= 31) { uint byte_pos = x + 128 * ((uint)y >> 3); lcd_pix_buf2[byte_pos] &= ~(1 << (y & 7)); } - return py_const_none; + return mp_const_none; } -py_obj_t lcd_pix_show(void) { +mp_obj_t lcd_pix_show(void) { memcpy(lcd_pix_buf, lcd_pix_buf2, LCD_PIX_BUF_SIZE); for (uint page = 0; page < 4; page++) { lcd_out(LCD_INSTR, 0xb0 | page); // page address set @@ -160,12 +161,12 @@ py_obj_t lcd_pix_show(void) { lcd_out(LCD_DATA, lcd_pix_buf[i + 128 * page]); } } - return py_const_none; + return mp_const_none; } -py_obj_t lcd_print(py_obj_t text) { - lcd_print_str(qstr_str(py_obj_get_qstr(text))); - return py_const_none; +mp_obj_t lcd_print(mp_obj_t text) { + lcd_print_str(qstr_str(mp_obj_get_qstr(text))); + return mp_const_none; } void lcd_init(void) { @@ -219,7 +220,7 @@ void lcd_init(void) { lcd_next_line = 0; // Python interface - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_2(lcd_draw_pixel_8)); rt_store_attr(m, qstr_from_str_static("clear"), rt_make_function_0(lcd_pix_clear)); rt_store_attr(m, qstr_from_str_static("get"), rt_make_function_2(lcd_pix_get)); diff --git a/stm/led.c b/stm/led.c index a48ccf5f0880b0886631913ba518e2611147182d..08077641a9cccbbad82f88e669fe07fc22da8364 100644 --- a/stm/led.c +++ b/stm/led.c @@ -1,5 +1,10 @@ +#include <stdio.h> #include <stm32f4xx.h> #include <stm32f4xx_gpio.h> + +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" #include "led.h" #define PYB_LED_R_PORT (GPIOA) @@ -64,3 +69,60 @@ void led_toggle(pyb_led_t led) { port->BSRRH = pin; } } + +/******************************************************************************/ +/* Micro Python bindings */ + +typedef struct _pyb_led_obj_t { + mp_obj_base_t base; + uint led_id; +} pyb_led_obj_t; + +void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + print(env, "<LED %lu>", self->led_id); +} + +mp_obj_t led_obj_on(mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + switch (self->led_id) { + case 1: led_state(PYB_LED_G1, 1); break; + case 2: led_state(PYB_LED_G2, 1); break; + } + return mp_const_none; +} + +mp_obj_t led_obj_off(mp_obj_t self_in) { + pyb_led_obj_t *self = self_in; + switch (self->led_id) { + case 1: led_state(PYB_LED_G1, 0); break; + case 2: led_state(PYB_LED_G2, 0); break; + } + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on); +static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off); + +static const mp_obj_type_t led_obj_type = { + { &mp_const_type }, + "Led", + led_obj_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "on", &led_obj_on_obj }, + { "off", &led_obj_off_obj }, + { NULL, NULL }, + } +}; + +mp_obj_t pyb_Led(mp_obj_t led_id) { + pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t); + o->base.type = &led_obj_type; + o->led_id = mp_obj_get_int(led_id); + return o; +} diff --git a/stm/led.h b/stm/led.h index c4b68196b2a4a443bb0717af93a7bbab09eec10b..e6d0c30bcabc073572e0989707b9a280d44904b9 100644 --- a/stm/led.h +++ b/stm/led.h @@ -8,3 +8,5 @@ typedef enum { void led_init(void); void led_state(pyb_led_t led, int state); void led_toggle(pyb_led_t led); + +mp_obj_t pyb_Led(mp_obj_t led_id); diff --git a/stm/lexerstm.c b/stm/lexerstm.c index 06ea04d1b977aa09126973de4527af271393e7ac..4e99052242230f5c913b9e2baa717ac8cf23888b 100644 --- a/stm/lexerstm.c +++ b/stm/lexerstm.c @@ -7,37 +7,37 @@ #include "lexer.h" #include "lexerstm.h" -unichar str_buf_next_char(py_lexer_str_buf_t *sb) { +unichar str_buf_next_char(mp_lexer_str_buf_t *sb) { if (sb->src_cur < sb->src_end) { return *sb->src_cur++; } else { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } } -void str_buf_free(py_lexer_str_buf_t *sb) { +void str_buf_free(mp_lexer_str_buf_t *sb) { if (sb->free) { m_free((char*)sb->src_beg); } } -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, py_lexer_str_buf_t *sb) { +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, mp_lexer_str_buf_t *sb) { sb->free = free_str; sb->src_beg = str; sb->src_cur = str; sb->src_end = str + len; - return py_lexer_new(src_name, sb, (py_lexer_stream_next_char_t)str_buf_next_char, (py_lexer_stream_close_t)str_buf_free); + return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_char_t)str_buf_next_char, (mp_lexer_stream_close_t)str_buf_free); } -unichar file_buf_next_char(py_lexer_file_buf_t *fb) { +unichar file_buf_next_char(mp_lexer_file_buf_t *fb) { if (fb->pos >= fb->len) { if (fb->len < sizeof(fb->buf)) { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } else { UINT n; f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n); if (n == 0) { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } fb->len = n; fb->pos = 0; @@ -46,11 +46,11 @@ unichar file_buf_next_char(py_lexer_file_buf_t *fb) { return fb->buf[fb->pos++]; } -void file_buf_close(py_lexer_file_buf_t *fb) { +void file_buf_close(mp_lexer_file_buf_t *fb) { f_close(&fb->fp); } -py_lexer_t *py_lexer_new_from_file(const char *filename, py_lexer_file_buf_t *fb) { +mp_lexer_t *mp_lexer_new_from_file(const char *filename, mp_lexer_file_buf_t *fb) { FRESULT res = f_open(&fb->fp, filename, FA_READ); if (res != FR_OK) { return NULL; @@ -59,5 +59,5 @@ py_lexer_t *py_lexer_new_from_file(const char *filename, py_lexer_file_buf_t *fb f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n); fb->len = n; fb->pos = 0; - return py_lexer_new(filename, fb, (py_lexer_stream_next_char_t)file_buf_next_char, (py_lexer_stream_close_t)file_buf_close); + return mp_lexer_new(filename, fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close); } diff --git a/stm/lexerstm.h b/stm/lexerstm.h index f57d1faa9d2f46b5e3917a72f3d5768a838e8a47..7e090898a2fd2449b31ae2bb556e2cdf81ff32eb 100644 --- a/stm/lexerstm.h +++ b/stm/lexerstm.h @@ -3,14 +3,14 @@ typedef struct _py_lexer_str_buf_t { const char *src_beg; // beginning of source const char *src_cur; // current location in source const char *src_end; // end (exclusive) of source -} py_lexer_str_buf_t; +} mp_lexer_str_buf_t; typedef struct _py_lexer_file_buf_t { FIL fp; char buf[20]; uint16_t len; uint16_t pos; -} py_lexer_file_buf_t; +} mp_lexer_file_buf_t; -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, py_lexer_str_buf_t *sb); -py_lexer_t *py_lexer_new_from_file(const char *filename, py_lexer_file_buf_t *fb); +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, mp_lexer_str_buf_t *sb); +mp_lexer_t *mp_lexer_new_from_file(const char *filename, mp_lexer_file_buf_t *fb); diff --git a/stm/main.c b/stm/main.c index a262a917e787553ef9d5b55094b0e89a0a1d1134..f45e8998541d864f8c53f5d074114aefe0da943f 100644 --- a/stm/main.c +++ b/stm/main.c @@ -13,16 +13,27 @@ #include "std.h" #include "misc.h" -#include "mpyconfig.h" +#include "ff.h" +#include "mpconfig.h" +#include "nlr.h" +#include "misc.h" +#include "lexer.h" +#include "lexerstm.h" +#include "parse.h" +#include "compile.h" +#include "obj.h" +#include "runtime0.h" +#include "runtime.h" +#include "repl.h" #include "gc.h" #include "systick.h" #include "led.h" +#include "servo.h" #include "lcd.h" #include "storage.h" #include "mma.h" #include "usart.h" #include "usb.h" -#include "ff.h" #include "timer.h" #include "audio.h" #include "pybwlan.h" @@ -114,128 +125,43 @@ void __fatal_error(const char *msg) { } } -#include "nlr.h" -#include "misc.h" -#include "lexer.h" -#include "lexerstm.h" -#include "mpyconfig.h" -#include "parse.h" -#include "compile.h" -#include "runtime.h" -#include "obj.h" -#include "repl.h" - static qstr pyb_config_source_dir = 0; static qstr pyb_config_main = 0; -py_obj_t pyb_source_dir(py_obj_t source_dir) { - pyb_config_source_dir = py_obj_get_qstr(source_dir); - return py_const_none; +mp_obj_t pyb_source_dir(mp_obj_t source_dir) { + pyb_config_source_dir = mp_obj_get_qstr(source_dir); + return mp_const_none; } -py_obj_t pyb_main(py_obj_t main) { - pyb_config_main = py_obj_get_qstr(main); - return py_const_none; +mp_obj_t pyb_main(mp_obj_t main) { + pyb_config_main = mp_obj_get_qstr(main); + return mp_const_none; } // sync all file systems -py_obj_t pyb_sync(void) { +mp_obj_t pyb_sync(void) { storage_flush(); - return py_const_none; + return mp_const_none; } -py_obj_t pyb_delay(py_obj_t count) { - sys_tick_delay_ms(py_obj_get_int(count)); - return py_const_none; +mp_obj_t pyb_delay(mp_obj_t count) { + sys_tick_delay_ms(mp_obj_get_int(count)); + return mp_const_none; } -py_obj_t pyb_led(py_obj_t state) { +mp_obj_t pyb_led(mp_obj_t state) { led_state(PYB_LED_G1, rt_is_true(state)); return state; } -void led_obj_print(py_obj_t self) { - machine_uint_t led_id; - py_user_get_data(self, &led_id, NULL); - printf("<LED %lu>", led_id); -} - -py_obj_t led_obj_on(py_obj_t self) { - machine_uint_t led_id; - py_user_get_data(self, &led_id, NULL); - switch (led_id) { - case 1: led_state(PYB_LED_G1, 1); break; - case 2: led_state(PYB_LED_G2, 1); break; - } - return py_const_none; -} - -py_obj_t led_obj_off(py_obj_t self) { - machine_uint_t led_id; - py_user_get_data(self, &led_id, NULL); - switch (led_id) { - case 1: led_state(PYB_LED_G1, 0); break; - case 2: led_state(PYB_LED_G2, 0); break; - } - return py_const_none; -} - -const py_user_info_t led_obj_info = { - "Led", - led_obj_print, - { - {"on", 0, led_obj_on}, - {"off", 0, led_obj_off}, - {NULL, 0, NULL}, - } -}; - -py_obj_t pyb_Led(py_obj_t led_id) { - return py_obj_new_user(&led_obj_info, (machine_uint_t)py_obj_get_int(led_id), 0); -} - -py_obj_t pyb_sw(void) { +mp_obj_t pyb_sw(void) { if (sw_get()) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } -void servo_obj_print(py_obj_t self) { - machine_uint_t servo_id; - py_user_get_data(self, &servo_id, NULL); - printf("<Servo %lu>", servo_id); -} - -py_obj_t servo_obj_angle(py_obj_t self, py_obj_t angle) { - machine_uint_t servo_id; - py_user_get_data(self, &servo_id, NULL); - machine_int_t v = 152 + 85.0 * py_obj_get_float(angle) / 90.0; - if (v < 65) { v = 65; } - if (v > 210) { v = 210; } - switch (servo_id) { - case 1: TIM2->CCR1 = v; break; - case 2: TIM2->CCR2 = v; break; - case 3: TIM2->CCR3 = v; break; - case 4: TIM2->CCR4 = v; break; - } - return py_const_none; -} - -const py_user_info_t servo_obj_info = { - "Servo", - servo_obj_print, - { - {"angle", 1, servo_obj_angle}, - {NULL, 0, NULL}, - } -}; - -py_obj_t pyb_Servo(py_obj_t servo_id) { - return py_obj_new_user(&servo_obj_info, (machine_uint_t)py_obj_get_int(servo_id), 0); -} - /* void g(uint i) { printf("g:%d\n", i); @@ -306,13 +232,13 @@ static const char *help_text = ; // get some help about available functions -static py_obj_t pyb_help(void) { +static mp_obj_t pyb_help(void) { printf("%s", help_text); - return py_const_none; + return mp_const_none; } // get lots of info about the board -static py_obj_t pyb_info(void) { +static mp_obj_t pyb_info(void) { // get and print unique id; 96 bits { byte *id = (byte*)0x1fff7a10; @@ -364,14 +290,14 @@ static py_obj_t pyb_info(void) { printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512)); } - return py_const_none; + return mp_const_none; } // SD card test -static py_obj_t pyb_sd_test(void) { +static mp_obj_t pyb_sd_test(void) { extern void sdio_init(void); sdio_init(); - return py_const_none; + return mp_const_none; } static void SYSCLKConfig_STOP(void) { @@ -398,7 +324,7 @@ static void SYSCLKConfig_STOP(void) { } } -static py_obj_t pyb_stop(void) { +static mp_obj_t pyb_stop(void) { PWR_EnterSTANDBYMode(); //PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this @@ -411,28 +337,28 @@ static py_obj_t pyb_stop(void) { //PWR_FlashPowerDownCmd(DISABLE); - return py_const_none; + return mp_const_none; } -static py_obj_t pyb_standby(void) { +static mp_obj_t pyb_standby(void) { PWR_EnterSTANDBYMode(); - return py_const_none; + return mp_const_none; } -py_obj_t pyb_usart_send(py_obj_t data) { - usart_tx_char(py_obj_get_int(data)); - return py_const_none; +mp_obj_t pyb_usart_send(mp_obj_t data) { + usart_tx_char(mp_obj_get_int(data)); + return mp_const_none; } -py_obj_t pyb_usart_receive(void) { - return py_obj_new_int(usart_rx_char()); +mp_obj_t pyb_usart_receive(void) { + return mp_obj_new_int(usart_rx_char()); } -py_obj_t pyb_usart_status(void) { +mp_obj_t pyb_usart_status(void) { if (usart_rx_any()) { - return py_const_true; + return mp_const_true; } else { - return py_const_false; + return mp_const_false; } } @@ -544,7 +470,7 @@ void do_repl(void) { continue; } - if (py_repl_is_compound_stmt(vstr_str(&line))) { + if (mp_repl_is_compound_stmt(vstr_str(&line))) { for (;;) { vstr_add_char(&line, '\n'); int len = vstr_len(&line); @@ -556,16 +482,16 @@ void do_repl(void) { } } - py_lexer_str_buf_t sb; - py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), false, &sb); - py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT); - py_lexer_free(lex); + mp_lexer_str_buf_t sb; + mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), false, &sb); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT); + mp_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { - bool comp_ok = py_compile(pn, true); + if (pn != MP_PARSE_NODE_NULL) { + bool comp_ok = mp_compile(pn, true); if (comp_ok) { - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != mp_const_none) { nlr_buf_t nlr; uint32_t start = sys_tick_counter; if (nlr_push(&nlr) == 0) { @@ -578,7 +504,7 @@ void do_repl(void) { } } else { // uncaught exception - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } @@ -590,28 +516,28 @@ void do_repl(void) { } bool do_file(const char *filename) { - py_lexer_file_buf_t fb; - py_lexer_t *lex = py_lexer_new_from_file(filename, &fb); + mp_lexer_file_buf_t fb; + mp_lexer_t *lex = mp_lexer_new_from_file(filename, &fb); if (lex == NULL) { printf("could not open file '%s' for reading\n", filename); return false; } - py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT); - py_lexer_free(lex); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); - if (pn == PY_PARSE_NODE_NULL) { + if (pn == MP_PARSE_NODE_NULL) { return false; } - bool comp_ok = py_compile(pn, false); + bool comp_ok = mp_compile(pn, false); if (!comp_ok) { return false; } - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun == py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun == mp_const_none) { return false; } @@ -622,7 +548,7 @@ bool do_file(const char *filename) { return true; } else { // uncaught exception - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); return false; } @@ -655,115 +581,16 @@ void gc_collect(void) { } } -py_obj_t pyb_gc(void) { +mp_obj_t pyb_gc(void) { gc_collect(); - return py_const_none; -} - -// PWM -// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively -// they are both 32-bit counters -// 16-bit prescaler -// TIM2_CH3 also on PB10 (used below) -void servo_init(void) { - // TIM2 clock enable - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); - - // for PB10 - /* - // GPIOB Configuration: TIM2_CH3 (PB10) - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - // Connect TIM2 pins to AF1 - GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2); - */ - - // for PA0, PA1, PA2, PA3 - { - // GPIOA Configuration: TIM2_CH0, TIM2_CH1 (PA0, PA1) - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - // Connect TIM2 pins to AF1 - GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2); - } - - // Compute the prescaler value so TIM2 runs at 100kHz - uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 100000) - 1; - - // Time base configuration - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_TimeBaseStructure.TIM_Period = 2000; // timer cycles at 50Hz - TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); - - // PWM Mode configuration - TIM_OCInitTypeDef TIM_OCInitStructure; - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; - TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - TIM_OCInitStructure.TIM_Pulse = 150; // units of 10us - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; - TIM_OC1Init(TIM2, &TIM_OCInitStructure); // channel 1 - TIM_OC2Init(TIM2, &TIM_OCInitStructure); // channel 2 - TIM_OC3Init(TIM2, &TIM_OCInitStructure); // channel 3 - TIM_OC4Init(TIM2, &TIM_OCInitStructure); // channel 4 - - // ? - TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 1 - TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 2 - TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 3 - TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 4 - - // ? - TIM_ARRPreloadConfig(TIM2, ENABLE); - - // TIM2 enable counter - TIM_Cmd(TIM2, ENABLE); -} - -py_obj_t pyb_servo_set(py_obj_t port, py_obj_t value) { - int p = py_obj_get_int(port); - int v = py_obj_get_int(value); - if (v < 50) { v = 50; } - if (v > 250) { v = 250; } - switch (p) { - case 1: TIM2->CCR1 = v; break; - case 2: TIM2->CCR2 = v; break; - case 3: TIM2->CCR3 = v; break; - case 4: TIM2->CCR4 = v; break; - } - return py_const_none; -} - -py_obj_t pyb_pwm_set(py_obj_t period, py_obj_t pulse) { - int pe = py_obj_get_int(period); - int pu = py_obj_get_int(pulse); - TIM2->ARR = pe; - TIM2->CCR3 = pu; - return py_const_none; + return mp_const_none; } #define MMA_ADDR (0x4c) int mma_buf[12]; -py_obj_t pyb_mma_read(void) { +mp_obj_t pyb_mma_read(void) { for (int i = 0; i <= 6; i += 3) { mma_buf[0 + i] = mma_buf[0 + i + 3]; mma_buf[1 + i] = mma_buf[1 + i + 3]; @@ -782,24 +609,24 @@ py_obj_t pyb_mma_read(void) { } int jolt_info = mma_read_nack(); - py_obj_t data[4]; - data[0] = py_obj_new_int(jolt_info); - data[1] = py_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]); - data[2] = py_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]); - data[3] = py_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]); + mp_obj_t data[4]; + data[0] = mp_obj_new_int(jolt_info); + data[1] = mp_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]); + data[2] = mp_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]); + data[3] = mp_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]); return rt_build_tuple(4, data); // items in reverse order in data } -py_obj_t pyb_hid_send_report(py_obj_t arg) { - py_obj_t *items = py_obj_get_array_fixed_n(arg, 4); +mp_obj_t pyb_hid_send_report(mp_obj_t arg) { + mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4); uint8_t data[4]; - data[0] = py_obj_get_int(items[0]); - data[1] = py_obj_get_int(items[1]); - data[2] = py_obj_get_int(items[2]); - data[3] = py_obj_get_int(items[3]); + data[0] = mp_obj_get_int(items[0]); + data[1] = mp_obj_get_int(items[1]); + data[2] = mp_obj_get_int(items[2]); + data[3] = mp_obj_get_int(items[3]); usb_hid_send_report(data); - return py_const_none; + return mp_const_none; } static void rtc_init(void) { @@ -855,90 +682,102 @@ static void rtc_init(void) { //RTC_WriteBackupRegister(RTC_BKP_DR0, 0x32F2); } -py_obj_t pyb_rtc_read(void) { +mp_obj_t pyb_rtc_read(void) { RTC_TimeTypeDef RTC_TimeStructure; RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure); printf("%02d:%02d:%02d\n", RTC_TimeStructure.RTC_Hours, RTC_TimeStructure.RTC_Minutes, RTC_TimeStructure.RTC_Seconds); - return py_const_none; + return mp_const_none; } -void file_obj_print(py_obj_t o) { - FIL *fp; - py_user_get_data(o, (machine_uint_t*)&fp, NULL); - printf("<file %p>", fp); +typedef struct _pyb_file_obj_t { + mp_obj_base_t base; + FIL fp; +} pyb_file_obj_t; + +void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + printf("<file %p>", self_in); } -py_obj_t file_obj_read(py_obj_t self, py_obj_t arg) { - FIL *fp; - py_user_get_data(self, (machine_uint_t*)&fp, NULL); - int n = py_obj_get_int(arg); +mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) { + pyb_file_obj_t *self = self_in; + int n = mp_obj_get_int(arg); char *buf = m_new(char, n + 1); UINT n_out; - f_read(fp, buf, n, &n_out); + f_read(&self->fp, buf, n, &n_out); buf[n_out] = 0; - return py_obj_new_str(qstr_from_str_take(buf)); + return mp_obj_new_str(qstr_from_str_take(buf)); } -py_obj_t file_obj_write(py_obj_t self, py_obj_t arg) { - FIL *fp; - py_user_get_data(self, (machine_uint_t*)&fp, NULL); - const char *s = qstr_str(py_obj_get_qstr(arg)); +mp_obj_t file_obj_write(mp_obj_t self_in, mp_obj_t arg) { + pyb_file_obj_t *self = self_in; + const char *s = qstr_str(mp_obj_get_qstr(arg)); UINT n_out; - FRESULT res = f_write(fp, s, strlen(s), &n_out); + FRESULT res = f_write(&self->fp, s, strlen(s), &n_out); if (res != FR_OK) { printf("File error: could not write to file; error code %d\n", res); } else if (n_out != strlen(s)) { printf("File error: could not write all data to file; wrote %d / %d bytes\n", n_out, strlen(s)); } - return py_const_none; + return mp_const_none; } -py_obj_t file_obj_close(py_obj_t self) { - FIL *fp; - py_user_get_data(self, (machine_uint_t*)&fp, NULL); - f_close(fp); - return py_const_none; +mp_obj_t file_obj_close(mp_obj_t self_in) { + pyb_file_obj_t *self = self_in; + f_close(&self->fp); + return mp_const_none; } +static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_read_obj, file_obj_read); +static MP_DEFINE_CONST_FUN_OBJ_2(file_obj_write_obj, file_obj_write); +static MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close); + // TODO gc hook to close the file if not already closed -const py_user_info_t file_obj_info = { + +static const mp_obj_type_t file_obj_type = { + { &mp_const_type }, "File", - file_obj_print, - { - {"read", 1, file_obj_read}, - {"write", 1, file_obj_write}, - {"close", 0, file_obj_close}, - {NULL, 0, NULL}, + file_obj_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "read", &file_obj_read_obj }, + { "write", &file_obj_write_obj }, + { "close", &file_obj_close_obj }, + {NULL, NULL}, } }; -py_obj_t pyb_io_open(py_obj_t o_filename, py_obj_t o_mode) { - const char *filename = qstr_str(py_obj_get_qstr(o_filename)); - const char *mode = qstr_str(py_obj_get_qstr(o_mode)); - FIL *fp = m_new(FIL, 1); +mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) { + const char *filename = qstr_str(mp_obj_get_qstr(o_filename)); + const char *mode = qstr_str(mp_obj_get_qstr(o_mode)); + pyb_file_obj_t *self = m_new_obj(pyb_file_obj_t); + self->base.type = &file_obj_type; if (mode[0] == 'r') { // open for reading - FRESULT res = f_open(fp, filename, FA_READ); + FRESULT res = f_open(&self->fp, filename, FA_READ); if (res != FR_OK) { printf("FileNotFoundError: [Errno 2] No such file or directory: '%s'\n", filename); - return py_const_none; + return mp_const_none; } } else if (mode[0] == 'w') { // open for writing, truncate the file first - FRESULT res = f_open(fp, filename, FA_WRITE | FA_CREATE_ALWAYS); + FRESULT res = f_open(&self->fp, filename, FA_WRITE | FA_CREATE_ALWAYS); if (res != FR_OK) { printf("?FileError: could not create file: '%s'\n", filename); - return py_const_none; + return mp_const_none; } } else { printf("ValueError: invalid mode: '%s'\n", mode); - return py_const_none; + return mp_const_none; } - return py_obj_new_user(&file_obj_info, (machine_uint_t)fp, 0); + return self; } -py_obj_t pyb_rng_get(void) { - return py_obj_new_int(RNG_GetRandomNumber() >> 16); +mp_obj_t pyb_rng_get(void) { + return mp_obj_new_int(RNG_GetRandomNumber() >> 16); } int main(void) { @@ -1015,7 +854,7 @@ soft_reset: { rt_store_name(qstr_from_str_static("help"), rt_make_function_0(pyb_help)); - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info)); rt_store_attr(m, qstr_from_str_static("sd_test"), rt_make_function_0(pyb_sd_test)); rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_0(pyb_stop)); @@ -1312,19 +1151,19 @@ soft_reset: " pass\n" "f()\n"; - py_lexer_str_buf_t py_lexer_str_buf; - py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", pysrc, strlen(pysrc), false, &py_lexer_str_buf); + mp_lexer_str_buf_t mp_lexer_str_buf; + mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", pysrc, strlen(pysrc), false, &mp_lexer_str_buf); // nalloc=1740;6340;6836 -> 140;4600;496 bytes for lexer, parser, compiler printf("lex; al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); - py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT); - py_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); + if (pn != MP_PARSE_NODE_NULL) { printf("pars;al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); //parse_node_show(pn, 0); - bool comp_ok = py_compile(pn, false); + bool comp_ok = mp_compile(pn, false); printf("comp;al=%u\n", m_get_total_bytes_allocated()); sys_tick_delay_ms(1000); @@ -1333,7 +1172,7 @@ soft_reset: } else { // execute it! - py_obj_t module_fun = rt_make_function_from_id(1); + mp_obj_t module_fun = rt_make_function_from_id(1); // flash once led_state(PYB_LED_G1, 1); @@ -1342,15 +1181,15 @@ soft_reset: nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - py_obj_t ret = rt_call_function_0(module_fun); + mp_obj_t ret = rt_call_function_0(module_fun); printf("done! got: "); - py_obj_print(ret); + mp_obj_print(ret); printf("\n"); nlr_pop(); } else { // uncaught exception printf("exception: "); - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } diff --git a/stm/malloc0.c b/stm/malloc0.c index 7157252ed20a04ab8e0d2f60cb407edf8d1aa8e4..7e3f620db25067534e0cdd397b733cc7f2d56365 100644 --- a/stm/malloc0.c +++ b/stm/malloc0.c @@ -1,6 +1,6 @@ #include <stdint.h> #include "std.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "gc.h" #if 0 diff --git a/stm/mpyconfig.h b/stm/mpconfig.h similarity index 89% rename from stm/mpyconfig.h rename to stm/mpconfig.h index 3fa3ac6524ac3e3464493cf49cbb45c30791fbb8..1f9529e11ba8df1afdb692e129061534878b9870 100644 --- a/stm/mpyconfig.h +++ b/stm/mpconfig.h @@ -13,6 +13,7 @@ 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); diff --git a/stm/pybwlan.c b/stm/pybwlan.c index 3d1f216f881e6818d33f3152b58a6461cd17d567..863c241b60a2f591434f779908b279327c00be9b 100644 --- a/stm/pybwlan.c +++ b/stm/pybwlan.c @@ -11,7 +11,7 @@ #include "std.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "systick.h" #include "nlr.h" @@ -19,6 +19,7 @@ #include "lexer.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "cc3k/ccspi.h" @@ -28,27 +29,27 @@ #include "cc3k/wlan.h" #include "cc3k/nvmem.h" -py_obj_t pyb_wlan_connect(int n_args, const py_obj_t *args) { +mp_obj_t pyb_wlan_connect(int n_args, const mp_obj_t *args) { const char *ap; const char *key; if (n_args == 2) { - ap = qstr_str(py_obj_get_qstr(args[0])); - key = qstr_str(py_obj_get_qstr(args[1])); + ap = qstr_str(mp_obj_get_qstr(args[0])); + key = qstr_str(mp_obj_get_qstr(args[1])); } else { - ap = "Rama3"; - key = "underthechristmastree"; + ap = "your-ssid"; + key = "your-password"; } // might want to set wlan_ioctl_set_connection_policy int ret = wlan_connect(WLAN_SEC_WPA2, ap, strlen(ap), NULL, (byte*)key, strlen(key)); - return py_obj_new_int(ret); + return mp_obj_new_int(ret); } -py_obj_t pyb_wlan_disconnect(void) { +mp_obj_t pyb_wlan_disconnect(void) { int ret = wlan_disconnect(); - return py_obj_new_int(ret); + return mp_obj_new_int(ret); } -py_obj_t decode_addr(unsigned char *ip, int nBytes) { +mp_obj_t decode_addr(unsigned char *ip, int nBytes) { char data[64] = ""; if (nBytes == 4) { snprintf(data, 64, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]); @@ -57,21 +58,21 @@ py_obj_t decode_addr(unsigned char *ip, int nBytes) { } else if (nBytes == 32) { snprintf(data, 64, "%s", ip); } - return py_obj_new_str(qstr_from_strn_copy(data, strlen(data))); + return mp_obj_new_str(qstr_from_strn_copy(data, strlen(data))); } -void _wlan_getIP_get_address(py_obj_t object, qstr q_attr, unsigned char *ip, int nBytes) { +void _wlan_getIP_get_address(mp_obj_t object, qstr q_attr, unsigned char *ip, int nBytes) { rt_store_attr(object, q_attr, decode_addr(ip, nBytes)); } -py_obj_t pyb_wlan_get_ip(void) { +mp_obj_t pyb_wlan_get_ip(void) { tNetappIpconfigRetArgs ipconfig; netapp_ipconfig(&ipconfig); /* If byte 1 is 0 we don't have a valid address */ - if (ipconfig.aucIP[3] == 0) return py_const_none; + if (ipconfig.aucIP[3] == 0) return mp_const_none; - py_obj_t data = py_module_new(); // TODO should really be a class + mp_obj_t data = mp_module_new(); // TODO should really be a class _wlan_getIP_get_address(data, qstr_from_str_static("ip"), &ipconfig.aucIP[0], 4); _wlan_getIP_get_address(data, qstr_from_str_static("subnet"), &ipconfig.aucSubnetMask[0], 4); _wlan_getIP_get_address(data, qstr_from_str_static("gateway"), &ipconfig.aucDefaultGateway[0], 4); @@ -84,16 +85,16 @@ py_obj_t pyb_wlan_get_ip(void) { } uint32_t last_ip = 0; // XXX such a hack! -py_obj_t pyb_wlan_get_host(py_obj_t host_name) { - const char *host = qstr_str(py_obj_get_qstr(host_name)); +mp_obj_t pyb_wlan_get_host(mp_obj_t host_name) { + const char *host = qstr_str(mp_obj_get_qstr(host_name)); uint32_t ip; if (gethostbyname(host, strlen(host), &ip) < 0) { printf("gethostbyname failed\n"); - return py_const_none; + return mp_const_none; } if (ip == 0) { // unknown host - return py_const_none; + return mp_const_none; } last_ip = ip; byte ip_data[4]; @@ -104,19 +105,17 @@ py_obj_t pyb_wlan_get_host(py_obj_t host_name) { return decode_addr(ip_data, 4); } -py_obj_t py_obj_new_exception_2(qstr, const char *, void*, void*); - -py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { - if (host_name == py_const_none) { +mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) { + if (host_name == mp_const_none) { last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3); } else { - if (pyb_wlan_get_host(host_name) == py_const_none) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "unknown host", NULL, NULL)); + if (pyb_wlan_get_host(host_name) == mp_const_none) { + nlr_jump(mp_obj_new_exception_msg(qstr_from_str_static("WlanError"), "unknown host")); } } int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sd < 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd)); } //printf("socket seemed to work\n"); //sys_tick_delay_ms(200); @@ -127,13 +126,13 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { remote.sin_addr.s_addr = htonl(last_ip); int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr)); if (ret != 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "connect failed: %d", (void*)ret, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "connect failed: %d", (void*)ret)); } //printf("connect seemed to work\n"); //sys_tick_delay_ms(200); vstr_t *vstr = vstr_new(); - vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", qstr_str(py_obj_get_qstr(host_path)), qstr_str(py_obj_get_qstr(host_name))); + vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", qstr_str(mp_obj_get_qstr(host_path)), qstr_str(mp_obj_get_qstr(host_name))); const char *query = vstr_str(vstr); // send query @@ -148,7 +147,7 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { ret = send(sd, query + sent, strlen(query + sent), 0); //printf("sent %d bytes\n", ret); if (ret < 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "send failed", NULL, NULL)); + nlr_jump(mp_obj_new_exception_msg(qstr_from_str_static("WlanError"), "send failed")); } sent += ret; //sys_tick_delay_ms(200); @@ -159,7 +158,7 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { //sys_tick_delay_ms(5000); // receive reply - py_obj_t py_ret = py_const_none; + mp_obj_t mp_ret = mp_const_none; { //printf("doing receive\n"); char buf[64]; @@ -185,33 +184,33 @@ py_obj_t pyb_wlan_http_get(py_obj_t host_name, py_obj_t host_path) { // read data ret = recv(sd, buf, 64, 0); if (ret < 0) { - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "recv failed %d", (void*)ret, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "recv failed %d", (void*)ret)); } vstr_add_strn(vstr, buf, ret); } - py_ret = py_obj_new_str(qstr_from_str_take(vstr_str(vstr))); + mp_ret = mp_obj_new_str(qstr_from_str_take(vstr_str(vstr))); } closesocket(sd); - return py_ret; + return mp_ret; } -py_obj_t pyb_wlan_serve(void) { +mp_obj_t pyb_wlan_serve(void) { printf("serve socket\n"); int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); printf("serve socket got %d\n", sd); sys_tick_delay_ms(500); if (sd < 0) { printf("socket fail\n"); - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "socket failed: %d", (void*)sd)); } /* if (setsockopt(sd, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, SOCK_ON, sizeof(SOCK_ON)) < 0) { printf("couldn't set socket as non-blocking\n"); - return py_const_none; + return mp_const_none; } */ @@ -226,7 +225,7 @@ py_obj_t pyb_wlan_serve(void) { sys_tick_delay_ms(100); if (ret != 0) { printf("bind fail\n"); - nlr_jump(py_obj_new_exception_2(qstr_from_str_static("WlanError"), "bind failed: %d", (void*)ret, NULL)); + nlr_jump(mp_obj_new_exception_msg_1_arg(qstr_from_str_static("WlanError"), "bind failed: %d", (void*)ret)); } printf("bind seemed to work\n"); @@ -268,7 +267,7 @@ py_obj_t pyb_wlan_serve(void) { closesocket(fd); closesocket(sd); - return py_const_none; + return mp_const_none; } //***************************************************************************** @@ -344,7 +343,7 @@ void pyb_wlan_init(void) { SpiInit(); wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin); - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("connect"), rt_make_function_var(0, pyb_wlan_connect)); rt_store_attr(m, qstr_from_str_static("disconnect"), rt_make_function_0(pyb_wlan_disconnect)); rt_store_attr(m, qstr_from_str_static("ip"), rt_make_function_0(pyb_wlan_get_ip)); diff --git a/stm/servo.c b/stm/servo.c new file mode 100644 index 0000000000000000000000000000000000000000..ae421048b92cebbbdca415eccd36d4d9f4d77e65 --- /dev/null +++ b/stm/servo.c @@ -0,0 +1,160 @@ +#include <stdio.h> +#include <stm32f4xx.h> +#include <stm32f4xx_rcc.h> +#include <stm32f4xx_gpio.h> +#include <stm32f4xx_tim.h> + +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" +#include "servo.h" + +// PWM +// TIM2 and TIM5 have CH1, CH2, CH3, CH4 on PA0-PA3 respectively +// they are both 32-bit counters +// 16-bit prescaler +// TIM2_CH3 also on PB10 (used below) +void servo_init(void) { + // TIM2 clock enable + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + + // for PB10 + /* + // GPIOB Configuration: TIM2_CH3 (PB10) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // Connect TIM2 pins to AF1 + GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2); + */ + + // for PA0, PA1, PA2, PA3 + { + // GPIOA Configuration: TIM2_CH0, TIM2_CH1 (PA0, PA1) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + // Connect TIM2 pins to AF1 + GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2); + GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2); + } + + // Compute the prescaler value so TIM2 runs at 100kHz + uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 100000) - 1; + + // Time base configuration + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_TimeBaseStructure.TIM_Period = 2000; // timer cycles at 50Hz + TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + + // PWM Mode configuration + TIM_OCInitTypeDef TIM_OCInitStructure; + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 150; // units of 10us + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OC1Init(TIM2, &TIM_OCInitStructure); // channel 1 + TIM_OC2Init(TIM2, &TIM_OCInitStructure); // channel 2 + TIM_OC3Init(TIM2, &TIM_OCInitStructure); // channel 3 + TIM_OC4Init(TIM2, &TIM_OCInitStructure); // channel 4 + + // ? + TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 1 + TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 2 + TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 3 + TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); // channel 4 + + // ? + TIM_ARRPreloadConfig(TIM2, ENABLE); + + // TIM2 enable counter + TIM_Cmd(TIM2, ENABLE); +} + +/******************************************************************************/ +/* Micro Python bindings */ + +mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value) { + int p = mp_obj_get_int(port); + int v = mp_obj_get_int(value); + if (v < 50) { v = 50; } + if (v > 250) { v = 250; } + switch (p) { + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; + } + return mp_const_none; +} + +mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse) { + int pe = mp_obj_get_int(period); + int pu = mp_obj_get_int(pulse); + TIM2->ARR = pe; + TIM2->CCR3 = pu; + return mp_const_none; +} + +typedef struct _pyb_servo_obj_t { + mp_obj_base_t base; + uint servo_id; +} pyb_servo_obj_t; + +static void servo_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + pyb_servo_obj_t *self = self_in; + print(env, "<Servo %lu>", self->servo_id); +} + +static mp_obj_t servo_obj_angle(mp_obj_t self_in, mp_obj_t angle) { + pyb_servo_obj_t *self = self_in; + machine_int_t v = 152 + 85.0 * mp_obj_get_float(angle) / 90.0; + if (v < 65) { v = 65; } + if (v > 210) { v = 210; } + switch (self->servo_id) { + case 1: TIM2->CCR1 = v; break; + case 2: TIM2->CCR2 = v; break; + case 3: TIM2->CCR3 = v; break; + case 4: TIM2->CCR4 = v; break; + } + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_2(servo_obj_angle_obj, servo_obj_angle); + +static const mp_obj_type_t servo_obj_type = { + { &mp_const_type }, + "Servo", + servo_obj_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "angle", &servo_obj_angle_obj }, + { NULL, NULL }, + } +}; + +mp_obj_t pyb_Servo(mp_obj_t servo_id) { + pyb_servo_obj_t *o = m_new_obj(pyb_servo_obj_t); + o->base.type = &servo_obj_type; + o->servo_id = mp_obj_get_int(servo_id); + return o; +} diff --git a/stm/servo.h b/stm/servo.h new file mode 100644 index 0000000000000000000000000000000000000000..02702e067268a9c3f39872621e18c23454da023d --- /dev/null +++ b/stm/servo.h @@ -0,0 +1,5 @@ +void servo_init(void); + +mp_obj_t pyb_servo_set(mp_obj_t port, mp_obj_t value); +mp_obj_t pyb_pwm_set(mp_obj_t period, mp_obj_t pulse); +mp_obj_t pyb_Servo(mp_obj_t servo_id); diff --git a/stm/stm32fxxx_it.c b/stm/stm32fxxx_it.c index 0f17681e5f85ccc8e63145ca51d6df53d3815121..4c185d0341d6f23d86668da901cc545e92b2fb3d 100644 --- a/stm/stm32fxxx_it.c +++ b/stm/stm32fxxx_it.c @@ -267,6 +267,9 @@ void TIM6_DAC_IRQHandler(void) { } #include "std.h" +#include "misc.h" +#include "mpconfig.h" +#include "obj.h" #include "led.h" // EXTI // for USRSW on A13 diff --git a/stm/storage.c b/stm/storage.c index ac0458d136970381d824cb686bf7461608a41432..6878de22e67fbd0df4b2fcc3d5a2c4e1af378456 100644 --- a/stm/storage.c +++ b/stm/storage.c @@ -3,6 +3,8 @@ #include "misc.h" #include "systick.h" +#include "mpconfig.h" +#include "obj.h" #include "led.h" #include "flash.h" #include "storage.h" diff --git a/stm/timer.c b/stm/timer.c index ecfc2bb2894be5d78e3533767d95db8d3158e1ed..2236bbce47b2ae821d65333f7dc4659fc5a3a84b 100644 --- a/stm/timer.c +++ b/stm/timer.c @@ -7,37 +7,38 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "parse.h" #include "compile.h" +#include "obj.h" #include "runtime.h" #include "timer.h" // TIM6 is used as an internal interrup to schedule something at a specific rate -py_obj_t timer_py_callback; +mp_obj_t timer_py_callback; -py_obj_t timer_py_set_callback(py_obj_t f) { +mp_obj_t timer_py_set_callback(mp_obj_t f) { timer_py_callback = f; - return py_const_none; + return mp_const_none; } -py_obj_t timer_py_set_period(py_obj_t period) { - TIM6->ARR = py_obj_get_int(period) & 0xffff; - return py_const_none; +mp_obj_t timer_py_set_period(mp_obj_t period) { + TIM6->ARR = mp_obj_get_int(period) & 0xffff; + return mp_const_none; } -py_obj_t timer_py_set_prescaler(py_obj_t prescaler) { - TIM6->PSC = py_obj_get_int(prescaler) & 0xffff; - return py_const_none; +mp_obj_t timer_py_set_prescaler(mp_obj_t prescaler) { + TIM6->PSC = mp_obj_get_int(prescaler) & 0xffff; + return mp_const_none; } -py_obj_t timer_py_get_value(void) { - return py_obj_new_int(TIM6->CNT & 0xfffff); +mp_obj_t timer_py_get_value(void) { + return mp_obj_new_int(TIM6->CNT & 0xfffff); } void timer_init(void) { - timer_py_callback = py_const_none; + timer_py_callback = mp_const_none; // TIM6 clock enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); @@ -71,7 +72,7 @@ void timer_init(void) { TIM_Cmd(TIM6, ENABLE); // Python interface - py_obj_t m = py_module_new(); + mp_obj_t m = mp_module_new(); rt_store_attr(m, qstr_from_str_static("callback"), rt_make_function_1(timer_py_set_callback)); rt_store_attr(m, qstr_from_str_static("period"), rt_make_function_1(timer_py_set_period)); rt_store_attr(m, qstr_from_str_static("prescaler"), rt_make_function_1(timer_py_set_prescaler)); @@ -80,7 +81,7 @@ void timer_init(void) { } void timer_interrupt(void) { - if (timer_py_callback != py_const_none) { + if (timer_py_callback != mp_const_none) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { // XXX what to do if the GC is in the middle of running?? @@ -89,7 +90,7 @@ void timer_interrupt(void) { } else { // uncaught exception printf("exception in timer interrupt\n"); - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } diff --git a/unix/Makefile b/unix/Makefile index 76cc0a385523af8ffb63b3e33b2bc18597cc4876..463f6b170bc6f5d8153b370d67b4fab258c882de 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -31,6 +31,25 @@ PY_O = \ runtime.o \ map.o \ obj.o \ + objbool.o \ + objboundmeth.o \ + objcell.o \ + objclass.o \ + objclosure.o \ + objcomplex.o \ + objdict.o \ + objexcept.o \ + objfloat.o \ + objfun.o \ + objgenerator.o \ + objinstance.o \ + objlist.o \ + objnone.o \ + objrange.o \ + objset.o \ + objstr.o \ + objtuple.o \ + objtype.o \ builtin.o \ vm.o \ showbc.o \ @@ -42,6 +61,8 @@ PROG = py $(PROG): $(BUILD) $(OBJ) $(CC) -o $@ $(OBJ) $(LIB) $(LDFLAGS) + strip $(PROG) + size $(PROG) $(BUILD): mkdir $@ @@ -52,7 +73,7 @@ $(BUILD)/%.o: %.c $(BUILD)/%.o: $(PYSRC)/%.s $(AS) -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h @@ -65,7 +86,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h $(BUILD)/vm.o: $(PYSRC)/vm.c $(CC) $(CFLAGS) -O3 -c -o $@ $< -$(BUILD)/main.o: mpyconfig.h +$(BUILD)/main.o: mpconfig.h $(BUILD)/parse.o: $(PYSRC)/grammar.h $(BUILD)/compile.o: $(PYSRC)/grammar.h $(BUILD)/emitcpy.o: $(PYSRC)/emit.h diff --git a/unix/lexerunix.c b/unix/lexerunix.c index e76d7f2c2113e14fc1c80611a98bae69d6a99365..ac07781b5a3efeda7724cadfac7d7399eba752a7 100644 --- a/unix/lexerunix.c +++ b/unix/lexerunix.c @@ -17,7 +17,7 @@ unichar str_buf_next_char(str_buf_t *sb) { if (sb->src_cur < sb->src_end) { return *sb->src_cur++; } else { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } } @@ -30,16 +30,16 @@ void str_buf_free(str_buf_t *sb) { } } -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str) { +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str) { str_buf_t *sb = m_new(str_buf_t, 1); sb->free = free_str; sb->src_beg = str; sb->src_cur = str; sb->src_end = str + len; - return py_lexer_new(src_name, sb, (py_lexer_stream_next_char_t)str_buf_next_char, (py_lexer_stream_close_t)str_buf_free); + return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_char_t)str_buf_next_char, (mp_lexer_stream_close_t)str_buf_free); } -py_lexer_t *py_lexer_new_from_file(const char *filename) { +mp_lexer_t *mp_lexer_new_from_file(const char *filename) { int fd = open(filename, O_RDONLY); if (fd < 0) { printf("cannot open file %s\n", filename); @@ -51,5 +51,5 @@ py_lexer_t *py_lexer_new_from_file(const char *filename) { read(fd, data, size); close(fd); - return py_lexer_new_from_str_len(filename, data, size, true); + return mp_lexer_new_from_str_len(filename, data, size, true); } diff --git a/unix/lexerunix.h b/unix/lexerunix.h index aa7631cb0b514ec404e8721ddef42564c3dfb653..d86f202d53b4a8cc350c3f2b24b6c67929412bc9 100644 --- a/unix/lexerunix.h +++ b/unix/lexerunix.h @@ -1,2 +1,2 @@ -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str); -py_lexer_t *py_lexer_new_from_file(const char *filename); +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str); +mp_lexer_t *mp_lexer_new_from_file(const char *filename); diff --git a/unix/main.c b/unix/main.c index e5aa9de15be1f058c71ee0de8ddc054bda08d30c..295e82d26a0435d68b39326e7dffbfbb6524cba5 100644 --- a/unix/main.c +++ b/unix/main.c @@ -4,18 +4,19 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "lexerunix.h" #include "parse.h" #include "compile.h" -#include "runtime.h" #include "obj.h" +#include "runtime0.h" +#include "runtime.h" #include "repl.h" #include <readline/readline.h> -char *str_join(const char *s1, int sep_char, const char *s2) { +static char *str_join(const char *s1, int sep_char, const char *s2) { int l1 = strlen(s1); int l2 = strlen(s2); char *s = m_new(char, l1 + l2 + 2); @@ -29,14 +30,14 @@ char *str_join(const char *s1, int sep_char, const char *s2) { return s; } -void do_repl(void) { +static void do_repl(void) { for (;;) { char *line = readline(">>> "); if (line == NULL) { // EOF return; } - if (py_repl_is_compound_stmt(line)) { + if (mp_repl_is_compound_stmt(line)) { for (;;) { char *line2 = readline("... "); if (line2 == NULL || strlen(line2) == 0) { @@ -49,23 +50,23 @@ void do_repl(void) { } } - py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", line, strlen(line), false); - py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT); - py_lexer_free(lex); + mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", line, strlen(line), false); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT); + mp_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { - //py_parse_node_show(pn, 0); - bool comp_ok = py_compile(pn, true); + if (pn != MP_PARSE_NODE_NULL) { + //mp_parse_node_show(pn, 0); + bool comp_ok = mp_compile(pn, true); if (comp_ok) { - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != mp_const_none) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { rt_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } @@ -75,32 +76,32 @@ void do_repl(void) { } void do_file(const char *file) { - py_lexer_t *lex = py_lexer_new_from_file(file); + mp_lexer_t *lex = mp_lexer_new_from_file(file); //const char *pysrc = "def f():\n x=x+1\n print(42)\n"; - //py_lexer_t *lex = py_lexer_from_str_len("<>", pysrc, strlen(pysrc), false); + //mp_lexer_t *lex = mp_lexer_from_str_len("<>", pysrc, strlen(pysrc), false); if (lex == NULL) { return; } if (0) { // just tokenise - while (!py_lexer_is_kind(lex, PY_TOKEN_END)) { - py_token_show(py_lexer_cur(lex)); - py_lexer_to_next(lex); + while (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { + mp_token_show(mp_lexer_cur(lex)); + mp_lexer_to_next(lex); } - py_lexer_free(lex); + mp_lexer_free(lex); } else { // compile - py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT); - py_lexer_free(lex); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { + if (pn != MP_PARSE_NODE_NULL) { //printf("----------------\n"); //parse_node_show(pn, 0); //printf("----------------\n"); - bool comp_ok = py_compile(pn, false); + bool comp_ok = mp_compile(pn, false); //printf("----------------\n"); #if MICROPY_EMIT_CPYTHON @@ -110,19 +111,19 @@ void do_file(const char *file) { #else if (1 && comp_ok) { // execute it - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != mp_const_none) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - py_obj_t ret = rt_call_function_0(module_fun); + mp_obj_t ret = rt_call_function_0(module_fun); printf("done! got: "); - py_obj_print(ret); + mp_obj_print(ret); printf("\n"); nlr_pop(); } else { // uncaught exception printf("exception: "); - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } @@ -132,37 +133,58 @@ void do_file(const char *file) { } } -void test_print(py_obj_t o_in) { - printf("<test>"); +typedef struct _test_obj_t { + mp_obj_base_t base; + bool value; +} test_obj_t; + +static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + test_obj_t *self = self_in; + print(env, "<test %d>", self->value); } -py_obj_t test_get(py_obj_t o_in) { - py_obj_t d1; - py_obj_t d2; - py_user_get_data(o_in, (machine_uint_t*)&d1, (machine_uint_t*)&d2); - return d1; +static mp_obj_t test_get(mp_obj_t self_in) { + test_obj_t *self = self_in; + return mp_obj_new_int(self->value); } -py_obj_t test_set(py_obj_t o_in, py_obj_t arg) { - py_user_set_data(o_in, (machine_uint_t)arg, (machine_uint_t)arg); - return py_const_none; +static mp_obj_t test_set(mp_obj_t self_in, mp_obj_t arg) { + test_obj_t *self = self_in; + self->value = mp_obj_get_int(arg); + return mp_const_none; } -const py_user_info_t test_obj_info = { +static MP_DEFINE_CONST_FUN_OBJ_1(test_get_obj, test_get); +static MP_DEFINE_CONST_FUN_OBJ_2(test_set_obj, test_set); + +static const mp_obj_type_t test_type = { + { &mp_const_type }, "Test", - test_print, - { - { "get", 0, test_get }, - { "set", 1, test_set }, - { NULL, 0, NULL }, + test_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "get", &test_get_obj }, + { "set", &test_set_obj }, + { NULL, NULL }, } }; +mp_obj_t test_obj_new(int value) { + test_obj_t *o = m_new_obj(test_obj_t); + o->base.type = &test_type; + o->value = value; + return o; +} + int main(int argc, char **argv) { qstr_init(); rt_init(); - rt_store_name(qstr_from_str_static("test"), py_obj_new_user(&test_obj_info, (machine_uint_t)py_obj_new_int(42), 0)); + rt_store_name(qstr_from_str_static("test"), test_obj_new(42)); if (argc == 1) { do_repl(); diff --git a/unix/mpyconfig.h b/unix/mpconfig.h similarity index 89% rename from unix/mpyconfig.h rename to unix/mpconfig.h index f187cbb4ea3fcae9824958cb856313aa982d5357..a358d7db814afdc66d1df13c4a982521d980f273 100644 --- a/unix/mpyconfig.h +++ b/unix/mpconfig.h @@ -13,6 +13,7 @@ typedef int64_t machine_int_t; // must be pointer size typedef uint64_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 double machine_float_t; machine_float_t machine_sqrt(machine_float_t x);