diff options
Diffstat (limited to 'stmhal/pyexec.c')
| -rw-r--r-- | stmhal/pyexec.c | 218 |
1 files changed, 140 insertions, 78 deletions
diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c index 1a121ce3e..aa7e35390 100644 --- a/stmhal/pyexec.c +++ b/stmhal/pyexec.c @@ -118,83 +118,81 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki return ret; } -int pyexec_raw_repl(void) { - vstr_t line; - vstr_init(&line, 32); - -raw_repl_reset: - mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); - - for (;;) { - vstr_reset(&line); - mp_hal_stdout_tx_str(">"); - for (;;) { - int c = mp_hal_stdin_rx_chr(); - if (c == CHAR_CTRL_A) { - // reset raw REPL - goto raw_repl_reset; - } else if (c == CHAR_CTRL_B) { - // change to friendly REPL - mp_hal_stdout_tx_str("\r\n"); - vstr_clear(&line); - pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; - return 0; - } else if (c == CHAR_CTRL_C) { - // clear line - vstr_reset(&line); - } else if (c == CHAR_CTRL_D) { - // input finished - break; - } else { - // let through any other raw 8-bit value - vstr_add_byte(&line, c); - } - } - - // indicate reception of command - mp_hal_stdout_tx_str("OK"); - - if (line.len == 0) { - // exit for a soft reset - mp_hal_stdout_tx_str("\r\n"); - vstr_clear(&line); - return PYEXEC_FORCED_EXIT; - } - - mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0); - if (lex == NULL) { - printf("\x04MemoryError\n\x04"); - } else { - int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF); - if (ret & PYEXEC_FORCED_EXIT) { - return ret; - } - } - } -} - #if MICROPY_REPL_EVENT_DRIVEN -typedef struct _friendly_repl_t { +typedef struct _repl_t { + // XXX line holds a root pointer! vstr_t line; bool cont_line; -} friendly_repl_t; +} repl_t; + +repl_t repl; -friendly_repl_t repl; +STATIC int pyexec_raw_repl_process_char(int c); +STATIC int pyexec_friendly_repl_process_char(int c); -void pyexec_friendly_repl_init(void) { +void pyexec_event_repl_init(void) { vstr_init(&repl.line, 32); repl.cont_line = false; readline_init(&repl.line, ">>> "); + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + pyexec_raw_repl_process_char(CHAR_CTRL_A); + } else { + pyexec_friendly_repl_process_char(CHAR_CTRL_B); + } } -void pyexec_friendly_repl_reset(void) { +STATIC int pyexec_raw_repl_process_char(int c) { + if (c == CHAR_CTRL_A) { + // reset raw REPL + mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); + goto reset; + } else if (c == CHAR_CTRL_B) { + // change to friendly REPL + pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; + repl.cont_line = false; + pyexec_friendly_repl_process_char(CHAR_CTRL_B); + return 0; + } else if (c == CHAR_CTRL_C) { + // clear line + vstr_reset(&repl.line); + return 0; + } else if (c == CHAR_CTRL_D) { + // input finished + } else { + // let through any other raw 8-bit value + vstr_add_byte(&repl.line, c); + return 0; + } + + // indicate reception of command + mp_hal_stdout_tx_str("OK"); + + if (repl.line.len == 0) { + // exit for a soft reset + mp_hal_stdout_tx_str("\r\n"); + vstr_clear(&repl.line); + return PYEXEC_FORCED_EXIT; + } + + mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, repl.line.buf, repl.line.len, 0); + if (lex == NULL) { + mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04"); + } else { + int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF); + if (ret & PYEXEC_FORCED_EXIT) { + return ret; + } + } + +reset: vstr_reset(&repl.line); - repl.cont_line = false; - readline_init(&repl.line, ">>> "); + mp_hal_stdout_tx_str(">"); + + return 0; } -int pyexec_friendly_repl_process_char(int c) { +STATIC int pyexec_friendly_repl_process_char(int c) { int ret = readline_process_char(c); if (!repl.cont_line) { @@ -203,12 +201,14 @@ int pyexec_friendly_repl_process_char(int c) { // change to raw REPL pyexec_mode_kind = PYEXEC_MODE_RAW_REPL; mp_hal_stdout_tx_str("\r\n"); - vstr_clear(&repl.line); - return PYEXEC_SWITCH_MODE; + pyexec_raw_repl_process_char(CHAR_CTRL_A); + return 0; } else if (ret == CHAR_CTRL_B) { // reset friendly REPL mp_hal_stdout_tx_str("\r\n"); - goto friendly_repl_reset; + mp_hal_stdout_tx_str("Micro Python " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n"); + mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); + goto input_restart; } else if (ret == CHAR_CTRL_C) { // break mp_hal_stdout_tx_str("\r\n"); @@ -218,8 +218,6 @@ int pyexec_friendly_repl_process_char(int c) { mp_hal_stdout_tx_str("\r\n"); vstr_clear(&repl.line); return PYEXEC_FORCED_EXIT; - } else if (vstr_len(&repl.line) == 0) { - //goto input_restart; } if (ret < 0) { @@ -238,13 +236,13 @@ int pyexec_friendly_repl_process_char(int c) { } else { if (ret == CHAR_CTRL_C) { - // cancel everything - mp_hal_stdout_tx_str("\r\n"); - repl.cont_line = false; - goto input_restart; + // cancel everything + mp_hal_stdout_tx_str("\r\n"); + repl.cont_line = false; + goto input_restart; } else if (ret == CHAR_CTRL_D) { - // stop entering compound statement - goto exec; + // stop entering compound statement + goto exec; } if (ret < 0) { @@ -268,14 +266,78 @@ exec: ; } } -friendly_repl_reset: // TODO input_restart: - pyexec_friendly_repl_reset(); + vstr_reset(&repl.line); + repl.cont_line = false; + readline_init(&repl.line, ">>> "); return 0; } } -#else //MICROPY_REPL_EVENT_DRIVEN +int pyexec_event_repl_process_char(int c) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + return pyexec_raw_repl_process_char(c); + } else { + return pyexec_friendly_repl_process_char(c); + } +} + +#else // MICROPY_REPL_EVENT_DRIVEN + +int pyexec_raw_repl(void) { + vstr_t line; + vstr_init(&line, 32); + +raw_repl_reset: + mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); + + for (;;) { + vstr_reset(&line); + mp_hal_stdout_tx_str(">"); + for (;;) { + int c = mp_hal_stdin_rx_chr(); + if (c == CHAR_CTRL_A) { + // reset raw REPL + goto raw_repl_reset; + } else if (c == CHAR_CTRL_B) { + // change to friendly REPL + mp_hal_stdout_tx_str("\r\n"); + vstr_clear(&line); + pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; + return 0; + } else if (c == CHAR_CTRL_C) { + // clear line + vstr_reset(&line); + } else if (c == CHAR_CTRL_D) { + // input finished + break; + } else { + // let through any other raw 8-bit value + vstr_add_byte(&line, c); + } + } + + // indicate reception of command + mp_hal_stdout_tx_str("OK"); + + if (line.len == 0) { + // exit for a soft reset + mp_hal_stdout_tx_str("\r\n"); + vstr_clear(&line); + return PYEXEC_FORCED_EXIT; + } + + mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0); + if (lex == NULL) { + printf("\x04MemoryError\n\x04"); + } else { + int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF); + if (ret & PYEXEC_FORCED_EXIT) { + return ret; + } + } + } +} int pyexec_friendly_repl(void) { vstr_t line; @@ -376,7 +438,7 @@ friendly_repl_reset: } } -#endif //MICROPY_REPL_EVENT_DRIVEN +#endif // MICROPY_REPL_EVENT_DRIVEN int pyexec_file(const char *filename) { mp_lexer_t *lex = mp_lexer_new_from_file(filename); |
