diff options
25 files changed, 59 insertions, 89 deletions
diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 81751bf0f..70e4f3391 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -220,6 +220,7 @@ SRC_C += \ SHARED_SRC_C += $(addprefix shared/,\ runtime/gchelper_generic.c \ + runtime/pyexec.c \ timeutils/timeutils.c \ $(SHARED_SRC_C_EXTRA) \ ) diff --git a/ports/unix/main.c b/ports/unix/main.c index db50e12f5..1c5c2266a 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -55,6 +55,7 @@ #include "genhdr/mpversion.h" #include "input.h" #include "stack_size.h" +#include "shared/runtime/pyexec.h" // Command line options, with their defaults static bool compile_only = false; @@ -195,95 +196,34 @@ static char *strjoin(const char *s1, int sep_char, const char *s2) { #endif static int do_repl(void) { - mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION); - mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE); - mp_hal_stdout_tx_str("\nUse Ctrl-D to exit, Ctrl-E for paste mode\n"); - #if MICROPY_USE_READLINE == 1 - // use MicroPython supplied readline + // use MicroPython supplied readline-based REPL - vstr_t line; - vstr_init(&line, 16); + int ret = 0; + mp_hal_stdio_mode_raw(); for (;;) { - mp_hal_stdio_mode_raw(); - - input_restart: - // If the GC is locked at this point there is no way out except a reset, - // so force the GC to be unlocked to help the user debug what went wrong. - MP_STATE_THREAD(gc_lock_depth) = 0; - vstr_reset(&line); - int ret = readline(&line, mp_repl_get_ps1()); - mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT; - - if (ret == CHAR_CTRL_C) { - // cancel input - mp_hal_stdout_tx_str("\r\n"); - goto input_restart; - } else if (ret == CHAR_CTRL_D) { - // EOF - printf("\n"); - mp_hal_stdio_mode_orig(); - vstr_clear(&line); - return 0; - } else if (ret == CHAR_CTRL_E) { - // paste mode - mp_hal_stdout_tx_str("\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\n=== "); - vstr_reset(&line); - for (;;) { - char c = mp_hal_stdin_rx_chr(); - if (c == CHAR_CTRL_C) { - // cancel everything - mp_hal_stdout_tx_str("\n"); - goto input_restart; - } else if (c == CHAR_CTRL_D) { - // end of input - mp_hal_stdout_tx_str("\n"); - break; - } else { - // add char to buffer and echo - vstr_add_byte(&line, c); - if (c == '\r') { - mp_hal_stdout_tx_str("\n=== "); - } else { - mp_hal_stdout_tx_strn(&c, 1); - } - } - } - parse_input_kind = MP_PARSE_FILE_INPUT; - } else if (line.len == 0) { - if (ret != 0) { - printf("\n"); + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if ((ret = pyexec_raw_repl()) != 0) { + break; } - goto input_restart; } else { - // got a line with non-zero length, see if it needs continuing - while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) { - vstr_add_byte(&line, '\n'); - ret = readline(&line, mp_repl_get_ps2()); - if (ret == CHAR_CTRL_C) { - // cancel everything - printf("\n"); - goto input_restart; - } else if (ret == CHAR_CTRL_D) { - // stop entering compound statement - break; - } + if ((ret = pyexec_friendly_repl()) != 0) { + break; } } - - mp_hal_stdio_mode_orig(); - - ret = execute_from_lexer(LEX_SRC_VSTR, &line, parse_input_kind, true); - if (ret & FORCED_EXIT) { - return ret; - } } + mp_hal_stdio_mode_orig(); + return ret; #else // use simple readline + mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION); + mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE); + mp_hal_stdout_tx_str("\nUse Ctrl-D to exit, Ctrl-E for paste mode\n"); + for (;;) { char *line = prompt((char *)mp_repl_get_ps1()); if (line == NULL) { diff --git a/ports/windows/Makefile b/ports/windows/Makefile index 9eee98cdd..4129b7fe2 100644 --- a/ports/windows/Makefile +++ b/ports/windows/Makefile @@ -83,6 +83,7 @@ OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) ifeq ($(MICROPY_USE_READLINE),1) CFLAGS += -DMICROPY_USE_READLINE=1 SRC_C += shared/readline/readline.c +SRC_C += shared/runtime/pyexec.c endif LIB += -lws2_32 diff --git a/ports/windows/micropython.vcxproj b/ports/windows/micropython.vcxproj index 9326f3f4c..f8bbec82c 100644 --- a/ports/windows/micropython.vcxproj +++ b/ports/windows/micropython.vcxproj @@ -89,6 +89,7 @@ <ClCompile Include="@(PyExtModSource)" /> <ClCompile Include="$(PyBaseDir)shared\readline\*.c" /> <ClCompile Include="$(PyBaseDir)shared\runtime\gchelper_generic.c" /> + <ClCompile Include="$(PyBaseDir)shared\runtime\pyexec.c" /> <ClCompile Include="$(PyBaseDir)ports\windows\*.c" /> <ClCompile Include="$(PyBaseDir)ports\windows\msvc\*.c" /> <ClCompile Include="$(PyBaseDir)ports\unix\gccollect.c"/> diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index cf17bd0dc..237a6f9df 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -37,6 +37,7 @@ #include "py/mphal.h" #include "shared/readline/readline.h" #include "shared/runtime/pyexec.h" +#include "extmod/modplatform.h" #include "genhdr/mpversion.h" pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; @@ -103,6 +104,14 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input // 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); + #if defined(MICROPY_UNIX_COVERAGE) + // allow to print the parse tree in the coverage build + if (mp_verbose_flag >= 3) { + printf("----------------\n"); + mp_parse_node_print(&mp_plat_print, parse_tree.root, 0); + printf("----------------\n"); + } + #endif module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL); #else mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("script compilation not supported")); diff --git a/tests/cmdline/cmd_sys_exit_0.py b/tests/cmdline/cmd_sys_exit_0.py new file mode 100644 index 000000000..1294b739e --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_0.py @@ -0,0 +1,5 @@ +# cmdline: +# test sys.exit(0) - success exit code +import sys + +sys.exit(0) diff --git a/tests/cmdline/cmd_sys_exit_0.py.exp b/tests/cmdline/cmd_sys_exit_0.py.exp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_0.py.exp @@ -0,0 +1 @@ + diff --git a/tests/cmdline/cmd_sys_exit_error.py b/tests/cmdline/cmd_sys_exit_error.py new file mode 100644 index 000000000..ecac15e94 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_error.py @@ -0,0 +1,5 @@ +# cmdline: +# test sys.exit() functionality and exit codes +import sys + +sys.exit(123) diff --git a/tests/cmdline/cmd_sys_exit_error.py.exp b/tests/cmdline/cmd_sys_exit_error.py.exp new file mode 100644 index 000000000..3911f71d6 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_error.py.exp @@ -0,0 +1 @@ +CRASH
\ No newline at end of file diff --git a/tests/cmdline/cmd_sys_exit_none.py b/tests/cmdline/cmd_sys_exit_none.py new file mode 100644 index 000000000..66e196665 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_none.py @@ -0,0 +1,5 @@ +# cmdline: +# test sys.exit(None) - should exit with code 0 +import sys + +sys.exit(None) diff --git a/tests/cmdline/cmd_sys_exit_none.py.exp b/tests/cmdline/cmd_sys_exit_none.py.exp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_none.py.exp @@ -0,0 +1 @@ + diff --git a/tests/cmdline/repl_autocomplete.py.exp b/tests/cmdline/repl_autocomplete.py.exp index 75002985e..8cf71bb44 100644 --- a/tests/cmdline/repl_autocomplete.py.exp +++ b/tests/cmdline/repl_autocomplete.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # tests for autocompletion >>> import sys >>> not_exist.[K[K[K[K[K[K[K[K[K[K diff --git a/tests/cmdline/repl_autocomplete_underscore.py.exp b/tests/cmdline/repl_autocomplete_underscore.py.exp index 35617554f..f9720ef23 100644 --- a/tests/cmdline/repl_autocomplete_underscore.py.exp +++ b/tests/cmdline/repl_autocomplete_underscore.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use Ctrl-D to exit, Ctrl-E for paste mode +Type "help()" for more information. >>> # Test REPL autocompletion filtering of underscore attributes >>> >>> # Start paste mode diff --git a/tests/cmdline/repl_autoindent.py.exp b/tests/cmdline/repl_autoindent.py.exp index 9127a7d31..f45bf840f 100644 --- a/tests/cmdline/repl_autoindent.py.exp +++ b/tests/cmdline/repl_autoindent.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # tests for autoindent >>> if 1: ... print(1) diff --git a/tests/cmdline/repl_basic.py.exp b/tests/cmdline/repl_basic.py.exp index 2b390ea98..a19068474 100644 --- a/tests/cmdline/repl_basic.py.exp +++ b/tests/cmdline/repl_basic.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # basic REPL tests >>> print(1) 1 diff --git a/tests/cmdline/repl_cont.py.exp b/tests/cmdline/repl_cont.py.exp index 834c18a4d..d0d20adc4 100644 --- a/tests/cmdline/repl_cont.py.exp +++ b/tests/cmdline/repl_cont.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # check REPL allows to continue input >>> 1 \\\\ ... + 2 diff --git a/tests/cmdline/repl_emacs_keys.py.exp b/tests/cmdline/repl_emacs_keys.py.exp index 6102c1963..b8b7b794f 100644 --- a/tests/cmdline/repl_emacs_keys.py.exp +++ b/tests/cmdline/repl_emacs_keys.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # REPL tests of GNU-ish readline navigation >>> # history buffer navigation >>> 1 diff --git a/tests/cmdline/repl_inspect.py.exp b/tests/cmdline/repl_inspect.py.exp index 051acfd15..89ae14201 100644 --- a/tests/cmdline/repl_inspect.py.exp +++ b/tests/cmdline/repl_inspect.py.exp @@ -1,6 +1,6 @@ test MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # cmdline: -i -c print("test") >>> # -c option combined with -i option results in REPL >>> diff --git a/tests/cmdline/repl_lock.py.exp b/tests/cmdline/repl_lock.py.exp index 7cce24f6c..d921fd6ae 100644 --- a/tests/cmdline/repl_lock.py.exp +++ b/tests/cmdline/repl_lock.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> import micropython >>> micropython.heap_lock() >>> 1+1 diff --git a/tests/cmdline/repl_micropyinspect.py.exp b/tests/cmdline/repl_micropyinspect.py.exp index 93ff43546..504bb07d7 100644 --- a/tests/cmdline/repl_micropyinspect.py.exp +++ b/tests/cmdline/repl_micropyinspect.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # cmdline: cmdline/repl_micropyinspect >>> # setting MICROPYINSPECT environment variable before program exit triggers REPL >>> diff --git a/tests/cmdline/repl_paste.py.exp b/tests/cmdline/repl_paste.py.exp index 22d9bd574..2b837f85c 100644 --- a/tests/cmdline/repl_paste.py.exp +++ b/tests/cmdline/repl_paste.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use Ctrl-D to exit, Ctrl-E for paste mode +Type "help()" for more information. >>> # Test REPL paste mode functionality >>> >>> # Basic paste mode with a simple function diff --git a/tests/cmdline/repl_sys_ps1_ps2.py.exp b/tests/cmdline/repl_sys_ps1_ps2.py.exp index 9e82db5e3..6781660bf 100644 --- a/tests/cmdline/repl_sys_ps1_ps2.py.exp +++ b/tests/cmdline/repl_sys_ps1_ps2.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # test changing ps1/ps2 >>> import sys >>> sys.ps1 = "PS1" diff --git a/tests/cmdline/repl_words_move.py.exp b/tests/cmdline/repl_words_move.py.exp index 86f6b7788..c4d22a0d9 100644 --- a/tests/cmdline/repl_words_move.py.exp +++ b/tests/cmdline/repl_words_move.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # word movement >>> # backward-word, start in word >>> \.\+ diff --git a/tests/feature_check/repl_emacs_check.py.exp b/tests/feature_check/repl_emacs_check.py.exp index 82a4e28ee..5fe8ba1cd 100644 --- a/tests/feature_check/repl_emacs_check.py.exp +++ b/tests/feature_check/repl_emacs_check.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # Check for emacs keys in REPL >>> t = \.\+ >>> t == 2 diff --git a/tests/feature_check/repl_words_move_check.py.exp b/tests/feature_check/repl_words_move_check.py.exp index 82a4e28ee..5fe8ba1cd 100644 --- a/tests/feature_check/repl_words_move_check.py.exp +++ b/tests/feature_check/repl_words_move_check.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # Check for emacs keys in REPL >>> t = \.\+ >>> t == 2 |
