summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-11 09:34:51 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-11 09:34:51 -0600
commit1c8234c117ca90e978e9c7af60fc36cae2a98f76 (patch)
treedb21840da240e82938c15db36102d52f236b0521
parentcea3147c69b1054b991e5324b529beec21307b7c (diff)
downloadnuttx-1c8234c117ca90e978e9c7af60fc36cae2a98f76.tar.gz
nuttx-1c8234c117ca90e978e9c7af60fc36cae2a98f76.tar.bz2
nuttx-1c8234c117ca90e978e9c7af60fc36cae2a98f76.zip
Port of Micro Python to NuttX. From Dave Marples
-rw-r--r--apps/interpreters/Make.defs12
-rw-r--r--apps/interpreters/Makefile2
-rw-r--r--apps/interpreters/README.txt19
-rw-r--r--apps/interpreters/micropython/.gitignore11
-rw-r--r--apps/interpreters/micropython/Kconfig34
-rw-r--r--apps/interpreters/micropython/Makefile143
-rw-r--r--apps/interpreters/micropython/micropython_main.c263
-rw-r--r--apps/interpreters/micropython/mpconfigport.h117
-rw-r--r--apps/interpreters/micropython/py_readline.c431
-rw-r--r--apps/interpreters/micropython/py_readline.h50
-rw-r--r--apps/interpreters/micropython/pyexec.c404
-rw-r--r--apps/interpreters/micropython/pyexec.h65
-rw-r--r--apps/interpreters/micropython/qstrdefsport.h1
13 files changed, 1547 insertions, 5 deletions
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 <gnutt@nuttx.org>
+# Dave Marples <dave@marples.net>
+#
+# 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 <gnutt@nuttx.org>
+ * Dave Marples <dave@marples.net>
+ *
+ * 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 <nuttx/config.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <debug.h>
+#include <stdio.h>
+#include <math.h>
+
+#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 <dave@marples.net>
+ *
+ * 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 <stdint.h>
+#include <wchar_t.h>
+
+/* We need to provide a declaration/definition of alloca() */
+
+#include <alloca.h>
+
+/****************************************************************************
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#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 <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <time.h>
+
+#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 */