STATIC mp_obj_t parse_compile_execute(mp_obj_t o_in, mp_parse_input_kind_t parse_input_kind) { uint str_len; const char *str = mp_obj_str_get_data(o_in, &str_len); // create the lexer mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, str, str_len, 0); qstr source_name = mp_lexer_source_name(lex); // parse the string mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_error_kind); mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; raise exception nlr_jump(mp_parse_make_exception(parse_error_kind)); } // compile the string mp_obj_t module_fun = mp_compile(pn, source_name, false); mp_parse_node_free(pn); if (module_fun == mp_const_none) { // TODO handle compile error correctly return mp_const_none; } // complied successfully, execute it return rt_call_function_0(module_fun); }
static mp_obj_t mp_builtin_eval(mp_obj_t o_in) { uint str_len; const byte *str = mp_obj_str_get_data(o_in, &str_len); // create the lexer mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, (const char*)str, str_len, 0); qstr source_name = mp_lexer_source_name(lex); // parse the string qstr parse_exc_id; const char *parse_exc_msg; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_EVAL_INPUT, &parse_exc_id, &parse_exc_msg); mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; raise exception nlr_jump(mp_obj_new_exception_msg(parse_exc_id, parse_exc_msg)); } // compile the string mp_obj_t module_fun = mp_compile(pn, source_name, false); mp_parse_node_free(pn); if (module_fun == mp_const_none) { // TODO handle compile error correctly return mp_const_none; } // complied successfully, execute it return rt_call_function_0(module_fun); }
// Returns standard error codes: 0 for success, 1 for all other errors, // except if FORCED_EXIT bit is set then script raised SystemExit and the // value of the exit is in the lower 8 bits of the return value STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) { if (lex == NULL) { printf("MemoryError: lexer could not allocate memory\n"); return 1; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; #if MICROPY_PY___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } #endif mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, emit_opt, is_repl); if (!compile_only) { // execute it mp_call_function_0(module_fun); } nlr_pop(); return 0; } else { // uncaught exception return handle_uncaught_exception((mp_obj_t)nlr.ret_val); } }
inline void do_str(const char *src) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { tt_abort_msg("Lexer initialization error"); } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true); mp_call_function_0(module_fun); nlr_pop(); } else { mp_obj_t exc = (mp_obj_t)nlr.ret_val; if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) { // Assume that sys.exit() is called to skip the test. // TODO: That can be always true, we should set up convention to // use specific exit code as skip indicator. tinytest_set_test_skipped_(); return; } mp_obj_print_exception(&mp_plat_print, exc); tt_abort_msg("Uncaught exception"); } end: ; }
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { // create the lexer mp_lexer_t *lex = mp_lexer_new_from_file(vstr_str(file)); if (lex == NULL) { // we verified the file exists using stat, but lexer could still fail nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", vstr_str(file))); } qstr source_name = mp_lexer_source_name(lex); // save the old context mp_obj_dict_t *old_locals = mp_locals_get(); mp_obj_dict_t *old_globals = mp_globals_get(); // set the new context mp_locals_set(mp_obj_module_get_globals(module_obj)); mp_globals_set(mp_obj_module_get_globals(module_obj)); // parse the imported script mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { // parse error; clean up and raise exception mp_obj_t exc = mp_parse_make_exception(lex, parse_error_kind); mp_lexer_free(lex); mp_locals_set(old_locals); mp_globals_set(old_globals); nlr_raise(exc); } mp_lexer_free(lex); // compile the imported script mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_parse_node_free(pn); if (module_fun == mp_const_none) { // TODO handle compile error correctly mp_locals_set(old_locals); mp_globals_set(old_globals); nlr_raise(mp_obj_new_exception_msg(&mp_type_SyntaxError, "Syntax error in imported module")); } // complied successfully, execute it nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_0(module_fun); nlr_pop(); } else { // exception; restore context and re-raise same exception mp_locals_set(old_locals); mp_globals_set(old_globals); nlr_raise(nlr.ret_val); } mp_locals_set(old_locals); mp_globals_set(old_globals); }
// Returns standard error codes: 0 for success, 1 for all other errors, // except if FORCED_EXIT bit is set then script raised SystemExit and the // value of the exit is in the lower 8 bits of the return value STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) { if (lex == NULL) { printf("MemoryError: lexer could not allocate memory\n"); return 1; } #ifndef _WIN32 // enable signal handler struct sigaction sa; sa.sa_handler = sighandler; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sa.sa_handler = SIG_DFL; #endif nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; #if MICROPY_PY___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } #endif mp_parse_node_t pn = mp_parse(lex, input_kind); /* printf("----------------\n"); mp_parse_node_print(pn, 0); printf("----------------\n"); */ mp_obj_t module_fun = mp_compile(pn, source_name, emit_opt, is_repl); if (!compile_only) { // execute it mp_call_function_0(module_fun); } #ifndef _WIN32 // disable signal handler sigaction(SIGINT, &sa, NULL); #endif nlr_pop(); return 0; } else { // uncaught exception #ifndef _WIN32 // disable signal handler sigaction(SIGINT, &sa, NULL); #endif return handle_uncaught_exception((mp_obj_t)nlr.ret_val); } }
STATIC void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) { if (lex == NULL) { return; } if (0) { // just tokenise while (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { mp_token_show(mp_lexer_cur(lex)); mp_lexer_to_next(lex); } mp_lexer_free(lex); return; } mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); return; } qstr source_name = mp_lexer_source_name(lex); mp_lexer_free(lex); /* printf("----------------\n"); mp_parse_node_print(pn, 0); printf("----------------\n"); */ mp_obj_t module_fun = mp_compile(pn, source_name, emit_opt, is_repl); if (module_fun == mp_const_none) { // compile error return; } if (compile_only) { return; } // execute it nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception mp_obj_print_exception((mp_obj_t)nlr.ret_val); } }
mp_obj_t execute_from_str(const char *str) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false); mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false); mp_call_function_0(module_fun); nlr_pop(); return 0; } else { // uncaught exception return (mp_obj_t)nlr.ret_val; } }
// Returns standard error codes: 0 for success, 1 for all other errors, // except if FORCED_EXIT bit is set then script raised SystemExit and the // value of the exit is in the lower 8 bits of the return value STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) { if (lex == NULL) { printf("MemoryError: lexer could not allocate memory\n"); return 1; } mp_hal_set_interrupt_char(CHAR_CTRL_C); nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; #if MICROPY_PY___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } #endif mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); /* printf("----------------\n"); mp_parse_node_print(parse_tree.root, 0); printf("----------------\n"); */ mp_obj_t module_fun = mp_compile(&parse_tree, source_name, emit_opt, is_repl); if (!compile_only) { // execute it mp_call_function_0(module_fun); // check for pending exception if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) { mp_obj_t obj = MP_STATE_VM(mp_pending_exception); MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; nlr_raise(obj); } } mp_hal_set_interrupt_char(-1); nlr_pop(); return 0; } else { // uncaught exception mp_hal_set_interrupt_char(-1); return handle_uncaught_exception(nlr.ret_val); } }
void do_file(const char *file) { mp_lexer_t *lex = mp_lexer_new_from_file(file); if (lex == NULL) { return; } if (0) { // just tokenise while (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { mp_token_show(mp_lexer_cur(lex)); mp_lexer_to_next(lex); } mp_lexer_free(lex); } else { // parse qstr parse_exc_id; const char *parse_exc_msg; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_lexer_show_error_pythonic_prefix(lex); printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg); mp_lexer_free(lex); return; } mp_lexer_free(lex); if (pn != MP_PARSE_NODE_NULL) { //printf("----------------\n"); //mp_parse_node_print(pn, 0); //printf("----------------\n"); // compile mp_obj_t module_fun = mp_compile(pn, 0, false); //printf("----------------\n"); if (module_fun == mp_const_none) { printf("compile error\n"); } } } }
void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { return; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); mp_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } }
void do_str(const char *src, mp_parse_input_kind_t input_kind) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false); mp_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) { // at the moment, the value of SystemExit is unused } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } } }
void do_file(const char *file) { mp_lexer_t *lex = mp_lexer_new_from_file(file); if (lex == NULL) { return; } if (0) { // just tokenise while (lex->tok_kind != MP_TOKEN_END) { mp_lexer_show_token(lex); mp_lexer_to_next(lex); } mp_lexer_free(lex); } else { // parse mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); return; } mp_lexer_free(lex); if (pn != MP_PARSE_NODE_NULL) { //printf("----------------\n"); //mp_parse_node_print(pn, 0); //printf("----------------\n"); // compile mp_obj_t module_fun = mp_compile(pn, 0, MP_EMIT_OPT_NONE, false); //printf("----------------\n"); if (mp_obj_is_exception_instance(module_fun)) { mp_obj_print_exception(module_fun); } } } }
void do_file(const char *file) { mp_lexer_t *lex = mp_lexer_new_from_file(file); if (lex == NULL) { return; } if (0) { // just tokenise while (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { mp_token_show(mp_lexer_cur(lex)); mp_lexer_to_next(lex); } mp_lexer_free(lex); } else { // parse mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); return; } mp_lexer_free(lex); if (pn != MP_PARSE_NODE_NULL) { //printf("----------------\n"); //mp_parse_node_print(pn, 0); //printf("----------------\n"); // compile mp_obj_t module_fun = mp_compile(pn, 0, false); //printf("----------------\n"); if (module_fun == mp_const_none) { printf("compile error\n"); } } } }
void do_str(const char *src) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { printf("MemoryError: lexer could not allocate memory\n"); return; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true); mp_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } }
STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t kind, bool repl) { if (lex == NULL) { init_console(); printf("MemoryError: lexer could not allocate memory\n"); return ERR_MEMORY_ALLOC; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; if (kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } mp_parse_tree_t parse_tree = mp_parse(lex, kind); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, repl); mp_call_function_0(module_fun); if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) { mp_obj_t obj = MP_STATE_VM(mp_pending_exception); MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; nlr_raise(obj); } nlr_pop(); return 0; } else { if (mp_obj_exception_match(nlr.ret_val, &mp_type_SystemExit)) { return ERR_SYS_EXIT; } if (mp_obj_is_exception_type(nlr.ret_val) && ((mp_obj_exception_t *) nlr.ret_val)->args != NULL && ((mp_obj_exception_t *) nlr.ret_val)->args->len == 1) { int code = mp_obj_get_int(((mp_obj_exception_t *) nlr.ret_val)->args->items[0]); if (code == 0xDEAD0000) { return ERR_NETLOAD; } } init_console(); mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); return ERR_PARSE; } }
void do_strn(const char *src, size_t len) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR___main__, src, len, 0); if (lex == NULL) { printf("MemoryError: lexer could not allocate memory\n"); return; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false); mp_hal_set_interrupt_char(3); // allow ctrl-C to interrupt us mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); } else { // uncaught exception mp_hal_set_interrupt_char(-1); // disable interrupt mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); microbit_display_exception(nlr.ret_val); } }
void do_str(const char *src) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { return; } mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); return; } // parse okay qstr source_name = mp_lexer_source_name(lex); mp_lexer_free(lex); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true); if (mp_obj_is_exception_instance(module_fun)) { // compile error mp_obj_print_exception(module_fun); return; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception mp_obj_print_exception((mp_obj_t)nlr.ret_val); } }
static int py_compile(py_handle_t* py, const char* s) { static const mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT; static const uint emit_opt = MP_EMIT_OPT_NATIVE_PYTHON; nlr_buf_t nlr; int err = -1; if (nlr_push(&nlr)) return -1; py->lex = mp_lexer_new_from_str_len (MP_QSTR__lt_stdin_gt_, s, strlen(s), false); if (py->lex == NULL) goto on_error_0; py->parse_tree = mp_parse(py->lex, input_kind); py->module_fun = mp_compile (&py->parse_tree, py->lex->source_name, emit_opt, false); err = 0; on_error_0: nlr_pop(); return err; }
inline void do_str(const char *src) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { tt_abort_msg("Lexer initialization error"); } mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); tt_abort_msg("Parser error"); } // parse okay qstr source_name = mp_lexer_source_name(lex); mp_lexer_free(lex); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true); mp_parse_node_free(pn); if (module_fun == mp_const_none) { tt_abort_msg("Computer error"); } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_0(module_fun); nlr_pop(); } else { mp_obj_print_exception((mp_obj_t)nlr.ret_val); tt_abort_msg("Uncaught exception"); } end: ; }
// parses, compiles and executes the code in the lexer // frees the lexer before returning // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile) STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) { int ret = 0; uint32_t start = 0; // by default a SystemExit exception returns 0 pyexec_system_exit = 0; nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_obj_t module_fun; #if MICROPY_MODULE_FROZEN_MPY if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) { // source is a raw_code object, create the function module_fun = mp_make_function_from_raw_code(source, MP_OBJ_NULL, MP_OBJ_NULL); } else #endif { #if MICROPY_ENABLE_COMPILER mp_lexer_t *lex; if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) { const vstr_t *vstr = source; lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0); } else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) { lex = mp_lexer_new_from_file(source); } else { lex = (mp_lexer_t*)source; } // source is a lexer, parse and compile the script qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL); #else mp_raise_msg(&mp_type_RuntimeError, "script compilation not supported"); #endif } // execute code mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us start = mp_hal_ticks_ms(); mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); ret = 1; if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } } else { // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here mp_hal_set_interrupt_char(-1); // disable interrupt // print EOF after normal output if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } // check for SystemExit if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) { // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); ret = 0; } } // display debugging info if wanted if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) { mp_uint_t ticks = mp_hal_ticks_ms() - start; // TODO implement a function that does this properly printf("took " UINT_FMT " ms\n", ticks); // qstr info { size_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes; qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n " "n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", (unsigned)n_pool, (unsigned)n_qstr, (unsigned)n_str_data_bytes, (unsigned)n_total_bytes); } #if MICROPY_ENABLE_GC // run collection and print GC info gc_collect(); gc_dump_info(); #endif } if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } return ret; }
// parses, compiles and executes the code in the lexer // frees the lexer before returning // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile) STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) { int ret = 0; // by default a SystemExit exception returns 0 pyexec_system_exit = 0; nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_obj_t module_fun; #if MICROPY_MODULE_FROZEN_MPY if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) { // source is a raw_code object, create the function module_fun = mp_make_function_from_raw_code(source, MP_OBJ_NULL, MP_OBJ_NULL); } else #endif { #if MICROPY_ENABLE_COMPILER mp_lexer_t *lex; if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) { const vstr_t *vstr = source; lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0); } else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) { lex = mp_lexer_new_from_file(source); } else { lex = (mp_lexer_t*)source; } // source is a lexer, parse and compile the script qstr source_name = lex->source_name; mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL); #else mp_raise_msg(&mp_type_RuntimeError, "script compilation not supported"); #endif } // execute code mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); ret = 1; if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } } else { // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here mp_hal_set_interrupt_char(-1); // disable interrupt // print EOF after normal output if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } // check for SystemExit if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) { // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); ret = 0; } } if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } return ret; }
// parses, compiles and executes the code in the lexer // frees the lexer before returning // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile) STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, int exec_flags) { int ret = 0; uint32_t start = 0; nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { // parse and compile the script qstr source_name = lex->source_name; mp_parse_node_t pn = mp_parse(lex, input_kind); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL); // execute code mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us start = HAL_GetTick(); mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); ret = 1; if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } } else { // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here mp_hal_set_interrupt_char(-1); // disable interrupt // print EOF after normal output if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } // check for SystemExit if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) { // at the moment, the value of SystemExit is unused ret = PYEXEC_FORCED_EXIT; } else { mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val); ret = 0; } } // display debugging info if wanted if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) { mp_uint_t ticks = HAL_GetTick() - start; // TODO implement a function that does this properly printf("took " UINT_FMT " ms\n", ticks); gc_collect(); // qstr info { mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes; qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes); } // GC info gc_dump_info(); } if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } return ret; }
// parses, compiles and executes the code in the lexer // frees the lexer before returning bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) { mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind); qstr source_name = mp_lexer_source_name(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); return false; } mp_lexer_free(lex); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, is_repl); if (mp_obj_is_exception_instance(module_fun)) { mp_obj_print_exception(module_fun); return false; } nlr_buf_t nlr; bool ret; uint32_t start = HAL_GetTick(); if (nlr_push(&nlr) == 0) { usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); // allow ctrl-C to interrupt us mp_call_function_0(module_fun); usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt nlr_pop(); ret = true; } else { // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt mp_obj_print_exception((mp_obj_t)nlr.ret_val); ret = false; } // display debugging info if wanted if (is_repl && repl_display_debugging_info) { uint32_t ticks = HAL_GetTick() - start; // TODO implement a function that does this properly printf("took %lu ms\n", ticks); gc_collect(); // qstr info { mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes; qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes); } // GC info { gc_info_t info; gc_info(&info); printf("GC:\n"); printf(" " UINT_FMT " total\n", info.total); printf(" " UINT_FMT " : " UINT_FMT "\n", info.used, info.free); printf(" 1=" UINT_FMT " 2=" UINT_FMT " m=" UINT_FMT "\n", info.num_1block, info.num_2block, info.max_block); } } return ret; }
// parses, compiles and executes the code in the lexer // frees the lexer before returning // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile) STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, int exec_flags) { int ret = 0; mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind); qstr source_name = mp_lexer_source_name(lex); // check for parse error if (pn == MP_PARSE_NODE_NULL) { if (exec_flags & EXEC_FLAG_PRINT_EOF) { stdout_tx_strn("\x04", 1); } mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); goto finish; } mp_lexer_free(lex); mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL); // check for compile error if (mp_obj_is_exception_instance(module_fun)) { if (exec_flags & EXEC_FLAG_PRINT_EOF) { stdout_tx_strn("\x04", 1); } mp_obj_print_exception(module_fun); goto finish; } // execute code nlr_buf_t nlr; uint32_t start = HAL_GetTick(); if (nlr_push(&nlr) == 0) { mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us mp_call_function_0(module_fun); mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); ret = 1; if (exec_flags & EXEC_FLAG_PRINT_EOF) { stdout_tx_strn("\x04", 1); } } else { // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here mp_hal_set_interrupt_char(-1); // disable interrupt // print EOF after normal output if (exec_flags & EXEC_FLAG_PRINT_EOF) { stdout_tx_strn("\x04", 1); } // check for SystemExit if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) { // at the moment, the value of SystemExit is unused ret = PYEXEC_FORCED_EXIT; } else { mp_obj_print_exception((mp_obj_t)nlr.ret_val); ret = 0; } } // display debugging info if wanted if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) { mp_uint_t ticks = HAL_GetTick() - start; // TODO implement a function that does this properly printf("took " UINT_FMT " ms\n", ticks); gc_collect(); // qstr info { mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes; qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes); } // GC info { gc_info_t info; gc_info(&info); printf("GC:\n"); printf(" " UINT_FMT " total\n", info.total); printf(" " UINT_FMT " : " UINT_FMT "\n", info.used, info.free); printf(" 1=" UINT_FMT " 2=" UINT_FMT " m=" UINT_FMT "\n", info.num_1block, info.num_2block, info.max_block); } } finish: if (exec_flags & EXEC_FLAG_PRINT_EOF) { stdout_tx_strn("\x04", 1); } return ret; }
int main(void) { // Stack limit should be less than real stack size, so we // had chance to recover from limit hit. mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024); /* STM32F4xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); // basic sub-system init pendsv_init(); timer_tim3_init(); led_init(); soft_reset: // check if user switch held to select the reset mode led_state(LED_RED, 1); led_state(LED_GREEN, 1); led_state(LED_BLUE, 1); #if MICROPY_HW_ENABLE_RTC rtc_init(); #endif // GC init gc_init(&_heap_start, &_heap_end); // Micro Python init mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_init(mp_sys_argv, 0); readline_init0(); pin_init0(); extint_init0(); timer_init0(); rng_init0(); i2c_init0(); spi_init0(); uart_init0(); pyb_usb_init0(); usbdbg_init(); if (sensor_init() != 0) { __fatal_error("Failed to init sensor"); } /* Export functions to the global python namespace */ mp_store_global(qstr_from_str("randint"), (mp_obj_t)&py_randint_obj); mp_store_global(qstr_from_str("cpu_freq"), (mp_obj_t)&py_cpu_freq_obj); mp_store_global(qstr_from_str("Image"), (mp_obj_t)&py_image_load_image_obj); mp_store_global(qstr_from_str("HaarCascade"), (mp_obj_t)&py_image_load_cascade_obj); mp_store_global(qstr_from_str("FreakDesc"), (mp_obj_t)&py_image_load_descriptor_obj); mp_store_global(qstr_from_str("FreakDescSave"), (mp_obj_t)&py_image_save_descriptor_obj); mp_store_global(qstr_from_str("LBPDesc"), (mp_obj_t)&py_image_load_lbp_obj); mp_store_global(qstr_from_str("vcp_is_connected"), (mp_obj_t)&py_vcp_is_connected_obj); if (sdcard_is_present()) { sdcard_init(); FRESULT res = f_mount(&fatfs, "1:", 1); if (res != FR_OK) { __fatal_error("could not mount SD\n"); } // Set CWD and USB medium to SD f_chdrive("1:"); pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_SDCARD; } else { storage_init(); // try to mount the flash FRESULT res = f_mount(&fatfs, "0:", 1); if (res == FR_NO_FILESYSTEM) { // create a fresh fs make_flash_fs(); } else if (res != FR_OK) { __fatal_error("could not access LFS\n"); } // Set CWD and USB medium to flash f_chdrive("0:"); pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_FLASH; } // turn boot-up LEDs off led_state(LED_RED, 0); led_state(LED_GREEN, 0); led_state(LED_BLUE, 0); // init USB device to default setting if it was not already configured if (!(pyb_usb_flags & PYB_USB_FLAG_USB_MODE_CALLED)) { pyb_usb_dev_init(USBD_VID, USBD_PID_CDC_MSC, USBD_MODE_CDC_MSC, NULL); } // Run the main script from the current directory. FRESULT res = f_stat("main.py", NULL); if (res == FR_OK) { if (!pyexec_file("main.py")) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { flash_error(3); nlr_pop(); } } } // Enter REPL nlr_buf_t nlr; for (;;) { if (nlr_push(&nlr) == 0) { while (usbdbg_script_ready()) { nlr_buf_t nlr; vstr_t *script_buf = usbdbg_get_script(); // clear script flag usbdbg_clr_script(); // execute the script if (nlr_push(&nlr) == 0) { pyexec_push_scope(); // parse and compile script mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(script_buf), vstr_len(script_buf), 0); mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_obj_t script = mp_compile(pn, lex->source_name, MP_EMIT_OPT_NONE, false); // execute the script mp_call_function_0(script); nlr_pop(); } else { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } pyexec_pop_scope(); } // clear script flag usbdbg_clr_script(); // no script run REPL pyexec_friendly_repl(); nlr_pop(); } } printf("PYB: sync filesystems\n"); storage_flush(); printf("PYB: soft reboot\n"); goto soft_reset; }
// returns standard error codes: 0 for success, 1 for all other errors STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) { if (lex == NULL) { return 1; } if (0) { // just tokenise while (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { mp_token_show(mp_lexer_cur(lex)); mp_lexer_to_next(lex); } mp_lexer_free(lex); return 0; } mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind); if (pn == MP_PARSE_NODE_NULL) { // parse error mp_parse_show_exception(lex, parse_error_kind); mp_lexer_free(lex); return 1; } qstr source_name = mp_lexer_source_name(lex); #if MICROPY_PY___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } #endif mp_lexer_free(lex); /* printf("----------------\n"); mp_parse_node_print(pn, 0); printf("----------------\n"); */ mp_obj_t module_fun = mp_compile(pn, source_name, emit_opt, is_repl); if (module_fun == mp_const_none) { // compile error return 1; } if (compile_only) { return 0; } // execute it nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_0(module_fun); nlr_pop(); return 0; } else { // uncaught exception // check for SystemExit mp_obj_t exc = (mp_obj_t)nlr.ret_val; if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) { mp_obj_t exit_val = mp_obj_exception_get_value(exc); mp_int_t val; if (!mp_obj_get_int_maybe(exit_val, &val)) { val = 0; } exit(val); } mp_obj_print_exception((mp_obj_t)nlr.ret_val); return 1; } }