mirror of
https://github.com/micropython/micropython.git
synced 2026-01-06 20:20:14 +01:00
unix/main: Use standard pyexec REPL for unix and windows ports.
This improves REPL usage consistency across ports, by utilizing the pyexec code for the unix REPL. Only enabled when MICROPY_USE_READLINE == 1 (the default). Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
This commit is contained in:
committed by
Damien George
parent
40df95357c
commit
5b3c928f53
@@ -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) \
|
||||
)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
if ((ret = pyexec_raw_repl()) != 0) {
|
||||
break;
|
||||
}
|
||||
parse_input_kind = MP_PARSE_FILE_INPUT;
|
||||
} else if (line.len == 0) {
|
||||
if (ret != 0) {
|
||||
printf("\n");
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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"));
|
||||
|
||||
5
tests/cmdline/cmd_sys_exit_0.py
Normal file
5
tests/cmdline/cmd_sys_exit_0.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# cmdline:
|
||||
# test sys.exit(0) - success exit code
|
||||
import sys
|
||||
|
||||
sys.exit(0)
|
||||
1
tests/cmdline/cmd_sys_exit_0.py.exp
Normal file
1
tests/cmdline/cmd_sys_exit_0.py.exp
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
5
tests/cmdline/cmd_sys_exit_error.py
Normal file
5
tests/cmdline/cmd_sys_exit_error.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# cmdline:
|
||||
# test sys.exit() functionality and exit codes
|
||||
import sys
|
||||
|
||||
sys.exit(123)
|
||||
1
tests/cmdline/cmd_sys_exit_error.py.exp
Normal file
1
tests/cmdline/cmd_sys_exit_error.py.exp
Normal file
@@ -0,0 +1 @@
|
||||
CRASH
|
||||
5
tests/cmdline/cmd_sys_exit_none.py
Normal file
5
tests/cmdline/cmd_sys_exit_none.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# cmdline:
|
||||
# test sys.exit(None) - should exit with code 0
|
||||
import sys
|
||||
|
||||
sys.exit(None)
|
||||
1
tests/cmdline/cmd_sys_exit_none.py.exp
Normal file
1
tests/cmdline/cmd_sys_exit_none.py.exp
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # tests for autoindent
|
||||
>>> if 1:
|
||||
... print(1)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # basic REPL tests
|
||||
>>> print(1)
|
||||
1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # check REPL allows to continue input
|
||||
>>> 1 \\\\
|
||||
... + 2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # REPL tests of GNU-ish readline navigation
|
||||
>>> # history buffer navigation
|
||||
>>> 1
|
||||
|
||||
@@ -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
|
||||
>>>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> import micropython
|
||||
>>> micropython.heap_lock()
|
||||
>>> 1+1
|
||||
|
||||
@@ -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
|
||||
>>>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # test changing ps1/ps2
|
||||
>>> import sys
|
||||
>>> sys.ps1 = "PS1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # word movement
|
||||
>>> # backward-word, start in word
|
||||
>>> \.\+
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # Check for emacs keys in REPL
|
||||
>>> t = \.\+
|
||||
>>> t == 2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MicroPython \.\+ version
|
||||
Use \.\+
|
||||
Type "help()" for more information.
|
||||
>>> # Check for emacs keys in REPL
|
||||
>>> t = \.\+
|
||||
>>> t == 2
|
||||
|
||||
Reference in New Issue
Block a user