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:
Andrew Leech
2023-10-26 09:02:16 +11:00
committed by Damien George
parent 40df95357c
commit 5b3c928f53
25 changed files with 59 additions and 89 deletions

View File

@@ -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) \
)

View File

@@ -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) {