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:
Sat Apr 16 22:43:41 2016 +0100
Revision:
2:c89e95946844
Parent:
0:5868e8752d44
Child:
5:1d19b8110e11
py: update to upstream master

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