Port of MicroPython to the mbed platform. See micropython-repl for an interactive program.

Dependents:   micropython-repl

This a port of MicroPython to the mbed Classic platform.

This provides an interpreter running on the board's USB serial connection.

Getting Started

Import the micropython-repl program into your IDE workspace on developer.mbed.org. Compile and download to your board. Connect to the USB serial port in your usual manner. You should get a startup message similar to the following:

  MicroPython v1.7-155-gdddcdd8 on 2016-04-23; K64F with ARM
  Type "help()" for more information.
  >>>

Then you can start using micropython. For example:

  >>> from mbed import DigitalOut
  >>> from pins import LED1
  >>> led = DigitalOut(LED1)
  >>> led.write(1)

Requirements

You need approximately 100K of flash memory, so this will be no good for boards with smaller amounts of storage.

Caveats

This can be considered an alpha release of the port; things may not work; APIs may change in later releases. It is NOT an official part part the micropython project, so if anything doesn't work, blame me. If it does work, most of the credit is due to micropython.

  • Only a few of the mbed classes are available in micropython so far, and not all methods of those that are.
  • Only a few boards have their full range of pin names available; for others, only a few standard ones (USBTX, USBRX, LED1) are implemented.
  • The garbage collector is not yet implemented. The interpreter will gradually consume memory and then fail.
  • Exceptions from the mbed classes are not yet handled.
  • Asynchronous processing (e.g. events on inputs) is not supported.

Credits

  • Damien P. George and other contributors who created micropython.
  • Colin Hogben, author of this port.
Committer:
pythontech
Date:
Sat Apr 16 17:11:56 2016 +0000
Revision:
0:5868e8752d44
Child:
2:c89e95946844
Split off library from repl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pythontech 0:5868e8752d44 1 /*
pythontech 0:5868e8752d44 2 * This file is part of the Micro Python project, http://micropython.org/
pythontech 0:5868e8752d44 3 *
pythontech 0:5868e8752d44 4 * The MIT License (MIT)
pythontech 0:5868e8752d44 5 *
pythontech 0:5868e8752d44 6 * Copyright (c) 2013, 2014 Damien P. George
pythontech 0:5868e8752d44 7 *
pythontech 0:5868e8752d44 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 9 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 10 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 12 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 13 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 14 *
pythontech 0:5868e8752d44 15 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 16 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 17 *
pythontech 0:5868e8752d44 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 24 * THE SOFTWARE.
pythontech 0:5868e8752d44 25 */
pythontech 0:5868e8752d44 26
pythontech 0:5868e8752d44 27 #include <stdlib.h>
pythontech 0:5868e8752d44 28 #include <stdio.h>
pythontech 0:5868e8752d44 29 #include <stdint.h>
pythontech 0:5868e8752d44 30 #include <string.h>
pythontech 0:5868e8752d44 31
pythontech 0:5868e8752d44 32 #include "py/nlr.h"
pythontech 0:5868e8752d44 33 #include "py/compile.h"
pythontech 0:5868e8752d44 34 #include "py/runtime.h"
pythontech 0:5868e8752d44 35 #include "py/repl.h"
pythontech 0:5868e8752d44 36 #include "py/gc.h"
pythontech 0:5868e8752d44 37 #include "py/frozenmod.h"
pythontech 0:5868e8752d44 38 #include "py/mphal.h"
pythontech 0:5868e8752d44 39 #if defined(USE_DEVICE_MODE)
pythontech 0:5868e8752d44 40 #include "irq.h"
pythontech 0:5868e8752d44 41 #include "usb.h"
pythontech 0:5868e8752d44 42 #endif
pythontech 0:5868e8752d44 43 #include "readline.h"
pythontech 0:5868e8752d44 44 #include "lib/utils/pyexec.h"
pythontech 0:5868e8752d44 45 #include "genhdr/mpversion.h"
pythontech 0:5868e8752d44 46
pythontech 0:5868e8752d44 47 pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
pythontech 0:5868e8752d44 48 STATIC bool repl_display_debugging_info = 0;
pythontech 0:5868e8752d44 49
pythontech 0:5868e8752d44 50 #define EXEC_FLAG_PRINT_EOF (1)
pythontech 0:5868e8752d44 51 #define EXEC_FLAG_ALLOW_DEBUGGING (2)
pythontech 0:5868e8752d44 52 #define EXEC_FLAG_IS_REPL (4)
pythontech 0:5868e8752d44 53
pythontech 0:5868e8752d44 54 // parses, compiles and executes the code in the lexer
pythontech 0:5868e8752d44 55 // frees the lexer before returning
pythontech 0:5868e8752d44 56 // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
pythontech 0:5868e8752d44 57 // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
pythontech 0:5868e8752d44 58 // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
pythontech 0:5868e8752d44 59 STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, int exec_flags) {
pythontech 0:5868e8752d44 60 int ret = 0;
pythontech 0:5868e8752d44 61 uint32_t start = 0;
pythontech 0:5868e8752d44 62
pythontech 0:5868e8752d44 63 nlr_buf_t nlr;
pythontech 0:5868e8752d44 64 if (nlr_push(&nlr) == 0) {
pythontech 0:5868e8752d44 65 // parse and compile the script
pythontech 0:5868e8752d44 66 qstr source_name = lex->source_name;
pythontech 0:5868e8752d44 67 mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
pythontech 0:5868e8752d44 68 mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
pythontech 0:5868e8752d44 69
pythontech 0:5868e8752d44 70 // execute code
pythontech 0:5868e8752d44 71 mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us
pythontech 0:5868e8752d44 72 start = mp_hal_ticks_ms();
pythontech 0:5868e8752d44 73 mp_call_function_0(module_fun);
pythontech 0:5868e8752d44 74 mp_hal_set_interrupt_char(-1); // disable interrupt
pythontech 0:5868e8752d44 75 nlr_pop();
pythontech 0:5868e8752d44 76 ret = 1;
pythontech 0:5868e8752d44 77 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
pythontech 0:5868e8752d44 78 mp_hal_stdout_tx_strn("\x04", 1);
pythontech 0:5868e8752d44 79 }
pythontech 0:5868e8752d44 80 } else {
pythontech 0:5868e8752d44 81 // uncaught exception
pythontech 0:5868e8752d44 82 // FIXME it could be that an interrupt happens just before we disable it here
pythontech 0:5868e8752d44 83 mp_hal_set_interrupt_char(-1); // disable interrupt
pythontech 0:5868e8752d44 84 // print EOF after normal output
pythontech 0:5868e8752d44 85 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
pythontech 0:5868e8752d44 86 mp_hal_stdout_tx_strn("\x04", 1);
pythontech 0:5868e8752d44 87 }
pythontech 0:5868e8752d44 88 // check for SystemExit
pythontech 0:5868e8752d44 89 if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) {
pythontech 0:5868e8752d44 90 // at the moment, the value of SystemExit is unused
pythontech 0:5868e8752d44 91 ret = PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 92 } else {
pythontech 0:5868e8752d44 93 mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
pythontech 0:5868e8752d44 94 ret = 0;
pythontech 0:5868e8752d44 95 }
pythontech 0:5868e8752d44 96 }
pythontech 0:5868e8752d44 97
pythontech 0:5868e8752d44 98 // display debugging info if wanted
pythontech 0:5868e8752d44 99 if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) {
pythontech 0:5868e8752d44 100 mp_uint_t ticks = mp_hal_ticks_ms() - start; // TODO implement a function that does this properly
pythontech 0:5868e8752d44 101 printf("took " UINT_FMT " ms\n", ticks);
pythontech 0:5868e8752d44 102 gc_collect();
pythontech 0:5868e8752d44 103 // qstr info
pythontech 0:5868e8752d44 104 {
pythontech 0:5868e8752d44 105 mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
pythontech 0:5868e8752d44 106 qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
pythontech 0:5868e8752d44 107 printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
pythontech 0:5868e8752d44 108 }
pythontech 0:5868e8752d44 109
pythontech 0:5868e8752d44 110 // GC info
pythontech 0:5868e8752d44 111 gc_dump_info();
pythontech 0:5868e8752d44 112 }
pythontech 0:5868e8752d44 113
pythontech 0:5868e8752d44 114 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
pythontech 0:5868e8752d44 115 mp_hal_stdout_tx_strn("\x04", 1);
pythontech 0:5868e8752d44 116 }
pythontech 0:5868e8752d44 117
pythontech 0:5868e8752d44 118 return ret;
pythontech 0:5868e8752d44 119 }
pythontech 0:5868e8752d44 120
pythontech 0:5868e8752d44 121 #if MICROPY_REPL_EVENT_DRIVEN
pythontech 0:5868e8752d44 122
pythontech 0:5868e8752d44 123 typedef struct _repl_t {
pythontech 0:5868e8752d44 124 // This structure originally also held current REPL line,
pythontech 0:5868e8752d44 125 // but it was moved to MP_STATE_VM(repl_line) as containing
pythontech 0:5868e8752d44 126 // root pointer. Still keep structure in case more state
pythontech 0:5868e8752d44 127 // will be added later.
pythontech 0:5868e8752d44 128 //vstr_t line;
pythontech 0:5868e8752d44 129 bool cont_line;
pythontech 0:5868e8752d44 130 } repl_t;
pythontech 0:5868e8752d44 131
pythontech 0:5868e8752d44 132 repl_t repl;
pythontech 0:5868e8752d44 133
pythontech 0:5868e8752d44 134 STATIC int pyexec_raw_repl_process_char(int c);
pythontech 0:5868e8752d44 135 STATIC int pyexec_friendly_repl_process_char(int c);
pythontech 0:5868e8752d44 136
pythontech 0:5868e8752d44 137 void pyexec_event_repl_init(void) {
pythontech 0:5868e8752d44 138 MP_STATE_VM(repl_line) = vstr_new_size(32);
pythontech 0:5868e8752d44 139 repl.cont_line = false;
pythontech 0:5868e8752d44 140 readline_init(MP_STATE_VM(repl_line), ">>> ");
pythontech 0:5868e8752d44 141 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
pythontech 0:5868e8752d44 142 pyexec_raw_repl_process_char(CHAR_CTRL_A);
pythontech 0:5868e8752d44 143 } else {
pythontech 0:5868e8752d44 144 pyexec_friendly_repl_process_char(CHAR_CTRL_B);
pythontech 0:5868e8752d44 145 }
pythontech 0:5868e8752d44 146 }
pythontech 0:5868e8752d44 147
pythontech 0:5868e8752d44 148 STATIC int pyexec_raw_repl_process_char(int c) {
pythontech 0:5868e8752d44 149 if (c == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 150 // reset raw REPL
pythontech 0:5868e8752d44 151 mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
pythontech 0:5868e8752d44 152 goto reset;
pythontech 0:5868e8752d44 153 } else if (c == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 154 // change to friendly REPL
pythontech 0:5868e8752d44 155 pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
pythontech 0:5868e8752d44 156 repl.cont_line = false;
pythontech 0:5868e8752d44 157 pyexec_friendly_repl_process_char(CHAR_CTRL_B);
pythontech 0:5868e8752d44 158 return 0;
pythontech 0:5868e8752d44 159 } else if (c == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 160 // clear line
pythontech 0:5868e8752d44 161 vstr_reset(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 162 return 0;
pythontech 0:5868e8752d44 163 } else if (c == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 164 // input finished
pythontech 0:5868e8752d44 165 } else {
pythontech 0:5868e8752d44 166 // let through any other raw 8-bit value
pythontech 0:5868e8752d44 167 vstr_add_byte(MP_STATE_VM(repl_line), c);
pythontech 0:5868e8752d44 168 return 0;
pythontech 0:5868e8752d44 169 }
pythontech 0:5868e8752d44 170
pythontech 0:5868e8752d44 171 // indicate reception of command
pythontech 0:5868e8752d44 172 mp_hal_stdout_tx_str("OK");
pythontech 0:5868e8752d44 173
pythontech 0:5868e8752d44 174 if (MP_STATE_VM(repl_line)->len == 0) {
pythontech 0:5868e8752d44 175 // exit for a soft reset
pythontech 0:5868e8752d44 176 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 177 vstr_clear(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 178 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 179 }
pythontech 0:5868e8752d44 180
pythontech 0:5868e8752d44 181 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);
pythontech 0:5868e8752d44 182 if (lex == NULL) {
pythontech 0:5868e8752d44 183 mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
pythontech 0:5868e8752d44 184 } else {
pythontech 0:5868e8752d44 185 int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
pythontech 0:5868e8752d44 186 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 187 return ret;
pythontech 0:5868e8752d44 188 }
pythontech 0:5868e8752d44 189 }
pythontech 0:5868e8752d44 190
pythontech 0:5868e8752d44 191 reset:
pythontech 0:5868e8752d44 192 vstr_reset(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 193 mp_hal_stdout_tx_str(">");
pythontech 0:5868e8752d44 194
pythontech 0:5868e8752d44 195 return 0;
pythontech 0:5868e8752d44 196 }
pythontech 0:5868e8752d44 197
pythontech 0:5868e8752d44 198 STATIC int pyexec_friendly_repl_process_char(int c) {
pythontech 0:5868e8752d44 199 int ret = readline_process_char(c);
pythontech 0:5868e8752d44 200
pythontech 0:5868e8752d44 201 if (!repl.cont_line) {
pythontech 0:5868e8752d44 202
pythontech 0:5868e8752d44 203 if (ret == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 204 // change to raw REPL
pythontech 0:5868e8752d44 205 pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
pythontech 0:5868e8752d44 206 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 207 pyexec_raw_repl_process_char(CHAR_CTRL_A);
pythontech 0:5868e8752d44 208 return 0;
pythontech 0:5868e8752d44 209 } else if (ret == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 210 // reset friendly REPL
pythontech 0:5868e8752d44 211 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 212 mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n");
pythontech 0:5868e8752d44 213 mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
pythontech 0:5868e8752d44 214 goto input_restart;
pythontech 0:5868e8752d44 215 } else if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 216 // break
pythontech 0:5868e8752d44 217 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 218 goto input_restart;
pythontech 0:5868e8752d44 219 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 220 // exit for a soft reset
pythontech 0:5868e8752d44 221 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 222 vstr_clear(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 223 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 224 }
pythontech 0:5868e8752d44 225
pythontech 0:5868e8752d44 226 if (ret < 0) {
pythontech 0:5868e8752d44 227 return 0;
pythontech 0:5868e8752d44 228 }
pythontech 0:5868e8752d44 229
pythontech 0:5868e8752d44 230 if (!mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) {
pythontech 0:5868e8752d44 231 goto exec;
pythontech 0:5868e8752d44 232 }
pythontech 0:5868e8752d44 233
pythontech 0:5868e8752d44 234 vstr_add_byte(MP_STATE_VM(repl_line), '\n');
pythontech 0:5868e8752d44 235 repl.cont_line = true;
pythontech 0:5868e8752d44 236 readline_note_newline("... ");
pythontech 0:5868e8752d44 237 return 0;
pythontech 0:5868e8752d44 238
pythontech 0:5868e8752d44 239 } else {
pythontech 0:5868e8752d44 240
pythontech 0:5868e8752d44 241 if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 242 // cancel everything
pythontech 0:5868e8752d44 243 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 244 repl.cont_line = false;
pythontech 0:5868e8752d44 245 goto input_restart;
pythontech 0:5868e8752d44 246 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 247 // stop entering compound statement
pythontech 0:5868e8752d44 248 goto exec;
pythontech 0:5868e8752d44 249 }
pythontech 0:5868e8752d44 250
pythontech 0:5868e8752d44 251 if (ret < 0) {
pythontech 0:5868e8752d44 252 return 0;
pythontech 0:5868e8752d44 253 }
pythontech 0:5868e8752d44 254
pythontech 0:5868e8752d44 255 if (mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) {
pythontech 0:5868e8752d44 256 vstr_add_byte(MP_STATE_VM(repl_line), '\n');
pythontech 0:5868e8752d44 257 readline_note_newline("... ");
pythontech 0:5868e8752d44 258 return 0;
pythontech 0:5868e8752d44 259 }
pythontech 0:5868e8752d44 260
pythontech 0:5868e8752d44 261 exec: ;
pythontech 0:5868e8752d44 262 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);
pythontech 0:5868e8752d44 263 if (lex == NULL) {
pythontech 0:5868e8752d44 264 printf("MemoryError\n");
pythontech 0:5868e8752d44 265 } else {
pythontech 0:5868e8752d44 266 int ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
pythontech 0:5868e8752d44 267 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 268 return ret;
pythontech 0:5868e8752d44 269 }
pythontech 0:5868e8752d44 270 }
pythontech 0:5868e8752d44 271
pythontech 0:5868e8752d44 272 input_restart:
pythontech 0:5868e8752d44 273 vstr_reset(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 274 repl.cont_line = false;
pythontech 0:5868e8752d44 275 readline_init(MP_STATE_VM(repl_line), ">>> ");
pythontech 0:5868e8752d44 276 return 0;
pythontech 0:5868e8752d44 277 }
pythontech 0:5868e8752d44 278 }
pythontech 0:5868e8752d44 279
pythontech 0:5868e8752d44 280 uint8_t pyexec_repl_active;
pythontech 0:5868e8752d44 281 int pyexec_event_repl_process_char(int c) {
pythontech 0:5868e8752d44 282 pyexec_repl_active = 1;
pythontech 0:5868e8752d44 283 int res;
pythontech 0:5868e8752d44 284 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
pythontech 0:5868e8752d44 285 res = pyexec_raw_repl_process_char(c);
pythontech 0:5868e8752d44 286 } else {
pythontech 0:5868e8752d44 287 res = pyexec_friendly_repl_process_char(c);
pythontech 0:5868e8752d44 288 }
pythontech 0:5868e8752d44 289 pyexec_repl_active = 0;
pythontech 0:5868e8752d44 290 return res;
pythontech 0:5868e8752d44 291 }
pythontech 0:5868e8752d44 292
pythontech 0:5868e8752d44 293 #else // MICROPY_REPL_EVENT_DRIVEN
pythontech 0:5868e8752d44 294
pythontech 0:5868e8752d44 295 int pyexec_raw_repl(void) {
pythontech 0:5868e8752d44 296 vstr_t line;
pythontech 0:5868e8752d44 297 vstr_init(&line, 32);
pythontech 0:5868e8752d44 298
pythontech 0:5868e8752d44 299 raw_repl_reset:
pythontech 0:5868e8752d44 300 mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
pythontech 0:5868e8752d44 301
pythontech 0:5868e8752d44 302 for (;;) {
pythontech 0:5868e8752d44 303 vstr_reset(&line);
pythontech 0:5868e8752d44 304 mp_hal_stdout_tx_str(">");
pythontech 0:5868e8752d44 305 for (;;) {
pythontech 0:5868e8752d44 306 int c = mp_hal_stdin_rx_chr();
pythontech 0:5868e8752d44 307 if (c == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 308 // reset raw REPL
pythontech 0:5868e8752d44 309 goto raw_repl_reset;
pythontech 0:5868e8752d44 310 } else if (c == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 311 // change to friendly REPL
pythontech 0:5868e8752d44 312 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 313 vstr_clear(&line);
pythontech 0:5868e8752d44 314 pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
pythontech 0:5868e8752d44 315 return 0;
pythontech 0:5868e8752d44 316 } else if (c == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 317 // clear line
pythontech 0:5868e8752d44 318 vstr_reset(&line);
pythontech 0:5868e8752d44 319 } else if (c == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 320 // input finished
pythontech 0:5868e8752d44 321 break;
pythontech 0:5868e8752d44 322 } else {
pythontech 0:5868e8752d44 323 // let through any other raw 8-bit value
pythontech 0:5868e8752d44 324 vstr_add_byte(&line, c);
pythontech 0:5868e8752d44 325 }
pythontech 0:5868e8752d44 326 }
pythontech 0:5868e8752d44 327
pythontech 0:5868e8752d44 328 // indicate reception of command
pythontech 0:5868e8752d44 329 mp_hal_stdout_tx_str("OK");
pythontech 0:5868e8752d44 330
pythontech 0:5868e8752d44 331 if (line.len == 0) {
pythontech 0:5868e8752d44 332 // exit for a soft reset
pythontech 0:5868e8752d44 333 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 334 vstr_clear(&line);
pythontech 0:5868e8752d44 335 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 336 }
pythontech 0:5868e8752d44 337
pythontech 0:5868e8752d44 338 mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
pythontech 0:5868e8752d44 339 if (lex == NULL) {
pythontech 0:5868e8752d44 340 printf("\x04MemoryError\n\x04");
pythontech 0:5868e8752d44 341 } else {
pythontech 0:5868e8752d44 342 int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
pythontech 0:5868e8752d44 343 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 344 return ret;
pythontech 0:5868e8752d44 345 }
pythontech 0:5868e8752d44 346 }
pythontech 0:5868e8752d44 347 }
pythontech 0:5868e8752d44 348 }
pythontech 0:5868e8752d44 349
pythontech 0:5868e8752d44 350 int pyexec_friendly_repl(void) {
pythontech 0:5868e8752d44 351 vstr_t line;
pythontech 0:5868e8752d44 352 vstr_init(&line, 32);
pythontech 0:5868e8752d44 353
pythontech 0:5868e8752d44 354 #if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
pythontech 0:5868e8752d44 355 // in host mode, we enable the LCD for the repl
pythontech 0:5868e8752d44 356 mp_obj_t lcd_o = mp_call_function_0(mp_load_name(qstr_from_str("LCD")));
pythontech 0:5868e8752d44 357 mp_call_function_1(mp_load_attr(lcd_o, qstr_from_str("light")), mp_const_true);
pythontech 0:5868e8752d44 358 #endif
pythontech 0:5868e8752d44 359
pythontech 0:5868e8752d44 360 friendly_repl_reset:
pythontech 0:5868e8752d44 361 mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n");
pythontech 0:5868e8752d44 362 mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
pythontech 0:5868e8752d44 363
pythontech 0:5868e8752d44 364 // to test ctrl-C
pythontech 0:5868e8752d44 365 /*
pythontech 0:5868e8752d44 366 {
pythontech 0:5868e8752d44 367 uint32_t x[4] = {0x424242, 0xdeaddead, 0x242424, 0xdeadbeef};
pythontech 0:5868e8752d44 368 for (;;) {
pythontech 0:5868e8752d44 369 nlr_buf_t nlr;
pythontech 0:5868e8752d44 370 printf("pyexec_repl: %p\n", x);
pythontech 0:5868e8752d44 371 mp_hal_set_interrupt_char(CHAR_CTRL_C);
pythontech 0:5868e8752d44 372 if (nlr_push(&nlr) == 0) {
pythontech 0:5868e8752d44 373 for (;;) {
pythontech 0:5868e8752d44 374 }
pythontech 0:5868e8752d44 375 } else {
pythontech 0:5868e8752d44 376 printf("break\n");
pythontech 0:5868e8752d44 377 }
pythontech 0:5868e8752d44 378 }
pythontech 0:5868e8752d44 379 }
pythontech 0:5868e8752d44 380 */
pythontech 0:5868e8752d44 381
pythontech 0:5868e8752d44 382 for (;;) {
pythontech 0:5868e8752d44 383 input_restart:
pythontech 0:5868e8752d44 384
pythontech 0:5868e8752d44 385 #if defined(USE_DEVICE_MODE)
pythontech 0:5868e8752d44 386 if (usb_vcp_is_enabled()) {
pythontech 0:5868e8752d44 387 // If the user gets to here and interrupts are disabled then
pythontech 0:5868e8752d44 388 // they'll never see the prompt, traceback etc. The USB REPL needs
pythontech 0:5868e8752d44 389 // interrupts to be enabled or no transfers occur. So we try to
pythontech 0:5868e8752d44 390 // do the user a favor and reenable interrupts.
pythontech 0:5868e8752d44 391 if (query_irq() == IRQ_STATE_DISABLED) {
pythontech 0:5868e8752d44 392 enable_irq(IRQ_STATE_ENABLED);
pythontech 0:5868e8752d44 393 mp_hal_stdout_tx_str("PYB: enabling IRQs\r\n");
pythontech 0:5868e8752d44 394 }
pythontech 0:5868e8752d44 395 }
pythontech 0:5868e8752d44 396 #endif
pythontech 0:5868e8752d44 397
pythontech 0:5868e8752d44 398 vstr_reset(&line);
pythontech 0:5868e8752d44 399 int ret = readline(&line, ">>> ");
pythontech 0:5868e8752d44 400 mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT;
pythontech 0:5868e8752d44 401
pythontech 0:5868e8752d44 402 if (ret == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 403 // change to raw REPL
pythontech 0:5868e8752d44 404 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 405 vstr_clear(&line);
pythontech 0:5868e8752d44 406 pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
pythontech 0:5868e8752d44 407 return 0;
pythontech 0:5868e8752d44 408 } else if (ret == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 409 // reset friendly REPL
pythontech 0:5868e8752d44 410 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 411 goto friendly_repl_reset;
pythontech 0:5868e8752d44 412 } else if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 413 // break
pythontech 0:5868e8752d44 414 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 415 continue;
pythontech 0:5868e8752d44 416 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 417 // exit for a soft reset
pythontech 0:5868e8752d44 418 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 419 vstr_clear(&line);
pythontech 0:5868e8752d44 420 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 421 } else if (ret == CHAR_CTRL_E) {
pythontech 0:5868e8752d44 422 // paste mode
pythontech 0:5868e8752d44 423 mp_hal_stdout_tx_str("\r\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== ");
pythontech 0:5868e8752d44 424 vstr_reset(&line);
pythontech 0:5868e8752d44 425 for (;;) {
pythontech 0:5868e8752d44 426 char c = mp_hal_stdin_rx_chr();
pythontech 0:5868e8752d44 427 if (c == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 428 // cancel everything
pythontech 0:5868e8752d44 429 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 430 goto input_restart;
pythontech 0:5868e8752d44 431 } else if (c == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 432 // end of input
pythontech 0:5868e8752d44 433 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 434 break;
pythontech 0:5868e8752d44 435 } else {
pythontech 0:5868e8752d44 436 // add char to buffer and echo
pythontech 0:5868e8752d44 437 vstr_add_byte(&line, c);
pythontech 0:5868e8752d44 438 if (c == '\r') {
pythontech 0:5868e8752d44 439 mp_hal_stdout_tx_str("\r\n=== ");
pythontech 0:5868e8752d44 440 } else {
pythontech 0:5868e8752d44 441 mp_hal_stdout_tx_strn(&c, 1);
pythontech 0:5868e8752d44 442 }
pythontech 0:5868e8752d44 443 }
pythontech 0:5868e8752d44 444 }
pythontech 0:5868e8752d44 445 parse_input_kind = MP_PARSE_FILE_INPUT;
pythontech 0:5868e8752d44 446 } else if (vstr_len(&line) == 0) {
pythontech 0:5868e8752d44 447 continue;
pythontech 0:5868e8752d44 448 } else {
pythontech 0:5868e8752d44 449 // got a line with non-zero length, see if it needs continuing
pythontech 0:5868e8752d44 450 while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) {
pythontech 0:5868e8752d44 451 vstr_add_byte(&line, '\n');
pythontech 0:5868e8752d44 452 ret = readline(&line, "... ");
pythontech 0:5868e8752d44 453 if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 454 // cancel everything
pythontech 0:5868e8752d44 455 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 456 goto input_restart;
pythontech 0:5868e8752d44 457 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 458 // stop entering compound statement
pythontech 0:5868e8752d44 459 break;
pythontech 0:5868e8752d44 460 }
pythontech 0:5868e8752d44 461 }
pythontech 0:5868e8752d44 462 }
pythontech 0:5868e8752d44 463
pythontech 0:5868e8752d44 464 mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
pythontech 0:5868e8752d44 465 if (lex == NULL) {
pythontech 0:5868e8752d44 466 printf("MemoryError\n");
pythontech 0:5868e8752d44 467 } else {
pythontech 0:5868e8752d44 468 ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
pythontech 0:5868e8752d44 469 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 470 return ret;
pythontech 0:5868e8752d44 471 }
pythontech 0:5868e8752d44 472 }
pythontech 0:5868e8752d44 473 }
pythontech 0:5868e8752d44 474 }
pythontech 0:5868e8752d44 475
pythontech 0:5868e8752d44 476 #endif // MICROPY_REPL_EVENT_DRIVEN
pythontech 0:5868e8752d44 477
pythontech 0:5868e8752d44 478 int pyexec_file(const char *filename) {
pythontech 0:5868e8752d44 479 mp_lexer_t *lex = mp_lexer_new_from_file(filename);
pythontech 0:5868e8752d44 480
pythontech 0:5868e8752d44 481 if (lex == NULL) {
pythontech 0:5868e8752d44 482 printf("could not open file '%s' for reading\n", filename);
pythontech 0:5868e8752d44 483 return false;
pythontech 0:5868e8752d44 484 }
pythontech 0:5868e8752d44 485
pythontech 0:5868e8752d44 486 return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
pythontech 0:5868e8752d44 487 }
pythontech 0:5868e8752d44 488
pythontech 0:5868e8752d44 489 #if MICROPY_MODULE_FROZEN
pythontech 0:5868e8752d44 490 int pyexec_frozen_module(const char *name) {
pythontech 0:5868e8752d44 491 mp_lexer_t *lex = mp_find_frozen_module(name, strlen(name));
pythontech 0:5868e8752d44 492
pythontech 0:5868e8752d44 493 if (lex == NULL) {
pythontech 0:5868e8752d44 494 printf("could not find module '%s'\n", name);
pythontech 0:5868e8752d44 495 return false;
pythontech 0:5868e8752d44 496 }
pythontech 0:5868e8752d44 497
pythontech 0:5868e8752d44 498 return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
pythontech 0:5868e8752d44 499 }
pythontech 0:5868e8752d44 500 #endif
pythontech 0:5868e8752d44 501
pythontech 0:5868e8752d44 502 mp_obj_t pyb_set_repl_info(mp_obj_t o_value) {
pythontech 0:5868e8752d44 503 repl_display_debugging_info = mp_obj_get_int(o_value);
pythontech 0:5868e8752d44 504 return mp_const_none;
pythontech 0:5868e8752d44 505 }
pythontech 0:5868e8752d44 506
pythontech 0:5868e8752d44 507 MP_DEFINE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj, pyb_set_repl_info);