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); }
mp_lexer_t *mp_import_open_file(qstr mod_name) { vstr_t *vstr = vstr_new(); if (import_base_dir != NULL) { vstr_printf(vstr, "%s/", import_base_dir); } vstr_printf(vstr, "%s.py", qstr_str(mod_name)); return mp_lexer_new_from_file(vstr_str(vstr)); // TODO does lexer need to copy the string? can we free it here? }
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #if MICROPY_MODULE_FROZEN || MICROPY_PERSISTENT_CODE_LOAD || MICROPY_ENABLE_COMPILER char *file_str = vstr_null_terminated_str(file); #endif printf("+++++++++do_load: %s\n",file_str); _do_load = 1; // If we support frozen modules (either as str or mpy) then try to find the // requested filename in the list of frozen module filenames. #if MICROPY_MODULE_FROZEN void *modref; int frozen_type = mp_find_frozen_module(file_str, file->len, &modref); #endif // If we support frozen str modules and the compiler is enabled, and we // found the filename in the list of frozen files, then load and execute it. #if MICROPY_MODULE_FROZEN_STR if (frozen_type == MP_FROZEN_STR) { do_load_from_lexer(module_obj, modref); goto _return; } #endif // If we support frozen mpy modules and we found a corresponding file (and // its data) in the list of frozen files, execute it. #if MICROPY_MODULE_FROZEN_MPY if (frozen_type == MP_FROZEN_MPY) { do_execute_raw_code(module_obj, modref); goto _return; } #endif // If we support loading .mpy files then check if the file extension is of // the correct format and, if so, load and execute the file. #if MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); do_execute_raw_code(module_obj, raw_code); goto _return; } #endif // If we can compile scripts then load the file and compile and execute it. #if MICROPY_ENABLE_COMPILER { mp_lexer_t *lex = mp_lexer_new_from_file(file_str); do_load_from_lexer(module_obj, lex); goto _return; } #else // If we get here then the file was not frozen and we can't compile scripts. mp_raise_msg(&mp_type_ImportError, "script compilation not supported"); #endif _return: _do_load = 0; return; }
int pyexec_file(const char *filename) { mp_lexer_t *lex = mp_lexer_new_from_file(filename); if (lex == NULL) { printf("could not open file '%s' for reading\n", filename); return false; } return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0); }
STATIC int do_file(const char *file) { struct stat st; stat(file, &st); if (!S_ISREG(st.st_mode)) { init_console(); printf("Could not locate \"%s\"\n", file); return ERR_FILE_NOT_FOUND; } mp_lexer_t *lex = mp_lexer_new_from_file(file); return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false); }
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { // create the lexer char *file_str = vstr_null_terminated_str(file); #if MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); do_execute_raw_code(module_obj, raw_code); } else #endif { mp_lexer_t *lex = mp_lexer_new_from_file(file_str); do_load_from_lexer(module_obj, lex, file_str); } }
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"); } } } }
STATIC int compile_and_save(const char *file, const char *output_file, const char *source_file) { mp_lexer_t *lex = mp_lexer_new_from_file(file); if (lex == NULL) { printf("could not open file '%s' for reading\n", file); return 1; } nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { qstr source_name; if (source_file == NULL) { source_name = lex->source_name; } else { source_name = qstr_from_str(source_file); } #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, MP_PARSE_FILE_INPUT); mp_raw_code_t *rc = mp_compile_to_raw_code(&parse_tree, source_name, emit_opt, false); vstr_t vstr; vstr_init(&vstr, 16); if (output_file == NULL) { vstr_add_str(&vstr, file); vstr_cut_tail_bytes(&vstr, 2); vstr_add_str(&vstr, "mpy"); } else { vstr_add_str(&vstr, output_file); } mp_raw_code_save_file(rc, vstr_null_terminated_str(&vstr)); vstr_clear(&vstr); nlr_pop(); return 0; } else { // uncaught exception mp_obj_print_exception(&mp_stderr_print, (mp_obj_t)nlr.ret_val); return 1; } }
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))); } #if MICROPY_PY___FILE__ qstr source_name = mp_lexer_source_name(lex); mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif // parse, compile and execute the module in its context mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj); mp_parse_compile_execute(lex, MP_PARSE_FILE_INPUT, mod_globals, mod_globals); }
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_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); } } } }
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_ENABLE_COMPILER char *file_str = vstr_null_terminated_str(file); #endif #if MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); do_execute_raw_code(module_obj, raw_code); return; } #endif #if MICROPY_ENABLE_COMPILER { mp_lexer_t *lex = mp_lexer_new_from_file(file_str); do_load_from_lexer(module_obj, lex, file_str); } #else nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "script compilation not supported")); #endif }
STATIC int do_file(const char *file) { mp_lexer_t *lex = mp_lexer_new_from_file(file); return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false); }
STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { // create the lexer char *file_str = vstr_null_terminated_str(file); mp_lexer_t *lex = mp_lexer_new_from_file(file_str); do_load_from_lexer(module_obj, lex, file_str); }
// 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; }
int do_file(const char *file, uint emit_opt) { mp_lexer_t *lex = mp_lexer_new_from_file(file); return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, emit_opt, false); }
// 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; }