@@ -56,7 +56,7 @@ STATIC bool repl_display_debugging_info = 0;
5656
5757// parses, compiles and executes the code in the lexer
5858// frees the lexer before returning
59- bool parse_compile_execute (mp_lexer_t * lex , mp_parse_input_kind_t input_kind , bool is_repl ) {
59+ int parse_compile_execute (mp_lexer_t * lex , mp_parse_input_kind_t input_kind , bool is_repl ) {
6060 mp_parse_error_kind_t parse_error_kind ;
6161 mp_parse_node_t pn = mp_parse (lex , input_kind , & parse_error_kind );
6262 qstr source_name = mp_lexer_source_name (lex );
@@ -65,7 +65,7 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
6565 // parse error
6666 mp_parse_show_exception (lex , parse_error_kind );
6767 mp_lexer_free (lex );
68- return false ;
68+ return 0 ;
6969 }
7070
7171 mp_lexer_free (lex );
@@ -74,24 +74,35 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
7474
7575 if (mp_obj_is_exception_instance (module_fun )) {
7676 mp_obj_print_exception (module_fun );
77- return false ;
77+ return 0 ;
7878 }
7979
8080 nlr_buf_t nlr ;
81- bool ret ;
81+ int ret ;
8282 uint32_t start = HAL_GetTick ();
8383 if (nlr_push (& nlr ) == 0 ) {
8484 usb_vcp_set_interrupt_char (VCP_CHAR_CTRL_C ); // allow ctrl-C to interrupt us
8585 mp_call_function_0 (module_fun );
8686 usb_vcp_set_interrupt_char (VCP_CHAR_NONE ); // disable interrupt
8787 nlr_pop ();
88- ret = true ;
88+ ret = 1 ;
8989 } else {
9090 // uncaught exception
9191 // FIXME it could be that an interrupt happens just before we disable it here
9292 usb_vcp_set_interrupt_char (VCP_CHAR_NONE ); // disable interrupt
93+ // check for SystemExit
94+ mp_obj_t exc = (mp_obj_t )nlr .ret_val ;
95+ if (mp_obj_is_subclass_fast (mp_obj_get_type (exc ), & mp_type_SystemExit )) {
96+ // None is an exit value of 0; an int is its value; anything else is 1
97+ mp_obj_t exit_val = mp_obj_exception_get_value (exc );
98+ mp_int_t val = 0 ;
99+ if (exit_val != mp_const_none && !mp_obj_get_int_maybe (exit_val , & val )) {
100+ val = 1 ;
101+ }
102+ return PYEXEC_FORCED_EXIT | (val & 255 );
103+ }
93104 mp_obj_print_exception ((mp_obj_t )nlr .ret_val );
94- ret = false ;
105+ ret = 0 ;
95106 }
96107
97108 // display debugging info if wanted
@@ -160,14 +171,17 @@ int pyexec_raw_repl(void) {
160171 // exit for a soft reset
161172 stdout_tx_str ("\r\n" );
162173 vstr_clear (& line );
163- return 1 ;
174+ return PYEXEC_FORCED_EXIT ;
164175 }
165176
166177 mp_lexer_t * lex = mp_lexer_new_from_str_len (MP_QSTR__lt_stdin_gt_ , line .buf , line .len , 0 );
167178 if (lex == NULL ) {
168179 printf ("MemoryError\n" );
169180 } else {
170- parse_compile_execute (lex , MP_PARSE_FILE_INPUT , false);
181+ int ret = parse_compile_execute (lex , MP_PARSE_FILE_INPUT , false);
182+ if (ret & PYEXEC_FORCED_EXIT ) {
183+ return ret ;
184+ }
171185 }
172186
173187 // indicate end of output with EOF character
@@ -229,7 +243,7 @@ int pyexec_friendly_repl(void) {
229243 // exit for a soft reset
230244 stdout_tx_str ("\r\n" );
231245 vstr_clear (& line );
232- return 1 ;
246+ return PYEXEC_FORCED_EXIT ;
233247 } else if (vstr_len (& line ) == 0 ) {
234248 continue ;
235249 }
@@ -247,7 +261,10 @@ int pyexec_friendly_repl(void) {
247261 if (lex == NULL ) {
248262 printf ("MemoryError\n" );
249263 } else {
250- parse_compile_execute (lex , MP_PARSE_SINGLE_INPUT , true);
264+ int ret = parse_compile_execute (lex , MP_PARSE_SINGLE_INPUT , true);
265+ if (ret & PYEXEC_FORCED_EXIT ) {
266+ return ret ;
267+ }
251268 }
252269 }
253270}
0 commit comments