lib/utils/pyexec: Refactor to put lexer constructors all in one place.
The lexer can now raise an exception on construction so it must go within an nlr handler block.
This commit is contained in:
parent
1831034be1
commit
56b238393b
|
@ -52,13 +52,15 @@ STATIC bool repl_display_debugging_info = 0;
|
||||||
#define EXEC_FLAG_ALLOW_DEBUGGING (2)
|
#define EXEC_FLAG_ALLOW_DEBUGGING (2)
|
||||||
#define EXEC_FLAG_IS_REPL (4)
|
#define EXEC_FLAG_IS_REPL (4)
|
||||||
#define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
|
#define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
|
||||||
|
#define EXEC_FLAG_SOURCE_IS_VSTR (16)
|
||||||
|
#define EXEC_FLAG_SOURCE_IS_FILENAME (32)
|
||||||
|
|
||||||
// parses, compiles and executes the code in the lexer
|
// parses, compiles and executes the code in the lexer
|
||||||
// frees the lexer before returning
|
// frees the lexer before returning
|
||||||
// EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
|
// EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
|
||||||
// EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
|
// EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
|
||||||
// EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
|
// EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
|
||||||
STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
|
STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t start = 0;
|
uint32_t start = 0;
|
||||||
|
|
||||||
|
@ -76,8 +78,16 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MICROPY_ENABLE_COMPILER
|
#if MICROPY_ENABLE_COMPILER
|
||||||
|
mp_lexer_t *lex;
|
||||||
|
if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) {
|
||||||
|
const vstr_t *vstr = source;
|
||||||
|
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0);
|
||||||
|
} else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) {
|
||||||
|
lex = mp_lexer_new_from_file(source);
|
||||||
|
} else {
|
||||||
|
lex = (mp_lexer_t*)source;
|
||||||
|
}
|
||||||
// source is a lexer, parse and compile the script
|
// source is a lexer, parse and compile the script
|
||||||
mp_lexer_t *lex = source;
|
|
||||||
qstr source_name = lex->source_name;
|
qstr source_name = lex->source_name;
|
||||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||||
module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
|
module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
|
||||||
|
@ -202,14 +212,9 @@ STATIC int pyexec_raw_repl_process_char(int c) {
|
||||||
return PYEXEC_FORCED_EXIT;
|
return PYEXEC_FORCED_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, MP_STATE_VM(repl_line)->buf, MP_STATE_VM(repl_line)->len, 0);
|
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||||
if (lex == NULL) {
|
if (ret & PYEXEC_FORCED_EXIT) {
|
||||||
mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
|
return ret;
|
||||||
} else {
|
|
||||||
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
|
|
||||||
if (ret & PYEXEC_FORCED_EXIT) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reset:
|
reset:
|
||||||
|
@ -285,14 +290,9 @@ STATIC int pyexec_friendly_repl_process_char(int c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exec: ;
|
exec: ;
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(MP_STATE_VM(repl_line)), vstr_len(MP_STATE_VM(repl_line)), 0);
|
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||||
if (lex == NULL) {
|
if (ret & PYEXEC_FORCED_EXIT) {
|
||||||
printf("MemoryError\n");
|
return ret;
|
||||||
} else {
|
|
||||||
int ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
|
|
||||||
if (ret & PYEXEC_FORCED_EXIT) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input_restart:
|
input_restart:
|
||||||
|
@ -361,14 +361,9 @@ raw_repl_reset:
|
||||||
return PYEXEC_FORCED_EXIT;
|
return PYEXEC_FORCED_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
|
int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||||
if (lex == NULL) {
|
if (ret & PYEXEC_FORCED_EXIT) {
|
||||||
printf("\x04MemoryError\n\x04");
|
return ret;
|
||||||
} else {
|
|
||||||
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
|
|
||||||
if (ret & PYEXEC_FORCED_EXIT) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,14 +484,9 @@ friendly_repl_reset:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
|
ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||||
if (lex == NULL) {
|
if (ret & PYEXEC_FORCED_EXIT) {
|
||||||
printf("MemoryError\n");
|
return ret;
|
||||||
} else {
|
|
||||||
ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
|
|
||||||
if (ret & PYEXEC_FORCED_EXIT) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,14 +495,7 @@ friendly_repl_reset:
|
||||||
#endif // MICROPY_ENABLE_COMPILER
|
#endif // MICROPY_ENABLE_COMPILER
|
||||||
|
|
||||||
int pyexec_file(const char *filename) {
|
int pyexec_file(const char *filename) {
|
||||||
mp_lexer_t *lex = mp_lexer_new_from_file(filename);
|
return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, 0);
|
||||||
|
|
||||||
if (lex == NULL) {
|
|
||||||
printf("could not open file '%s' for reading\n", filename);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_MODULE_FROZEN
|
#if MICROPY_MODULE_FROZEN
|
||||||
|
|
Loading…
Reference in New Issue