-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
unix/main: Use standard pyexec/repl for unix port. #12802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
b02e79f
03fe1aa
3a77db6
e2cd5a0
dbda928
11241da
b1917e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,9 +54,10 @@ | |
#include "extmod/vfs_posix.h" | ||
#include "genhdr/mpversion.h" | ||
#include "input.h" | ||
#include "shared/runtime/pyexec.h" | ||
|
||
// Command line options, with their defaults | ||
static bool compile_only = false; | ||
bool mp_compile_only = false; | ||
static uint emit_opt = MP_EMIT_OPT_NONE; | ||
|
||
#if MICROPY_ENABLE_GC | ||
|
@@ -109,8 +110,6 @@ static int handle_uncaught_exception(mp_obj_base_t *exc) { | |
} | ||
|
||
#define LEX_SRC_STR (1) | ||
#define LEX_SRC_VSTR (2) | ||
#define LEX_SRC_FILENAME (3) | ||
#define LEX_SRC_STDIN (4) | ||
|
||
// Returns standard error codes: 0 for success, 1 for all other errors, | ||
|
@@ -126,12 +125,6 @@ static int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu | |
if (source_kind == LEX_SRC_STR) { | ||
const char *line = source; | ||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false); | ||
} else if (source_kind == LEX_SRC_VSTR) { | ||
const vstr_t *vstr = source; | ||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, false); | ||
} else if (source_kind == LEX_SRC_FILENAME) { | ||
const char *filename = (const char *)source; | ||
lex = mp_lexer_new_from_file(qstr_from_str(filename)); | ||
} else { // LEX_SRC_STDIN | ||
lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false); | ||
} | ||
|
@@ -157,7 +150,7 @@ static int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu | |
|
||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, is_repl); | ||
|
||
if (!compile_only) { | ||
if (!mp_compile_only) { | ||
// execute it | ||
mp_call_function_0(module_fun); | ||
} | ||
|
@@ -194,91 +187,27 @@ 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"); | ||
|
||
int ret = 0; | ||
#if MICROPY_USE_READLINE == 1 | ||
|
||
// use MicroPython supplied readline | ||
|
||
vstr_t line; | ||
vstr_init(&line, 16); | ||
// use MicroPython supplied readline based repl | ||
mp_hal_stdio_mode_raw(); | ||
for (;;) { | ||
mp_hal_stdio_mode_raw(); | ||
|
||
input_restart: | ||
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(); | ||
#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()); | ||
|
@@ -297,22 +226,43 @@ static int do_repl(void) { | |
line = line3; | ||
} | ||
|
||
int ret = execute_from_lexer(LEX_SRC_STR, line, MP_PARSE_SINGLE_INPUT, true); | ||
ret = execute_from_lexer(LEX_SRC_STR, line, MP_PARSE_SINGLE_INPUT, true); | ||
free(line); | ||
if (ret & FORCED_EXIT) { | ||
return ret; | ||
} | ||
} | ||
|
||
#endif | ||
return ret; | ||
} | ||
|
||
|
||
static int do_file(const char *file) { | ||
return execute_from_lexer(LEX_SRC_FILENAME, file, MP_PARSE_FILE_INPUT, false); | ||
int ret = pyexec_file(file); | ||
// pyexec returns 1 for success, 0 for exception, PYEXEC_FORCED_EXIT for SystemExit | ||
// Convert to unix port's expected codes: 0 for success, 1 for exception, FORCED_EXIT|val for SystemExit | ||
if (ret == 1) { | ||
return 0; // success | ||
} else if (ret & PYEXEC_FORCED_EXIT) { | ||
return ret; // SystemExit with exit value in lower 8 bits | ||
} else { | ||
return 1; // exception | ||
} | ||
} | ||
|
||
static int do_str(const char *str) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be possible to replace the Might be worth doing that as part of this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, I think we should do that and get rid of
Yes. |
||
return execute_from_lexer(LEX_SRC_STR, str, MP_PARSE_FILE_INPUT, false); | ||
vstr_t vstr; | ||
vstr_init(&vstr, strlen(str)); | ||
vstr_add_strn(&vstr, str, strlen(str)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allocates RAM unnecessarily. I suggest using |
||
int ret = pyexec_vstr(&vstr, false); | ||
vstr_clear(&vstr); | ||
if (ret == 1) { | ||
return 0; // success | ||
} else if (ret & PYEXEC_FORCED_EXIT) { | ||
return ret; // SystemExit with exit value in lower 8 bits | ||
} else { | ||
return 1; // exception | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code should be factored/shared with |
||
} | ||
|
||
static void print_help(char **argv) { | ||
|
@@ -381,7 +331,7 @@ static void pre_process_options(int argc, char **argv) { | |
} | ||
if (0) { | ||
} else if (strcmp(argv[a + 1], "compile-only") == 0) { | ||
compile_only = true; | ||
mp_compile_only = true; | ||
} else if (strcmp(argv[a + 1], "emit=bytecode") == 0) { | ||
emit_opt = MP_EMIT_OPT_BYTECODE; | ||
#if MICROPY_EMIT_NATIVE | ||
|
Uh oh!
There was an error while loading. Please reload this page.