Merge branch 'master' into nrf5_no_sdk
This commit is contained in:
commit
23163154b9
@ -39,7 +39,7 @@ script:
|
||||
- make -C bare-arm
|
||||
- make -C qemu-arm test
|
||||
- make -C stmhal
|
||||
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||
- make -C stmhal BOARD=PYBV11 MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||
- make -C stmhal BOARD=STM32F7DISC
|
||||
- make -C stmhal BOARD=STM32L476DISC
|
||||
- make -C teensy
|
||||
|
14
README.md
14
README.md
@ -18,13 +18,13 @@ WARNING: this project is in beta stage and is subject to changes of the
|
||||
code-base, including project-wide name changes and API changes.
|
||||
|
||||
MicroPython implements the entire Python 3.4 syntax (including exceptions,
|
||||
"with", "yield from", etc., and additionally "async" keyword from Python 3.5).
|
||||
The following core datatypes are provided: str (including basic Unicode
|
||||
support), bytes, bytearray, tuple, list, dict, set, frozenset, array.array,
|
||||
collections.namedtuple, classes and instances. Builtin modules include sys,
|
||||
time, and struct, etc. Select ports have support for _thread module
|
||||
(multithreading). Note that only subset of Python 3.4 functionality
|
||||
implemented for the data types and modules.
|
||||
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
|
||||
Python 3.5). The following core datatypes are provided: `str` (including
|
||||
basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`,
|
||||
`frozenset`, `array.array`, `collections.namedtuple`, classes and instances.
|
||||
Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have
|
||||
support for `_thread` module (multithreading). Note that only a subset of
|
||||
Python 3 functionality is implemented for the data types and modules.
|
||||
|
||||
See the repository www.github.com/micropython/pyboard for the MicroPython
|
||||
board (PyBoard), the officially supported reference electronic circuit board.
|
||||
|
@ -6,15 +6,12 @@
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
@ -35,7 +32,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
|
@ -98,7 +98,6 @@ OsiTaskHandle svTaskHandle;
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static fs_user_mount_t *sflash_vfs_fat;
|
||||
static mp_vfs_mount_t sflash_vfs_mount;
|
||||
|
||||
static const char fresh_main_py[] = "# main.py -- put your code here!\r\n";
|
||||
static const char fresh_boot_py[] = "# boot.py -- run on boot-up\r\n"
|
||||
@ -303,8 +302,6 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
// Initialise the local flash filesystem.
|
||||
// init the vfs object
|
||||
fs_user_mount_t *vfs_fat = sflash_vfs_fat;
|
||||
vfs_fat->str = NULL;
|
||||
vfs_fat->len = 0;
|
||||
vfs_fat->flags = 0;
|
||||
pyb_flash_init_vfs(vfs_fat);
|
||||
|
||||
@ -328,11 +325,16 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
mptask_create_main_py();
|
||||
}
|
||||
} else {
|
||||
fail:
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
|
||||
// mount the flash device (there should be no other devices mounted at this point)
|
||||
mp_vfs_mount_t *vfs = &sflash_vfs_mount;
|
||||
// we allocate this structure on the heap because vfs->next is a root pointer
|
||||
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
|
||||
if (vfs == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
vfs->str = "/flash";
|
||||
vfs->len = 6;
|
||||
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
|
||||
|
@ -39,7 +39,7 @@ Constructors
|
||||
- `height` is the height of the FrameBuffer in pixels
|
||||
- `format` specifies the type of pixel used in the FrameBuffer;
|
||||
valid values are ``framebuf.MVLSB``, ``framebuf.RGB565``
|
||||
and ``framebuf.GS4_HMSB``. MVLSB is monochrome 8-bit color,
|
||||
and ``framebuf.GS4_HMSB``. MVLSB is monochrome 1-bit color,
|
||||
RGB565 is RGB 16-bit color, and GS4_HMSB is grayscale 4-bit color.
|
||||
Where a color value c is passed to a method, c is a small integer
|
||||
with an encoding that is dependent on the format of the FrameBuffer.
|
||||
|
@ -58,10 +58,7 @@ STATIC void str32_buf_free(void *sb_in) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_str32(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len) {
|
||||
mp_lexer_str32_buf_t *sb = m_new_obj_maybe(mp_lexer_str32_buf_t);
|
||||
if (sb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
mp_lexer_str32_buf_t *sb = m_new_obj(mp_lexer_str32_buf_t);
|
||||
sb->byte_off = (uint32_t)str & 3;
|
||||
sb->src_cur = (uint32_t*)(str - sb->byte_off);
|
||||
sb->val = *sb->src_cur++ >> sb->byte_off * 8;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/gc.h"
|
||||
#include "lib/mp-readline/readline.h"
|
||||
@ -64,7 +65,9 @@ STATIC void mp_reset(void) {
|
||||
#if MICROPY_MODULE_FROZEN
|
||||
pyexec_frozen_module("_boot.py");
|
||||
pyexec_file("boot.py");
|
||||
pyexec_file("main.py");
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
|
||||
pyexec_file("main.py");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -111,7 +114,7 @@ void user_init(void) {
|
||||
|
||||
#if !MICROPY_VFS
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
|
@ -35,9 +35,10 @@
|
||||
|
||||
static char heap[16384];
|
||||
|
||||
mp_obj_t execute_from_lexer(mp_lexer_t *lex) {
|
||||
mp_obj_t execute_from_str(const char *str) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false);
|
||||
mp_parse_tree_t pt = mp_parse(lex, MP_PARSE_FILE_INPUT);
|
||||
mp_obj_t module_fun = mp_compile(&pt, lex->source_name, MP_EMIT_OPT_NONE, false);
|
||||
mp_call_function_0(module_fun);
|
||||
@ -58,8 +59,7 @@ int main() {
|
||||
mp_init();
|
||||
|
||||
const char str[] = "print('Hello world of easy embedding!')";
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(0/*MP_QSTR_*/, str, strlen(str), false);
|
||||
if (execute_from_lexer(lex)) {
|
||||
if (execute_from_str(str)) {
|
||||
printf("Error\n");
|
||||
}
|
||||
}
|
||||
|
49
extmod/vfs.c
49
extmod/vfs.c
@ -43,33 +43,38 @@
|
||||
// Returns MP_VFS_ROOT for root dir (and then path_out is undefined) and
|
||||
// MP_VFS_NONE for path not found.
|
||||
mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) {
|
||||
if (path[0] == '/' && path[1] == 0) {
|
||||
return MP_VFS_ROOT;
|
||||
} else if (MP_STATE_VM(vfs_cur) == MP_VFS_ROOT) {
|
||||
// in root dir
|
||||
if (path[0] == 0) {
|
||||
return MP_VFS_ROOT;
|
||||
if (*path == '/' || MP_STATE_VM(vfs_cur) == MP_VFS_ROOT) {
|
||||
// an absolute path, or the current volume is root, so search root dir
|
||||
bool is_abs = 0;
|
||||
if (*path == '/') {
|
||||
++path;
|
||||
is_abs = 1;
|
||||
}
|
||||
} else if (*path != '/') {
|
||||
// a relative path within a mounted device
|
||||
*path_out = path;
|
||||
return MP_STATE_VM(vfs_cur);
|
||||
}
|
||||
|
||||
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
|
||||
if (strncmp(path, vfs->str, vfs->len) == 0) {
|
||||
if (path[vfs->len] == '/') {
|
||||
*path_out = path + vfs->len;
|
||||
return vfs;
|
||||
} else if (path[vfs->len] == '\0') {
|
||||
*path_out = "/";
|
||||
return vfs;
|
||||
for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) {
|
||||
size_t len = vfs->len - 1;
|
||||
if (strncmp(path, vfs->str + 1, len) == 0) {
|
||||
if (path[len] == '/') {
|
||||
*path_out = path + len;
|
||||
return vfs;
|
||||
} else if (path[len] == '\0') {
|
||||
*path_out = "/";
|
||||
return vfs;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (*path == '\0') {
|
||||
// path was "" or "/" so return virtual root
|
||||
return MP_VFS_ROOT;
|
||||
}
|
||||
if (is_abs) {
|
||||
// path began with / and was not found
|
||||
return MP_VFS_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// mount point not found
|
||||
return MP_VFS_NONE;
|
||||
// a relative path within a mounted device
|
||||
*path_out = path;
|
||||
return MP_STATE_VM(vfs_cur);
|
||||
}
|
||||
|
||||
// Version of mp_vfs_lookup_path that takes and returns uPy string objects.
|
||||
|
@ -55,8 +55,6 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
||||
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
|
||||
vfs->base.type = type;
|
||||
vfs->flags = FSUSER_FREE_OBJ;
|
||||
vfs->str = NULL;
|
||||
vfs->len = 0;
|
||||
vfs->fatfs.drv = vfs;
|
||||
|
||||
// load block protocol methods
|
||||
|
@ -36,8 +36,6 @@
|
||||
|
||||
typedef struct _fs_user_mount_t {
|
||||
mp_obj_base_t base;
|
||||
const char *str;
|
||||
uint16_t len; // length of str
|
||||
uint16_t flags;
|
||||
mp_obj_t readblocks[4];
|
||||
mp_obj_t writeblocks[4];
|
||||
|
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_VFS
|
||||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -277,4 +277,4 @@ DRESULT disk_ioctl (
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MICROPY_VFS
|
||||
#endif // MICROPY_VFS && MICROPY_VFS_FAT
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_VFS
|
||||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
@ -37,10 +37,8 @@
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "extmod/vfs_fat.h"
|
||||
|
||||
#if MICROPY_VFS_FAT
|
||||
#define mp_type_fileio fatfs_type_fileio
|
||||
#define mp_type_textio fatfs_type_textio
|
||||
#endif
|
||||
|
||||
extern const mp_obj_type_t mp_type_fileio;
|
||||
extern const mp_obj_type_t mp_type_textio;
|
||||
@ -300,4 +298,4 @@ mp_obj_t fatfs_builtin_open_self(mp_obj_t self_in, mp_obj_t path, mp_obj_t mode)
|
||||
return file_open(self, &mp_type_textio, arg_vals);
|
||||
}
|
||||
|
||||
#endif // MICROPY_VFS
|
||||
#endif // MICROPY_VFS && MICROPY_VFS_FAT
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/reader.h"
|
||||
#include "extmod/vfs.h"
|
||||
@ -69,30 +69,19 @@ STATIC void mp_reader_vfs_close(void *data) {
|
||||
m_del_obj(mp_reader_vfs_t, reader);
|
||||
}
|
||||
|
||||
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
|
||||
mp_reader_vfs_t *rf = m_new_obj_maybe(mp_reader_vfs_t);
|
||||
if (rf == NULL) {
|
||||
return MP_ENOMEM;
|
||||
}
|
||||
// TODO we really should just let this function raise a uPy exception
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false);
|
||||
rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map);
|
||||
int errcode;
|
||||
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
||||
nlr_pop();
|
||||
if (errcode != 0) {
|
||||
return errcode;
|
||||
}
|
||||
} else {
|
||||
return MP_ENOENT; // assume error was "file not found"
|
||||
void mp_reader_new_file(mp_reader_t *reader, const char *filename) {
|
||||
mp_reader_vfs_t *rf = m_new_obj(mp_reader_vfs_t);
|
||||
mp_obj_t arg = mp_obj_new_str(filename, strlen(filename), false);
|
||||
rf->file = mp_vfs_open(1, &arg, (mp_map_t*)&mp_const_empty_map);
|
||||
int errcode;
|
||||
rf->len = mp_stream_rw(rf->file, rf->buf, sizeof(rf->buf), &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE);
|
||||
if (errcode != 0) {
|
||||
mp_raise_OSError(errcode);
|
||||
}
|
||||
rf->pos = 0;
|
||||
reader->data = rf;
|
||||
reader->readbyte = mp_reader_vfs_readbyte;
|
||||
reader->close = mp_reader_vfs_close;
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
#endif // MICROPY_READER_VFS
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "py/lexer.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "memzip.h"
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename)
|
||||
@ -9,7 +11,7 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename)
|
||||
size_t len;
|
||||
|
||||
if (memzip_locate(filename, &data, &len) != MZ_OK) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
return mp_lexer_new_from_str_len(qstr_from_str(filename), (const char *)data, (mp_uint_t)len, 0);
|
||||
|
@ -52,13 +52,15 @@ STATIC bool repl_display_debugging_info = 0;
|
||||
#define EXEC_FLAG_ALLOW_DEBUGGING (2)
|
||||
#define EXEC_FLAG_IS_REPL (4)
|
||||
#define EXEC_FLAG_SOURCE_IS_RAW_CODE (8)
|
||||
#define EXEC_FLAG_SOURCE_IS_VSTR (16)
|
||||
#define EXEC_FLAG_SOURCE_IS_FILENAME (32)
|
||||
|
||||
// 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(void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
|
||||
STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input_kind, int exec_flags) {
|
||||
int ret = 0;
|
||||
uint32_t start = 0;
|
||||
|
||||
@ -76,8 +78,16 @@ STATIC int parse_compile_execute(void *source, mp_parse_input_kind_t input_kind,
|
||||
#endif
|
||||
{
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
mp_lexer_t *lex;
|
||||
if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) {
|
||||
const vstr_t *vstr = source;
|
||||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0);
|
||||
} else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) {
|
||||
lex = mp_lexer_new_from_file(source);
|
||||
} else {
|
||||
lex = (mp_lexer_t*)source;
|
||||
}
|
||||
// source is a lexer, parse and compile the script
|
||||
mp_lexer_t *lex = source;
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, exec_flags & EXEC_FLAG_IS_REPL);
|
||||
@ -202,14 +212,9 @@ STATIC int pyexec_raw_repl_process_char(int c) {
|
||||
return PYEXEC_FORCED_EXIT;
|
||||
}
|
||||
|
||||
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);
|
||||
if (lex == NULL) {
|
||||
mp_hal_stdout_tx_str("\x04MemoryError\r\n\x04");
|
||||
} else {
|
||||
int ret = parse_compile_execute(lex, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
reset:
|
||||
@ -285,14 +290,9 @@ STATIC int pyexec_friendly_repl_process_char(int c) {
|
||||
}
|
||||
|
||||
exec: ;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
int ret = parse_compile_execute(MP_STATE_VM(repl_line), MP_PARSE_SINGLE_INPUT, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_restart:
|
||||
@ -361,14 +361,9 @@ raw_repl_reset:
|
||||
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;
|
||||
}
|
||||
int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,14 +484,9 @@ friendly_repl_reset:
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
ret = parse_compile_execute(lex, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -505,14 +495,7 @@ friendly_repl_reset:
|
||||
#endif // MICROPY_ENABLE_COMPILER
|
||||
|
||||
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);
|
||||
return parse_compile_execute(filename, MP_PARSE_FILE_INPUT, EXEC_FLAG_SOURCE_IS_FILENAME);
|
||||
}
|
||||
|
||||
#if MICROPY_MODULE_FROZEN
|
||||
|
@ -7,18 +7,14 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
printf("MemoryError: lexer could not allocate memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
@ -74,7 +70,7 @@ void gc_collect(void) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
|
@ -57,14 +57,10 @@ STATIC void stderr_print_strn(void *env, const char *str, mp_uint_t len) {
|
||||
STATIC const mp_print_t mp_stderr_print = {NULL, stderr_print_strn};
|
||||
|
||||
STATIC int compile_and_save(const char *file, const char *output_file, const char *source_file) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_file(file);
|
||||
if (lex == NULL) {
|
||||
printf("could not open file '%s' for reading\n", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_file(file);
|
||||
|
||||
qstr source_name;
|
||||
if (source_file == NULL) {
|
||||
source_name = lex->source_name;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
#include "readline.h"
|
||||
#include "board.h"
|
||||
@ -98,7 +99,7 @@ void gc_collect(void) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
@ -111,6 +112,7 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
|
@ -136,9 +136,6 @@ STATIC mp_obj_t eval_exec_helper(size_t n_args, const mp_obj_t *args, mp_parse_i
|
||||
mp_lexer_t *lex;
|
||||
if (MICROPY_PY_BUILTINS_EXECFILE && parse_input_kind == MP_PARSE_SINGLE_INPUT) {
|
||||
lex = mp_lexer_new_from_file(str);
|
||||
if (lex == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "could not open file '%s'", str));
|
||||
}
|
||||
parse_input_kind = MP_PARSE_FILE_INPUT;
|
||||
} else {
|
||||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, str, str_len, 0);
|
||||
|
@ -131,18 +131,7 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d
|
||||
}
|
||||
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex, const char *fname) {
|
||||
|
||||
if (lex == NULL) {
|
||||
// we verified the file exists using stat, but lexer could still fail
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_msg(&mp_type_ImportError, "module not found");
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
|
||||
"no module named '%s'", fname));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex) {
|
||||
#if MICROPY_PY___FILE__
|
||||
qstr source_name = lex->source_name;
|
||||
mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name));
|
||||
@ -207,7 +196,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
|
||||
// found the filename in the list of frozen files, then load and execute it.
|
||||
#if MICROPY_MODULE_FROZEN_STR
|
||||
if (frozen_type == MP_FROZEN_STR) {
|
||||
do_load_from_lexer(module_obj, modref, file_str);
|
||||
do_load_from_lexer(module_obj, modref);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -235,7 +224,7 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
{
|
||||
mp_lexer_t *lex = mp_lexer_new_from_file(file_str);
|
||||
do_load_from_lexer(module_obj, lex, file_str);
|
||||
do_load_from_lexer(module_obj, lex);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -385,11 +385,9 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
||||
ASM_MOV_REG_REG(emit->as, REG_LOCAL_2, REG_ARG_2);
|
||||
} else if (i == 2) {
|
||||
ASM_MOV_REG_REG(emit->as, REG_LOCAL_3, REG_ARG_3);
|
||||
} else if (i == 3) {
|
||||
ASM_MOV_REG_TO_LOCAL(emit->as, REG_ARG_4, i - REG_LOCAL_NUM);
|
||||
} else {
|
||||
// TODO not implemented
|
||||
mp_not_implemented("more than 4 viper args");
|
||||
assert(i == 3); // should be true; max 4 args is checked above
|
||||
ASM_MOV_REG_TO_LOCAL(emit->as, REG_ARG_4, i - REG_LOCAL_NUM);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -527,9 +525,7 @@ STATIC void emit_native_end_pass(emit_t *emit) {
|
||||
ASM_END_PASS(emit->as);
|
||||
|
||||
// check stack is back to zero size
|
||||
if (emit->stack_size != 0) {
|
||||
mp_printf(&mp_plat_print, "ERROR: stack size not back to zero; got %d\n", emit->stack_size);
|
||||
}
|
||||
assert(emit->stack_size == 0);
|
||||
|
||||
if (emit->pass == MP_PASS_EMIT) {
|
||||
void *f = mp_asm_base_get_code(&emit->as->base);
|
||||
@ -595,38 +591,9 @@ STATIC void emit_native_set_source_line(emit_t *emit, mp_uint_t source_line) {
|
||||
(void)source_line;
|
||||
}
|
||||
|
||||
/*
|
||||
STATIC void emit_pre_raw(emit_t *emit, int stack_size_delta) {
|
||||
adjust_stack(emit, stack_size_delta);
|
||||
emit->last_emit_was_return_value = false;
|
||||
}
|
||||
*/
|
||||
|
||||
// this must be called at start of emit functions
|
||||
STATIC void emit_native_pre(emit_t *emit) {
|
||||
emit->last_emit_was_return_value = false;
|
||||
// settle the stack
|
||||
/*
|
||||
if (regs_needed != 0) {
|
||||
for (int i = 0; i < emit->stack_size; i++) {
|
||||
switch (emit->stack_info[i].kind) {
|
||||
case STACK_VALUE:
|
||||
break;
|
||||
|
||||
case STACK_REG:
|
||||
// TODO only push reg if in regs_needed
|
||||
emit->stack_info[i].kind = STACK_VALUE;
|
||||
ASM_MOV_REG_TO_LOCAL(emit->as, emit->stack_info[i].data.u_reg, emit->stack_start + i);
|
||||
break;
|
||||
|
||||
case STACK_IMM:
|
||||
// don't think we ever need to push imms for settling
|
||||
//ASM_MOV_IMM_TO_LOCAL(emit->last_imm, emit->stack_start + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// depth==0 is top, depth==1 is before top, etc
|
||||
@ -867,7 +834,7 @@ STATIC void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, mp_uint_t reg_de
|
||||
break;
|
||||
default:
|
||||
// not handled
|
||||
assert(0);
|
||||
mp_not_implemented("conversion to object");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1011,9 +978,7 @@ STATIC void emit_native_load_const_str(emit_t *emit, qstr qst) {
|
||||
// do native array access. For now we just load them as any other object.
|
||||
/*
|
||||
if (emit->do_viper_types) {
|
||||
// not implemented properly
|
||||
// load a pointer to the asciiz string?
|
||||
assert(0);
|
||||
emit_post_push_imm(emit, VTYPE_PTR, (mp_uint_t)qstr_str(qst));
|
||||
} else
|
||||
*/
|
||||
@ -1843,12 +1808,6 @@ STATIC void emit_native_pop_block(emit_t *emit) {
|
||||
|
||||
STATIC void emit_native_pop_except(emit_t *emit) {
|
||||
(void)emit;
|
||||
/*
|
||||
emit_native_pre(emit);
|
||||
emit_call(emit, MP_F_NLR_POP);
|
||||
adjust_stack(emit, -(mp_int_t)(sizeof(nlr_buf_t) / sizeof(mp_uint_t)));
|
||||
emit_post(emit);
|
||||
*/
|
||||
}
|
||||
|
||||
STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
|
||||
@ -2202,7 +2161,8 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
|
||||
emit_post_top_set_vtype(emit, vtype_cast);
|
||||
break;
|
||||
default:
|
||||
assert(!"TODO: convert obj to int");
|
||||
// this can happen when casting a cast: int(int)
|
||||
mp_not_implemented("casting");
|
||||
}
|
||||
} else {
|
||||
assert(vtype_fun == VTYPE_PYOBJ);
|
||||
@ -2259,7 +2219,6 @@ STATIC void emit_native_return_value(emit_t *emit) {
|
||||
assert(vtype == VTYPE_PYOBJ);
|
||||
}
|
||||
emit->last_emit_was_return_value = true;
|
||||
//ASM_BREAK_POINT(emit->as); // to insert a break-point for debugging
|
||||
ASM_EXIT(emit->as);
|
||||
}
|
||||
|
||||
|
31
py/lexer.c
31
py/lexer.c
@ -699,13 +699,7 @@ void mp_lexer_to_next(mp_lexer_t *lex) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
|
||||
mp_lexer_t *lex = m_new_obj_maybe(mp_lexer_t);
|
||||
|
||||
// check for memory allocation error
|
||||
if (lex == NULL) {
|
||||
reader.close(reader.data);
|
||||
return NULL;
|
||||
}
|
||||
mp_lexer_t *lex = m_new_obj(mp_lexer_t);
|
||||
|
||||
lex->source_name = src_name;
|
||||
lex->reader = reader;
|
||||
@ -715,16 +709,9 @@ mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
|
||||
lex->nested_bracket_level = 0;
|
||||
lex->alloc_indent_level = MICROPY_ALLOC_LEXER_INDENT_INIT;
|
||||
lex->num_indent_level = 1;
|
||||
lex->indent_level = m_new_maybe(uint16_t, lex->alloc_indent_level);
|
||||
lex->indent_level = m_new(uint16_t, lex->alloc_indent_level);
|
||||
vstr_init(&lex->vstr, 32);
|
||||
|
||||
// check for memory allocation error
|
||||
// note: vstr_init above may fail on malloc, but so may mp_lexer_to_next below
|
||||
if (lex->indent_level == NULL) {
|
||||
mp_lexer_free(lex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// store sentinel for first indentation level
|
||||
lex->indent_level[0] = 0;
|
||||
|
||||
@ -764,9 +751,7 @@ mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) {
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, size_t len, size_t free_len) {
|
||||
mp_reader_t reader;
|
||||
if (!mp_reader_new_mem(&reader, (const byte*)str, len, free_len)) {
|
||||
return NULL;
|
||||
}
|
||||
mp_reader_new_mem(&reader, (const byte*)str, len, free_len);
|
||||
return mp_lexer_new(src_name, reader);
|
||||
}
|
||||
|
||||
@ -774,10 +759,7 @@ mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, size_t len
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
mp_reader_t reader;
|
||||
int ret = mp_reader_new_file(&reader, filename);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
mp_reader_new_file(&reader, filename);
|
||||
return mp_lexer_new(qstr_from_str(filename), reader);
|
||||
}
|
||||
|
||||
@ -785,10 +767,7 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_fd(qstr filename, int fd, bool close_fd) {
|
||||
mp_reader_t reader;
|
||||
int ret = mp_reader_new_file_from_fd(&reader, fd, close_fd);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
mp_reader_new_file_from_fd(&reader, fd, close_fd);
|
||||
return mp_lexer_new(filename, reader);
|
||||
}
|
||||
|
||||
|
@ -71,12 +71,7 @@ $(OBJ): | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/mpversion.h
|
||||
|
||||
$(HEADER_BUILD)/qstr.i.last: $(SRC_QSTR) | $(HEADER_BUILD)/mpversion.h
|
||||
$(ECHO) "GEN $@"
|
||||
$(Q)if [ "$?" = "" ]; then \
|
||||
echo "QSTR Looks like -B used, trying to emulate"; \
|
||||
$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $^ >$(HEADER_BUILD)/qstr.i.last; \
|
||||
else \
|
||||
$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $? >$(HEADER_BUILD)/qstr.i.last; \
|
||||
fi
|
||||
$(Q)$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $? >$(HEADER_BUILD)/qstr.i.last;
|
||||
|
||||
$(HEADER_BUILD)/qstr.split: $(HEADER_BUILD)/qstr.i.last
|
||||
$(ECHO) "GEN $@"
|
||||
|
@ -222,7 +222,7 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char
|
||||
char prefix_buf[4];
|
||||
char *prefix = prefix_buf;
|
||||
|
||||
if (mp_obj_int_sign(x) > 0) {
|
||||
if (mp_obj_int_sign(x) >= 0) {
|
||||
if (flags & PF_FLAG_SHOW_SIGN) {
|
||||
*prefix++ = '+';
|
||||
} else if (flags & PF_FLAG_SPACE_SIGN) {
|
||||
|
@ -61,6 +61,9 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||
#else
|
||||
|
||||
__asm volatile (
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
"pop %rbp \n" // undo function's prelude
|
||||
#endif
|
||||
"movq (%rsp), %rax \n" // load return %rip
|
||||
"movq %rax, 16(%rdi) \n" // store %rip into nlr_buf
|
||||
"movq %rbp, 24(%rdi) \n" // store %rbp into nlr_buf
|
||||
@ -70,7 +73,11 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||
"movq %r13, 56(%rdi) \n" // store %r13 into nlr_buf
|
||||
"movq %r14, 64(%rdi) \n" // store %r14 into nlr_buf
|
||||
"movq %r15, 72(%rdi) \n" // store %r15 into nlr_buf
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
"jmp _nlr_push_tail \n" // do the rest in C
|
||||
#else
|
||||
"jmp nlr_push_tail \n" // do the rest in C
|
||||
#endif
|
||||
);
|
||||
|
||||
#endif
|
||||
|
14
py/objint.c
14
py/objint.c
@ -127,11 +127,17 @@ mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) {
|
||||
#undef MP_FLOAT_EXP_SHIFT_I32
|
||||
#endif
|
||||
|
||||
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
|
||||
typedef mp_longint_impl_t fmt_int_t;
|
||||
#else
|
||||
typedef mp_int_t fmt_int_t;
|
||||
#endif
|
||||
|
||||
void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
// The size of this buffer is rather arbitrary. If it's not large
|
||||
// enough, a dynamic one will be allocated.
|
||||
char stack_buf[sizeof(mp_int_t) * 4];
|
||||
char stack_buf[sizeof(fmt_int_t) * 4];
|
||||
char *buf = stack_buf;
|
||||
size_t buf_size = sizeof(stack_buf);
|
||||
size_t fmt_size;
|
||||
@ -144,12 +150,6 @@ void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
|
||||
typedef mp_longint_impl_t fmt_int_t;
|
||||
#else
|
||||
typedef mp_int_t fmt_int_t;
|
||||
#endif
|
||||
|
||||
STATIC const uint8_t log_base2_floor[] = {
|
||||
0, 1, 1, 2,
|
||||
2, 2, 2, 3,
|
||||
|
@ -54,7 +54,17 @@ const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX};
|
||||
#endif
|
||||
|
||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf) {
|
||||
mp_not_implemented("");
|
||||
int delta = 1;
|
||||
if (!big_endian) {
|
||||
buf += len - 1;
|
||||
delta = -1;
|
||||
}
|
||||
|
||||
mp_longint_impl_t value = 0;
|
||||
for (; len--; buf += delta) {
|
||||
value = (value << 8) | *buf;
|
||||
}
|
||||
return mp_obj_new_int_from_ll(value);
|
||||
}
|
||||
|
||||
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) {
|
||||
|
@ -354,7 +354,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
switch (op) {
|
||||
case MP_BINARY_OP_ADD:
|
||||
case MP_BINARY_OP_INPLACE_ADD: {
|
||||
if (lhs_len == 0) {
|
||||
if (lhs_len == 0 && mp_obj_get_type(rhs_in) == lhs_type) {
|
||||
return rhs_in;
|
||||
}
|
||||
if (rhs_len == 0) {
|
||||
|
@ -225,18 +225,13 @@ mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) {
|
||||
|
||||
mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) {
|
||||
mp_reader_t reader;
|
||||
if (!mp_reader_new_mem(&reader, buf, len, 0)) {
|
||||
m_malloc_fail(BYTES_PER_WORD); // we need to raise a MemoryError
|
||||
}
|
||||
mp_reader_new_mem(&reader, buf, len, 0);
|
||||
return mp_raw_code_load(&reader);
|
||||
}
|
||||
|
||||
mp_raw_code_t *mp_raw_code_load_file(const char *filename) {
|
||||
mp_reader_t reader;
|
||||
int ret = mp_reader_new_file(&reader, filename);
|
||||
if (ret != 0) {
|
||||
mp_raise_OSError(ret);
|
||||
}
|
||||
mp_reader_new_file(&reader, filename);
|
||||
return mp_raw_code_load(&reader);
|
||||
}
|
||||
|
||||
|
28
py/reader.c
28
py/reader.c
@ -27,6 +27,7 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/reader.h"
|
||||
|
||||
@ -54,11 +55,8 @@ STATIC void mp_reader_mem_close(void *data) {
|
||||
m_del_obj(mp_reader_mem_t, reader);
|
||||
}
|
||||
|
||||
bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) {
|
||||
mp_reader_mem_t *rm = m_new_obj_maybe(mp_reader_mem_t);
|
||||
if (rm == NULL) {
|
||||
return false;
|
||||
}
|
||||
void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len) {
|
||||
mp_reader_mem_t *rm = m_new_obj(mp_reader_mem_t);
|
||||
rm->free_len = free_len;
|
||||
rm->beg = buf;
|
||||
rm->cur = buf;
|
||||
@ -66,7 +64,6 @@ bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t
|
||||
reader->data = rm;
|
||||
reader->readbyte = mp_reader_mem_readbyte;
|
||||
reader->close = mp_reader_mem_close;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if MICROPY_READER_POSIX
|
||||
@ -110,14 +107,8 @@ STATIC void mp_reader_posix_close(void *data) {
|
||||
m_del_obj(mp_reader_posix_t, reader);
|
||||
}
|
||||
|
||||
int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
|
||||
mp_reader_posix_t *rp = m_new_obj_maybe(mp_reader_posix_t);
|
||||
if (rp == NULL) {
|
||||
if (close_fd) {
|
||||
close(fd);
|
||||
}
|
||||
return MP_ENOMEM;
|
||||
}
|
||||
void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
|
||||
mp_reader_posix_t *rp = m_new_obj(mp_reader_posix_t);
|
||||
rp->close_fd = close_fd;
|
||||
rp->fd = fd;
|
||||
int n = read(rp->fd, rp->buf, sizeof(rp->buf));
|
||||
@ -125,22 +116,21 @@ int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd) {
|
||||
if (close_fd) {
|
||||
close(fd);
|
||||
}
|
||||
return errno;
|
||||
mp_raise_OSError(errno);
|
||||
}
|
||||
rp->len = n;
|
||||
rp->pos = 0;
|
||||
reader->data = rp;
|
||||
reader->readbyte = mp_reader_posix_readbyte;
|
||||
reader->close = mp_reader_posix_close;
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
int mp_reader_new_file(mp_reader_t *reader, const char *filename) {
|
||||
void mp_reader_new_file(mp_reader_t *reader, const char *filename) {
|
||||
int fd = open(filename, O_RDONLY, 0644);
|
||||
if (fd < 0) {
|
||||
return errno;
|
||||
mp_raise_OSError(errno);
|
||||
}
|
||||
return mp_reader_new_file_from_fd(reader, fd, true);
|
||||
mp_reader_new_file_from_fd(reader, fd, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -39,8 +39,8 @@ typedef struct _mp_reader_t {
|
||||
void (*close)(void *data);
|
||||
} mp_reader_t;
|
||||
|
||||
bool mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len);
|
||||
int mp_reader_new_file(mp_reader_t *reader, const char *filename);
|
||||
int mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd);
|
||||
void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t free_len);
|
||||
void mp_reader_new_file(mp_reader_t *reader, const char *filename);
|
||||
void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd);
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_READER_H
|
||||
|
@ -36,10 +36,12 @@ LDFLAGS= --specs=nano.specs --specs=rdimon.specs -Wl,--gc-sections -Wl,-Map=$(@:
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
moduos.c \
|
||||
modmachine.c \
|
||||
|
||||
SRC_TEST_C = \
|
||||
test_main.c \
|
||||
moduos.c \
|
||||
modmachine.c \
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
|
@ -12,15 +12,12 @@
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
@ -47,7 +44,7 @@ void gc_collect(void) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
|
52
qemu-arm/moduos.c
Normal file
52
qemu-arm/moduos.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 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.
|
||||
*/
|
||||
|
||||
#include "extmod/vfs.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
|
||||
|
||||
// MicroPython extensions
|
||||
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uos = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&os_module_globals,
|
||||
};
|
@ -35,6 +35,7 @@
|
||||
#define MICROPY_PY_UHASHLIB (1)
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||
#define MICROPY_VFS (1)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
@ -58,7 +59,11 @@ typedef long mp_off_t;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||
|
||||
// extra built-in modules to add to the list of known ones
|
||||
extern const struct _mp_obj_module_t mp_module_uos;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, \
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
#include "tinytest.h"
|
||||
#include "tinytest_macros.h"
|
||||
@ -24,13 +24,9 @@ inline void do_str(const char *src) {
|
||||
gc_init(heap, (char*)heap + HEAP_SIZE);
|
||||
mp_init();
|
||||
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
tt_abort_msg("Lexer initialization error");
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, false);
|
||||
@ -80,7 +76,7 @@ void gc_collect(void) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
|
@ -65,7 +65,6 @@ void SystemClock_Config(void);
|
||||
|
||||
pyb_thread_t pyb_thread_main;
|
||||
fs_user_mount_t fs_user_mount_flash;
|
||||
mp_vfs_mount_t mp_vfs_mount_flash;
|
||||
|
||||
void flash_error(int n) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
@ -168,8 +167,6 @@ static const char fresh_readme_txt[] =
|
||||
MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
|
||||
// init the vfs object
|
||||
fs_user_mount_t *vfs_fat = &fs_user_mount_flash;
|
||||
vfs_fat->str = NULL;
|
||||
vfs_fat->len = 0;
|
||||
vfs_fat->flags = 0;
|
||||
pyb_flash_init_vfs(vfs_fat);
|
||||
|
||||
@ -219,12 +216,17 @@ MP_NOINLINE STATIC bool init_flash_fs(uint reset_mode) {
|
||||
} else if (res == FR_OK) {
|
||||
// mount sucessful
|
||||
} else {
|
||||
fail:
|
||||
printf("PYB: can't mount flash\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// mount the flash device (there should be no other devices mounted at this point)
|
||||
mp_vfs_mount_t *vfs = &mp_vfs_mount_flash;
|
||||
// we allocate this structure on the heap because vfs->next is a root pointer
|
||||
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
|
||||
if (vfs == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
vfs->str = "/flash";
|
||||
vfs->len = 6;
|
||||
vfs->obj = MP_OBJ_FROM_PTR(vfs_fat);
|
||||
@ -270,8 +272,6 @@ STATIC bool init_sdcard_fs(bool first_soft_reset) {
|
||||
if (vfs == NULL || vfs_fat == NULL) {
|
||||
break;
|
||||
}
|
||||
vfs_fat->str = NULL;
|
||||
vfs_fat->len = 0;
|
||||
vfs_fat->flags = FSUSER_FREE_OBJ;
|
||||
sdcard_init_vfs(vfs_fat, part_num);
|
||||
|
||||
|
@ -72,6 +72,10 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, size_t len) {
|
||||
void mp_hal_ticks_cpu_enable(void) {
|
||||
if (!mp_hal_ticks_cpu_enabled) {
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
#if defined(__CORTEX_M) && __CORTEX_M == 7
|
||||
// on Cortex-M7 we must unlock the DWT before writing to its registers
|
||||
DWT->LAR = 0xc5acce55;
|
||||
#endif
|
||||
DWT->CYCCNT = 0;
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
mp_hal_ticks_cpu_enabled = true;
|
||||
|
@ -1,11 +1,13 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/lexer.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
@ -1,4 +1,10 @@
|
||||
# test builtin property
|
||||
try:
|
||||
property
|
||||
except:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# create a property object explicitly
|
||||
property()
|
||||
|
@ -1,4 +1,11 @@
|
||||
# test builtin sorted
|
||||
try:
|
||||
sorted
|
||||
set
|
||||
except:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
print(sorted(set(range(100))))
|
||||
print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))
|
||||
|
@ -1,12 +1,6 @@
|
||||
# test construction of bytearray from different objects
|
||||
|
||||
from array import array
|
||||
|
||||
# bytes, tuple, list
|
||||
print(bytearray(b'123'))
|
||||
print(bytearray((1, 2)))
|
||||
print(bytearray([1, 2]))
|
||||
|
||||
# arrays
|
||||
print(bytearray(array('b', [1, 2])))
|
||||
print(bytearray(array('h', [0x101, 0x202])))
|
||||
|
11
tests/basics/bytearray_construct_array.py
Normal file
11
tests/basics/bytearray_construct_array.py
Normal file
@ -0,0 +1,11 @@
|
||||
# test construction of bytearray from different objects
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# arrays
|
||||
print(bytearray(array('b', [1, 2])))
|
||||
print(bytearray(array('h', [0x101, 0x202])))
|
@ -1,6 +1,10 @@
|
||||
# test construction of bytearray from different objects
|
||||
|
||||
from array import array
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# arrays
|
||||
print(bytearray(array('h', [1, 2])))
|
||||
|
@ -3,9 +3,6 @@
|
||||
print(b"123" + b"456")
|
||||
print(b"123" + bytearray(2))
|
||||
|
||||
import array
|
||||
|
||||
# should be byteorder-neutral
|
||||
print(b"123" + array.array('h', [0x1515]))
|
||||
|
||||
print(b"\x01\x02" + array.array('b', [1, 2]))
|
||||
print(b"123" + b"") # RHS is empty, can be optimised
|
||||
print(b"" + b"123") # LHS is empty, can be optimised
|
||||
print(b"" + bytearray(1)) # LHS is empty but can't be optimised
|
||||
|
12
tests/basics/bytes_add_array.py
Normal file
12
tests/basics/bytes_add_array.py
Normal file
@ -0,0 +1,12 @@
|
||||
# test bytes + other
|
||||
try:
|
||||
import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# should be byteorder-neutral
|
||||
print(b"123" + array.array('h', [0x1515]))
|
||||
|
||||
print(b"\x01\x02" + array.array('b', [1, 2]))
|
@ -1,5 +1,9 @@
|
||||
# test bytes + other
|
||||
|
||||
import array
|
||||
try:
|
||||
import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
print(b"123" + array.array('i', [1]))
|
||||
|
@ -3,9 +3,3 @@ print(b"123" == bytearray(b"123"))
|
||||
print(b'123' < bytearray(b"124"))
|
||||
print(b'123' > bytearray(b"122"))
|
||||
print(bytearray(b"23") in b"1234")
|
||||
|
||||
import array
|
||||
|
||||
print(array.array('b', [1, 2]) in b'\x01\x02\x03')
|
||||
# CPython gives False here
|
||||
#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3]))
|
||||
|
10
tests/basics/bytes_compare_array.py
Normal file
10
tests/basics/bytes_compare_array.py
Normal file
@ -0,0 +1,10 @@
|
||||
try:
|
||||
import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
print(array.array('b', [1, 2]) in b'\x01\x02\x03')
|
||||
# CPython gives False here
|
||||
#print(b"\x01\x02\x03" == array.array("B", [1, 2, 3]))
|
@ -1,16 +1,10 @@
|
||||
# test construction of bytes from different objects
|
||||
|
||||
from array import array
|
||||
|
||||
# tuple, list, bytearray
|
||||
print(bytes((1, 2)))
|
||||
print(bytes([1, 2]))
|
||||
print(bytes(bytearray(4)))
|
||||
|
||||
# arrays
|
||||
print(bytes(array('b', [1, 2])))
|
||||
print(bytes(array('h', [0x101, 0x202])))
|
||||
|
||||
# constructor value out of range
|
||||
try:
|
||||
bytes([-1])
|
||||
|
11
tests/basics/bytes_construct_array.py
Normal file
11
tests/basics/bytes_construct_array.py
Normal file
@ -0,0 +1,11 @@
|
||||
# test construction of bytes from different objects
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# arrays
|
||||
print(bytes(array('b', [1, 2])))
|
||||
print(bytes(array('h', [0x101, 0x202])))
|
@ -1,6 +1,11 @@
|
||||
# test construction of bytes from different objects
|
||||
|
||||
from array import array
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# arrays
|
||||
print(bytes(array('h', [1, 2])))
|
||||
|
@ -7,8 +7,3 @@ d = dict.fromkeys([1, 2, 3, 4], 42)
|
||||
l = list(d.values())
|
||||
l.sort()
|
||||
print(l)
|
||||
|
||||
# argument to fromkeys has no __len__
|
||||
d = dict.fromkeys(reversed(range(1)))
|
||||
#d = dict.fromkeys((x for x in range(1)))
|
||||
print(d)
|
||||
|
11
tests/basics/dict_fromkeys2.py
Normal file
11
tests/basics/dict_fromkeys2.py
Normal file
@ -0,0 +1,11 @@
|
||||
try:
|
||||
reversed
|
||||
except:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# argument to fromkeys has no __len__
|
||||
d = dict.fromkeys(reversed(range(1)))
|
||||
#d = dict.fromkeys((x for x in range(1)))
|
||||
print(d)
|
@ -27,8 +27,5 @@ test_exc("[].sort(1)", TypeError)
|
||||
# function with keyword args given extra keyword args
|
||||
test_exc("[].sort(noexist=1)", TypeError)
|
||||
|
||||
# function with keyword args not given a specific keyword arg
|
||||
test_exc("enumerate()", TypeError)
|
||||
|
||||
# kw given for positional, but a different positional is missing
|
||||
test_exc("def f(x, y): pass\nf(x=1)", TypeError)
|
||||
|
19
tests/basics/fun_error2.py
Normal file
19
tests/basics/fun_error2.py
Normal file
@ -0,0 +1,19 @@
|
||||
# test errors from bad function calls
|
||||
try:
|
||||
enumerate
|
||||
except:
|
||||
print("SKIP")
|
||||
import sys
|
||||
sys.exit()
|
||||
|
||||
def test_exc(code, exc):
|
||||
try:
|
||||
exec(code)
|
||||
print("no exception")
|
||||
except exc:
|
||||
print("right exception")
|
||||
except:
|
||||
print("wrong exception")
|
||||
|
||||
# function with keyword args not given a specific keyword arg
|
||||
test_exc("enumerate()", TypeError)
|
@ -1,6 +1,6 @@
|
||||
# comprehensive functionality test for {} format string
|
||||
|
||||
int_tests = False # these take a while, and some give wrong results
|
||||
int_tests = False # these take a while
|
||||
char_tests = True
|
||||
str_tests = True
|
||||
|
||||
|
@ -33,38 +33,6 @@ print("%c" % 48)
|
||||
print("%c" % 'a')
|
||||
print("%10s" % 'abc')
|
||||
print("%-10s" % 'abc')
|
||||
print("%d" % 10)
|
||||
print("%+d" % 10)
|
||||
print("% d" % 10)
|
||||
print("%d" % -10)
|
||||
print("%d" % True)
|
||||
print("%i" % -10)
|
||||
print("%i" % True)
|
||||
print("%u" % -10)
|
||||
print("%u" % True)
|
||||
print("%x" % 18)
|
||||
print("%o" % 18)
|
||||
print("%X" % 18)
|
||||
print("%#x" % 18)
|
||||
print("%#X" % 18)
|
||||
print("%#6o" % 18)
|
||||
print("%#6x" % 18)
|
||||
print("%#06x" % 18)
|
||||
|
||||
print("%*d" % (5, 10))
|
||||
print("%*.*d" % (2, 2, 20))
|
||||
print("%*.*d" % (5, 8, 20))
|
||||
|
||||
print(">%8.4d<" % -12)
|
||||
print(">% 8.4d<" % -12)
|
||||
print(">%+8.4d<" % 12)
|
||||
print(">%+8.4d<" % -12)
|
||||
print(">%08.4d<" % -12)
|
||||
print(">%08.4d<" % 12)
|
||||
print(">%-8.4d<" % -12)
|
||||
print(">%-08.4d<" % -12)
|
||||
print(">%-+08.4d<" % -12)
|
||||
print(">%-+08.4d<" % 12)
|
||||
|
||||
# Should be able to print dicts; in this case they aren't used
|
||||
# to lookup keywords in formats like %(foo)s
|
||||
|
41
tests/basics/string_format_modulo_int.py
Normal file
41
tests/basics/string_format_modulo_int.py
Normal file
@ -0,0 +1,41 @@
|
||||
# test string modulo formatting with int values
|
||||
|
||||
# basic cases
|
||||
print("%d" % 10)
|
||||
print("%+d" % 10)
|
||||
print("% d" % 10)
|
||||
print("%d" % -10)
|
||||
print("%d" % True)
|
||||
print("%i" % -10)
|
||||
print("%i" % True)
|
||||
print("%u" % -10)
|
||||
print("%u" % True)
|
||||
print("%x" % 18)
|
||||
print("%o" % 18)
|
||||
print("%X" % 18)
|
||||
print("%#x" % 18)
|
||||
print("%#X" % 18)
|
||||
print("%#6o" % 18)
|
||||
print("%#6x" % 18)
|
||||
print("%#06x" % 18)
|
||||
|
||||
# with *
|
||||
print("%*d" % (5, 10))
|
||||
print("%*.*d" % (2, 2, 20))
|
||||
print("%*.*d" % (5, 8, 20))
|
||||
|
||||
# precision
|
||||
for val in (-12, 12):
|
||||
print(">%8.4d<" % val)
|
||||
print(">% 8.4d<" % val)
|
||||
print(">%+8.4d<" % val)
|
||||
print(">%08.4d<" % val)
|
||||
print(">%-8.4d<" % val)
|
||||
print(">%-08.4d<" % val)
|
||||
print(">%-+08.4d<" % val)
|
||||
|
||||
# test + option with various amount of padding
|
||||
for pad in ('', ' ', '0'):
|
||||
for n in (1, 2, 3):
|
||||
for val in (-1, 0, 1):
|
||||
print(('%+' + pad + str(n) + 'd') % val)
|
@ -18,3 +18,16 @@ o = A()
|
||||
s = struct.pack("<O", o)
|
||||
o2 = struct.unpack("<O", s)
|
||||
print(o is o2[0])
|
||||
|
||||
# pack and unpack pointer to a string
|
||||
# This requires uctypes to get the address of the string and instead of
|
||||
# putting this in a dedicated test that can be skipped we simply pass
|
||||
# if the import fails.
|
||||
try:
|
||||
import uctypes
|
||||
o = uctypes.addressof('abc')
|
||||
s = struct.pack("<S", o)
|
||||
o2 = struct.unpack("<S", s)
|
||||
assert o2[0] == 'abc'
|
||||
except ImportError:
|
||||
pass
|
||||
|
@ -72,6 +72,11 @@ m = re.match('^ab$', 'ab'); print(m.group(0))
|
||||
m = re.match('a|b', 'b'); print(m.group(0))
|
||||
m = re.match('a|b|c', 'c'); print(m.group(0))
|
||||
|
||||
# Case where anchors fail to match
|
||||
r = re.compile("^b|b$")
|
||||
m = r.search("abc")
|
||||
print(m)
|
||||
|
||||
try:
|
||||
re.compile("*")
|
||||
except:
|
||||
|
52
tests/extmod/ussl_basic.py
Normal file
52
tests/extmod/ussl_basic.py
Normal file
@ -0,0 +1,52 @@
|
||||
# very basic test of ssl module, just to test the methods exist
|
||||
|
||||
try:
|
||||
import uio as io
|
||||
import ussl as ssl
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
import sys
|
||||
sys.exit()
|
||||
|
||||
# create in client mode
|
||||
try:
|
||||
ss = ssl.wrap_socket(io.BytesIO())
|
||||
except OSError as er:
|
||||
print('wrap_socket:', repr(er))
|
||||
|
||||
# create in server mode (can use this object for further tests)
|
||||
socket = io.BytesIO()
|
||||
ss = ssl.wrap_socket(socket, server_side=1)
|
||||
|
||||
# print
|
||||
print(repr(ss)[:12])
|
||||
|
||||
# setblocking
|
||||
try:
|
||||
ss.setblocking(False)
|
||||
except NotImplementedError:
|
||||
print('setblocking: NotImplementedError')
|
||||
ss.setblocking(True)
|
||||
|
||||
# write
|
||||
print(ss.write(b'aaaa'))
|
||||
|
||||
# read (underlying socket has no data)
|
||||
print(ss.read(8))
|
||||
|
||||
# read (underlying socket has data, but it's bad data)
|
||||
socket.write(b'aaaaaaaaaaaaaaaa')
|
||||
socket.seek(0)
|
||||
try:
|
||||
ss.read(8)
|
||||
except OSError as er:
|
||||
print('read:', repr(er))
|
||||
|
||||
# close
|
||||
ss.close()
|
||||
|
||||
# write on closed socket
|
||||
try:
|
||||
ss.write(b'aaaa')
|
||||
except OSError as er:
|
||||
print('write:', repr(er))
|
8
tests/extmod/ussl_basic.py.exp
Normal file
8
tests/extmod/ussl_basic.py.exp
Normal file
@ -0,0 +1,8 @@
|
||||
ssl_handshake_status: -256
|
||||
wrap_socket: OSError(5,)
|
||||
<_SSLSocket
|
||||
setblocking: NotImplementedError
|
||||
4
|
||||
b''
|
||||
read: OSError(-261,)
|
||||
write: OSError(-256,)
|
@ -20,6 +20,16 @@ print(inp.read(1))
|
||||
print(inp.read())
|
||||
print(buf.seek(0, 1))
|
||||
|
||||
# Check FHCRC field
|
||||
buf = io.BytesIO(b'\x1f\x8b\x08\x02\x99\x0c\xe5W\x00\x03\x00\x00\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
|
||||
inp = zlib.DecompIO(buf, 16 + 8)
|
||||
print(inp.read())
|
||||
|
||||
# Check FEXTRA field
|
||||
buf = io.BytesIO(b'\x1f\x8b\x08\x04\x99\x0c\xe5W\x00\x03\x01\x00X\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
|
||||
inp = zlib.DecompIO(buf, 16 + 8)
|
||||
print(inp.read())
|
||||
|
||||
# broken header
|
||||
buf = io.BytesIO(b'\x1f\x8c\x08\x08\x99\x0c\xe5W\x00\x03hello\x00\xcbH\xcd\xc9\xc9\x07\x00\x86\xa6\x106\x05\x00\x00\x00')
|
||||
try:
|
||||
|
@ -7,5 +7,7 @@ b'lo'
|
||||
b''
|
||||
b''
|
||||
31
|
||||
b'hello'
|
||||
b'hello'
|
||||
ValueError
|
||||
OSError(22,)
|
||||
|
111
tests/extmod/vfs_basic.py
Normal file
111
tests/extmod/vfs_basic.py
Normal file
@ -0,0 +1,111 @@
|
||||
# test VFS functionality without any particular filesystem type
|
||||
|
||||
try:
|
||||
try:
|
||||
import uos_vfs as uos
|
||||
open = uos.vfs_open
|
||||
except ImportError:
|
||||
import uos
|
||||
uos.mount
|
||||
except (ImportError, AttributeError):
|
||||
print("SKIP")
|
||||
import sys
|
||||
sys.exit()
|
||||
|
||||
|
||||
class Filesystem:
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
def mount(self, readonly, mkfs):
|
||||
print(self.id, 'mount', readonly, mkfs)
|
||||
def umount(self):
|
||||
print(self.id, 'umount')
|
||||
def listdir(self, dir):
|
||||
print(self.id, 'listdir', dir)
|
||||
return ['a%d' % self.id]
|
||||
def chdir(self, dir):
|
||||
print(self.id, 'chdir', dir)
|
||||
def getcwd(self):
|
||||
print(self.id, 'getcwd')
|
||||
return 'dir%d' % self.id
|
||||
def mkdir(self, path):
|
||||
print(self.id, 'mkdir', path)
|
||||
def remove(self, path):
|
||||
print(self.id, 'remove', path)
|
||||
def rename(self, old_path, new_path):
|
||||
print(self.id, 'rename', old_path, new_path)
|
||||
def rmdir(self, path):
|
||||
print(self.id, 'rmdir', path)
|
||||
def stat(self, path):
|
||||
print(self.id, 'stat', path)
|
||||
return (self.id,)
|
||||
def statvfs(self, path):
|
||||
print(self.id, 'statvfs', path)
|
||||
return (self.id,)
|
||||
def open(self, file, mode):
|
||||
print(self.id, 'open', file, mode)
|
||||
|
||||
|
||||
# first we umount any existing mount points the target may have
|
||||
for path in uos.listdir('/'):
|
||||
uos.umount('/' + path)
|
||||
|
||||
# stat root dir
|
||||
print(uos.stat('/'))
|
||||
|
||||
# getcwd when in root dir
|
||||
print(uos.getcwd())
|
||||
|
||||
# basic mounting and listdir
|
||||
uos.mount(Filesystem(1), '/test_mnt')
|
||||
print(uos.listdir())
|
||||
|
||||
# referencing the mount point in different ways
|
||||
print(uos.listdir('test_mnt'))
|
||||
print(uos.listdir('/test_mnt'))
|
||||
|
||||
# mounting another filesystem
|
||||
uos.mount(Filesystem(2), '/test_mnt2', readonly=True)
|
||||
print(uos.listdir())
|
||||
print(uos.listdir('/test_mnt2'))
|
||||
|
||||
# mounting over an existing mount point
|
||||
try:
|
||||
uos.mount(Filesystem(3), '/test_mnt2')
|
||||
except OSError:
|
||||
print('OSError')
|
||||
|
||||
# mkdir of a mount point
|
||||
try:
|
||||
uos.mkdir('/test_mnt')
|
||||
except OSError:
|
||||
print('OSError')
|
||||
|
||||
# rename across a filesystem
|
||||
try:
|
||||
uos.rename('/test_mnt/a', '/test_mnt2/b')
|
||||
except OSError:
|
||||
print('OSError')
|
||||
|
||||
# delegating to mounted filesystem
|
||||
uos.chdir('test_mnt')
|
||||
print(uos.listdir())
|
||||
print(uos.getcwd())
|
||||
uos.mkdir('test_dir')
|
||||
uos.remove('test_file')
|
||||
uos.rename('test_file', 'test_file2')
|
||||
uos.rmdir('test_dir')
|
||||
print(uos.stat('test_file'))
|
||||
print(uos.statvfs('/test_mnt'))
|
||||
open('test_file')
|
||||
open('test_file', 'wb')
|
||||
|
||||
# umount
|
||||
uos.umount('/test_mnt')
|
||||
uos.umount('/test_mnt2')
|
||||
|
||||
# umount a non-existent mount point
|
||||
try:
|
||||
uos.umount('/test_mnt')
|
||||
except OSError:
|
||||
print('OSError')
|
34
tests/extmod/vfs_basic.py.exp
Normal file
34
tests/extmod/vfs_basic.py.exp
Normal file
@ -0,0 +1,34 @@
|
||||
(16384, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
/
|
||||
1 mount False False
|
||||
['test_mnt']
|
||||
1 listdir /
|
||||
['a1']
|
||||
1 listdir /
|
||||
['a1']
|
||||
2 mount True False
|
||||
['test_mnt', 'test_mnt2']
|
||||
2 listdir /
|
||||
['a2']
|
||||
3 mount False False
|
||||
OSError
|
||||
OSError
|
||||
OSError
|
||||
1 chdir /
|
||||
1 listdir
|
||||
['a1']
|
||||
1 getcwd
|
||||
/test_mntdir1
|
||||
1 mkdir test_dir
|
||||
1 remove test_file
|
||||
1 rename test_file test_file2
|
||||
1 rmdir test_dir
|
||||
1 stat test_file
|
||||
(1,)
|
||||
1 statvfs /
|
||||
(1,)
|
||||
1 open test_file r
|
||||
1 open test_file wb
|
||||
1 umount
|
||||
2 umount
|
||||
OSError
|
61
tests/extmod/websocket_basic.py
Normal file
61
tests/extmod/websocket_basic.py
Normal file
@ -0,0 +1,61 @@
|
||||
try:
|
||||
import uio
|
||||
import uerrno
|
||||
import websocket
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# put raw data in the stream and do a websocket read
|
||||
def ws_read(msg, sz):
|
||||
ws = websocket.websocket(uio.BytesIO(msg))
|
||||
return ws.read(sz)
|
||||
|
||||
# do a websocket write and then return the raw data from the stream
|
||||
def ws_write(msg, sz):
|
||||
s = uio.BytesIO()
|
||||
ws = websocket.websocket(s)
|
||||
ws.write(msg)
|
||||
s.seek(0)
|
||||
return s.read(sz)
|
||||
|
||||
# basic frame
|
||||
print(ws_read(b"\x81\x04ping", 4))
|
||||
print(ws_read(b"\x80\x04ping", 4)) # FRAME_CONT
|
||||
print(ws_write(b"pong", 6))
|
||||
|
||||
# split frames are not supported
|
||||
# print(ws_read(b"\x01\x04ping", 4))
|
||||
|
||||
# extended payloads
|
||||
print(ws_read(b'\x81~\x00\x80' + b'ping' * 32, 128))
|
||||
print(ws_write(b"pong" * 32, 132))
|
||||
|
||||
# mask (returned data will be 'mask' ^ 'mask')
|
||||
print(ws_read(b"\x81\x84maskmask", 4))
|
||||
|
||||
# close control frame
|
||||
s = uio.BytesIO(b'\x88\x00') # FRAME_CLOSE
|
||||
ws = websocket.websocket(s)
|
||||
print(ws.read(1))
|
||||
s.seek(2)
|
||||
print(s.read(4))
|
||||
|
||||
# misc control frames
|
||||
print(ws_read(b"\x89\x00\x81\x04ping", 4)) # FRAME_PING
|
||||
print(ws_read(b"\x8a\x00\x81\x04pong", 4)) # FRAME_PONG
|
||||
|
||||
# close method
|
||||
ws = websocket.websocket(uio.BytesIO())
|
||||
ws.close()
|
||||
|
||||
# ioctl
|
||||
ws = websocket.websocket(uio.BytesIO())
|
||||
print(ws.ioctl(8)) # GET_DATA_OPTS
|
||||
print(ws.ioctl(9, 2)) # SET_DATA_OPTS
|
||||
print(ws.ioctl(9))
|
||||
try:
|
||||
ws.ioctl(-1)
|
||||
except OSError as e:
|
||||
print("ioctl: EINVAL:", e.args[0] == uerrno.EINVAL)
|
14
tests/extmod/websocket_basic.py.exp
Normal file
14
tests/extmod/websocket_basic.py.exp
Normal file
@ -0,0 +1,14 @@
|
||||
b'ping'
|
||||
b'ping'
|
||||
b'\x81\x04pong'
|
||||
b'pingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingping'
|
||||
b'\x81~\x00\x80pongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpong'
|
||||
b'\x00\x00\x00\x00'
|
||||
b''
|
||||
b'\x81\x02\x88\x00'
|
||||
b'ping'
|
||||
b'pong'
|
||||
0
|
||||
1
|
||||
2
|
||||
ioctl: EINVAL: True
|
@ -1,2 +1,2 @@
|
||||
# Check whether arbitrary-precision integers (MPZ) are supported
|
||||
1000000000000000000000000000000000000000000000
|
||||
print(1000000000000000000000000000000000000000000000)
|
||||
|
@ -0,0 +1 @@
|
||||
1000000000000000000000000000000000000000000000
|
@ -1,6 +1,11 @@
|
||||
# test construction of array from array with float type
|
||||
|
||||
from array import array
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
print(array('f', array('h', [1, 2])))
|
||||
print(array('d', array('f', [1, 2])))
|
||||
|
@ -1,4 +1,11 @@
|
||||
# test builtin min and max functions with float args
|
||||
try:
|
||||
min
|
||||
max
|
||||
except:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
print(min(0,1.0))
|
||||
print(min(1.0,0))
|
||||
|
@ -1,4 +1,9 @@
|
||||
from array import array
|
||||
try:
|
||||
from array import array
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
def test(a):
|
||||
print(a)
|
||||
|
@ -1,9 +1,13 @@
|
||||
# test struct package with floats
|
||||
|
||||
try:
|
||||
import ustruct as struct
|
||||
except:
|
||||
import struct
|
||||
try:
|
||||
import ustruct as struct
|
||||
except:
|
||||
import struct
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
i = 1. + 1/2
|
||||
# TODO: it looks like '=' format modifier is not yet supported
|
||||
|
@ -1,4 +1,10 @@
|
||||
import uio
|
||||
try:
|
||||
import uio
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
import micropython
|
||||
|
||||
data = b"1234" * 16
|
||||
|
@ -2,7 +2,12 @@
|
||||
|
||||
import micropython
|
||||
import sys
|
||||
import uio
|
||||
try:
|
||||
import uio
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# preallocate exception instance with some room for a traceback
|
||||
global_exc = StopIteration()
|
||||
|
@ -1,5 +1,5 @@
|
||||
StopIteration
|
||||
Traceback (most recent call last):
|
||||
File , line 18, in test
|
||||
File , line 23, in test
|
||||
StopIteration:
|
||||
|
||||
|
@ -14,5 +14,6 @@ exec('print(__debug__)')
|
||||
exec('assert 0')
|
||||
|
||||
# check that level 3 doesn't store line numbers
|
||||
# the expected output is that any line is printed as "line 1"
|
||||
micropython.opt_level(3)
|
||||
exec('try:\n xyz\nexcept NameError as er:\n import sys\n sys.print_exception(er)')
|
||||
|
@ -3,13 +3,19 @@
|
||||
def test(code):
|
||||
try:
|
||||
exec(code)
|
||||
except (SyntaxError, ViperTypeError) as e:
|
||||
except (SyntaxError, ViperTypeError, NotImplementedError) as e:
|
||||
print(repr(e))
|
||||
|
||||
# viper: annotations must be identifiers
|
||||
test("@micropython.viper\ndef f(a:1): pass")
|
||||
test("@micropython.viper\ndef f() -> 1: pass")
|
||||
|
||||
# unknown type
|
||||
test("@micropython.viper\ndef f(x:unknown_type): pass")
|
||||
|
||||
# too many arguments
|
||||
test("@micropython.viper\ndef f(a, b, c, d, e): pass")
|
||||
|
||||
# local used before type known
|
||||
test("""
|
||||
@micropython.viper
|
||||
@ -49,6 +55,9 @@ test("@micropython.viper\ndef f(): 1[x]")
|
||||
# can't store
|
||||
test("@micropython.viper\ndef f(): 1[0] = 1")
|
||||
test("@micropython.viper\ndef f(): 1[x] = 1")
|
||||
test("@micropython.viper\ndef f(x:int): x[0] = x")
|
||||
test("@micropython.viper\ndef f(x:ptr32): x[0] = None")
|
||||
test("@micropython.viper\ndef f(x:ptr32): x[x] = None")
|
||||
|
||||
# must raise an object
|
||||
test("@micropython.viper\ndef f(): raise 1")
|
||||
@ -57,3 +66,16 @@ test("@micropython.viper\ndef f(): raise 1")
|
||||
test("@micropython.viper\ndef f(x:int): +x")
|
||||
test("@micropython.viper\ndef f(x:int): -x")
|
||||
test("@micropython.viper\ndef f(x:int): ~x")
|
||||
|
||||
# binary op not implemented
|
||||
test("@micropython.viper\ndef f(x:int): res = x in x")
|
||||
|
||||
# yield (from) not implemented
|
||||
test("@micropython.viper\ndef f(): yield")
|
||||
test("@micropython.viper\ndef f(): yield from f")
|
||||
|
||||
# passing a ptr to a Python function not implemented
|
||||
test("@micropython.viper\ndef f(): print(ptr(1))")
|
||||
|
||||
# cast of a casting identifier not implemented
|
||||
test("@micropython.viper\ndef f(): int(int)")
|
||||
|
@ -1,5 +1,7 @@
|
||||
SyntaxError('parameter annotation must be an identifier',)
|
||||
SyntaxError('return annotation must be an identifier',)
|
||||
ViperTypeError("unknown type 'unknown_type'",)
|
||||
ViperTypeError("Viper functions don't currently support more than 4 arguments",)
|
||||
ViperTypeError("local 'x' used before type known",)
|
||||
ViperTypeError("local 'x' has type 'int' but source is 'object'",)
|
||||
ViperTypeError("can't implicitly convert 'ptr' to 'bool'",)
|
||||
@ -9,7 +11,15 @@ ViperTypeError("can't load from 'int'",)
|
||||
ViperTypeError("can't load from 'int'",)
|
||||
ViperTypeError("can't store to 'int'",)
|
||||
ViperTypeError("can't store to 'int'",)
|
||||
ViperTypeError("can't store to 'int'",)
|
||||
ViperTypeError("can't store 'None'",)
|
||||
ViperTypeError("can't store 'None'",)
|
||||
ViperTypeError('must raise an object',)
|
||||
ViperTypeError('unary op __pos__ not implemented',)
|
||||
ViperTypeError('unary op __neg__ not implemented',)
|
||||
ViperTypeError('unary op __invert__ not implemented',)
|
||||
ViperTypeError('binary op __contains__ not implemented',)
|
||||
NotImplementedError('native yield',)
|
||||
NotImplementedError('native yield from',)
|
||||
NotImplementedError('conversion to object',)
|
||||
NotImplementedError('casting',)
|
||||
|
@ -1,7 +1,12 @@
|
||||
# tests for things that are not implemented, or have non-compliant behaviour
|
||||
|
||||
import array
|
||||
import ustruct
|
||||
try:
|
||||
import array
|
||||
import ustruct
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# when super can't find self
|
||||
try:
|
||||
|
@ -1,8 +1,13 @@
|
||||
try:
|
||||
import uio as io
|
||||
except ImportError:
|
||||
import io
|
||||
import sys
|
||||
try:
|
||||
try:
|
||||
import uio as io
|
||||
except ImportError:
|
||||
import io
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
if hasattr(sys, 'print_exception'):
|
||||
print_exception = sys.print_exception
|
||||
else:
|
||||
|
@ -1,5 +1,10 @@
|
||||
# This tests that printing recursive data structure doesn't lead to segfault.
|
||||
import uio as io
|
||||
try:
|
||||
import uio as io
|
||||
except ImportError:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
l = [1, 2, 3, None]
|
||||
l[-1] = l
|
||||
|
@ -1,4 +1,14 @@
|
||||
# This tests that recursion with iternext doesn't lead to segfault.
|
||||
try:
|
||||
enumerate
|
||||
filter
|
||||
map
|
||||
max
|
||||
zip
|
||||
except:
|
||||
import sys
|
||||
print("SKIP")
|
||||
sys.exit()
|
||||
|
||||
# We need to pick an N that is large enough to hit the recursion
|
||||
# limit, but not too large that we run out of heap memory.
|
||||
|
@ -209,7 +209,7 @@ def run_tests(pyb, tests, args):
|
||||
|
||||
# Check if arbitrary-precision integers are supported, and skip such tests if it's not
|
||||
native = run_micropython(pyb, args, 'feature_check/int_big.py')
|
||||
if native == b'CRASH':
|
||||
if native != b'1000000000000000000000000000000000000000000000\n':
|
||||
skip_int_big = True
|
||||
|
||||
# Check if set type (and set literals) is supported, and skip such tests if it's not
|
||||
@ -261,7 +261,7 @@ def run_tests(pyb, tests, args):
|
||||
if pyb is not None:
|
||||
skip_tests.add('basics/exception_chain.py') # warning is not printed
|
||||
skip_tests.add('float/float_divmod.py') # tested by float/float_divmod_relaxed.py instead
|
||||
skip_tests.add('float/float2int_doubleprec.py') # requires double precision floating point to work
|
||||
skip_tests.add('float/float2int_doubleprec_intbig.py') # requires double precision floating point to work
|
||||
skip_tests.add('micropython/meminfo.py') # output is very different to PC output
|
||||
skip_tests.add('extmod/machine_mem.py') # raw memory access not supported
|
||||
|
||||
|
@ -43,6 +43,9 @@ Warning: test
|
||||
?
|
||||
+1e+00
|
||||
+1e+00
|
||||
# binary
|
||||
122
|
||||
456
|
||||
0123456789 b'0123456789'
|
||||
7300
|
||||
7300
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "py/emit.h"
|
||||
#include "py/formatfloat.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
#if defined(MICROPY_UNIX_COVERAGE)
|
||||
|
||||
@ -278,6 +279,19 @@ STATIC mp_obj_t extra_coverage(void) {
|
||||
mp_printf(&mp_plat_print, "%s\n", buf2);
|
||||
}
|
||||
|
||||
// binary
|
||||
{
|
||||
mp_printf(&mp_plat_print, "# binary\n");
|
||||
|
||||
// call function with float and double typecodes
|
||||
float far[1];
|
||||
double dar[1];
|
||||
mp_binary_set_val_array_from_int('f', far, 0, 123);
|
||||
mp_printf(&mp_plat_print, "%.0f\n", (double)far[0]);
|
||||
mp_binary_set_val_array_from_int('d', dar, 0, 456);
|
||||
mp_printf(&mp_plat_print, "%.0lf\n", dar[0]);
|
||||
}
|
||||
|
||||
mp_obj_streamtest_t *s = m_new_obj(mp_obj_streamtest_t);
|
||||
s->base.type = &mp_type_stest_fileio;
|
||||
s->buf = NULL;
|
||||
|
41
unix/main.c
41
unix/main.c
@ -90,19 +90,33 @@ STATIC int handle_uncaught_exception(mp_obj_base_t *exc) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define LEX_SRC_STR (1)
|
||||
#define LEX_SRC_VSTR (2)
|
||||
#define LEX_SRC_FILENAME (3)
|
||||
#define LEX_SRC_STDIN (4)
|
||||
|
||||
// Returns standard error codes: 0 for success, 1 for all other errors,
|
||||
// except if FORCED_EXIT bit is set then script raised SystemExit and the
|
||||
// value of the exit is in the lower 8 bits of the return value
|
||||
STATIC int execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bool is_repl) {
|
||||
if (lex == NULL) {
|
||||
printf("MemoryError: lexer could not allocate memory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
STATIC int execute_from_lexer(int source_kind, const void *source, mp_parse_input_kind_t input_kind, bool is_repl) {
|
||||
mp_hal_set_interrupt_char(CHAR_CTRL_C);
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
// create lexer based on source kind
|
||||
mp_lexer_t *lex;
|
||||
if (source_kind == LEX_SRC_STR) {
|
||||
const char *line = source;
|
||||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false);
|
||||
} else if (source_kind == LEX_SRC_VSTR) {
|
||||
const vstr_t *vstr = source;
|
||||
lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, false);
|
||||
} else if (source_kind == LEX_SRC_FILENAME) {
|
||||
lex = mp_lexer_new_from_file((const char*)source);
|
||||
} else { // LEX_SRC_STDIN
|
||||
lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false);
|
||||
}
|
||||
|
||||
qstr source_name = lex->source_name;
|
||||
|
||||
#if MICROPY_PY___FILE__
|
||||
@ -240,8 +254,7 @@ STATIC int do_repl(void) {
|
||||
|
||||
mp_hal_stdio_mode_orig();
|
||||
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, false);
|
||||
ret = execute_from_lexer(lex, parse_input_kind, true);
|
||||
ret = execute_from_lexer(LEX_SRC_VSTR, &line, parse_input_kind, true);
|
||||
if (ret & FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
@ -268,8 +281,7 @@ STATIC int do_repl(void) {
|
||||
line = line3;
|
||||
}
|
||||
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false);
|
||||
int ret = execute_from_lexer(lex, MP_PARSE_SINGLE_INPUT, true);
|
||||
int ret = execute_from_lexer(LEX_SRC_STR, line, MP_PARSE_SINGLE_INPUT, true);
|
||||
if (ret & FORCED_EXIT) {
|
||||
return ret;
|
||||
}
|
||||
@ -280,13 +292,11 @@ STATIC int do_repl(void) {
|
||||
}
|
||||
|
||||
STATIC int do_file(const char *file) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_file(file);
|
||||
return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false);
|
||||
return execute_from_lexer(LEX_SRC_FILENAME, file, MP_PARSE_FILE_INPUT, false);
|
||||
}
|
||||
|
||||
STATIC int do_str(const char *str) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, str, strlen(str), false);
|
||||
return execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false);
|
||||
return execute_from_lexer(LEX_SRC_STR, str, MP_PARSE_FILE_INPUT, false);
|
||||
}
|
||||
|
||||
STATIC int usage(char **argv) {
|
||||
@ -585,8 +595,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
|
||||
ret = do_repl();
|
||||
prompt_write_history();
|
||||
} else {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false);
|
||||
ret = execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false);
|
||||
ret = execute_from_lexer(LEX_SRC_STDIN, NULL, MP_PARSE_FILE_INPUT, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,17 +5,10 @@
|
||||
# recursively Makefile.zephyr to build complete application binary
|
||||
# using Zephyr build system.
|
||||
#
|
||||
# To build a "minimal" configuration, use "make-minimal" wrapper.
|
||||
|
||||
BOARD ?= qemu_x86
|
||||
ifeq ($(MAKECMDGOALS), minimal)
|
||||
# For minimal, CONF_FILE must be overriden early due to $(Z_EXPORTS) target
|
||||
CONF_FILE = prj_minimal.conf
|
||||
else
|
||||
CONF_FILE = prj.conf
|
||||
endif
|
||||
# Zephyr 1.5.0
|
||||
#OUTDIR_PREFIX =
|
||||
# Zephyr 1.6.0
|
||||
OUTDIR_PREFIX = $(BOARD)
|
||||
|
||||
# Default heap size is 16KB, which is on conservative side, to let
|
||||
@ -42,6 +35,7 @@ INC += -I$(ZEPHYR_BASE)/net/ip/contiki/os
|
||||
SRC_C = main.c \
|
||||
help.c \
|
||||
modutime.c \
|
||||
modzephyr.c \
|
||||
modmachine.c \
|
||||
machine_pin.c \
|
||||
uart_core.c \
|
||||
@ -65,7 +59,7 @@ include ../py/mkrules.mk
|
||||
$(Z_EXPORTS): $(CONF_FILE)
|
||||
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) CONF_FILE=$(CONF_FILE) initconfig outputexports
|
||||
|
||||
GENERIC_TARGETS = all zephyr qemu qemugdb flash debug
|
||||
GENERIC_TARGETS = all zephyr run qemu qemugdb flash debug
|
||||
KCONFIG_TARGETS = \
|
||||
initconfig config nconfig menuconfig xconfig gconfig \
|
||||
oldconfig silentoldconfig defconfig savedefconfig \
|
||||
@ -87,12 +81,6 @@ $(Z_SYSGEN_H):
|
||||
rm -f $(LIBMICROPYTHON)
|
||||
-$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) CONF_FILE=$(CONF_FILE)
|
||||
|
||||
minimal:
|
||||
$(MAKE) BOARD=$(BOARD) CONF_FILE=prj_minimal.conf CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_minimal.h>"' FROZEN_DIR=
|
||||
|
||||
qemu-minimal:
|
||||
$(MAKE) -f Makefile.zephyr BOARD=$(BOARD) CONF_FILE=prj_minimal.conf QEMU_NET=0 run
|
||||
|
||||
# Clean Zephyr things too
|
||||
clean: z_clean
|
||||
|
||||
@ -101,5 +89,4 @@ z_clean:
|
||||
|
||||
.PHONY: prj.conf
|
||||
prj.conf: prj_base.conf
|
||||
cat $< >$@
|
||||
if [ -f prj_$(BOARD).conf ]; then cat prj_$(BOARD).conf >>$@; fi
|
||||
$(PYTHON) makeprj.py prj_base.conf prj_$(BOARD).conf $@
|
||||
|
@ -98,17 +98,17 @@ below 128KB, as long as Zephyr project is committed to maintain stable
|
||||
minimal size of their kernel (which they appear to be). Note that at such
|
||||
size, there is no support for any Zephyr features beyond REPL over UART,
|
||||
and only very minimal set of builtin Python modules. Thus, this build
|
||||
is more suitable for code size control and quick demonstrations even on
|
||||
is more suitable for code size control and quick demonstrations on
|
||||
smaller systems. It's also suitable for careful enabling of features one
|
||||
by one to achieve needed functionality and code size. This is in contrast
|
||||
to the "default" build, which may get more and more features enabled by
|
||||
default over time.
|
||||
by one to achieve needed functionality and code size. This is in a
|
||||
contrast to the "default" build, which may get more and more features
|
||||
enabled over time.
|
||||
|
||||
To make a minimal build:
|
||||
|
||||
make BOARD=<board> minimal
|
||||
./make-minimal BOARD=<board>
|
||||
|
||||
To run a minimal build in QEMU without requiring TAP networking setup
|
||||
run the following after you built image with the previous command:
|
||||
|
||||
make BOARD=<qemu_x86|qemu_cortex_m3> qemu-minimal
|
||||
./make-minimal BOARD=<qemu_x86|qemu_cortex_m3> qemu
|
||||
|
@ -44,14 +44,9 @@
|
||||
#include "lib/mp-readline/readline.h"
|
||||
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
printf("MemoryError: lexer could not allocate memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
@ -130,7 +125,7 @@ void gc_collect(void) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
mp_raise_OSError(ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
@ -142,10 +137,7 @@ mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs)
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
NORETURN void nlr_jump_fail(void *val) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
16
zephyr/make-minimal
Executable file
16
zephyr/make-minimal
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This is a wrapper for make to build a "minimal" Zephyr port.
|
||||
# It should be run just like make (i.e. extra vars can be passed on the
|
||||
# command line, etc.), e.g.:
|
||||
#
|
||||
# ./make-minimal BOARD=qemu_cortex_m3
|
||||
# ./make-minimal BOARD=qemu_cortex_m3 run
|
||||
#
|
||||
|
||||
make \
|
||||
CONF_FILE=prj_minimal.conf \
|
||||
CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_minimal.h>"' \
|
||||
FROZEN_DIR= \
|
||||
QEMU_NET=0 \
|
||||
"$@"
|
29
zephyr/makeprj.py
Normal file
29
zephyr/makeprj.py
Normal file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
|
||||
def hash_file(fname):
|
||||
if not os.path.exists(fname):
|
||||
return b""
|
||||
hasher = hashlib.md5()
|
||||
with open(fname, "rb") as f:
|
||||
hasher.update(f.read())
|
||||
return hasher.digest()
|
||||
|
||||
|
||||
old_digest = hash_file(sys.argv[3])
|
||||
|
||||
with open(sys.argv[3] + ".tmp", "wb") as f:
|
||||
f.write(open(sys.argv[1], "rb").read())
|
||||
if os.path.exists(sys.argv[2]):
|
||||
f.write(open(sys.argv[2], "rb").read())
|
||||
|
||||
new_digest = hash_file(sys.argv[3] + ".tmp")
|
||||
|
||||
if new_digest != old_digest:
|
||||
print("Replacing")
|
||||
os.rename(sys.argv[3] + ".tmp", sys.argv[3])
|
||||
else:
|
||||
os.remove(sys.argv[3] + ".tmp")
|
51
zephyr/modzephyr.c
Normal file
51
zephyr/modzephyr.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Linaro Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_PY_ZEPHYR
|
||||
|
||||
#include <zephyr.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
STATIC mp_obj_t mod_is_preempt_thread(void) {
|
||||
return mp_obj_new_bool(k_is_preempt_thread());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_is_preempt_thread_obj, mod_is_preempt_thread);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_zephyr) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_is_preempt_thread), MP_ROM_PTR(&mod_is_preempt_thread_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_zephyr = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_time_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_ZEPHYR
|
@ -60,6 +60,7 @@
|
||||
#define MICROPY_PY_STRUCT (0)
|
||||
#define MICROPY_PY_UTIME (1)
|
||||
#define MICROPY_PY_UTIME_MP_HAL (1)
|
||||
#define MICROPY_PY_ZEPHYR (1)
|
||||
#define MICROPY_PY_SYS_MODULES (0)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||
@ -100,6 +101,7 @@ typedef long mp_off_t;
|
||||
|
||||
extern const struct _mp_obj_module_t mp_module_machine;
|
||||
extern const struct _mp_obj_module_t mp_module_time;
|
||||
extern const struct _mp_obj_module_t mp_module_zephyr;
|
||||
|
||||
#if MICROPY_PY_UTIME
|
||||
#define MICROPY_PY_UTIME_DEF { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_time) },
|
||||
@ -107,9 +109,16 @@ extern const struct _mp_obj_module_t mp_module_time;
|
||||
#define MICROPY_PY_UTIME_DEF
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_ZEPHYR
|
||||
#define MICROPY_PY_ZEPHYR_DEF { MP_ROM_QSTR(MP_QSTR_zephyr), MP_ROM_PTR(&mp_module_zephyr) },
|
||||
#else
|
||||
#define MICROPY_PY_ZEPHYR_DEF
|
||||
#endif
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \
|
||||
MICROPY_PY_UTIME_DEF \
|
||||
MICROPY_PY_ZEPHYR_DEF \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), MP_ROM_PTR(&mp_module_time) }, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user