1 /*
2 * This file is part of the MicroPython project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <stdint.h>
30 #include <string.h>
31
32 #include "py/compile.h"
33 #include "py/runtime.h"
34 #include "py/repl.h"
35 #include "py/gc.h"
36 #include "py/frozenmod.h"
37 #include "py/mphal.h"
38 #if MICROPY_HW_ENABLE_USB
39 #include "irq.h"
40 #include "usb.h"
41 #endif
42 #include "shared/readline/readline.h"
43 #include "shared/runtime/pyexec.h"
44 #include "genhdr/mpversion.h"
45
46 pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
47 int pyexec_system_exit = 0;
48
49 #if MICROPY_REPL_INFO
50 STATIC bool repl_display_debugging_info = 0;
51 #endif
52
53 #define EXEC_FLAG_PRINT_EOF (1)
54 #define EXEC_FLAG_ALLOW_DEBUGGING (2)
55 #define EXEC_FLAG_IS_REPL (4)
56 #define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
57 #define EXEC_FLAG_SOURCE_IS_VSTR (16)
58 #define EXEC_FLAG_SOURCE_IS_FILENAME (32)
59 #define EXEC_FLAG_SOURCE_IS_READER (64)
60
61 // parses, compiles and executes the code in the lexer
62 // frees the lexer before returning
63 // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
64 // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
65 // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
parse_compile_execute(const void * source,mp_parse_input_kind_t input_kind,int exec_flags)66 STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
67 int ret = 0;
68 #if MICROPY_REPL_INFO
69 uint32_t start = 0;
70 #endif
71
72 #ifdef MICROPY_BOARD_BEFORE_PYTHON_EXEC
73 MICROPY_BOARD_BEFORE_PYTHON_EXEC(input_kind, exec_flags);
74 #endif
75
76 // by default a SystemExit exception returns 0
77 pyexec_system_exit = 0;
78
79 nlr_buf_t nlr;
80 nlr.ret_val = NULL;
81 if (nlr_push(&nlr) == 0) {
82 mp_obj_t module_fun;
83 #if MICROPY_MODULE_FROZEN_MPY
84 if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) {
85 // source is a raw_code object, create the function
86 module_fun = mp_make_function_from_raw_code(source, MP_OBJ_NULL, MP_OBJ_NULL);
87 } else
88 #endif
89 {
90 #if MICROPY_ENABLE_COMPILER
91 mp_lexer_t *lex;
92 if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) {
93 const vstr_t *vstr = source;
94 lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0);
95 } else if (exec_flags & EXEC_FLAG_SOURCE_IS_READER) {
96 lex = mp_lexer_new(MP_QSTR__lt_stdin_gt_, *(mp_reader_t *)source);
97 } else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) {
98 lex = mp_lexer_new_from_file(source);
99 } else {
100 lex = (mp_lexer_t *)source;
101 }
102 // source is a lexer, parse and compile the script
103 qstr source_name = lex->source_name;
104 mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
105 module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL);
106 #else
107 mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("script compilation not supported"));
108 #endif
109 }
110
111 // execute code
112 mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us
113 #if MICROPY_REPL_INFO
114 start = mp_hal_ticks_ms();
115 #endif
116 mp_call_function_0(module_fun);
117 mp_hal_set_interrupt_char(-1); // disable interrupt
118 mp_handle_pending(true); // handle any pending exceptions (and any callbacks)
119 nlr_pop();
120 ret = 1;
121 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
122 mp_hal_stdout_tx_strn("\x04", 1);
123 }
124 } else {
125 // uncaught exception
126 mp_hal_set_interrupt_char(-1); // disable interrupt
127 mp_handle_pending(false); // clear any pending exceptions (and run any callbacks)
128
129 if (exec_flags & EXEC_FLAG_SOURCE_IS_READER) {
130 const mp_reader_t *reader = source;
131 reader->close(reader->data);
132 }
133
134 // print EOF after normal output
135 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
136 mp_hal_stdout_tx_strn("\x04", 1);
137 }
138 // check for SystemExit
139 if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) {
140 // at the moment, the value of SystemExit is unused
141 ret = pyexec_system_exit;
142 } else {
143 mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
144 ret = 0;
145 }
146 }
147
148 #if MICROPY_REPL_INFO
149 // display debugging info if wanted
150 if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) {
151 mp_uint_t ticks = mp_hal_ticks_ms() - start; // TODO implement a function that does this properly
152 printf("took " UINT_FMT " ms\n", ticks);
153 // qstr info
154 {
155 size_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
156 qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
157 printf("qstr:\n n_pool=%u\n n_qstr=%u\n "
158 "n_str_data_bytes=%u\n n_total_bytes=%u\n",
159 (unsigned)n_pool, (unsigned)n_qstr, (unsigned)n_str_data_bytes, (unsigned)n_total_bytes);
160 }
161
162 #if MICROPY_ENABLE_GC
163 // run collection and print GC info
164 gc_collect();
165 gc_dump_info();
166 #endif
167 }
168 #endif
169
170 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
171 mp_hal_stdout_tx_strn("\x04", 1);
172 }
173
174 #ifdef MICROPY_BOARD_AFTER_PYTHON_EXEC
175 MICROPY_BOARD_AFTER_PYTHON_EXEC(input_kind, exec_flags, nlr.ret_val, &ret);
176 #endif
177
178 return ret;
179 }
180
181 #if MICROPY_ENABLE_COMPILER
182
183 // This can be configured by a port (and even configured to a function to be
184 // computed dynamically) to indicate the maximum number of bytes that can be
185 // held in the stdin buffer.
186 #ifndef MICROPY_REPL_STDIN_BUFFER_MAX
187 #define MICROPY_REPL_STDIN_BUFFER_MAX (256)
188 #endif
189
190 typedef struct _mp_reader_stdin_t {
191 bool eof;
192 uint16_t window_max;
193 uint16_t window_remain;
194 } mp_reader_stdin_t;
195
mp_reader_stdin_readbyte(void * data)196 STATIC mp_uint_t mp_reader_stdin_readbyte(void *data) {
197 mp_reader_stdin_t *reader = (mp_reader_stdin_t *)data;
198
199 if (reader->eof) {
200 return MP_READER_EOF;
201 }
202
203 int c = mp_hal_stdin_rx_chr();
204
205 if (c == CHAR_CTRL_C || c == CHAR_CTRL_D) {
206 reader->eof = true;
207 mp_hal_stdout_tx_strn("\x04", 1); // indicate end to host
208 if (c == CHAR_CTRL_C) {
209 #if MICROPY_KBD_EXCEPTION
210 MP_STATE_VM(mp_kbd_exception).traceback_data = NULL;
211 nlr_raise(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)));
212 #else
213 mp_raise_type(&mp_type_KeyboardInterrupt);
214 #endif
215 } else {
216 return MP_READER_EOF;
217 }
218 }
219
220 if (--reader->window_remain == 0) {
221 mp_hal_stdout_tx_strn("\x01", 1); // indicate window available to host
222 reader->window_remain = reader->window_max;
223 }
224
225 return c;
226 }
227
mp_reader_stdin_close(void * data)228 STATIC void mp_reader_stdin_close(void *data) {
229 mp_reader_stdin_t *reader = (mp_reader_stdin_t *)data;
230 if (!reader->eof) {
231 reader->eof = true;
232 mp_hal_stdout_tx_strn("\x04", 1); // indicate end to host
233 for (;;) {
234 int c = mp_hal_stdin_rx_chr();
235 if (c == CHAR_CTRL_C || c == CHAR_CTRL_D) {
236 break;
237 }
238 }
239 }
240 }
241
mp_reader_new_stdin(mp_reader_t * reader,mp_reader_stdin_t * reader_stdin,uint16_t buf_max)242 STATIC void mp_reader_new_stdin(mp_reader_t *reader, mp_reader_stdin_t *reader_stdin, uint16_t buf_max) {
243 // Make flow-control window half the buffer size, and indicate to the host that 2x windows are
244 // free (sending the window size implicitly indicates that a window is free, and then the 0x01
245 // indicates that another window is free).
246 size_t window = buf_max / 2;
247 char reply[3] = { window & 0xff, window >> 8, 0x01 };
248 mp_hal_stdout_tx_strn(reply, sizeof(reply));
249
250 reader_stdin->eof = false;
251 reader_stdin->window_max = window;
252 reader_stdin->window_remain = window;
253 reader->data = reader_stdin;
254 reader->readbyte = mp_reader_stdin_readbyte;
255 reader->close = mp_reader_stdin_close;
256 }
257
do_reader_stdin(int c)258 STATIC int do_reader_stdin(int c) {
259 if (c != 'A') {
260 // Unsupported command.
261 mp_hal_stdout_tx_strn("R\x00", 2);
262 return 0;
263 }
264
265 // Indicate reception of command.
266 mp_hal_stdout_tx_strn("R\x01", 2);
267
268 mp_reader_t reader;
269 mp_reader_stdin_t reader_stdin;
270 mp_reader_new_stdin(&reader, &reader_stdin, MICROPY_REPL_STDIN_BUFFER_MAX);
271 int exec_flags = EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_READER;
272 return parse_compile_execute(&reader, MP_PARSE_FILE_INPUT, exec_flags);
273 }
274
275 #if MICROPY_REPL_EVENT_DRIVEN
276
277 typedef struct _repl_t {
278 // This structure originally also held current REPL line,
279 // but it was moved to MP_STATE_VM(repl_line) as containing
280 // root pointer. Still keep structure in case more state
281 // will be added later.
282 // vstr_t line;
283 bool cont_line;
284 bool paste_mode;
285 } repl_t;
286
287 repl_t repl;
288
289 STATIC int pyexec_raw_repl_process_char(int c);
290 STATIC int pyexec_friendly_repl_process_char(int c);
291
pyexec_event_repl_init(void)292 void pyexec_event_repl_init(void) {
293 MP_STATE_VM(repl_line) = vstr_new(32);
294 repl.cont_line = false;
295 repl.paste_mode = false;
296 // no prompt before printing friendly REPL banner or entering raw REPL
297 readline_init(MP_STATE_VM(repl_line), "");
298 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
299 pyexec_raw_repl_process_char(CHAR_CTRL_A);
300 } else {
301 pyexec_friendly_repl_process_char(CHAR_CTRL_B);
302 }
303 }
304
pyexec_raw_repl_process_char(int c)305 STATIC int pyexec_raw_repl_process_char(int c) {
306 if (c == CHAR_CTRL_A) {
307 // reset raw REPL
308 if (vstr_len(MP_STATE_VM(repl_line)) == 2 && vstr_str(MP_STATE_VM(repl_line))[0] == CHAR_CTRL_E) {
309 int ret = do_reader_stdin(vstr_str(MP_STATE_VM(repl_line))[1]);
310 if (ret & PYEXEC_FORCED_EXIT) {
311 return ret;
312 }
313 goto reset;
314 }
315 mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
316 goto reset;
317 } else if (c == CHAR_CTRL_B) {
318 // change to friendly REPL
319 pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
320 vstr_reset(MP_STATE_VM(repl_line));
321 repl.cont_line = false;
322 repl.paste_mode = false;
323 pyexec_friendly_repl_process_char(CHAR_CTRL_B);
324 return 0;
325 } else if (c == CHAR_CTRL_C) {
326 // clear line
327 vstr_reset(MP_STATE_VM(repl_line));
328 return 0;
329 } else if (c == CHAR_CTRL_D) {
330 // input finished
331 } else {
332 // let through any other raw 8-bit value
333 vstr_add_byte(MP_STATE_VM(repl_line), c);
334 return 0;
335 }
336
337 // indicate reception of command
338 mp_hal_stdout_tx_str("OK");
339
340 if (MP_STATE_VM(repl_line)->len == 0) {
341 // exit for a soft reset
342 mp_hal_stdout_tx_str("\r\n");
343 vstr_clear(MP_STATE_VM(repl_line));
344 return PYEXEC_FORCED_EXIT;
345 }
346
347 int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
348 if (ret & PYEXEC_FORCED_EXIT) {
349 return ret;
350 }
351
352 reset:
353 vstr_reset(MP_STATE_VM(repl_line));
354 mp_hal_stdout_tx_str(">");
355
356 return 0;
357 }
358
pyexec_friendly_repl_process_char(int c)359 STATIC int pyexec_friendly_repl_process_char(int c) {
360 if (repl.paste_mode) {
361 if (c == CHAR_CTRL_C) {
362 // cancel everything
363 mp_hal_stdout_tx_str("\r\n");
364 goto input_restart;
365 } else if (c == CHAR_CTRL_D) {
366 // end of input
367 mp_hal_stdout_tx_str("\r\n");
368 int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
369 if (ret & PYEXEC_FORCED_EXIT) {
370 return ret;
371 }
372 goto input_restart;
373 } else {
374 // add char to buffer and echo
375 vstr_add_byte(MP_STATE_VM(repl_line), c);
376 if (c == '\r') {
377 mp_hal_stdout_tx_str("\r\n=== ");
378 } else {
379 char buf[1] = {c};
380 mp_hal_stdout_tx_strn(buf, 1);
381 }
382 return 0;
383 }
384 }
385
386 int ret = readline_process_char(c);
387
388 if (!repl.cont_line) {
389
390 if (ret == CHAR_CTRL_A) {
391 // change to raw REPL
392 pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
393 mp_hal_stdout_tx_str("\r\n");
394 pyexec_raw_repl_process_char(CHAR_CTRL_A);
395 return 0;
396 } else if (ret == CHAR_CTRL_B) {
397 // reset friendly REPL
398 mp_hal_stdout_tx_str("\r\n");
399 mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n");
400 #if MICROPY_PY_BUILTINS_HELP
401 mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
402 #endif
403 goto input_restart;
404 } else if (ret == CHAR_CTRL_C) {
405 // break
406 mp_hal_stdout_tx_str("\r\n");
407 goto input_restart;
408 } else if (ret == CHAR_CTRL_D) {
409 // exit for a soft reset
410 mp_hal_stdout_tx_str("\r\n");
411 vstr_clear(MP_STATE_VM(repl_line));
412 return PYEXEC_FORCED_EXIT;
413 } else if (ret == CHAR_CTRL_E) {
414 // paste mode
415 mp_hal_stdout_tx_str("\r\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== ");
416 vstr_reset(MP_STATE_VM(repl_line));
417 repl.paste_mode = true;
418 return 0;
419 }
420
421 if (ret < 0) {
422 return 0;
423 }
424
425 if (!mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) {
426 goto exec;
427 }
428
429 vstr_add_byte(MP_STATE_VM(repl_line), '\n');
430 repl.cont_line = true;
431 readline_note_newline("... ");
432 return 0;
433
434 } else {
435
436 if (ret == CHAR_CTRL_C) {
437 // cancel everything
438 mp_hal_stdout_tx_str("\r\n");
439 repl.cont_line = false;
440 goto input_restart;
441 } else if (ret == CHAR_CTRL_D) {
442 // stop entering compound statement
443 goto exec;
444 }
445
446 if (ret < 0) {
447 return 0;
448 }
449
450 if (mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) {
451 vstr_add_byte(MP_STATE_VM(repl_line), '\n');
452 readline_note_newline("... ");
453 return 0;
454 }
455
456 exec:;
457 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);
458 if (ret & PYEXEC_FORCED_EXIT) {
459 return ret;
460 }
461
462 input_restart:
463 vstr_reset(MP_STATE_VM(repl_line));
464 repl.cont_line = false;
465 repl.paste_mode = false;
466 readline_init(MP_STATE_VM(repl_line), ">>> ");
467 return 0;
468 }
469 }
470
471 uint8_t pyexec_repl_active;
pyexec_event_repl_process_char(int c)472 int pyexec_event_repl_process_char(int c) {
473 pyexec_repl_active = 1;
474 int res;
475 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
476 res = pyexec_raw_repl_process_char(c);
477 } else {
478 res = pyexec_friendly_repl_process_char(c);
479 }
480 pyexec_repl_active = 0;
481 return res;
482 }
483
484 #else // MICROPY_REPL_EVENT_DRIVEN
485
pyexec_raw_repl(void)486 int pyexec_raw_repl(void) {
487 vstr_t line;
488 vstr_init(&line, 32);
489
490 raw_repl_reset:
491 mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
492
493 for (;;) {
494 vstr_reset(&line);
495 mp_hal_stdout_tx_str(">");
496 for (;;) {
497 int c = mp_hal_stdin_rx_chr();
498 if (c == CHAR_CTRL_A) {
499 // reset raw REPL
500 if (vstr_len(&line) == 2 && vstr_str(&line)[0] == CHAR_CTRL_E) {
501 int ret = do_reader_stdin(vstr_str(&line)[1]);
502 if (ret & PYEXEC_FORCED_EXIT) {
503 return ret;
504 }
505 vstr_reset(&line);
506 mp_hal_stdout_tx_str(">");
507 continue;
508 }
509 goto raw_repl_reset;
510 } else if (c == CHAR_CTRL_B) {
511 // change to friendly REPL
512 mp_hal_stdout_tx_str("\r\n");
513 vstr_clear(&line);
514 pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
515 return 0;
516 } else if (c == CHAR_CTRL_C) {
517 // clear line
518 vstr_reset(&line);
519 } else if (c == CHAR_CTRL_D) {
520 // input finished
521 break;
522 } else {
523 // let through any other raw 8-bit value
524 vstr_add_byte(&line, c);
525 }
526 }
527
528 // indicate reception of command
529 mp_hal_stdout_tx_str("OK");
530
531 if (line.len == 0) {
532 // exit for a soft reset
533 mp_hal_stdout_tx_str("\r\n");
534 vstr_clear(&line);
535 return PYEXEC_FORCED_EXIT;
536 }
537
538 int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
539 if (ret & PYEXEC_FORCED_EXIT) {
540 return ret;
541 }
542 }
543 }
544
pyexec_friendly_repl(void)545 int pyexec_friendly_repl(void) {
546 vstr_t line;
547 vstr_init(&line, 32);
548
549 friendly_repl_reset:
550 mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n");
551 #if MICROPY_PY_BUILTINS_HELP
552 mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
553 #endif
554
555 // to test ctrl-C
556 /*
557 {
558 uint32_t x[4] = {0x424242, 0xdeaddead, 0x242424, 0xdeadbeef};
559 for (;;) {
560 nlr_buf_t nlr;
561 printf("pyexec_repl: %p\n", x);
562 mp_hal_set_interrupt_char(CHAR_CTRL_C);
563 if (nlr_push(&nlr) == 0) {
564 for (;;) {
565 }
566 } else {
567 printf("break\n");
568 }
569 }
570 }
571 */
572
573 for (;;) {
574 input_restart:
575
576 #if MICROPY_HW_ENABLE_USB
577 if (usb_vcp_is_enabled()) {
578 // If the user gets to here and interrupts are disabled then
579 // they'll never see the prompt, traceback etc. The USB REPL needs
580 // interrupts to be enabled or no transfers occur. So we try to
581 // do the user a favor and reenable interrupts.
582 if (query_irq() == IRQ_STATE_DISABLED) {
583 enable_irq(IRQ_STATE_ENABLED);
584 mp_hal_stdout_tx_str("MPY: enabling IRQs\r\n");
585 }
586 }
587 #endif
588
589 // If the GC is locked at this point there is no way out except a reset,
590 // so force the GC to be unlocked to help the user debug what went wrong.
591 if (MP_STATE_MEM(gc_lock_depth) != 0) {
592 MP_STATE_MEM(gc_lock_depth) = 0;
593 }
594
595 vstr_reset(&line);
596 int ret = readline(&line, ">>> ");
597 mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT;
598
599 if (ret == CHAR_CTRL_A) {
600 // change to raw REPL
601 mp_hal_stdout_tx_str("\r\n");
602 vstr_clear(&line);
603 pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
604 return 0;
605 } else if (ret == CHAR_CTRL_B) {
606 // reset friendly REPL
607 mp_hal_stdout_tx_str("\r\n");
608 goto friendly_repl_reset;
609 } else if (ret == CHAR_CTRL_C) {
610 // break
611 mp_hal_stdout_tx_str("\r\n");
612 continue;
613 } else if (ret == CHAR_CTRL_D) {
614 // exit for a soft reset
615 mp_hal_stdout_tx_str("\r\n");
616 vstr_clear(&line);
617 return PYEXEC_FORCED_EXIT;
618 } else if (ret == CHAR_CTRL_E) {
619 // paste mode
620 mp_hal_stdout_tx_str("\r\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== ");
621 vstr_reset(&line);
622 for (;;) {
623 char c = mp_hal_stdin_rx_chr();
624 if (c == CHAR_CTRL_C) {
625 // cancel everything
626 mp_hal_stdout_tx_str("\r\n");
627 goto input_restart;
628 } else if (c == CHAR_CTRL_D) {
629 // end of input
630 mp_hal_stdout_tx_str("\r\n");
631 break;
632 } else {
633 // add char to buffer and echo
634 vstr_add_byte(&line, c);
635 if (c == '\r') {
636 mp_hal_stdout_tx_str("\r\n=== ");
637 } else {
638 mp_hal_stdout_tx_strn(&c, 1);
639 }
640 }
641 }
642 parse_input_kind = MP_PARSE_FILE_INPUT;
643 } else if (vstr_len(&line) == 0) {
644 continue;
645 } else {
646 // got a line with non-zero length, see if it needs continuing
647 while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) {
648 vstr_add_byte(&line, '\n');
649 ret = readline(&line, "... ");
650 if (ret == CHAR_CTRL_C) {
651 // cancel everything
652 mp_hal_stdout_tx_str("\r\n");
653 goto input_restart;
654 } else if (ret == CHAR_CTRL_D) {
655 // stop entering compound statement
656 break;
657 }
658 }
659 }
660
661 ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
662 if (ret & PYEXEC_FORCED_EXIT) {
663 return ret;
664 }
665 }
666 }
667
668 #endif // MICROPY_REPL_EVENT_DRIVEN
669 #endif // MICROPY_ENABLE_COMPILER
670
pyexec_file(const char * filename)671 int pyexec_file(const char *filename) {
672 return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME);
673 }
674
pyexec_file_if_exists(const char * filename)675 int pyexec_file_if_exists(const char *filename) {
676 #if MICROPY_MODULE_FROZEN
677 if (mp_frozen_stat(filename) == MP_IMPORT_STAT_FILE) {
678 return pyexec_frozen_module(filename);
679 }
680 #endif
681 if (mp_import_stat(filename) != MP_IMPORT_STAT_FILE) {
682 return 1; // success (no file is the same as an empty file executing without fail)
683 }
684 return pyexec_file(filename);
685 }
686
687 #if MICROPY_MODULE_FROZEN
pyexec_frozen_module(const char * name)688 int pyexec_frozen_module(const char *name) {
689 void *frozen_data;
690 int frozen_type = mp_find_frozen_module(name, strlen(name), &frozen_data);
691
692 switch (frozen_type) {
693 #if MICROPY_MODULE_FROZEN_STR
694 case MP_FROZEN_STR:
695 return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0);
696 #endif
697
698 #if MICROPY_MODULE_FROZEN_MPY
699 case MP_FROZEN_MPY:
700 return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE);
701 #endif
702
703 default:
704 printf("could not find module '%s'\n", name);
705 return false;
706 }
707 }
708 #endif
709
710 #if MICROPY_REPL_INFO
pyb_set_repl_info(mp_obj_t o_value)711 mp_obj_t pyb_set_repl_info(mp_obj_t o_value) {
712 repl_display_debugging_info = mp_obj_get_int(o_value);
713 return mp_const_none;
714 }
715 MP_DEFINE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj, pyb_set_repl_info);
716 #endif
717