From 1c8234c117ca90e978e9c7af60fc36cae2a98f76 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 11 Jan 2015 09:34:51 -0600 Subject: Port of Micro Python to NuttX. From Dave Marples --- apps/interpreters/Make.defs | 12 +- apps/interpreters/Makefile | 2 +- apps/interpreters/README.txt | 19 + apps/interpreters/micropython/.gitignore | 11 + apps/interpreters/micropython/Kconfig | 34 ++ apps/interpreters/micropython/Makefile | 143 ++++++++ apps/interpreters/micropython/micropython_main.c | 263 ++++++++++++++ apps/interpreters/micropython/mpconfigport.h | 117 ++++++ apps/interpreters/micropython/py_readline.c | 431 +++++++++++++++++++++++ apps/interpreters/micropython/py_readline.h | 50 +++ apps/interpreters/micropython/pyexec.c | 404 +++++++++++++++++++++ apps/interpreters/micropython/pyexec.h | 65 ++++ apps/interpreters/micropython/qstrdefsport.h | 1 + 13 files changed, 1547 insertions(+), 5 deletions(-) create mode 100644 apps/interpreters/micropython/.gitignore create mode 100644 apps/interpreters/micropython/Kconfig create mode 100644 apps/interpreters/micropython/Makefile create mode 100644 apps/interpreters/micropython/micropython_main.c create mode 100644 apps/interpreters/micropython/mpconfigport.h create mode 100644 apps/interpreters/micropython/py_readline.c create mode 100644 apps/interpreters/micropython/py_readline.h create mode 100644 apps/interpreters/micropython/pyexec.c create mode 100644 apps/interpreters/micropython/pyexec.h create mode 100644 apps/interpreters/micropython/qstrdefsport.h diff --git a/apps/interpreters/Make.defs b/apps/interpreters/Make.defs index ad1b6903a..98a675ee3 100644 --- a/apps/interpreters/Make.defs +++ b/apps/interpreters/Make.defs @@ -38,10 +38,14 @@ ifeq ($(CONFIG_INTERPRETERS_BAS),y) CONFIGURED_APPS += interpreters/bas endif -ifeq ($(CONFIG_INTERPRETERS_PCODE),y) -CONFIGURED_APPS += interpreters/pcode -endif - ifeq ($(CONFIG_INTERPRETERS_FICL),y) CONFIGURED_APPS += interpreters/ficl endif + +ifeq ($(CONFIG_INTERPRETERS_MICROPYTHON),y) +CONFIGURED_APPS += interpreters/micropython +endif + +ifeq ($(CONFIG_INTERPRETERS_PCODE),y) +CONFIGURED_APPS += interpreters/pcode +endif diff --git a/apps/interpreters/Makefile b/apps/interpreters/Makefile index e7a1d2b00..acbbd6e3b 100644 --- a/apps/interpreters/Makefile +++ b/apps/interpreters/Makefile @@ -37,7 +37,7 @@ # Sub-directories containing interpreter runtime -SUBDIRS = pcode prun ficl bas +SUBDIRS = bas ficl micropython pcode prun # Create the list of installed runtime modules (INSTALLED_DIRS) diff --git a/apps/interpreters/README.txt b/apps/interpreters/README.txt index f4f990b57..7062a8094 100644 --- a/apps/interpreters/README.txt +++ b/apps/interpreters/README.txt @@ -12,6 +12,25 @@ ficl is not in that directory, only an environment and instructions that will let you build Ficl under NuttX. The rest is up to you. +micropython +----------- + + This is a port of a build environment for Micro Python: + + https://micropython.org/ + + NOTE that Micro Python is not included in this directory. Before building + this example, you must first download Micro Python from: + + https://micropython.org/download/ + + Or clone from the GIT repository: + + https://github.com/micropython/ + + This port was contributed by Dave Marples using Micro Python circu + 1.3.8. It may not be compatible with other versions. + pcode ----- diff --git a/apps/interpreters/micropython/.gitignore b/apps/interpreters/micropython/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/apps/interpreters/micropython/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/apps/interpreters/micropython/Kconfig b/apps/interpreters/micropython/Kconfig new file mode 100644 index 000000000..82f345148 --- /dev/null +++ b/apps/interpreters/micropython/Kconfig @@ -0,0 +1,34 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +config INTERPRETERS_MICROPYTHON + bool "Micro Python support" + default n + ---help--- + Enable support for the Micro Python interpreter + +if INTERPRETERS_MICROPYTHON + +config INTERPRETERS_MICROPYTHON_APPNAME + string "Executable name" + default "micropython" + depends on NSH_BUILTIN_APPS + +config INTERPRETERS_MICROPYTHON_STACKSIZE + int "Interpreter stack size" + default 2048 + depends on NSH_BUILTIN_APPS + +config INTERPRETERS_MICROPYTHON_PRIORITY + int "Interpreter priority" + default 100 + depends on NSH_BUILTIN_APPS + +CONFIG_INTERPRETERS_MICROPYTHON_PROGNAME + string "Program name" + default "micropython" + depends on BUILD_KERNEL + +endif # INTERPRETERS_MICROPYTHON \ No newline at end of file diff --git a/apps/interpreters/micropython/Makefile b/apps/interpreters/micropython/Makefile new file mode 100644 index 000000000..99df4031f --- /dev/null +++ b/apps/interpreters/micropython/Makefile @@ -0,0 +1,143 @@ +############################################################################ +# apps/ interpreters/micropython/Makefile +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Authors: Gregory Nutt +# Dave Marples +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +########################################################################### + +TOP ?= ../../../../micropython +TOPDIR ?= ../../../nuttx +APPDIR ?= ../../../apps + +MICROPYTHON_DIR = $(TOP)/py + +include $(MICROPYTHON_DIR)/mkenv.mk + +# qstr definitions (must come before including py.mk) + +QSTR_DEFS = qstrdefsport.h + +# include py core make definitions + +include $(MICROPYTHON_DIR)/py.mk + +-include $(TOPDIR)/.config +-include $(TOPDIR)/Make.defs +include $(APPDIR)/Make.defs + +# c99 is needed for micropython + +CFLAGS+=-std=c99 -Wno-shadow -Wno-strict-prototypes + +INC = -I. -I$(TOP) -I$(PY_SRC) -I$(BUILD) + +CFLAGS +=$(INC) + +CONFIG_INTERPRETERS_MICROPYTHON_APPNAME ?= micropython +CONFIG_INTERPRETERS_MICROPYTHON_STACKSIZE ?= 2048 +CONFIG_INTERPRETERS_MICROPYTHON_PRIORITY ?= SCHED_PRIORITY_DEFAULT + +APPNAME = $(CONFIG_INTERPRETERS_MICROPYTHON_APPNAME) +STACKSIZE = $(CONFIG_INTERPRETERS_MICROPYTHON_STACKSIZE) +PRIORITY = $(CONFIG_INTERPRETERS_MICROPYTHON_PRIORITY) + +CONFIG_INTERPRETERS_MICROPYTHON_PROGNAME ?= micropython$(EXEEXT) +PROGNAME = $(CONFIG_INTERPRETERS_MICROPYTHON_PROGNAME) + +ASRCS = +CSRCS = pyexec.c py_readline.c +MAINSRC = micropython_main.c + +OBJ = $(PY_O) $(addprefix $(BUILD)/, $(ASRC:.S=$(OBJEXT)) $(CSRCS:.c=$(OBJEXT))) + +ifneq ($(CONFIG_BUILD_KERNEL),y) + OBJ += $(addprefix $(BUILD)/, $(MAINSRC:.c=$(OBJEXT))) +endif + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BIN = ..\..\libapps$(LIBEXT) +else +ifeq ($(WINTOOL),y) + BIN = ..\\..\\libapps$(LIBEXT) +else + BIN = ../../libapps$(LIBEXT) +endif +endif + +ifeq ($(WINTOOL),y) + INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" +else + INSTALL_DIR = $(BIN_DIR) +endif + +ROOTDEPPATH = --dep-path . + +# Common build + +all: .built + +.built: $(OBJ) + $(call ARCHIVE, $(BIN), $(OBJ)) + @touch .built + +ifeq ($(CONFIG_BUILD_KERNEL),y) +$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJ) $(MAINOBJ) + @echo "LD: $(PROGNAME)" + $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) + $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) + +install: $(BIN_DIR)$(DELIM)$(PROGNAME) +else +install: +endif + +ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) +$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile + $(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),micropython_main) + +context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat +else +context: +endif + +.depend: Makefile $(SRCS) + @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + @touch $@ + +depend: .depend + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +include $(MICROPYTHON_DIR)/mkrules.mk +-include Make.dep diff --git a/apps/interpreters/micropython/micropython_main.c b/apps/interpreters/micropython/micropython_main.c new file mode 100644 index 000000000..a36bc0528 --- /dev/null +++ b/apps/interpreters/micropython/micropython_main.c @@ -0,0 +1,263 @@ +/**************************************************************************** + * interpreters/micropython/micropython_main.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * Dave Marples + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include "mpconfig.h" +#include "nlr.h" +#include "misc.h" +#include "qstr.h" +#include "lexer.h" +#include "parse.h" +#include "obj.h" +#include "parsehelper.h" +#include "compile.h" +#include "runtime0.h" +#include "runtime.h" +#include "repl.h" +#include "pfenv.h" +#include "pyexec.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FORCE_EVAL(x) do { \ + if (sizeof(x) == sizeof(float)) { \ + volatile float __x; \ + __x = (x); \ + (void)__x; \ + } else if (sizeof(x) == sizeof(double)) { \ + volatile double __x; \ + __x = (x); \ + (void)__x; \ + } else { \ + volatile long double __x; \ + __x = (x); \ + (void)__x; \ + } \ +} while(0); + +/**************************************************************************** + * Private Data +****************************************************************************/ + +/**************************************************************************** + * Private Function +****************************************************************************/ + +void do_str(FAR const char *src) +{ + FAR mp_lexer_t *lex = + mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); + if (lex == NULL) + { + return; + } + + mp_parse_error_kind_t parse_error_kind; + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind); + + if (pn == MP_PARSE_NODE_NULL) + { + /* parse error */ + + mp_parse_show_exception(lex, parse_error_kind); + mp_lexer_free(lex); + return; + } + + /* parse okay */ + + qstr source_name = lex->source_name; + mp_lexer_free(lex); + mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true); + + if (mp_obj_is_exception_instance(module_fun)) + { + /* compile error */ + + mp_obj_print_exception(printf_wrapper, NULL, module_fun); + return; + } + + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) + { + mp_call_function_0(module_fun); + nlr_pop(); + } + else + { + /* uncaught exception */ + + mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t) nlr.ret_val); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +float nanf(FAR const char *tagp) +{ + (void)tagp; + return 0; +} + +float copysignf(float x, float y) +{ + if (y < 0) + { + return -fabsf(x); + } + + return fabsf(x); +} + +float truncf(float x) +{ + union + { + float f; + uint32_t i; + } u = + { + x}; + int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9; + uint32_t m; + + if (e >= 23 + 9) + { + return x; + } + + if (e < 9) + { + e = 1; + } + + m = -1U >> e; + if ((u.i & m) == 0) + { + return x; + } + + FORCE_EVAL(x + 0x1 p120f); + u.i &= ~m; + return u.f; +} + +/**************************************************************************** + * mp_import_stat + ****************************************************************************/ + +mp_import_stat_t mp_import_stat(FAR const char *path) +{ + return MP_IMPORT_STAT_NO_EXIST; +} + +/**************************************************************************** + * mp_lexer_new_from_file + ****************************************************************************/ + +mp_lexer_t *mp_lexer_new_from_file(FAR const char *filename) +{ + return NULL; +} + +/**************************************************************************** + * mp_builtin_open + ****************************************************************************/ + +mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t * args, mp_map_t * kwargs) +{ + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); + +/**************************************************************************** + * nlr_jump_fail + ****************************************************************************/ + +void nlr_jump_fail(void *val) +{ + fprintf(stderr, "FATAL: uncaught exception %p\n", val); + exit(-1); +} + +/**************************************************************************** + * micropython_main + ****************************************************************************/ + +#ifdef CONFIG_INTERPRETERS_MICROPYTHON +int micropython_main(int argc, char *argv[]) +{ + mp_init(); + for (;;) + { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) + { + if (pyexec_raw_repl() != 0) + { + break; + } + } + else + { + if (pyexec_friendly_repl() != 0) + { + break; + } + } + } + + mp_deinit(); + return 0; +} +#endif diff --git a/apps/interpreters/micropython/mpconfigport.h b/apps/interpreters/micropython/mpconfigport.h new file mode 100644 index 000000000..12724bdd9 --- /dev/null +++ b/apps/interpreters/micropython/mpconfigport.h @@ -0,0 +1,117 @@ +/**************************************************************************** + * interpreters/micropython/mpconfigport.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Authors: Dave Marples + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __APPS_INTERPRETERS_MICROPYTHON_MPCONFIGPORT_H +#define __APPS_INTERPRETERS_MICROPYTHON_MPCONFIGPORT_H 1 + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/* We need to provide a declaration/definition of alloca() */ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* options to control how Micro Python is built */ + +#define MICROPY_ALLOC_PATH_MAX (512) +#define MICROPY_EMIT_X64 (0) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_INLINE_THUMB (0) +#define MICROPY_MEM_STATS (0) +#define MICROPY_DEBUG_PRINTERS (0) +#define MICROPY_ENABLE_GC (0) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_HELPER_LEXER_UNIX (0) +#define MICROPY_ENABLE_SOURCE_LINE (0) +#define MICROPY_ENABLE_DOC_STRING (0) +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_PY_BUILTINS_BYTEARRAY (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) +#define MICROPY_PY_BUILTINS_FROZENSET (0) +#define MICROPY_PY_BUILTINS_SET (0) +#define MICROPY_PY_BUILTINS_SLICE (0) +#define MICROPY_PY_BUILTINS_PROPERTY (0) +#define MICROPY_PY___FILE__ (0) +#define MICROPY_PY_GC (0) +#define MICROPY_PY_ARRAY (0) +#define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_CMATH (0) +#define MICROPY_PY_IO (0) +#define MICROPY_PY_STRUCT (0) +#define MICROPY_PY_SYS (0) +#define MICROPY_CPYTHON_COMPAT (0) +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPL) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) + +/* type definitions for the specific machine */ + +#define BYTES_PER_WORD (4) + +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1)) + +#define UINT_FMT "%lu" +#define INT_FMT "%ld" + +#define MICROPY_PORT_BUILTINS \ + { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef int32_t mp_int_t; /* must be pointer size */ +typedef uint32_t mp_uint_t; /* must be pointer size */ +typedef void *machine_ptr_t; /* must be of pointer size */ +typedef const void *machine_const_ptr_t; /* must be of pointer size */ +typedef long mp_off_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* extra built in names to add to the global namespace */ + +extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj; + +#endif /* __APPS_INTERPRETERS_MICROPYTHON_MPCONFIGPORT_H */ diff --git a/apps/interpreters/micropython/py_readline.c b/apps/interpreters/micropython/py_readline.c new file mode 100644 index 000000000..25093db3c --- /dev/null +++ b/apps/interpreters/micropython/py_readline.c @@ -0,0 +1,431 @@ +/**************************************************************************** + * interpreters/micropython/py_readline.c + * + * This file originated from the Micro Python project, http://micropython.org/ + * It has been hacked around to fit into Nuttx + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Further edits (c) 2015 Dave Marples + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "py/mpconfig.h" +#include "py/misc.h" +#include "py_readline.h" + +#if 0 /* print debugging info */ +# define DEBUG_PRINT (1) +# define DEBUG_printf printf +#else /* don't print debugging info */ +# define DEBUG_printf(...) (void)0 +#endif + +#define READLINE_HIST_SIZE (8) + +#define CURSOR_BACK ('\b') +#define KEY_TAB ('\t') + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum +{ + ESEQ_NONE, + ESEQ_ESC, + ESEQ_ESC_BRACKET, + ESEQ_ESC_BRACKET_DIGIT, + ESEQ_ESC_O +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const char *readline_hist[READLINE_HIST_SIZE]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +STATIC char *str_dup_maybe(const char *str) +{ + uint32_t len = strlen(str); + char *s2 = m_new_maybe(char, len + 1); + + if (s2 == NULL) + { + return NULL; + } + + memcpy(s2, str, len + 1); + return s2; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void readline_init0(void) +{ + memset(readline_hist, 0, READLINE_HIST_SIZE * sizeof(const char *)); +} + +int py_readline(vstr_t * line, const char *prompt) +{ + fprintf(stdout, prompt); + fflush(stdout); + int orig_line_len = line->len; + int escape_seq = ESEQ_NONE; + char escape_seq_buf[1] = { 0 }; + int hist_cur = -1; + int cursor_pos = orig_line_len; + + for (;;) + { + int c = getc(stdin); + int last_line_len = line->len; + int redraw_step_back = 0; + bool redraw_from_cursor = false; + int redraw_step_forward = 0; + if (escape_seq == ESEQ_NONE) + { + if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_D && + vstr_len(line) == orig_line_len) + { + /* control character with empty line */ + + return c; + } + else if (c == CHAR_CTRL_A) + { + /* CTRL-A with non-empty line is go-to-start-of-line */ + + goto home_key; + } + else if (c == CHAR_CTRL_C) + { + /* CTRL-C with non-empty line is cancel */ + + return c; + } + else if (c == CHAR_CTRL_E) + { + /* CTRL-E is go-to-end-of-line */ + + goto end_key; + } + else if (c == '\r') + { + /* newline */ + + fputs("\r\n", stdout); + if (line->len > orig_line_len && + (readline_hist[0] == NULL || + strcmp(readline_hist[0], line->buf + orig_line_len) != 0)) + { + /* a line which is not empty and different from the last one + * so update the history + */ + + char *most_recent_hist = + str_dup_maybe(line->buf + orig_line_len); + if (most_recent_hist != NULL) + { + for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) + { + readline_hist[i] = readline_hist[i - 1]; + } + + readline_hist[0] = most_recent_hist; + } + } + + return 0; + } + else if (c == 27) + { + /* escape sequence */ + + escape_seq = ESEQ_ESC; + } + else if (c == 8 || c == 127) + { + /* backspace/delete */ + + if (cursor_pos > orig_line_len) + { + vstr_cut_out_bytes(line, cursor_pos - 1, 1); + + /* set redraw parameters */ + + redraw_step_back = 1; + redraw_from_cursor = true; + } + } + else if ((KEY_TAB == c) || (32 <= c && c <= 126)) + { + /* printable character */ + + vstr_ins_char(line, cursor_pos, c); + + /* set redraw parameters */ + + redraw_from_cursor = true; + redraw_step_forward = 1; + } + } + else if (escape_seq == ESEQ_ESC) + { + switch (c) + { + case '[': + escape_seq = ESEQ_ESC_BRACKET; + break; + + case 'O': + escape_seq = ESEQ_ESC_O; + break; + + default: + DEBUG_printf("(ESC %d)", c); + escape_seq = ESEQ_NONE; + } + } + else if (escape_seq == ESEQ_ESC_BRACKET) + { + if ('0' <= c && c <= '9') + { + escape_seq = ESEQ_ESC_BRACKET_DIGIT; + escape_seq_buf[0] = c; + } + else + { + escape_seq = ESEQ_NONE; + if (c == 'A') + { + /* up arrow */ + + if (hist_cur + 1 < READLINE_HIST_SIZE && + readline_hist[hist_cur + 1] != NULL) + { + /* increase hist num */ + + hist_cur += 1; + + /* set line to history */ + + line->len = orig_line_len; + vstr_add_str(line, readline_hist[hist_cur]); + + /* set redraw parameters */ + + redraw_step_back = cursor_pos - orig_line_len; + redraw_from_cursor = true; + redraw_step_forward = line->len - orig_line_len; + } + } + else if (c == 'B') + { + /* down arrow */ + + if (hist_cur >= 0) + { + /* decrease hist num */ + + hist_cur -= 1; + + /* set line to history */ + + vstr_cut_tail_bytes(line, line->len - orig_line_len); + if (hist_cur >= 0) + { + vstr_add_str(line, readline_hist[hist_cur]); + } + + /* set redraw parameters */ + + redraw_step_back = cursor_pos - orig_line_len; + redraw_from_cursor = true; + redraw_step_forward = line->len - orig_line_len; + } + } + else if (c == 'C') + { + /* right arrow */ + + if (cursor_pos < line->len) + { + redraw_step_forward = 1; + } + } + else if (c == 'D') + { + /* left arrow */ + + if (cursor_pos > orig_line_len) + { + redraw_step_back = 1; + } + } + else if (c == 'H') + { + /* home */ + + goto home_key; + } + else if (c == 'F') + { + /* end */ + + goto end_key; + } + else + { + DEBUG_printf("(ESC [ %d)", c); + } + } + } + else if (escape_seq == ESEQ_ESC_BRACKET_DIGIT) + { + if (c == '~') + { + if (escape_seq_buf[0] == '1' || escape_seq_buf[0] == '7') + { + home_key: + redraw_step_back = cursor_pos - orig_line_len; + } + else if (escape_seq_buf[0] == '4' || escape_seq_buf[0] == '8') + { + end_key: + redraw_step_forward = line->len - cursor_pos; + } + else + { + DEBUG_printf("(ESC [ %c %d)", escape_seq_buf[0], c); + } + } + else + { + DEBUG_printf("(ESC [ %c %d)", escape_seq_buf[0], c); + } + + escape_seq = ESEQ_NONE; + } + else if (escape_seq == ESEQ_ESC_O) + { + switch (c) + { + case 'H': + goto home_key; + + case 'F': + goto end_key; + + default: + DEBUG_printf("(ESC O %d)", c); + escape_seq = ESEQ_NONE; + } + } + else + { + escape_seq = ESEQ_NONE; + } + + /* redraw command prompt, efficiently + * TODO we can probably use some more sophisticated VT100 commands here + */ + + if (redraw_step_back > 0) + { + for (int i = 0; i < redraw_step_back; i++) + { + fputc(CURSOR_BACK, stdout); + } + + cursor_pos -= redraw_step_back; + } + if (redraw_from_cursor) + { + if (line->len < last_line_len) + { + /* erase old chars */ + + for (int i = cursor_pos; i < last_line_len; i++) + { + fputc(' ', stdout); + } + + /* step back */ + + for (int i = cursor_pos; i < last_line_len; i++) + { + fputc(CURSOR_BACK, stdout); + } + } + + /* draw new chars */ + + int charCount = 0; + do + { + fputc(*(line->buf + cursor_pos + charCount), stdout); + } + while (charCount++ < (line->len - cursor_pos)); + + /* move cursor forward if needed (already moved forward by length of + * line, so move it back) + */ + + for (int i = cursor_pos + redraw_step_forward; i < line->len; i++) + { + fputc(CURSOR_BACK, stdout); + } + + cursor_pos += redraw_step_forward; + } + else if (redraw_step_forward > 0) + { + /* draw over old chars to move cursor forwards */ + + int charCount = 0; + do + { + fputc(*(line->buf + cursor_pos + charCount), stdout); + } + + while (charCount++ < redraw_step_forward); + cursor_pos += redraw_step_forward; + } + + fflush(stdout); + } +} diff --git a/apps/interpreters/micropython/py_readline.h b/apps/interpreters/micropython/py_readline.h new file mode 100644 index 000000000..cc2ce98cd --- /dev/null +++ b/apps/interpreters/micropython/py_readline.h @@ -0,0 +1,50 @@ +/**************************************************************************** + * interpreters/micropython/py_readline.h + * + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + ****************************************************************************/ + +#ifndef __APPS_INTERPRETERS_MICROPYTHON_PY_READLINE_H +#define __APPS_INTERPRETERS_MICROPYTHON_PY_READLINE_H 1 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_CTRL_A (1) +#define CHAR_CTRL_B (2) +#define CHAR_CTRL_C (3) +#define CHAR_CTRL_D (4) +#define CHAR_CTRL_E (5) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void readline_init0(void); +int py_readline(vstr_t *line, const char *prompt); + +#endif /* __APPS_INTERPRETERS_MICROPYTHON_PY_READLINE_H */ diff --git a/apps/interpreters/micropython/pyexec.c b/apps/interpreters/micropython/pyexec.c new file mode 100644 index 000000000..b8d95643b --- /dev/null +++ b/apps/interpreters/micropython/pyexec.c @@ -0,0 +1,404 @@ +/**************************************************************************** + * interpreters/micropython/py_readline.c + * + * This file was part of the Micro Python project, http://micropython.org/ + * and has been integrated into Nuttx by Dave Marples (dave@marples.net) + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "py/nlr.h" +#include "py/parsehelper.h" +#include "py/compile.h" +#include "py/runtime.h" +#include "py/repl.h" +#include "py/gc.h" +#include "py/pfenv.h" + +#include "py_readline.h" +#include "pyexec.h" +#include "genhdr/py-version.h" + +#define EXEC_FLAG_PRINT_EOF (1) +#define EXEC_FLAG_ALLOW_DEBUGGING (2) +#define EXEC_FLAG_IS_REPL (4) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; +STATIC bool repl_display_debugging_info = 0; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* parses, compiles and executes the code in the lexer + * frees the lexer before returning + * EXEC_FLAG_PRINT_EOF prints 2 EOF chars: 1 after normal output, 1 after + * exception output + * EXEC_FLAG_ALLOW_DEBUGGING allows debugging info to be printed after + * executing the code + * EXEC_FLAG_IS_REPL is used for REPL inputs (flag passed on to mp_compile) + */ + +STATIC int parse_compile_execute(mp_lexer_t * lex, + mp_parse_input_kind_t input_kind, + int exec_flags) +{ + int ret = 0; + + mp_parse_error_kind_t parse_error_kind; + mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind); + qstr source_name = lex->source_name; + + /* check for parse error */ + + if (pn == MP_PARSE_NODE_NULL) + { + if (exec_flags & EXEC_FLAG_PRINT_EOF) + { + fprintf(stdout, "\x04"); + } + + mp_parse_show_exception(lex, parse_error_kind); + mp_lexer_free(lex); + goto finish; + } + + mp_lexer_free(lex); + + mp_obj_t module_fun = + mp_compile(pn, source_name, MP_EMIT_OPT_NONE, + exec_flags & EXEC_FLAG_IS_REPL); + + /* check for compile error */ + + if (mp_obj_is_exception_instance(module_fun)) + { + if (exec_flags & EXEC_FLAG_PRINT_EOF) + { + fprintf(stdout, "\x04"); + } + + mp_obj_print_exception(printf_wrapper, NULL, module_fun); + goto finish; + } + + /* execute code */ + + nlr_buf_t nlr; + + struct timespec start; + clock_gettime(CLOCK_REALTIME, &start); + + if (nlr_push(&nlr) == 0) + { + // mp_hal_set_interrupt_char(CHAR_CTRL_C); /* allow ctrl-C to interrupt us */ + mp_call_function_0(module_fun); + // mp_hal_set_interrupt_char(-1); /* disable interrupt */ + + nlr_pop(); + ret = 1; + if (exec_flags & EXEC_FLAG_PRINT_EOF) + { + fprintf(stdout, "\x04"); + } + } + else + { + /* uncaught exception */ + + // mp_hal_set_interrupt_char(-1); /* disable interrupt */ + + /* print EOF after normal output */ + + if (exec_flags & EXEC_FLAG_PRINT_EOF) + { + fprintf(stdout, "\x04"); + } + + /* check for SystemExit */ + + if (mp_obj_is_subclass_fast + (mp_obj_get_type((mp_obj_t) nlr.ret_val), &mp_type_SystemExit)) + { + /* at the moment, the value of SystemExit is unused */ + + ret = PYEXEC_FORCED_EXIT; + } + else + { + mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t) nlr.ret_val); + ret = 0; + } + } + + /* display debugging info if wanted */ + + if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) + { + struct timespec endTime; + clock_gettime(CLOCK_REALTIME, &endTime); + + mp_uint_t ticks = ((endTime.tv_sec - start.tv_sec) * 1000) + + ((((endTime.tv_nsec / 1000000) + 1000) - + (start.tv_nsec / 1000000)) % 1000); + + printf("took " UINT_FMT " ms\n", ticks); + + /* qstr info */ + + { + mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes; + qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); + 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); + } + } + +finish: + if (exec_flags & EXEC_FLAG_PRINT_EOF) + { + fprintf(stdout, "\x04"); + } + + return ret; +} + +int pyexec_raw_repl(void) +{ + vstr_t line; + vstr_init(&line, 32); + +raw_repl_reset: + fprintf(stdout, "raw REPL; CTRL-B to exit\r\n"); + + for (;;) + { + vstr_reset(&line); + fputc('>', stdout); + fflush(stdout); + + for (;;) + { + char c = getc(stdin); + if (c == CHAR_CTRL_A) + { + /* reset raw REPL */ + + goto raw_repl_reset; + } + else if (c == CHAR_CTRL_B) + { + /* change to friendly REPL */ + + fprintf(stdout, "\r\n"); + vstr_clear(&line); + pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; + return 0; + } + else if (c == CHAR_CTRL_C) + { + /* clear line */ + + vstr_reset(&line); + } + else if (c == CHAR_CTRL_D) + { + /* input finished */ + + break; + } + else if (c <= 127) + { + /* let through any other ASCII character */ + + vstr_add_char(&line, c); + fputc(c, stdout); + } + fflush(stdout); + } + + /* indicate reception of command */ + + fprintf(stdout, "OK"); + + if (line.len == 0) + { + /* exit for a soft reset */ + + fprintf(stdout, "\r\n"); + vstr_clear(&line); + return PYEXEC_FORCED_EXIT; + } + + mp_lexer_t *lex = + mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0); + if (lex == NULL) + { + printf("\x04MemoryError\n\x04"); + } + else + { + int ret = + parse_compile_execute(lex, MP_PARSE_FILE_INPUT, + EXEC_FLAG_PRINT_EOF); + if (ret & PYEXEC_FORCED_EXIT) + { + return ret; + } + } + fflush(stdout); + } +} + +int pyexec_friendly_repl(void) +{ + vstr_t line; + vstr_init(&line, 32); + +friendly_repl_reset: + fprintf(stdout, + "Micro Python " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE + "; NuttX with " CONFIG_ARCH_FAMILY " " CONFIG_ARCH_CHIP "\r\n"); + fprintf(stdout, "Type \"help()\" for more information.\r\n"); + + for (;;) + { + input_restart: + vstr_reset(&line); + int ret = py_readline(&line, ">>> "); + + if (ret == CHAR_CTRL_A) + { + /* change to raw REPL */ + + fprintf(stdout, "\r\n"); + vstr_clear(&line); + pyexec_mode_kind = PYEXEC_MODE_RAW_REPL; + return 0; + } + else if (ret == CHAR_CTRL_B) + { + /* reset friendly REPL */ + + fprintf(stdout, "\r\n"); + goto friendly_repl_reset; + } + else if (ret == CHAR_CTRL_C) + { + /* break */ + + fprintf(stdout, "\r\n"); + continue; + } + else if (ret == CHAR_CTRL_D) + { + /* exit for a soft reset */ + + fprintf(stdout, "\r\n"); + vstr_clear(&line); + return PYEXEC_FORCED_EXIT; + } + else if (vstr_len(&line) == 0) + { + continue; + } + + while (mp_repl_continue_with_input(vstr_str(&line))) + { + vstr_add_char(&line, '\n'); + int ret = py_readline(&line, "... "); + if (ret == CHAR_CTRL_C) + { + /* cancel everything */ + + fprintf(stdout, "\r\n"); + goto input_restart; + } + else if (ret == CHAR_CTRL_D) + { + /* stop entering compound statement */ + + break; + } + } + + mp_lexer_t *lex = + mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), + vstr_len(&line), 0); + if (lex == NULL) + { + printf("MemoryError\n"); + } + else + { + int ret = + parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, + EXEC_FLAG_ALLOW_DEBUGGING | + EXEC_FLAG_IS_REPL); + if (ret & PYEXEC_FORCED_EXIT) + { + return ret; + } + } + } +} + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +int pyexec_file(const char *filename) +{ + mp_lexer_t *lex = mp_lexer_new_from_file(filename); + + if (lex == NULL) + { + printf("could not open file '%s' for reading\n", filename); + return false; + } + + return parse_compile_execute(lex, MP_PARSE_FILE_INPUT, 0); +} + +mp_obj_t pyb_set_repl_info(mp_obj_t o_value) +{ + repl_display_debugging_info = mp_obj_get_int(o_value); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_1(pyb_set_repl_info_obj, pyb_set_repl_info); diff --git a/apps/interpreters/micropython/pyexec.h b/apps/interpreters/micropython/pyexec.h new file mode 100644 index 000000000..3ef5b3673 --- /dev/null +++ b/apps/interpreters/micropython/pyexec.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * examples/micropython/pexec.h + * + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + ****************************************************************************/ + +#ifndef __APPS_INTERPRETERS_MICROPYTHON_PYEXEC_H +#define __APPS_INTERPRETERS_MICROPYTHON_PYEXEC_H 1 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PYEXEC_FORCED_EXIT (0x100) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef enum +{ + PYEXEC_MODE_RAW_REPL, + PYEXEC_MODE_FRIENDLY_REPL, +} pyexec_mode_kind_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern pyexec_mode_kind_t pyexec_mode_kind; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int pyexec_raw_repl(void); +int pyexec_friendly_repl(void); +int pyexec_file(const char *filename); + +MP_DECLARE_CONST_FUN_OBJ(pyb_set_repl_info_obj); + +#endif /* __APPS_INTERPRETERS_MICROPYTHON_PYEXEC_H */ diff --git a/apps/interpreters/micropython/qstrdefsport.h b/apps/interpreters/micropython/qstrdefsport.h new file mode 100644 index 000000000..5eb0aa77d --- /dev/null +++ b/apps/interpreters/micropython/qstrdefsport.h @@ -0,0 +1 @@ +/* qstrs specific to this port */ -- cgit v1.2.3