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:
Colin Hogben
Date:
Wed Apr 27 22:11:29 2016 +0100
Revision:
10:33521d742af1
Parent:
5:1d19b8110e11
Update README and version

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)
Colin Hogben 2:c89e95946844 53 #define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
pythontech 0:5868e8752d44 54
pythontech 0:5868e8752d44 55 // parses, compiles and executes the code in the lexer
pythontech 0:5868e8752d44 56 // frees the lexer before returning
pythontech 0:5868e8752d44 57 // EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after exception output
pythontech 0:5868e8752d44 58 // EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after executing the code
pythontech 0:5868e8752d44 59 // EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile)
Colin Hogben 2:c89e95946844 60 STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
pythontech 0:5868e8752d44 61 int ret = 0;
pythontech 0:5868e8752d44 62 uint32_t start = 0;
pythontech 0:5868e8752d44 63
pythontech 0:5868e8752d44 64 nlr_buf_t nlr;
pythontech 0:5868e8752d44 65 if (nlr_push(&nlr) == 0) {
Colin Hogben 2:c89e95946844 66 mp_obj_t module_fun;
Colin Hogben 2:c89e95946844 67 #if MICROPY_MODULE_FROZEN_MPY
Colin Hogben 2:c89e95946844 68 if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) {
Colin Hogben 2:c89e95946844 69 // source is a raw_code object, create the function
Colin Hogben 2:c89e95946844 70 module_fun = mp_make_function_from_raw_code(source, MP_OBJ_NULL, MP_OBJ_NULL);
Colin Hogben 2:c89e95946844 71 } else
Colin Hogben 2:c89e95946844 72 #endif
Colin Hogben 2:c89e95946844 73 {
Colin Hogben 2:c89e95946844 74 // source is a lexer, parse and compile the script
Colin Hogben 2:c89e95946844 75 mp_lexer_t *lex = source;
Colin Hogben 2:c89e95946844 76 qstr source_name = lex->source_name;
Colin Hogben 2:c89e95946844 77 mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
Colin Hogben 2:c89e95946844 78 module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
Colin Hogben 2:c89e95946844 79 }
pythontech 0:5868e8752d44 80
pythontech 0:5868e8752d44 81 // execute code
pythontech 0:5868e8752d44 82 mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us
pythontech 0:5868e8752d44 83 start = mp_hal_ticks_ms();
pythontech 0:5868e8752d44 84 mp_call_function_0(module_fun);
pythontech 0:5868e8752d44 85 mp_hal_set_interrupt_char(-1); // disable interrupt
pythontech 0:5868e8752d44 86 nlr_pop();
pythontech 0:5868e8752d44 87 ret = 1;
pythontech 0:5868e8752d44 88 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
pythontech 0:5868e8752d44 89 mp_hal_stdout_tx_strn("\x04", 1);
pythontech 0:5868e8752d44 90 }
pythontech 0:5868e8752d44 91 } else {
pythontech 0:5868e8752d44 92 // uncaught exception
pythontech 0:5868e8752d44 93 // FIXME it could be that an interrupt happens just before we disable it here
pythontech 0:5868e8752d44 94 mp_hal_set_interrupt_char(-1); // disable interrupt
pythontech 0:5868e8752d44 95 // print EOF after normal output
pythontech 0:5868e8752d44 96 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
pythontech 0:5868e8752d44 97 mp_hal_stdout_tx_strn("\x04", 1);
pythontech 0:5868e8752d44 98 }
pythontech 0:5868e8752d44 99 // check for SystemExit
pythontech 0:5868e8752d44 100 if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) {
pythontech 0:5868e8752d44 101 // at the moment, the value of SystemExit is unused
pythontech 0:5868e8752d44 102 ret = PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 103 } else {
pythontech 0:5868e8752d44 104 mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
pythontech 0:5868e8752d44 105 ret = 0;
pythontech 0:5868e8752d44 106 }
pythontech 0:5868e8752d44 107 }
pythontech 0:5868e8752d44 108
pythontech 0:5868e8752d44 109 // display debugging info if wanted
pythontech 0:5868e8752d44 110 if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) {
pythontech 0:5868e8752d44 111 mp_uint_t ticks = mp_hal_ticks_ms() - start; // TODO implement a function that does this properly
pythontech 0:5868e8752d44 112 printf("took " UINT_FMT " ms\n", ticks);
pythontech 0:5868e8752d44 113 // qstr info
pythontech 0:5868e8752d44 114 {
pythontech 0:5868e8752d44 115 mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
pythontech 0:5868e8752d44 116 qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
pythontech 0:5868e8752d44 117 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 118 }
pythontech 0:5868e8752d44 119
Colin Hogben 5:1d19b8110e11 120 #if MICROPY_ENABLE_GC
Colin Hogben 5:1d19b8110e11 121 // run collection and print GC info
Colin Hogben 5:1d19b8110e11 122 gc_collect();
pythontech 0:5868e8752d44 123 gc_dump_info();
Colin Hogben 5:1d19b8110e11 124 #endif
pythontech 0:5868e8752d44 125 }
pythontech 0:5868e8752d44 126
pythontech 0:5868e8752d44 127 if (exec_flags & EXEC_FLAG_PRINT_EOF) {
pythontech 0:5868e8752d44 128 mp_hal_stdout_tx_strn("\x04", 1);
pythontech 0:5868e8752d44 129 }
pythontech 0:5868e8752d44 130
pythontech 0:5868e8752d44 131 return ret;
pythontech 0:5868e8752d44 132 }
pythontech 0:5868e8752d44 133
pythontech 0:5868e8752d44 134 #if MICROPY_REPL_EVENT_DRIVEN
pythontech 0:5868e8752d44 135
pythontech 0:5868e8752d44 136 typedef struct _repl_t {
pythontech 0:5868e8752d44 137 // This structure originally also held current REPL line,
pythontech 0:5868e8752d44 138 // but it was moved to MP_STATE_VM(repl_line) as containing
pythontech 0:5868e8752d44 139 // root pointer. Still keep structure in case more state
pythontech 0:5868e8752d44 140 // will be added later.
pythontech 0:5868e8752d44 141 //vstr_t line;
pythontech 0:5868e8752d44 142 bool cont_line;
pythontech 0:5868e8752d44 143 } repl_t;
pythontech 0:5868e8752d44 144
pythontech 0:5868e8752d44 145 repl_t repl;
pythontech 0:5868e8752d44 146
pythontech 0:5868e8752d44 147 STATIC int pyexec_raw_repl_process_char(int c);
pythontech 0:5868e8752d44 148 STATIC int pyexec_friendly_repl_process_char(int c);
pythontech 0:5868e8752d44 149
pythontech 0:5868e8752d44 150 void pyexec_event_repl_init(void) {
pythontech 0:5868e8752d44 151 MP_STATE_VM(repl_line) = vstr_new_size(32);
pythontech 0:5868e8752d44 152 repl.cont_line = false;
pythontech 0:5868e8752d44 153 readline_init(MP_STATE_VM(repl_line), ">>> ");
pythontech 0:5868e8752d44 154 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
pythontech 0:5868e8752d44 155 pyexec_raw_repl_process_char(CHAR_CTRL_A);
pythontech 0:5868e8752d44 156 } else {
pythontech 0:5868e8752d44 157 pyexec_friendly_repl_process_char(CHAR_CTRL_B);
pythontech 0:5868e8752d44 158 }
pythontech 0:5868e8752d44 159 }
pythontech 0:5868e8752d44 160
pythontech 0:5868e8752d44 161 STATIC int pyexec_raw_repl_process_char(int c) {
pythontech 0:5868e8752d44 162 if (c == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 163 // reset raw REPL
pythontech 0:5868e8752d44 164 mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
pythontech 0:5868e8752d44 165 goto reset;
pythontech 0:5868e8752d44 166 } else if (c == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 167 // change to friendly REPL
pythontech 0:5868e8752d44 168 pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
pythontech 0:5868e8752d44 169 repl.cont_line = false;
pythontech 0:5868e8752d44 170 pyexec_friendly_repl_process_char(CHAR_CTRL_B);
pythontech 0:5868e8752d44 171 return 0;
pythontech 0:5868e8752d44 172 } else if (c == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 173 // clear line
pythontech 0:5868e8752d44 174 vstr_reset(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 175 return 0;
pythontech 0:5868e8752d44 176 } else if (c == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 177 // input finished
pythontech 0:5868e8752d44 178 } else {
pythontech 0:5868e8752d44 179 // let through any other raw 8-bit value
pythontech 0:5868e8752d44 180 vstr_add_byte(MP_STATE_VM(repl_line), c);
pythontech 0:5868e8752d44 181 return 0;
pythontech 0:5868e8752d44 182 }
pythontech 0:5868e8752d44 183
pythontech 0:5868e8752d44 184 // indicate reception of command
pythontech 0:5868e8752d44 185 mp_hal_stdout_tx_str("OK");
pythontech 0:5868e8752d44 186
pythontech 0:5868e8752d44 187 if (MP_STATE_VM(repl_line)->len == 0) {
pythontech 0:5868e8752d44 188 // exit for a soft reset
pythontech 0:5868e8752d44 189 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 190 vstr_clear(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 191 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 192 }
pythontech 0:5868e8752d44 193
pythontech 0:5868e8752d44 194 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 195 if (lex == NULL) {
pythontech 0:5868e8752d44 196 mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
pythontech 0:5868e8752d44 197 } else {
pythontech 0:5868e8752d44 198 int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
pythontech 0:5868e8752d44 199 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 200 return ret;
pythontech 0:5868e8752d44 201 }
pythontech 0:5868e8752d44 202 }
pythontech 0:5868e8752d44 203
pythontech 0:5868e8752d44 204 reset:
pythontech 0:5868e8752d44 205 vstr_reset(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 206 mp_hal_stdout_tx_str(">");
pythontech 0:5868e8752d44 207
pythontech 0:5868e8752d44 208 return 0;
pythontech 0:5868e8752d44 209 }
pythontech 0:5868e8752d44 210
pythontech 0:5868e8752d44 211 STATIC int pyexec_friendly_repl_process_char(int c) {
pythontech 0:5868e8752d44 212 int ret = readline_process_char(c);
pythontech 0:5868e8752d44 213
pythontech 0:5868e8752d44 214 if (!repl.cont_line) {
pythontech 0:5868e8752d44 215
pythontech 0:5868e8752d44 216 if (ret == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 217 // change to raw REPL
pythontech 0:5868e8752d44 218 pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
pythontech 0:5868e8752d44 219 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 220 pyexec_raw_repl_process_char(CHAR_CTRL_A);
pythontech 0:5868e8752d44 221 return 0;
pythontech 0:5868e8752d44 222 } else if (ret == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 223 // reset friendly REPL
pythontech 0:5868e8752d44 224 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 225 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 226 mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
pythontech 0:5868e8752d44 227 goto input_restart;
pythontech 0:5868e8752d44 228 } else if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 229 // break
pythontech 0:5868e8752d44 230 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 231 goto input_restart;
pythontech 0:5868e8752d44 232 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 233 // exit for a soft reset
pythontech 0:5868e8752d44 234 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 235 vstr_clear(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 236 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 237 }
pythontech 0:5868e8752d44 238
pythontech 0:5868e8752d44 239 if (ret < 0) {
pythontech 0:5868e8752d44 240 return 0;
pythontech 0:5868e8752d44 241 }
pythontech 0:5868e8752d44 242
pythontech 0:5868e8752d44 243 if (!mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) {
pythontech 0:5868e8752d44 244 goto exec;
pythontech 0:5868e8752d44 245 }
pythontech 0:5868e8752d44 246
pythontech 0:5868e8752d44 247 vstr_add_byte(MP_STATE_VM(repl_line), '\n');
pythontech 0:5868e8752d44 248 repl.cont_line = true;
pythontech 0:5868e8752d44 249 readline_note_newline("... ");
pythontech 0:5868e8752d44 250 return 0;
pythontech 0:5868e8752d44 251
pythontech 0:5868e8752d44 252 } else {
pythontech 0:5868e8752d44 253
pythontech 0:5868e8752d44 254 if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 255 // cancel everything
pythontech 0:5868e8752d44 256 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 257 repl.cont_line = false;
pythontech 0:5868e8752d44 258 goto input_restart;
pythontech 0:5868e8752d44 259 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 260 // stop entering compound statement
pythontech 0:5868e8752d44 261 goto exec;
pythontech 0:5868e8752d44 262 }
pythontech 0:5868e8752d44 263
pythontech 0:5868e8752d44 264 if (ret < 0) {
pythontech 0:5868e8752d44 265 return 0;
pythontech 0:5868e8752d44 266 }
pythontech 0:5868e8752d44 267
pythontech 0:5868e8752d44 268 if (mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) {
pythontech 0:5868e8752d44 269 vstr_add_byte(MP_STATE_VM(repl_line), '\n');
pythontech 0:5868e8752d44 270 readline_note_newline("... ");
pythontech 0:5868e8752d44 271 return 0;
pythontech 0:5868e8752d44 272 }
pythontech 0:5868e8752d44 273
pythontech 0:5868e8752d44 274 exec: ;
pythontech 0:5868e8752d44 275 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 276 if (lex == NULL) {
pythontech 0:5868e8752d44 277 printf("MemoryError\n");
pythontech 0:5868e8752d44 278 } else {
pythontech 0:5868e8752d44 279 int ret = parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
pythontech 0:5868e8752d44 280 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 281 return ret;
pythontech 0:5868e8752d44 282 }
pythontech 0:5868e8752d44 283 }
pythontech 0:5868e8752d44 284
pythontech 0:5868e8752d44 285 input_restart:
pythontech 0:5868e8752d44 286 vstr_reset(MP_STATE_VM(repl_line));
pythontech 0:5868e8752d44 287 repl.cont_line = false;
pythontech 0:5868e8752d44 288 readline_init(MP_STATE_VM(repl_line), ">>> ");
pythontech 0:5868e8752d44 289 return 0;
pythontech 0:5868e8752d44 290 }
pythontech 0:5868e8752d44 291 }
pythontech 0:5868e8752d44 292
pythontech 0:5868e8752d44 293 uint8_t pyexec_repl_active;
pythontech 0:5868e8752d44 294 int pyexec_event_repl_process_char(int c) {
pythontech 0:5868e8752d44 295 pyexec_repl_active = 1;
pythontech 0:5868e8752d44 296 int res;
pythontech 0:5868e8752d44 297 if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
pythontech 0:5868e8752d44 298 res = pyexec_raw_repl_process_char(c);
pythontech 0:5868e8752d44 299 } else {
pythontech 0:5868e8752d44 300 res = pyexec_friendly_repl_process_char(c);
pythontech 0:5868e8752d44 301 }
pythontech 0:5868e8752d44 302 pyexec_repl_active = 0;
pythontech 0:5868e8752d44 303 return res;
pythontech 0:5868e8752d44 304 }
pythontech 0:5868e8752d44 305
pythontech 0:5868e8752d44 306 #else // MICROPY_REPL_EVENT_DRIVEN
pythontech 0:5868e8752d44 307
pythontech 0:5868e8752d44 308 int pyexec_raw_repl(void) {
pythontech 0:5868e8752d44 309 vstr_t line;
pythontech 0:5868e8752d44 310 vstr_init(&line, 32);
pythontech 0:5868e8752d44 311
pythontech 0:5868e8752d44 312 raw_repl_reset:
pythontech 0:5868e8752d44 313 mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
pythontech 0:5868e8752d44 314
pythontech 0:5868e8752d44 315 for (;;) {
pythontech 0:5868e8752d44 316 vstr_reset(&line);
pythontech 0:5868e8752d44 317 mp_hal_stdout_tx_str(">");
pythontech 0:5868e8752d44 318 for (;;) {
pythontech 0:5868e8752d44 319 int c = mp_hal_stdin_rx_chr();
pythontech 0:5868e8752d44 320 if (c == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 321 // reset raw REPL
pythontech 0:5868e8752d44 322 goto raw_repl_reset;
pythontech 0:5868e8752d44 323 } else if (c == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 324 // change to friendly REPL
pythontech 0:5868e8752d44 325 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 326 vstr_clear(&line);
pythontech 0:5868e8752d44 327 pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
pythontech 0:5868e8752d44 328 return 0;
pythontech 0:5868e8752d44 329 } else if (c == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 330 // clear line
pythontech 0:5868e8752d44 331 vstr_reset(&line);
pythontech 0:5868e8752d44 332 } else if (c == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 333 // input finished
pythontech 0:5868e8752d44 334 break;
pythontech 0:5868e8752d44 335 } else {
pythontech 0:5868e8752d44 336 // let through any other raw 8-bit value
pythontech 0:5868e8752d44 337 vstr_add_byte(&line, c);
pythontech 0:5868e8752d44 338 }
pythontech 0:5868e8752d44 339 }
pythontech 0:5868e8752d44 340
pythontech 0:5868e8752d44 341 // indicate reception of command
pythontech 0:5868e8752d44 342 mp_hal_stdout_tx_str("OK");
pythontech 0:5868e8752d44 343
pythontech 0:5868e8752d44 344 if (line.len == 0) {
pythontech 0:5868e8752d44 345 // exit for a soft reset
pythontech 0:5868e8752d44 346 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 347 vstr_clear(&line);
pythontech 0:5868e8752d44 348 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 349 }
pythontech 0:5868e8752d44 350
pythontech 0:5868e8752d44 351 mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
pythontech 0:5868e8752d44 352 if (lex == NULL) {
pythontech 0:5868e8752d44 353 printf("\x04MemoryError\n\x04");
pythontech 0:5868e8752d44 354 } else {
pythontech 0:5868e8752d44 355 int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
pythontech 0:5868e8752d44 356 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 357 return ret;
pythontech 0:5868e8752d44 358 }
pythontech 0:5868e8752d44 359 }
pythontech 0:5868e8752d44 360 }
pythontech 0:5868e8752d44 361 }
pythontech 0:5868e8752d44 362
pythontech 0:5868e8752d44 363 int pyexec_friendly_repl(void) {
pythontech 0:5868e8752d44 364 vstr_t line;
pythontech 0:5868e8752d44 365 vstr_init(&line, 32);
pythontech 0:5868e8752d44 366
pythontech 0:5868e8752d44 367 #if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
pythontech 0:5868e8752d44 368 // in host mode, we enable the LCD for the repl
pythontech 0:5868e8752d44 369 mp_obj_t lcd_o = mp_call_function_0(mp_load_name(qstr_from_str("LCD")));
pythontech 0:5868e8752d44 370 mp_call_function_1(mp_load_attr(lcd_o, qstr_from_str("light")), mp_const_true);
pythontech 0:5868e8752d44 371 #endif
pythontech 0:5868e8752d44 372
pythontech 0:5868e8752d44 373 friendly_repl_reset:
pythontech 0:5868e8752d44 374 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 375 mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n");
pythontech 0:5868e8752d44 376
pythontech 0:5868e8752d44 377 // to test ctrl-C
pythontech 0:5868e8752d44 378 /*
pythontech 0:5868e8752d44 379 {
pythontech 0:5868e8752d44 380 uint32_t x[4] = {0x424242, 0xdeaddead, 0x242424, 0xdeadbeef};
pythontech 0:5868e8752d44 381 for (;;) {
pythontech 0:5868e8752d44 382 nlr_buf_t nlr;
pythontech 0:5868e8752d44 383 printf("pyexec_repl: %p\n", x);
pythontech 0:5868e8752d44 384 mp_hal_set_interrupt_char(CHAR_CTRL_C);
pythontech 0:5868e8752d44 385 if (nlr_push(&nlr) == 0) {
pythontech 0:5868e8752d44 386 for (;;) {
pythontech 0:5868e8752d44 387 }
pythontech 0:5868e8752d44 388 } else {
pythontech 0:5868e8752d44 389 printf("break\n");
pythontech 0:5868e8752d44 390 }
pythontech 0:5868e8752d44 391 }
pythontech 0:5868e8752d44 392 }
pythontech 0:5868e8752d44 393 */
pythontech 0:5868e8752d44 394
pythontech 0:5868e8752d44 395 for (;;) {
pythontech 0:5868e8752d44 396 input_restart:
pythontech 0:5868e8752d44 397
pythontech 0:5868e8752d44 398 #if defined(USE_DEVICE_MODE)
pythontech 0:5868e8752d44 399 if (usb_vcp_is_enabled()) {
pythontech 0:5868e8752d44 400 // If the user gets to here and interrupts are disabled then
pythontech 0:5868e8752d44 401 // they'll never see the prompt, traceback etc. The USB REPL needs
pythontech 0:5868e8752d44 402 // interrupts to be enabled or no transfers occur. So we try to
pythontech 0:5868e8752d44 403 // do the user a favor and reenable interrupts.
pythontech 0:5868e8752d44 404 if (query_irq() == IRQ_STATE_DISABLED) {
pythontech 0:5868e8752d44 405 enable_irq(IRQ_STATE_ENABLED);
pythontech 0:5868e8752d44 406 mp_hal_stdout_tx_str("PYB: enabling IRQs\r\n");
pythontech 0:5868e8752d44 407 }
pythontech 0:5868e8752d44 408 }
pythontech 0:5868e8752d44 409 #endif
pythontech 0:5868e8752d44 410
pythontech 0:5868e8752d44 411 vstr_reset(&line);
pythontech 0:5868e8752d44 412 int ret = readline(&line, ">>> ");
pythontech 0:5868e8752d44 413 mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT;
pythontech 0:5868e8752d44 414
pythontech 0:5868e8752d44 415 if (ret == CHAR_CTRL_A) {
pythontech 0:5868e8752d44 416 // change to raw REPL
pythontech 0:5868e8752d44 417 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 418 vstr_clear(&line);
pythontech 0:5868e8752d44 419 pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
pythontech 0:5868e8752d44 420 return 0;
pythontech 0:5868e8752d44 421 } else if (ret == CHAR_CTRL_B) {
pythontech 0:5868e8752d44 422 // reset friendly REPL
pythontech 0:5868e8752d44 423 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 424 goto friendly_repl_reset;
pythontech 0:5868e8752d44 425 } else if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 426 // break
pythontech 0:5868e8752d44 427 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 428 continue;
pythontech 0:5868e8752d44 429 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 430 // exit for a soft reset
pythontech 0:5868e8752d44 431 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 432 vstr_clear(&line);
pythontech 0:5868e8752d44 433 return PYEXEC_FORCED_EXIT;
pythontech 0:5868e8752d44 434 } else if (ret == CHAR_CTRL_E) {
pythontech 0:5868e8752d44 435 // paste mode
pythontech 0:5868e8752d44 436 mp_hal_stdout_tx_str("\r\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\r\n=== ");
pythontech 0:5868e8752d44 437 vstr_reset(&line);
pythontech 0:5868e8752d44 438 for (;;) {
pythontech 0:5868e8752d44 439 char c = mp_hal_stdin_rx_chr();
pythontech 0:5868e8752d44 440 if (c == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 441 // cancel everything
pythontech 0:5868e8752d44 442 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 443 goto input_restart;
pythontech 0:5868e8752d44 444 } else if (c == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 445 // end of input
pythontech 0:5868e8752d44 446 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 447 break;
pythontech 0:5868e8752d44 448 } else {
pythontech 0:5868e8752d44 449 // add char to buffer and echo
pythontech 0:5868e8752d44 450 vstr_add_byte(&line, c);
pythontech 0:5868e8752d44 451 if (c == '\r') {
pythontech 0:5868e8752d44 452 mp_hal_stdout_tx_str("\r\n=== ");
pythontech 0:5868e8752d44 453 } else {
pythontech 0:5868e8752d44 454 mp_hal_stdout_tx_strn(&c, 1);
pythontech 0:5868e8752d44 455 }
pythontech 0:5868e8752d44 456 }
pythontech 0:5868e8752d44 457 }
pythontech 0:5868e8752d44 458 parse_input_kind = MP_PARSE_FILE_INPUT;
pythontech 0:5868e8752d44 459 } else if (vstr_len(&line) == 0) {
pythontech 0:5868e8752d44 460 continue;
pythontech 0:5868e8752d44 461 } else {
pythontech 0:5868e8752d44 462 // got a line with non-zero length, see if it needs continuing
pythontech 0:5868e8752d44 463 while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) {
pythontech 0:5868e8752d44 464 vstr_add_byte(&line, '\n');
pythontech 0:5868e8752d44 465 ret = readline(&line, "... ");
pythontech 0:5868e8752d44 466 if (ret == CHAR_CTRL_C) {
pythontech 0:5868e8752d44 467 // cancel everything
pythontech 0:5868e8752d44 468 mp_hal_stdout_tx_str("\r\n");
pythontech 0:5868e8752d44 469 goto input_restart;
pythontech 0:5868e8752d44 470 } else if (ret == CHAR_CTRL_D) {
pythontech 0:5868e8752d44 471 // stop entering compound statement
pythontech 0:5868e8752d44 472 break;
pythontech 0:5868e8752d44 473 }
pythontech 0:5868e8752d44 474 }
pythontech 0:5868e8752d44 475 }
pythontech 0:5868e8752d44 476
pythontech 0:5868e8752d44 477 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 478 if (lex == NULL) {
pythontech 0:5868e8752d44 479 printf("MemoryError\n");
pythontech 0:5868e8752d44 480 } else {
pythontech 0:5868e8752d44 481 ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
pythontech 0:5868e8752d44 482 if (ret & PYEXEC_FORCED_EXIT) {
pythontech 0:5868e8752d44 483 return ret;
pythontech 0:5868e8752d44 484 }
pythontech 0:5868e8752d44 485 }
pythontech 0:5868e8752d44 486 }
pythontech 0:5868e8752d44 487 }
pythontech 0:5868e8752d44 488
pythontech 0:5868e8752d44 489 #endif // MICROPY_REPL_EVENT_DRIVEN
pythontech 0:5868e8752d44 490
pythontech 0:5868e8752d44 491 int pyexec_file(const char *filename) {
pythontech 0:5868e8752d44 492 mp_lexer_t *lex = mp_lexer_new_from_file(filename);
pythontech 0:5868e8752d44 493
pythontech 0:5868e8752d44 494 if (lex == NULL) {
pythontech 0:5868e8752d44 495 printf("could not open file '%s' for reading\n", filename);
pythontech 0:5868e8752d44 496 return false;
pythontech 0:5868e8752d44 497 }
pythontech 0:5868e8752d44 498
pythontech 0:5868e8752d44 499 return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0);
pythontech 0:5868e8752d44 500 }
pythontech 0:5868e8752d44 501
pythontech 0:5868e8752d44 502 #if MICROPY_MODULE_FROZEN
pythontech 0:5868e8752d44 503 int pyexec_frozen_module(const char *name) {
Colin Hogben 2:c89e95946844 504 void *frozen_data;
Colin Hogben 2:c89e95946844 505 int frozen_type = mp_find_frozen_module(name, strlen(name), &frozen_data);
Colin Hogben 2:c89e95946844 506
Colin Hogben 2:c89e95946844 507 switch (frozen_type) {
Colin Hogben 2:c89e95946844 508 #if MICROPY_MODULE_FROZEN_STR
Colin Hogben 2:c89e95946844 509 case MP_FROZEN_STR:
Colin Hogben 2:c89e95946844 510 return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, 0);
Colin Hogben 2:c89e95946844 511 #endif
pythontech 0:5868e8752d44 512
Colin Hogben 2:c89e95946844 513 #if MICROPY_MODULE_FROZEN_MPY
Colin Hogben 2:c89e95946844 514 case MP_FROZEN_MPY:
Colin Hogben 2:c89e95946844 515 return parse_compile_execute(frozen_data, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_RAW_CODE);
Colin Hogben 2:c89e95946844 516 #endif
Colin Hogben 2:c89e95946844 517
Colin Hogben 2:c89e95946844 518 default:
Colin Hogben 2:c89e95946844 519 printf("could not find module '%s'\n", name);
Colin Hogben 2:c89e95946844 520 return false;
pythontech 0:5868e8752d44 521 }
pythontech 0:5868e8752d44 522 }
pythontech 0:5868e8752d44 523 #endif
pythontech 0:5868e8752d44 524
pythontech 0:5868e8752d44 525 mp_obj_t pyb_set_repl_info(mp_obj_t o_value) {
pythontech 0:5868e8752d44 526 repl_display_debugging_info = mp_obj_get_int(o_value);
pythontech 0:5868e8752d44 527 return mp_const_none;
pythontech 0:5868e8752d44 528 }
pythontech 0:5868e8752d44 529
pythontech 0:5868e8752d44 530 MP_DEFINE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj, pyb_set_repl_info);