mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Upgrade to MicroPython 1.9.3
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#define MICROPY_VERSION_MAJOR 1
|
||||
#define MICROPY_VERSION_MINOR 9
|
||||
#define MICROPY_VERSION_MICRO 1
|
||||
#define MICROPY_VERSION_STRING "1.9.1"
|
||||
#define MICROPY_VERSION_MAJOR (1)
|
||||
#define MICROPY_VERSION_MINOR (9)
|
||||
#define MICROPY_VERSION_MICRO (3)
|
||||
#define MICROPY_VERSION_STRING "1.9.3"
|
||||
|
||||
@@ -73,8 +73,10 @@ Q(__getattr__)
|
||||
Q(__getitem__)
|
||||
Q(__gt__)
|
||||
Q(__hash__)
|
||||
Q(__iadd__)
|
||||
Q(__import__)
|
||||
Q(__init__)
|
||||
Q(__isub__)
|
||||
Q(__iter__)
|
||||
Q(__le__)
|
||||
Q(__len__)
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
//#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_URANDOM
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) {
|
||||
@@ -134,14 +133,12 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args,
|
||||
mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals);
|
||||
}
|
||||
|
||||
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || _MSC_VER
|
||||
NORETURN void mp_arg_error_terse_mismatch(void) {
|
||||
mp_raise_TypeError("argument num/types mismatch");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
NORETURN void mp_arg_error_unimpl_kw(void) {
|
||||
mp_not_implemented("keyword argument(s) not yet implemented - use normal args instead");
|
||||
mp_raise_NotImplementedError("keyword argument(s) not yet implemented - use normal args instead");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -33,6 +33,7 @@
|
||||
// wrapper around everything in this file
|
||||
#if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB
|
||||
|
||||
#include "py/mphal.h"
|
||||
#include "py/asmthumb.h"
|
||||
|
||||
#define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0)
|
||||
@@ -53,7 +54,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) {
|
||||
#if defined(MCU_SERIES_F7)
|
||||
if (as->base.pass == MP_ASM_PASS_EMIT) {
|
||||
// flush D-cache, so the code emitted is stored in memory
|
||||
SCB_CleanDCache_by_Addr((uint32_t*)as->base.code_base, as->base.code_size);
|
||||
MP_HAL_CLEAN_DCACHE(as->base.code_base, as->base.code_size);
|
||||
// invalidate I-cache
|
||||
SCB_InvalidateICache();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,13 +29,11 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/objfun.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/bc0.h"
|
||||
#include "py/bc.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_PRINT (0)
|
||||
@@ -323,7 +321,7 @@ STATIC const byte opcode_format_table[64] = {
|
||||
OC4(O, O, U, U), // 0x38-0x3b
|
||||
OC4(U, O, B, O), // 0x3c-0x3f
|
||||
OC4(O, B, B, O), // 0x40-0x43
|
||||
OC4(B, B, O, U), // 0x44-0x47
|
||||
OC4(B, B, O, B), // 0x44-0x47
|
||||
OC4(U, U, U, U), // 0x48-0x4b
|
||||
OC4(U, U, U, U), // 0x4c-0x4f
|
||||
OC4(V, V, U, V), // 0x50-0x53
|
||||
@@ -363,7 +361,7 @@ STATIC const byte opcode_format_table[64] = {
|
||||
OC4(B, B, B, B), // 0xcc-0xcf
|
||||
|
||||
OC4(B, B, B, B), // 0xd0-0xd3
|
||||
OC4(B, B, B, B), // 0xd4-0xd7
|
||||
OC4(U, U, U, B), // 0xd4-0xd7
|
||||
OC4(B, B, B, B), // 0xd8-0xdb
|
||||
OC4(B, B, B, B), // 0xdc-0xdf
|
||||
|
||||
@@ -374,7 +372,7 @@ STATIC const byte opcode_format_table[64] = {
|
||||
|
||||
OC4(B, B, B, B), // 0xf0-0xf3
|
||||
OC4(B, B, B, B), // 0xf4-0xf7
|
||||
OC4(B, B, B, U), // 0xf8-0xfb
|
||||
OC4(U, U, U, U), // 0xf8-0xfb
|
||||
OC4(U, U, U, U), // 0xfc-0xff
|
||||
};
|
||||
#undef OC4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,7 +27,6 @@
|
||||
#define MICROPY_INCLUDED_PY_BC_H
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objfun.h"
|
||||
|
||||
// bytecode layout:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef MICROPY_INCLUDED_PY_BC0_H
|
||||
#define MICROPY_INCLUDED_PY_BC0_H
|
||||
|
||||
// Micro Python byte-codes.
|
||||
// MicroPython byte-codes.
|
||||
// The comment at the end of the line (if it exists) tells the arguments to the byte-code.
|
||||
|
||||
#define MP_BC_LOAD_CONST_FALSE (0x10)
|
||||
@@ -113,7 +113,7 @@
|
||||
#define MP_BC_LOAD_CONST_SMALL_INT_MULTI (0x70) // + N(64)
|
||||
#define MP_BC_LOAD_FAST_MULTI (0xb0) // + N(16)
|
||||
#define MP_BC_STORE_FAST_MULTI (0xc0) // + N(16)
|
||||
#define MP_BC_UNARY_OP_MULTI (0xd0) // + op(7)
|
||||
#define MP_BC_BINARY_OP_MULTI (0xd7) // + op(36)
|
||||
#define MP_BC_UNARY_OP_MULTI (0xd0) // + op(<MP_UNARY_OP_NUM_BYTECODE)
|
||||
#define MP_BC_BINARY_OP_MULTI (0xd7) // + op(<MP_BINARY_OP_NUM_BYTECODE)
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_BC0_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -303,7 +303,10 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
|
||||
// zero/sign extend if needed
|
||||
if (BYTES_PER_WORD < 8 && size > sizeof(val)) {
|
||||
int c = (is_signed(val_type) && (mp_int_t)val < 0) ? 0xff : 0x00;
|
||||
memset(p + sizeof(val), c, size - sizeof(val));
|
||||
memset(p, c, size);
|
||||
if (struct_type == '>') {
|
||||
p += size - sizeof(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,8 +29,9 @@
|
||||
#include "py/obj.h"
|
||||
|
||||
// Use special typecode to differentiate repr() of bytearray vs array.array('B')
|
||||
// (underlyingly they're same).
|
||||
#define BYTEARRAY_TYPECODE 0
|
||||
// (underlyingly they're same). Can't use 0 here because that's used to detect
|
||||
// type-specification errors due to end-of-string.
|
||||
#define BYTEARRAY_TYPECODE 1
|
||||
|
||||
size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign);
|
||||
mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -118,6 +118,6 @@ extern const mp_obj_module_t mp_module_webrepl;
|
||||
extern const mp_obj_module_t mp_module_framebuf;
|
||||
extern const mp_obj_module_t mp_module_btree;
|
||||
|
||||
extern const char *MICROPY_PY_BUILTINS_HELP_TEXT;
|
||||
extern const char MICROPY_PY_BUILTINS_HELP_TEXT[];
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_BUILTIN_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/objfun.h"
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#if MICROPY_PY_BUILTINS_HELP
|
||||
|
||||
const char *mp_help_default_text =
|
||||
const char mp_help_default_text[] =
|
||||
"Welcome to MicroPython!\n"
|
||||
"\n"
|
||||
"For online docs please visit http://docs.micropython.org/\n"
|
||||
@@ -136,20 +136,19 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) {
|
||||
}
|
||||
#endif
|
||||
|
||||
mp_obj_type_t *type = mp_obj_get_type(obj);
|
||||
|
||||
// try to print something sensible about the given object
|
||||
mp_print_str(MP_PYTHON_PRINTER, "object ");
|
||||
mp_obj_print(obj, PRINT_STR);
|
||||
mp_printf(MP_PYTHON_PRINTER, " is of type %s\n", mp_obj_get_type_str(obj));
|
||||
mp_printf(MP_PYTHON_PRINTER, " is of type %q\n", type->name);
|
||||
|
||||
mp_map_t *map = NULL;
|
||||
if (MP_OBJ_IS_TYPE(obj, &mp_type_module)) {
|
||||
if (type == &mp_type_module) {
|
||||
map = mp_obj_dict_get_map(mp_obj_module_get_globals(obj));
|
||||
} else {
|
||||
mp_obj_type_t *type;
|
||||
if (MP_OBJ_IS_TYPE(obj, &mp_type_type)) {
|
||||
type = obj;
|
||||
} else {
|
||||
type = mp_obj_get_type(obj);
|
||||
if (type == &mp_type_type) {
|
||||
type = MP_OBJ_TO_PTR(obj);
|
||||
}
|
||||
if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) {
|
||||
map = mp_obj_dict_get_map(type->locals_dict);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/compile.h"
|
||||
#include "py/objmodule.h"
|
||||
#include "py/persistentcode.h"
|
||||
@@ -37,7 +36,7 @@
|
||||
#include "py/builtin.h"
|
||||
#include "py/frozenmod.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -569,7 +569,7 @@ STATIC void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int
|
||||
for (int j = 0; j < this_scope->id_info_len; j++) {
|
||||
id_info_t *id2 = &this_scope->id_info[j];
|
||||
if (id2->kind == ID_INFO_KIND_FREE && id->qst == id2->qst) {
|
||||
// in Micro Python we load closures using LOAD_FAST
|
||||
// in MicroPython we load closures using LOAD_FAST
|
||||
EMIT_LOAD_FAST(id->qst, id->local_num);
|
||||
nfree += 1;
|
||||
}
|
||||
@@ -613,13 +613,11 @@ STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn)
|
||||
|
||||
} else {
|
||||
mp_parse_node_t pn_id;
|
||||
mp_parse_node_t pn_colon;
|
||||
mp_parse_node_t pn_equal;
|
||||
if (pn_kind == -1) {
|
||||
// this parameter is just an id
|
||||
|
||||
pn_id = pn;
|
||||
pn_colon = MP_PARSE_NODE_NULL;
|
||||
pn_equal = MP_PARSE_NODE_NULL;
|
||||
|
||||
} else if (pn_kind == PN_typedargslist_name) {
|
||||
@@ -627,7 +625,7 @@ STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn)
|
||||
|
||||
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
|
||||
pn_id = pns->nodes[0];
|
||||
pn_colon = pns->nodes[1];
|
||||
//pn_colon = pns->nodes[1]; // unused
|
||||
pn_equal = pns->nodes[2];
|
||||
|
||||
} else {
|
||||
@@ -654,9 +652,9 @@ STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn)
|
||||
|
||||
if (comp->have_star) {
|
||||
comp->num_dict_params += 1;
|
||||
// in Micro Python we put the default dict parameters into a dictionary using the bytecode
|
||||
// in MicroPython we put the default dict parameters into a dictionary using the bytecode
|
||||
if (comp->num_dict_params == 1) {
|
||||
// in Micro Python we put the default positional parameters into a tuple using the bytecode
|
||||
// in MicroPython we put the default positional parameters into a tuple using the bytecode
|
||||
// we need to do this here before we start building the map for the default keywords
|
||||
if (comp->num_default_params > 0) {
|
||||
EMIT_ARG(build_tuple, comp->num_default_params);
|
||||
@@ -676,9 +674,6 @@ STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn)
|
||||
compile_node(comp, pn_equal);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO pn_colon not implemented
|
||||
(void)pn_colon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,7 +695,7 @@ STATIC void compile_funcdef_lambdef(compiler_t *comp, scope_t *scope, mp_parse_n
|
||||
return;
|
||||
}
|
||||
|
||||
// in Micro Python we put the default positional parameters into a tuple using the bytecode
|
||||
// in MicroPython we put the default positional parameters into a tuple using the bytecode
|
||||
// the default keywords args may have already made the tuple; if not, do it now
|
||||
if (comp->num_default_params > 0 && comp->num_dict_params == 0) {
|
||||
EMIT_ARG(build_tuple, comp->num_default_params);
|
||||
@@ -3275,7 +3270,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
|
||||
#endif
|
||||
|
||||
STATIC void scope_compute_things(scope_t *scope) {
|
||||
// in Micro Python we put the *x parameter after all other parameters (except **y)
|
||||
// in MicroPython we put the *x parameter after all other parameters (except **y)
|
||||
if (scope->scope_flags & MP_SCOPE_FLAG_VARARGS) {
|
||||
id_info_t *id_param = NULL;
|
||||
for (int i = scope->id_info_len - 1; i >= 0; i--) {
|
||||
@@ -3313,7 +3308,7 @@ STATIC void scope_compute_things(scope_t *scope) {
|
||||
// compute the index of cell vars
|
||||
for (int i = 0; i < scope->id_info_len; i++) {
|
||||
id_info_t *id = &scope->id_info[i];
|
||||
// in Micro Python the cells come right after the fast locals
|
||||
// in MicroPython the cells come right after the fast locals
|
||||
// parameters are not counted here, since they remain at the start
|
||||
// of the locals, even if they are cell vars
|
||||
if (id->kind == ID_INFO_KIND_CELL && !(id->flags & ID_FLAG_IS_PARAM)) {
|
||||
@@ -3333,14 +3328,14 @@ STATIC void scope_compute_things(scope_t *scope) {
|
||||
id_info_t *id2 = &scope->id_info[j];
|
||||
if (id2->kind == ID_INFO_KIND_FREE && id->qst == id2->qst) {
|
||||
assert(!(id2->flags & ID_FLAG_IS_PARAM)); // free vars should not be params
|
||||
// in Micro Python the frees come first, before the params
|
||||
// in MicroPython the frees come first, before the params
|
||||
id2->local_num = num_free;
|
||||
num_free += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// in Micro Python shift all other locals after the free locals
|
||||
// in MicroPython shift all other locals after the free locals
|
||||
if (num_free > 0) {
|
||||
for (int i = 0; i < scope->id_info_len; i++) {
|
||||
id_info_t *id = &scope->id_info[i];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "py/lexer.h"
|
||||
#include "py/scope.h"
|
||||
#include "py/runtime0.h"
|
||||
|
||||
/* Notes on passes:
|
||||
* We don't know exactly the opcodes in pass 1 because they depend on the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -550,7 +550,7 @@ void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj) {
|
||||
void mp_emit_bc_load_null(emit_t *emit) {
|
||||
emit_bc_pre(emit, 1);
|
||||
emit_write_bytecode_byte(emit, MP_BC_LOAD_NULL);
|
||||
};
|
||||
}
|
||||
|
||||
void mp_emit_bc_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) {
|
||||
(void)qst;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "py/runtime0.h"
|
||||
#include "py/bc.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define WRITE_CODE (1)
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -46,11 +46,10 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/emit.h"
|
||||
#include "py/bc.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
@@ -124,6 +123,8 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = {
|
||||
[MP_F_NEW_CELL] = 1,
|
||||
[MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3,
|
||||
[MP_F_SETUP_CODE_STATE] = 5,
|
||||
[MP_F_SMALL_INT_FLOOR_DIVIDE] = 2,
|
||||
[MP_F_SMALL_INT_MODULO] = 2,
|
||||
};
|
||||
|
||||
#include "py/asmx86.h"
|
||||
@@ -824,7 +825,7 @@ STATIC void emit_get_stack_pointer_to_reg_for_pop(emit_t *emit, mp_uint_t reg_de
|
||||
break;
|
||||
default:
|
||||
// not handled
|
||||
mp_not_implemented("conversion to object");
|
||||
mp_raise_NotImplementedError("conversion to object");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1824,18 +1825,20 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
|
||||
vtype_kind_t vtype_lhs = peek_vtype(emit, 1);
|
||||
vtype_kind_t vtype_rhs = peek_vtype(emit, 0);
|
||||
if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) {
|
||||
// for integers, inplace and normal ops are equivalent, so use just normal ops
|
||||
if (MP_BINARY_OP_INPLACE_OR <= op && op <= MP_BINARY_OP_INPLACE_POWER) {
|
||||
op += MP_BINARY_OP_OR - MP_BINARY_OP_INPLACE_OR;
|
||||
}
|
||||
|
||||
#if N_X64 || N_X86
|
||||
// special cases for x86 and shifting
|
||||
if (op == MP_BINARY_OP_LSHIFT
|
||||
|| op == MP_BINARY_OP_INPLACE_LSHIFT
|
||||
|| op == MP_BINARY_OP_RSHIFT
|
||||
|| op == MP_BINARY_OP_INPLACE_RSHIFT) {
|
||||
if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_RSHIFT) {
|
||||
#if N_X64
|
||||
emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X64_REG_RCX, &vtype_lhs, REG_RET);
|
||||
#else
|
||||
emit_pre_pop_reg_reg(emit, &vtype_rhs, ASM_X86_REG_ECX, &vtype_lhs, REG_RET);
|
||||
#endif
|
||||
if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
|
||||
if (op == MP_BINARY_OP_LSHIFT) {
|
||||
ASM_LSL_REG(emit->as, REG_RET);
|
||||
} else {
|
||||
ASM_ASR_REG(emit->as, REG_RET);
|
||||
@@ -1844,35 +1847,48 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// special cases for floor-divide and module because we dispatch to helper functions
|
||||
if (op == MP_BINARY_OP_FLOOR_DIVIDE || op == MP_BINARY_OP_MODULO) {
|
||||
emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_2, &vtype_lhs, REG_ARG_1);
|
||||
if (op == MP_BINARY_OP_FLOOR_DIVIDE) {
|
||||
emit_call(emit, MP_F_SMALL_INT_FLOOR_DIVIDE);
|
||||
} else {
|
||||
emit_call(emit, MP_F_SMALL_INT_MODULO);
|
||||
}
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_RET);
|
||||
return;
|
||||
}
|
||||
|
||||
int reg_rhs = REG_ARG_3;
|
||||
emit_pre_pop_reg_flexible(emit, &vtype_rhs, ®_rhs, REG_RET, REG_ARG_2);
|
||||
emit_pre_pop_reg(emit, &vtype_lhs, REG_ARG_2);
|
||||
if (0) {
|
||||
// dummy
|
||||
#if !(N_X64 || N_X86)
|
||||
} else if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) {
|
||||
} else if (op == MP_BINARY_OP_LSHIFT) {
|
||||
ASM_LSL_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (op == MP_BINARY_OP_RSHIFT || op == MP_BINARY_OP_INPLACE_RSHIFT) {
|
||||
} else if (op == MP_BINARY_OP_RSHIFT) {
|
||||
ASM_ASR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
#endif
|
||||
} else if (op == MP_BINARY_OP_OR || op == MP_BINARY_OP_INPLACE_OR) {
|
||||
} else if (op == MP_BINARY_OP_OR) {
|
||||
ASM_OR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (op == MP_BINARY_OP_XOR || op == MP_BINARY_OP_INPLACE_XOR) {
|
||||
} else if (op == MP_BINARY_OP_XOR) {
|
||||
ASM_XOR_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (op == MP_BINARY_OP_AND || op == MP_BINARY_OP_INPLACE_AND) {
|
||||
} else if (op == MP_BINARY_OP_AND) {
|
||||
ASM_AND_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (op == MP_BINARY_OP_ADD || op == MP_BINARY_OP_INPLACE_ADD) {
|
||||
} else if (op == MP_BINARY_OP_ADD) {
|
||||
ASM_ADD_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (op == MP_BINARY_OP_SUBTRACT || op == MP_BINARY_OP_INPLACE_SUBTRACT) {
|
||||
} else if (op == MP_BINARY_OP_SUBTRACT) {
|
||||
ASM_SUB_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (op == MP_BINARY_OP_MULTIPLY || op == MP_BINARY_OP_INPLACE_MULTIPLY) {
|
||||
} else if (op == MP_BINARY_OP_MULTIPLY) {
|
||||
ASM_MUL_REG_REG(emit->as, REG_ARG_2, reg_rhs);
|
||||
emit_post_push_reg(emit, VTYPE_INT, REG_ARG_2);
|
||||
} else if (MP_BINARY_OP_LESS <= op && op <= MP_BINARY_OP_NOT_EQUAL) {
|
||||
@@ -2158,7 +2174,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u
|
||||
break;
|
||||
default:
|
||||
// this can happen when casting a cast: int(int)
|
||||
mp_not_implemented("casting");
|
||||
mp_raise_NotImplementedError("casting");
|
||||
}
|
||||
} else {
|
||||
assert(vtype_fun == VTYPE_PYOBJ);
|
||||
@@ -2232,12 +2248,12 @@ STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) {
|
||||
STATIC void emit_native_yield_value(emit_t *emit) {
|
||||
// not supported (for now)
|
||||
(void)emit;
|
||||
mp_not_implemented("native yield");
|
||||
mp_raise_NotImplementedError("native yield");
|
||||
}
|
||||
STATIC void emit_native_yield_from(emit_t *emit) {
|
||||
// not supported (for now)
|
||||
(void)emit;
|
||||
mp_not_implemented("native yield from");
|
||||
mp_raise_NotImplementedError("native yield from");
|
||||
}
|
||||
|
||||
STATIC void emit_native_start_except_handler(emit_t *emit) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "py/formatfloat.h"
|
||||
|
||||
/***********************************************************************
|
||||
@@ -68,12 +69,10 @@ union floatbits {
|
||||
uint32_t u;
|
||||
};
|
||||
static inline int fp_signbit(float x) { union floatbits fb = {x}; return fb.u & FLT_SIGN_MASK; }
|
||||
static inline int fp_isspecial(float x) { union floatbits fb = {x}; return (fb.u & FLT_EXP_MASK) == FLT_EXP_MASK; }
|
||||
static inline int fp_isinf(float x) { union floatbits fb = {x}; return (fb.u & FLT_MAN_MASK) == 0; }
|
||||
#define fp_isnan(x) isnan(x)
|
||||
#define fp_isinf(x) isinf(x)
|
||||
static inline int fp_iszero(float x) { union floatbits fb = {x}; return fb.u == 0; }
|
||||
static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u < 0x3f800000; }
|
||||
// Assumes both fp_isspecial() and fp_isinf() were applied before
|
||||
#define fp_isnan(x) 1
|
||||
|
||||
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
|
||||
|
||||
@@ -82,9 +81,7 @@ static inline int fp_isless1(float x) { union floatbits fb = {x}; return fb.u <
|
||||
#define FPROUND_TO_ONE 0.999999999995
|
||||
#define FPDECEXP 256
|
||||
#define FPMIN_BUF_SIZE 7 // +9e+199
|
||||
#include <math.h>
|
||||
#define fp_signbit(x) signbit(x)
|
||||
#define fp_isspecial(x) 1
|
||||
#define fp_isnan(x) isnan(x)
|
||||
#define fp_isinf(x) isinf(x)
|
||||
#define fp_iszero(x) (x == 0)
|
||||
@@ -118,11 +115,11 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
|
||||
*s++ = '?';
|
||||
}
|
||||
if (buf_size >= 1) {
|
||||
*s++ = '\0';
|
||||
*s = '\0';
|
||||
}
|
||||
return buf_size >= 2;
|
||||
}
|
||||
if (fp_signbit(f)) {
|
||||
if (fp_signbit(f) && !fp_isnan(f)) {
|
||||
*s++ = '-';
|
||||
f = -f;
|
||||
} else {
|
||||
@@ -135,7 +132,7 @@ int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, ch
|
||||
// It is buf_size minus room for the sign and null byte.
|
||||
int buf_remaining = buf_size - 1 - (s - buf);
|
||||
|
||||
if (fp_isspecial(f)) {
|
||||
{
|
||||
char uc = fmt & 0x20;
|
||||
if (fp_isinf(f)) {
|
||||
*s++ = 'I' ^ uc;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,14 +28,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_ENABLE_GC
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -32,7 +32,7 @@
|
||||
// # single_input is a single interactive statement;
|
||||
// # file_input is a module or sequence of commands read from an input file;
|
||||
// # eval_input is the input for the eval() functions.
|
||||
// # NB: compound_stmt in single_input is followed by extra NEWLINE! --> not in Micro Python
|
||||
// # NB: compound_stmt in single_input is followed by extra NEWLINE! --> not in MicroPython
|
||||
// single_input: NEWLINE | simple_stmt | compound_stmt
|
||||
// file_input: (NEWLINE | stmt)* ENDMARKER
|
||||
// eval_input: testlist NEWLINE* ENDMARKER
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/reader.h"
|
||||
#include "py/lexer.h"
|
||||
#include "py/runtime.h"
|
||||
@@ -341,7 +340,7 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw) {
|
||||
// 3MB of text; even gzip-compressed and with minimal structure, it'll take
|
||||
// roughly half a meg of storage. This form of Unicode escape may be added
|
||||
// later on, but it's definitely not a priority right now. -- CJA 20140607
|
||||
mp_not_implemented("unicode name escapes");
|
||||
mp_raise_NotImplementedError("unicode name escapes");
|
||||
break;
|
||||
default:
|
||||
if (c >= '0' && c <= '7') {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "py/qstr.h"
|
||||
#include "py/reader.h"
|
||||
|
||||
/* lexer.h -- simple tokeniser for Micro Python
|
||||
/* lexer.h -- simple tokeniser for MicroPython
|
||||
*
|
||||
* Uses (byte) length instead of null termination.
|
||||
* Tokens are the same - UTF-8 with (byte) length.
|
||||
|
||||
@@ -108,7 +108,15 @@ def parse_input_headers(infiles):
|
||||
continue
|
||||
|
||||
# add the qstr to the list, with order number to retain original order in file
|
||||
qstrs[ident] = (len(qstrs), ident, qstr)
|
||||
order = len(qstrs)
|
||||
# but put special method names like __add__ at the top of list, so
|
||||
# that their id's fit into a byte
|
||||
if ident == "":
|
||||
# Sort empty qstr above all still
|
||||
order = -200000
|
||||
elif ident.startswith("__"):
|
||||
order -= 100000
|
||||
qstrs[ident] = (order, ident, qstr)
|
||||
|
||||
if not qcfgs:
|
||||
sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "py/misc.h"
|
||||
#include "py/mpstate.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_printf(...) (void)0
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "py/gc.h"
|
||||
|
||||
// We redirect standard alloc functions to GC heap - just for the rest of
|
||||
// this module. In the rest of micropython source, system malloc can be
|
||||
// this module. In the rest of MicroPython source, system malloc can be
|
||||
// freely accessed - for interfacing with system and 3rd-party libs for
|
||||
// example. On the other hand, some (e.g. bare-metal) ports may use GC
|
||||
// heap as system heap, so, to avoid warnings, we do undef's first.
|
||||
@@ -74,7 +74,7 @@ STATIC void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) {
|
||||
void *m_malloc(size_t num_bytes) {
|
||||
void *ptr = malloc(num_bytes);
|
||||
if (ptr == NULL && num_bytes != 0) {
|
||||
return m_malloc_fail(num_bytes);
|
||||
m_malloc_fail(num_bytes);
|
||||
}
|
||||
#if MICROPY_MEM_STATS
|
||||
MP_STATE_MEM(total_bytes_allocated) += num_bytes;
|
||||
@@ -100,7 +100,7 @@ void *m_malloc_maybe(size_t num_bytes) {
|
||||
void *m_malloc_with_finaliser(size_t num_bytes) {
|
||||
void *ptr = malloc_with_finaliser(num_bytes);
|
||||
if (ptr == NULL && num_bytes != 0) {
|
||||
return m_malloc_fail(num_bytes);
|
||||
m_malloc_fail(num_bytes);
|
||||
}
|
||||
#if MICROPY_MEM_STATS
|
||||
MP_STATE_MEM(total_bytes_allocated) += num_bytes;
|
||||
@@ -115,7 +115,7 @@ void *m_malloc_with_finaliser(size_t num_bytes) {
|
||||
void *m_malloc0(size_t num_bytes) {
|
||||
void *ptr = m_malloc(num_bytes);
|
||||
if (ptr == NULL && num_bytes != 0) {
|
||||
return m_malloc_fail(num_bytes);
|
||||
m_malloc_fail(num_bytes);
|
||||
}
|
||||
// If this config is set then the GC clears all memory, so we don't need to.
|
||||
#if !MICROPY_GC_CONSERVATIVE_CLEAR
|
||||
@@ -131,7 +131,7 @@ void *m_realloc(void *ptr, size_t new_num_bytes) {
|
||||
#endif
|
||||
void *new_ptr = realloc(ptr, new_num_bytes);
|
||||
if (new_ptr == NULL && new_num_bytes != 0) {
|
||||
return m_malloc_fail(new_num_bytes);
|
||||
m_malloc_fail(new_num_bytes);
|
||||
}
|
||||
#if MICROPY_MEM_STATS
|
||||
// At first thought, "Total bytes allocated" should only grow,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/misc.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
// Fixed empty map. Useful when need to call kw-receiving functions
|
||||
@@ -93,12 +92,6 @@ void mp_map_init_fixed_table(mp_map_t *map, size_t n, const mp_obj_t *table) {
|
||||
map->table = (mp_map_elem_t*)table;
|
||||
}
|
||||
|
||||
mp_map_t *mp_map_new(size_t n) {
|
||||
mp_map_t *map = m_new(mp_map_t, 1);
|
||||
mp_map_init(map, n);
|
||||
return map;
|
||||
}
|
||||
|
||||
// Differentiate from mp_map_clear() - semantics is different
|
||||
void mp_map_deinit(mp_map_t *map) {
|
||||
if (!map->is_fixed) {
|
||||
@@ -107,11 +100,6 @@ void mp_map_deinit(mp_map_t *map) {
|
||||
map->used = map->alloc = 0;
|
||||
}
|
||||
|
||||
void mp_map_free(mp_map_t *map) {
|
||||
mp_map_deinit(map);
|
||||
m_del_obj(mp_map_t, map);
|
||||
}
|
||||
|
||||
void mp_map_clear(mp_map_t *map) {
|
||||
if (!map->is_fixed) {
|
||||
m_del(mp_map_elem_t, map->table, map->alloc);
|
||||
@@ -148,11 +136,8 @@ STATIC void mp_map_rehash(mp_map_t *map) {
|
||||
// MP_MAP_LOOKUP_REMOVE_IF_FOUND behaviour:
|
||||
// - returns NULL if not found, else the slot if was found in with key null and value non-null
|
||||
mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
|
||||
|
||||
if (map->is_fixed && lookup_kind != MP_MAP_LOOKUP) {
|
||||
// can't add/remove from a fixed array
|
||||
return NULL;
|
||||
}
|
||||
// If the map is a fixed array then we must only be called for a lookup
|
||||
assert(!map->is_fixed || lookup_kind == MP_MAP_LOOKUP);
|
||||
|
||||
// Work out if we can compare just pointers
|
||||
bool compare_only_ptrs = map->all_keys_are_qstrs;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -92,7 +92,7 @@ void *m_realloc(void *ptr, size_t new_num_bytes);
|
||||
void *m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move);
|
||||
void m_free(void *ptr);
|
||||
#endif
|
||||
NORETURN void *m_malloc_fail(size_t num_bytes);
|
||||
NORETURN void m_malloc_fail(size_t num_bytes);
|
||||
|
||||
#if MICROPY_MEM_STATS
|
||||
size_t m_get_total_bytes_allocated(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,12 +27,10 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/objtype.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/stream.h"
|
||||
@@ -91,26 +89,7 @@ STATIC mp_obj_t mp_builtin___build_class__(size_t n_args, const mp_obj_t *args)
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj, 2, mp_builtin___build_class__);
|
||||
|
||||
STATIC mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
if (mp_obj_is_float(o_in)) {
|
||||
mp_float_t value = mp_obj_float_get(o_in);
|
||||
// TODO check for NaN etc
|
||||
if (value < 0) {
|
||||
return mp_obj_new_float(-value);
|
||||
} else {
|
||||
return o_in;
|
||||
}
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
} else if (MP_OBJ_IS_TYPE(o_in, &mp_type_complex)) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_complex_get(o_in, &real, &imag);
|
||||
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(real*real + imag*imag));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// this will raise a TypeError if the argument is not integral
|
||||
return mp_obj_int_abs(o_in);
|
||||
return mp_unary_op(MP_UNARY_OP_ABS, o_in);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_abs_obj, mp_builtin_abs);
|
||||
|
||||
@@ -369,31 +348,16 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
|
||||
if (MP_OBJ_IS_STR(o_in)) {
|
||||
len = unichar_charlen(str, len);
|
||||
if (len == 1) {
|
||||
if (!UTF8_IS_NONASCII(*str)) {
|
||||
goto return_first_byte;
|
||||
}
|
||||
mp_int_t ord = *str++ & 0x7F;
|
||||
for (mp_int_t mask = 0x40; ord & mask; mask >>= 1) {
|
||||
ord &= ~mask;
|
||||
}
|
||||
while (UTF8_IS_CONT(*str)) {
|
||||
ord = (ord << 6) | (*str++ & 0x3F);
|
||||
}
|
||||
return mp_obj_new_int(ord);
|
||||
return mp_obj_new_int(utf8_get_char((const byte*)str));
|
||||
}
|
||||
} else {
|
||||
// a bytes object
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// a bytes object, or a str without unicode support (don't sign extend the char)
|
||||
if (len == 1) {
|
||||
return_first_byte:
|
||||
return MP_OBJ_NEW_SMALL_INT(((const byte*)str)[0]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (len == 1) {
|
||||
// don't sign extend when converting to ord
|
||||
return mp_obj_new_int(((const byte*)str)[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("ord expects a character");
|
||||
@@ -540,7 +504,7 @@ STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
|
||||
|
||||
// See mp_load_attr() if making any changes
|
||||
STATIC inline mp_obj_t mp_load_attr_default(mp_obj_t base, qstr attr, mp_obj_t defval) {
|
||||
static inline mp_obj_t mp_load_attr_default(mp_obj_t base, qstr attr, mp_obj_t defval) {
|
||||
mp_obj_t dest[2];
|
||||
// use load_method, raising or not raising exception
|
||||
((defval == MP_OBJ_NULL) ? mp_load_method : mp_load_method_maybe)(base, attr, dest);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -30,13 +30,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/// \module cmath - mathematical functions for complex numbers
|
||||
///
|
||||
/// The `cmath` module provides some basic mathematical funtions for
|
||||
/// working with complex numbers.
|
||||
|
||||
/// \function phase(z)
|
||||
/// Returns the phase of the number `z`, in the range (-pi, +pi].
|
||||
// phase(z): returns the phase of the number z in the range (-pi, +pi]
|
||||
STATIC mp_obj_t mp_cmath_phase(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
@@ -44,8 +38,7 @@ STATIC mp_obj_t mp_cmath_phase(mp_obj_t z_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_phase_obj, mp_cmath_phase);
|
||||
|
||||
/// \function polar(z)
|
||||
/// Returns, as a tuple, the polar form of `z`.
|
||||
// polar(z): returns the polar form of z as a tuple
|
||||
STATIC mp_obj_t mp_cmath_polar(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
@@ -57,8 +50,7 @@ STATIC mp_obj_t mp_cmath_polar(mp_obj_t z_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_polar_obj, mp_cmath_polar);
|
||||
|
||||
/// \function rect(r, phi)
|
||||
/// Returns the complex number with modulus `r` and phase `phi`.
|
||||
// rect(r, phi): returns the complex number with modulus r and phase phi
|
||||
STATIC mp_obj_t mp_cmath_rect(mp_obj_t r_obj, mp_obj_t phi_obj) {
|
||||
mp_float_t r = mp_obj_get_float(r_obj);
|
||||
mp_float_t phi = mp_obj_get_float(phi_obj);
|
||||
@@ -66,8 +58,7 @@ STATIC mp_obj_t mp_cmath_rect(mp_obj_t r_obj, mp_obj_t phi_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_cmath_rect_obj, mp_cmath_rect);
|
||||
|
||||
/// \function exp(z)
|
||||
/// Return the exponential of `z`.
|
||||
// exp(z): return the exponential of z
|
||||
STATIC mp_obj_t mp_cmath_exp(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
@@ -76,8 +67,7 @@ STATIC mp_obj_t mp_cmath_exp(mp_obj_t z_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_exp_obj, mp_cmath_exp);
|
||||
|
||||
/// \function log(z)
|
||||
/// Return the natural logarithm of `z`. The branch cut is along the negative real axis.
|
||||
// log(z): return the natural logarithm of z, with branch cut along the negative real axis
|
||||
// TODO can take second argument, being the base
|
||||
STATIC mp_obj_t mp_cmath_log(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
@@ -87,8 +77,7 @@ STATIC mp_obj_t mp_cmath_log(mp_obj_t z_obj) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_log_obj, mp_cmath_log);
|
||||
|
||||
#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
|
||||
/// \function log10(z)
|
||||
/// Return the base-10 logarithm of `z`. The branch cut is along the negative real axis.
|
||||
// log10(z): return the base-10 logarithm of z, with branch cut along the negative real axis
|
||||
STATIC mp_obj_t mp_cmath_log10(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
@@ -97,8 +86,7 @@ STATIC mp_obj_t mp_cmath_log10(mp_obj_t z_obj) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_log10_obj, mp_cmath_log10);
|
||||
#endif
|
||||
|
||||
/// \function sqrt(z)
|
||||
/// Return the square-root of `z`.
|
||||
// sqrt(z): return the square-root of z
|
||||
STATIC mp_obj_t mp_cmath_sqrt(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
@@ -108,8 +96,7 @@ STATIC mp_obj_t mp_cmath_sqrt(mp_obj_t z_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_sqrt_obj, mp_cmath_sqrt);
|
||||
|
||||
/// \function cos(z)
|
||||
/// Return the cosine of `z`.
|
||||
// cos(z): return the cosine of z
|
||||
STATIC mp_obj_t mp_cmath_cos(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
@@ -117,8 +104,7 @@ STATIC mp_obj_t mp_cmath_cos(mp_obj_t z_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_cmath_cos_obj, mp_cmath_cos);
|
||||
|
||||
/// \function sin(z)
|
||||
/// Return the sine of `z`.
|
||||
// sin(z): return the sine of z
|
||||
STATIC mp_obj_t mp_cmath_sin(mp_obj_t z_obj) {
|
||||
mp_float_t real, imag;
|
||||
mp_obj_get_complex(z_obj, &real, &imag);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -30,10 +30,7 @@
|
||||
|
||||
#if MICROPY_PY_GC && MICROPY_ENABLE_GC
|
||||
|
||||
/// \module gc - control the garbage collector
|
||||
|
||||
/// \function collect()
|
||||
/// Run a garbage collection.
|
||||
// collect(): run a garbage collection
|
||||
STATIC mp_obj_t py_gc_collect(void) {
|
||||
gc_collect();
|
||||
#if MICROPY_PY_GC_COLLECT_RETVAL
|
||||
@@ -44,16 +41,14 @@ STATIC mp_obj_t py_gc_collect(void) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_collect_obj, py_gc_collect);
|
||||
|
||||
/// \function disable()
|
||||
/// Disable the garbage collector.
|
||||
// disable(): disable the garbage collector
|
||||
STATIC mp_obj_t gc_disable(void) {
|
||||
MP_STATE_MEM(gc_auto_collect_enabled) = 0;
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_disable_obj, gc_disable);
|
||||
|
||||
/// \function enable()
|
||||
/// Enable the garbage collector.
|
||||
// enable(): enable the garbage collector
|
||||
STATIC mp_obj_t gc_enable(void) {
|
||||
MP_STATE_MEM(gc_auto_collect_enabled) = 1;
|
||||
return mp_const_none;
|
||||
@@ -65,8 +60,7 @@ STATIC mp_obj_t gc_isenabled(void) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_isenabled_obj, gc_isenabled);
|
||||
|
||||
/// \function mem_free()
|
||||
/// Return the number of bytes of available heap RAM.
|
||||
// mem_free(): return the number of bytes of available heap RAM
|
||||
STATIC mp_obj_t gc_mem_free(void) {
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
@@ -74,8 +68,7 @@ STATIC mp_obj_t gc_mem_free(void) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(gc_mem_free_obj, gc_mem_free);
|
||||
|
||||
/// \function mem_alloc()
|
||||
/// Return the number of bytes of heap RAM that are allocated.
|
||||
// mem_alloc(): return the number of bytes of heap RAM that are allocated
|
||||
STATIC mp_obj_t gc_mem_alloc(void) {
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -112,9 +112,9 @@ STATIC mp_obj_t bufwriter_flush(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bufwriter_flush_obj, bufwriter_flush);
|
||||
|
||||
STATIC const mp_map_elem_t bufwriter_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flush), (mp_obj_t)&bufwriter_flush_obj },
|
||||
STATIC const mp_rom_map_elem_t bufwriter_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&bufwriter_flush_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(bufwriter_locals_dict, bufwriter_locals_dict_table);
|
||||
|
||||
@@ -127,7 +127,7 @@ STATIC const mp_obj_type_t bufwriter_type = {
|
||||
.name = MP_QSTR_BufferedWriter,
|
||||
.make_new = bufwriter_make_new,
|
||||
.protocol = &bufwriter_stream_p,
|
||||
.locals_dict = (mp_obj_t)&bufwriter_locals_dict,
|
||||
.locals_dict = (mp_obj_dict_t*)&bufwriter_locals_dict,
|
||||
};
|
||||
#endif // MICROPY_PY_IO_BUFFEREDWRITER
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2013-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
|
||||
@@ -35,22 +35,34 @@
|
||||
// And by defining our own we can ensure it uses the correct const format.
|
||||
#define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846)
|
||||
|
||||
/// \module math - mathematical functions
|
||||
///
|
||||
/// The `math` module provides some basic mathematical funtions for
|
||||
/// working with floating-point numbers.
|
||||
|
||||
STATIC NORETURN void math_error(void) {
|
||||
mp_raise_ValueError("math domain error");
|
||||
}
|
||||
|
||||
#define MATH_FUN_1(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
STATIC mp_obj_t math_generic_1(mp_obj_t x_obj, mp_float_t (*f)(mp_float_t)) {
|
||||
mp_float_t x = mp_obj_get_float(x_obj);
|
||||
mp_float_t ans = f(x);
|
||||
if ((isnan(ans) && !isnan(x)) || (isinf(ans) && !isinf(x))) {
|
||||
math_error();
|
||||
}
|
||||
return mp_obj_new_float(ans);
|
||||
}
|
||||
|
||||
#define MATH_FUN_2(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
STATIC mp_obj_t math_generic_2(mp_obj_t x_obj, mp_obj_t y_obj, mp_float_t (*f)(mp_float_t, mp_float_t)) {
|
||||
mp_float_t x = mp_obj_get_float(x_obj);
|
||||
mp_float_t y = mp_obj_get_float(y_obj);
|
||||
mp_float_t ans = f(x, y);
|
||||
if ((isnan(ans) && !isnan(x) && !isnan(y)) || (isinf(ans) && !isinf(x))) {
|
||||
math_error();
|
||||
}
|
||||
return mp_obj_new_float(ans);
|
||||
}
|
||||
|
||||
#define MATH_FUN_1(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { \
|
||||
return math_generic_1(x_obj, MICROPY_FLOAT_C_FUN(c_name)); \
|
||||
} \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
|
||||
#define MATH_FUN_1_TO_BOOL(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_bool(c_name(mp_obj_get_float(x_obj))); } \
|
||||
@@ -60,95 +72,101 @@ STATIC NORETURN void math_error(void) {
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_int_from_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
|
||||
#define MATH_FUN_1_ERRCOND(py_name, c_name, error_condition) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { \
|
||||
mp_float_t x = mp_obj_get_float(x_obj); \
|
||||
if (error_condition) { \
|
||||
math_error(); \
|
||||
} \
|
||||
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(x)); \
|
||||
#define MATH_FUN_2(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { \
|
||||
return math_generic_2(x_obj, y_obj, MICROPY_FLOAT_C_FUN(c_name)); \
|
||||
} \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
|
||||
#define MATH_FUN_2_FLT_INT(py_name, c_name) \
|
||||
STATIC mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { \
|
||||
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_int(y_obj))); \
|
||||
} \
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name);
|
||||
|
||||
#if MP_NEED_LOG2
|
||||
#undef log2
|
||||
#undef log2f
|
||||
// 1.442695040888963407354163704 is 1/_M_LN2
|
||||
#define log2(x) (log(x) * 1.442695040888963407354163704)
|
||||
mp_float_t MICROPY_FLOAT_C_FUN(log2)(mp_float_t x) {
|
||||
return MICROPY_FLOAT_C_FUN(log)(x) * MICROPY_FLOAT_CONST(1.442695040888963407354163704);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \function sqrt(x)
|
||||
/// Returns the square root of `x`.
|
||||
MATH_FUN_1_ERRCOND(sqrt, sqrt, (x < (mp_float_t)0.0))
|
||||
/// \function pow(x, y)
|
||||
/// Returns `x` to the power of `y`.
|
||||
// sqrt(x): returns the square root of x
|
||||
MATH_FUN_1(sqrt, sqrt)
|
||||
// pow(x, y): returns x to the power of y
|
||||
MATH_FUN_2(pow, pow)
|
||||
/// \function exp(x)
|
||||
// exp(x)
|
||||
MATH_FUN_1(exp, exp)
|
||||
#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
|
||||
/// \function expm1(x)
|
||||
// expm1(x)
|
||||
MATH_FUN_1(expm1, expm1)
|
||||
/// \function log2(x)
|
||||
MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0))
|
||||
/// \function log10(x)
|
||||
MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0))
|
||||
/// \function cosh(x)
|
||||
// log2(x)
|
||||
MATH_FUN_1(log2, log2)
|
||||
// log10(x)
|
||||
MATH_FUN_1(log10, log10)
|
||||
// cosh(x)
|
||||
MATH_FUN_1(cosh, cosh)
|
||||
/// \function sinh(x)
|
||||
// sinh(x)
|
||||
MATH_FUN_1(sinh, sinh)
|
||||
/// \function tanh(x)
|
||||
// tanh(x)
|
||||
MATH_FUN_1(tanh, tanh)
|
||||
/// \function acosh(x)
|
||||
// acosh(x)
|
||||
MATH_FUN_1(acosh, acosh)
|
||||
/// \function asinh(x)
|
||||
// asinh(x)
|
||||
MATH_FUN_1(asinh, asinh)
|
||||
/// \function atanh(x)
|
||||
// atanh(x)
|
||||
MATH_FUN_1(atanh, atanh)
|
||||
#endif
|
||||
/// \function cos(x)
|
||||
// cos(x)
|
||||
MATH_FUN_1(cos, cos)
|
||||
/// \function sin(x)
|
||||
// sin(x)
|
||||
MATH_FUN_1(sin, sin)
|
||||
/// \function tan(x)
|
||||
// tan(x)
|
||||
MATH_FUN_1(tan, tan)
|
||||
/// \function acos(x)
|
||||
// acos(x)
|
||||
MATH_FUN_1(acos, acos)
|
||||
/// \function asin(x)
|
||||
// asin(x)
|
||||
MATH_FUN_1(asin, asin)
|
||||
/// \function atan(x)
|
||||
// atan(x)
|
||||
MATH_FUN_1(atan, atan)
|
||||
/// \function atan2(y, x)
|
||||
// atan2(y, x)
|
||||
MATH_FUN_2(atan2, atan2)
|
||||
/// \function ceil(x)
|
||||
// ceil(x)
|
||||
MATH_FUN_1_TO_INT(ceil, ceil)
|
||||
/// \function copysign(x, y)
|
||||
MATH_FUN_2(copysign, copysign)
|
||||
/// \function fabs(x)
|
||||
MATH_FUN_1(fabs, fabs)
|
||||
/// \function floor(x)
|
||||
// copysign(x, y)
|
||||
STATIC mp_float_t MICROPY_FLOAT_C_FUN(copysign_func)(mp_float_t x, mp_float_t y) {
|
||||
return MICROPY_FLOAT_C_FUN(copysign)(x, y);
|
||||
}
|
||||
MATH_FUN_2(copysign, copysign_func)
|
||||
// fabs(x)
|
||||
STATIC mp_float_t MICROPY_FLOAT_C_FUN(fabs_func)(mp_float_t x) {
|
||||
return MICROPY_FLOAT_C_FUN(fabs)(x);
|
||||
}
|
||||
MATH_FUN_1(fabs, fabs_func)
|
||||
// floor(x)
|
||||
MATH_FUN_1_TO_INT(floor, floor) //TODO: delegate to x.__floor__() if x is not a float
|
||||
/// \function fmod(x, y)
|
||||
// fmod(x, y)
|
||||
MATH_FUN_2(fmod, fmod)
|
||||
/// \function isfinite(x)
|
||||
// isfinite(x)
|
||||
MATH_FUN_1_TO_BOOL(isfinite, isfinite)
|
||||
/// \function isinf(x)
|
||||
// isinf(x)
|
||||
MATH_FUN_1_TO_BOOL(isinf, isinf)
|
||||
/// \function isnan(x)
|
||||
// isnan(x)
|
||||
MATH_FUN_1_TO_BOOL(isnan, isnan)
|
||||
/// \function trunc(x)
|
||||
// trunc(x)
|
||||
MATH_FUN_1_TO_INT(trunc, trunc)
|
||||
/// \function ldexp(x, exp)
|
||||
MATH_FUN_2(ldexp, ldexp)
|
||||
// ldexp(x, exp)
|
||||
MATH_FUN_2_FLT_INT(ldexp, ldexp)
|
||||
#if MICROPY_PY_MATH_SPECIAL_FUNCTIONS
|
||||
/// \function erf(x)
|
||||
/// Return the error function of `x`.
|
||||
// erf(x): return the error function of x
|
||||
MATH_FUN_1(erf, erf)
|
||||
/// \function erfc(x)
|
||||
/// Return the complementary error function of `x`.
|
||||
// erfc(x): return the complementary error function of x
|
||||
MATH_FUN_1(erfc, erfc)
|
||||
/// \function gamma(x)
|
||||
/// Return the gamma function of `x`.
|
||||
// gamma(x): return the gamma function of x
|
||||
MATH_FUN_1(gamma, tgamma)
|
||||
/// \function lgamma(x)
|
||||
/// return the natural logarithm of the gamma function of `x`.
|
||||
// lgamma(x): return the natural logarithm of the gamma function of x
|
||||
MATH_FUN_1(lgamma, lgamma)
|
||||
#endif
|
||||
//TODO: factorial, fsum
|
||||
@@ -178,8 +196,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_math_log_obj, 1, 2, mp_math_log);
|
||||
|
||||
// Functions that return a tuple
|
||||
|
||||
/// \function frexp(x)
|
||||
/// Converts a floating-point number to fractional and integral components.
|
||||
// frexp(x): converts a floating-point number to fractional and integral components
|
||||
STATIC mp_obj_t mp_math_frexp(mp_obj_t x_obj) {
|
||||
int int_exponent = 0;
|
||||
mp_float_t significand = MICROPY_FLOAT_C_FUN(frexp)(mp_obj_get_float(x_obj), &int_exponent);
|
||||
@@ -190,7 +207,7 @@ STATIC mp_obj_t mp_math_frexp(mp_obj_t x_obj) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_frexp_obj, mp_math_frexp);
|
||||
|
||||
/// \function modf(x)
|
||||
// modf(x)
|
||||
STATIC mp_obj_t mp_math_modf(mp_obj_t x_obj) {
|
||||
mp_float_t int_part = 0.0;
|
||||
mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(mp_obj_get_float(x_obj), &int_part);
|
||||
@@ -203,13 +220,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_modf_obj, mp_math_modf);
|
||||
|
||||
// Angular conversions
|
||||
|
||||
/// \function radians(x)
|
||||
// radians(x)
|
||||
STATIC mp_obj_t mp_math_radians(mp_obj_t x_obj) {
|
||||
return mp_obj_new_float(mp_obj_get_float(x_obj) * (MP_PI / MICROPY_FLOAT_CONST(180.0)));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_radians_obj, mp_math_radians);
|
||||
|
||||
/// \function degrees(x)
|
||||
// degrees(x)
|
||||
STATIC mp_obj_t mp_math_degrees(mp_obj_t x_obj) {
|
||||
return mp_obj_new_float(mp_obj_get_float(x_obj) * (MICROPY_FLOAT_CONST(180.0) / MP_PI));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -82,26 +82,10 @@ STATIC mp_uint_t get_fmt_num(const char **p) {
|
||||
return val;
|
||||
}
|
||||
|
||||
STATIC uint calcsize_items(const char *fmt) {
|
||||
uint cnt = 0;
|
||||
while (*fmt) {
|
||||
int num = 1;
|
||||
if (unichar_isdigit(*fmt)) {
|
||||
num = get_fmt_num(&fmt);
|
||||
if (*fmt == 's') {
|
||||
num = 1;
|
||||
}
|
||||
}
|
||||
cnt += num;
|
||||
fmt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
|
||||
const char *fmt = mp_obj_str_get_str(fmt_in);
|
||||
STATIC size_t calc_size_items(const char *fmt, size_t *total_sz) {
|
||||
char fmt_type = get_fmt_type(&fmt);
|
||||
mp_uint_t size;
|
||||
size_t total_cnt = 0;
|
||||
size_t size;
|
||||
for (size = 0; *fmt; fmt++) {
|
||||
mp_uint_t cnt = 1;
|
||||
if (unichar_isdigit(*fmt)) {
|
||||
@@ -109,8 +93,10 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
|
||||
}
|
||||
|
||||
if (*fmt == 's') {
|
||||
total_cnt += 1;
|
||||
size += cnt;
|
||||
} else {
|
||||
total_cnt += cnt;
|
||||
mp_uint_t align;
|
||||
size_t sz = mp_binary_get_size(fmt_type, *fmt, &align);
|
||||
while (cnt--) {
|
||||
@@ -120,6 +106,14 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*total_sz = size;
|
||||
return total_cnt;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
|
||||
const char *fmt = mp_obj_str_get_str(fmt_in);
|
||||
size_t size;
|
||||
calc_size_items(fmt, &size);
|
||||
return MP_OBJ_NEW_SMALL_INT(size);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);
|
||||
@@ -130,8 +124,9 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
|
||||
// Since we implement unpack and unpack_from using the same function
|
||||
// we relax the "exact" requirement, and only implement "big enough".
|
||||
const char *fmt = mp_obj_str_get_str(args[0]);
|
||||
size_t total_sz;
|
||||
size_t num_items = calc_size_items(fmt, &total_sz);
|
||||
char fmt_type = get_fmt_type(&fmt);
|
||||
uint num_items = calcsize_items(fmt);
|
||||
mp_obj_tuple_t *res = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_items, NULL));
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
|
||||
@@ -152,21 +147,23 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
|
||||
p += offset;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < num_items;) {
|
||||
mp_uint_t sz = 1;
|
||||
// Check that the input buffer is big enough to unpack all the values
|
||||
if (p + total_sz > end_p) {
|
||||
mp_raise_ValueError("buffer too small");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_items;) {
|
||||
mp_uint_t cnt = 1;
|
||||
if (unichar_isdigit(*fmt)) {
|
||||
sz = get_fmt_num(&fmt);
|
||||
}
|
||||
if (p + sz > end_p) {
|
||||
mp_raise_ValueError("buffer too small");
|
||||
cnt = get_fmt_num(&fmt);
|
||||
}
|
||||
mp_obj_t item;
|
||||
if (*fmt == 's') {
|
||||
item = mp_obj_new_bytes(p, sz);
|
||||
p += sz;
|
||||
item = mp_obj_new_bytes(p, cnt);
|
||||
p += cnt;
|
||||
res->items[i++] = item;
|
||||
} else {
|
||||
while (sz--) {
|
||||
while (cnt--) {
|
||||
item = mp_binary_get_val(fmt_type, *fmt, &p);
|
||||
res->items[i++] = item;
|
||||
}
|
||||
@@ -177,36 +174,35 @@ STATIC mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_from_obj, 2, 3, struct_unpack_from);
|
||||
|
||||
STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, byte* end_p, size_t n_args, const mp_obj_t *args) {
|
||||
// This function assumes there is enough room in p to store all the values
|
||||
STATIC void struct_pack_into_internal(mp_obj_t fmt_in, byte *p, size_t n_args, const mp_obj_t *args) {
|
||||
const char *fmt = mp_obj_str_get_str(fmt_in);
|
||||
char fmt_type = get_fmt_type(&fmt);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < n_args;) {
|
||||
mp_uint_t sz = 1;
|
||||
mp_uint_t cnt = 1;
|
||||
if (*fmt == '\0') {
|
||||
// more arguments given than used by format string; CPython raises struct.error here
|
||||
break;
|
||||
}
|
||||
if (unichar_isdigit(*fmt)) {
|
||||
sz = get_fmt_num(&fmt);
|
||||
}
|
||||
if (p + sz > end_p) {
|
||||
mp_raise_ValueError("buffer too small");
|
||||
cnt = get_fmt_num(&fmt);
|
||||
}
|
||||
|
||||
if (*fmt == 's') {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[i++], &bufinfo, MP_BUFFER_READ);
|
||||
mp_uint_t to_copy = sz;
|
||||
mp_uint_t to_copy = cnt;
|
||||
if (bufinfo.len < to_copy) {
|
||||
to_copy = bufinfo.len;
|
||||
}
|
||||
memcpy(p, bufinfo.buf, to_copy);
|
||||
memset(p + to_copy, 0, sz - to_copy);
|
||||
p += sz;
|
||||
memset(p + to_copy, 0, cnt - to_copy);
|
||||
p += cnt;
|
||||
} else {
|
||||
while (sz--) {
|
||||
// If we run out of args then we just finish; CPython would raise struct.error
|
||||
while (cnt-- && i < n_args) {
|
||||
mp_binary_set_val(fmt_type, *fmt, args[i++], &p);
|
||||
}
|
||||
}
|
||||
@@ -221,8 +217,7 @@ STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
|
||||
vstr_init_len(&vstr, size);
|
||||
byte *p = (byte*)vstr.buf;
|
||||
memset(p, 0, size);
|
||||
byte *end_p = &p[size];
|
||||
struct_pack_into_internal(args[0], p, end_p, n_args - 1, &args[1]);
|
||||
struct_pack_into_internal(args[0], p, n_args - 1, &args[1]);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
|
||||
@@ -242,7 +237,13 @@ STATIC mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) {
|
||||
byte *end_p = &p[bufinfo.len];
|
||||
p += offset;
|
||||
|
||||
struct_pack_into_internal(args[0], p, end_p, n_args - 3, &args[3]);
|
||||
// Check that the output buffer is big enough to hold all the values
|
||||
mp_int_t sz = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0]));
|
||||
if (p + sz > end_p) {
|
||||
mp_raise_ValueError("buffer too small");
|
||||
}
|
||||
|
||||
struct_pack_into_internal(args[0], p, n_args - 3, &args[3]);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX, struct_pack_into);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2014-2017 Paul Sokolovsky
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,22 +25,20 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/objtype.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_SYS
|
||||
|
||||
#include "genhdr/mpversion.h"
|
||||
|
||||
/// \module sys - system specific functions
|
||||
|
||||
// defined per port; type of these is irrelevant, just need pointer
|
||||
extern struct _mp_dummy_t mp_sys_stdin_obj;
|
||||
extern struct _mp_dummy_t mp_sys_stdout_obj;
|
||||
@@ -49,10 +48,10 @@ extern struct _mp_dummy_t mp_sys_stderr_obj;
|
||||
const mp_print_t mp_sys_stdout_print = {&mp_sys_stdout_obj, mp_stream_write_adaptor};
|
||||
#endif
|
||||
|
||||
/// \constant version - Python language version that this implementation conforms to, as a string
|
||||
// version - Python language version that this implementation conforms to, as a string
|
||||
STATIC const MP_DEFINE_STR_OBJ(version_obj, "3.4.0");
|
||||
|
||||
/// \constant version_info - Python language version that this implementation conforms to, as a tuple of ints
|
||||
// version_info - Python language version that this implementation conforms to, as a tuple of ints
|
||||
#define I(n) MP_OBJ_NEW_SMALL_INT(n)
|
||||
// TODO: CPython is now at 5-element array, but save 2 els so far...
|
||||
STATIC const mp_obj_tuple_t mp_sys_version_info_obj = {{&mp_type_tuple}, 3, {I(3), I(4), I(0)}};
|
||||
@@ -87,13 +86,11 @@ STATIC const mp_rom_obj_tuple_t mp_sys_implementation_obj = {
|
||||
#undef I
|
||||
|
||||
#ifdef MICROPY_PY_SYS_PLATFORM
|
||||
/// \constant platform - the platform that Micro Python is running on
|
||||
// platform - the platform that MicroPython is running on
|
||||
STATIC const MP_DEFINE_STR_OBJ(platform_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
#endif
|
||||
|
||||
/// \function exit([retval])
|
||||
/// Raise a `SystemExit` exception. If an argument is given, it is the
|
||||
/// value given to `SystemExit`.
|
||||
// exit([retval]): raise SystemExit, with optional argument given to the exception
|
||||
STATIC mp_obj_t mp_sys_exit(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t exc;
|
||||
if (n_args == 0) {
|
||||
@@ -143,6 +140,11 @@ STATIC mp_obj_t mp_sys_exc_info(void) {
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(mp_sys_exc_info_obj, mp_sys_exc_info);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t mp_sys_getsizeof(mp_obj_t obj) {
|
||||
return mp_unary_op(MP_UNARY_OP_SIZEOF, obj);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(mp_sys_getsizeof_obj, mp_sys_getsizeof);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys) },
|
||||
|
||||
@@ -154,7 +156,6 @@ STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = {
|
||||
#ifdef MICROPY_PY_SYS_PLATFORM
|
||||
{ MP_ROM_QSTR(MP_QSTR_platform), MP_ROM_PTR(&platform_obj) },
|
||||
#endif
|
||||
/// \constant byteorder - the byte order of the system ("little" or "big")
|
||||
#if MP_ENDIANNESS_LITTLE
|
||||
{ MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_QSTR(MP_QSTR_little) },
|
||||
#else
|
||||
@@ -168,19 +169,17 @@ STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = {
|
||||
// to not try to compare sys.maxsize to some literal number (as this
|
||||
// number might not fit in available int size), but instead count number
|
||||
// of "one" bits in sys.maxsize.
|
||||
{ MP_ROM_QSTR(MP_QSTR_maxsize), MP_OBJ_NEW_SMALL_INT(MP_SMALL_INT_MAX) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_maxsize), MP_ROM_INT(MP_SMALL_INT_MAX) },
|
||||
#else
|
||||
{ MP_ROM_QSTR(MP_QSTR_maxsize), MP_ROM_PTR(&mp_maxsize_obj) },
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_SYS_EXIT
|
||||
// documented per-port
|
||||
{ MP_ROM_QSTR(MP_QSTR_exit), MP_ROM_PTR(&mp_sys_exit_obj) },
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_SYS_STDFILES
|
||||
// documented per-port
|
||||
{ MP_ROM_QSTR(MP_QSTR_stdin), MP_ROM_PTR(&mp_sys_stdin_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stdout), MP_ROM_PTR(&mp_sys_stdout_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_stderr), MP_ROM_PTR(&mp_sys_stderr_obj) },
|
||||
@@ -192,6 +191,9 @@ STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = {
|
||||
#if MICROPY_PY_SYS_EXC_INFO
|
||||
{ MP_ROM_QSTR(MP_QSTR_exc_info), MP_ROM_PTR(&mp_sys_exc_info_obj) },
|
||||
#endif
|
||||
#if MICROPY_PY_SYS_GETSIZEOF
|
||||
{ MP_ROM_QSTR(MP_QSTR_getsizeof), MP_ROM_PTR(&mp_sys_getsizeof_obj) },
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Extensions to CPython
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include "py/mpthread.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
@@ -192,10 +192,10 @@ STATIC void *thread_entry(void *args_in) {
|
||||
// swallow exception silently
|
||||
} else {
|
||||
// print exception out
|
||||
mp_printf(&mp_plat_print, "Unhandled exception in thread started by ");
|
||||
mp_obj_print_helper(&mp_plat_print, args->fun, PRINT_REPR);
|
||||
mp_printf(&mp_plat_print, "\n");
|
||||
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(exc));
|
||||
mp_printf(MICROPY_ERROR_PRINTER, "Unhandled exception in thread started by ");
|
||||
mp_obj_print_helper(MICROPY_ERROR_PRINTER, args->fun, PRINT_REPR);
|
||||
mp_printf(MICROPY_ERROR_PRINTER, "\n");
|
||||
mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(exc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -373,11 +373,18 @@
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#endif
|
||||
|
||||
// Whether to enable all debugging outputs (it will be extremely verbose)
|
||||
#ifndef MICROPY_DEBUG_VERBOSE
|
||||
#define MICROPY_DEBUG_VERBOSE (0)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Optimisations */
|
||||
|
||||
// Whether to use computed gotos in the VM, or a switch
|
||||
// Computed gotos are roughly 10% faster, and increase VM code size by a little
|
||||
// Note: enabling this will use the gcc-specific extensions of ranged designated
|
||||
// initialisers and addresses of labels, which are not part of the C99 standard.
|
||||
#ifndef MICROPY_OPT_COMPUTED_GOTO
|
||||
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
||||
#endif
|
||||
@@ -526,6 +533,11 @@ typedef long long mp_longint_impl_t;
|
||||
#define MICROPY_WARNINGS (0)
|
||||
#endif
|
||||
|
||||
// This macro is used when printing runtime warnings and errors
|
||||
#ifndef MICROPY_ERROR_PRINTER
|
||||
#define MICROPY_ERROR_PRINTER (&mp_plat_print)
|
||||
#endif
|
||||
|
||||
// Float and complex implementation
|
||||
#define MICROPY_FLOAT_IMPL_NONE (0)
|
||||
#define MICROPY_FLOAT_IMPL_FLOAT (1)
|
||||
@@ -686,6 +698,11 @@ typedef double mp_float_t;
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (0)
|
||||
#endif
|
||||
|
||||
// Whether to check for valid UTF-8 when converting bytes to str
|
||||
#ifndef MICROPY_PY_BUILTINS_STR_UNICODE_CHECK
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE_CHECK (MICROPY_PY_BUILTINS_STR_UNICODE)
|
||||
#endif
|
||||
|
||||
// Whether str.center() method provided
|
||||
#ifndef MICROPY_PY_BUILTINS_STR_CENTER
|
||||
#define MICROPY_PY_BUILTINS_STR_CENTER (0)
|
||||
@@ -748,12 +765,28 @@ typedef double mp_float_t;
|
||||
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (0)
|
||||
#endif
|
||||
|
||||
// Whether to support complete set of special methods
|
||||
// for user classes, otherwise only the most used
|
||||
// Whether to support complete set of special methods for user
|
||||
// classes, or only the most used ones. "Inplace" methods are
|
||||
// controlled by MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS below.
|
||||
// "Reverse" methods are controlled by
|
||||
// MICROPY_PY_REVERSE_SPECIAL_METHODS below.
|
||||
#ifndef MICROPY_PY_ALL_SPECIAL_METHODS
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
|
||||
#endif
|
||||
|
||||
// Whether to support all inplace arithmetic operarion methods
|
||||
// (__imul__, etc.)
|
||||
#ifndef MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS
|
||||
#define MICROPY_PY_ALL_INPLACE_SPECIAL_METHODS (0)
|
||||
#endif
|
||||
|
||||
// Whether to support reverse arithmetic operarion methods
|
||||
// (__radd__, etc.). Additionally gated by
|
||||
// MICROPY_PY_ALL_SPECIAL_METHODS.
|
||||
#ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS
|
||||
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
|
||||
#endif
|
||||
|
||||
// Whether to support compile function
|
||||
#ifndef MICROPY_PY_BUILTINS_COMPILE
|
||||
#define MICROPY_PY_BUILTINS_COMPILE (0)
|
||||
@@ -944,6 +977,11 @@ typedef double mp_float_t;
|
||||
#define MICROPY_PY_SYS_EXIT (1)
|
||||
#endif
|
||||
|
||||
// Whether to provide "sys.getsizeof" function
|
||||
#ifndef MICROPY_PY_SYS_GETSIZEOF
|
||||
#define MICROPY_PY_SYS_GETSIZEOF (0)
|
||||
#endif
|
||||
|
||||
// Whether to provide sys.{stdin,stdout,stderr} objects
|
||||
#ifndef MICROPY_PY_SYS_STDFILES
|
||||
#define MICROPY_PY_SYS_STDFILES (0)
|
||||
@@ -1044,12 +1082,12 @@ typedef double mp_float_t;
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_URANDOM
|
||||
#define MICROPY_PY_URANDOM (1)
|
||||
#define MICROPY_PY_URANDOM (0)
|
||||
#endif
|
||||
|
||||
// Whether to include: randrange, randint, choice, random, uniform
|
||||
#ifndef MICROPY_PY_URANDOM_EXTRA_FUNCS
|
||||
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
|
||||
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_MACHINE
|
||||
@@ -1071,6 +1109,8 @@ typedef double mp_float_t;
|
||||
|
||||
#ifndef MICROPY_PY_USSL
|
||||
#define MICROPY_PY_USSL (0)
|
||||
// Whether to add finaliser code to ussl objects
|
||||
#define MICROPY_PY_USSL_FINALISER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_WEBSOCKET
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -485,14 +485,17 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
|
||||
case 's':
|
||||
{
|
||||
const char *str = va_arg(args, const char*);
|
||||
if (str) {
|
||||
if (prec < 0) {
|
||||
prec = strlen(str);
|
||||
}
|
||||
chrs += mp_print_strn(print, str, prec, flags, fill, width);
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
// With debugging enabled, catch printing of null string pointers
|
||||
if (prec != 0 && str == NULL) {
|
||||
chrs += mp_print_strn(print, "(null)", 6, flags, fill, width);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (prec < 0) {
|
||||
prec = strlen(str);
|
||||
}
|
||||
chrs += mp_print_strn(print, str, prec, flags, fill, width);
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "py/objlist.h"
|
||||
#include "py/objexcept.h"
|
||||
|
||||
// This file contains structures defining the state of the Micro Python
|
||||
// This file contains structures defining the state of the MicroPython
|
||||
// memory system, runtime and virtual machine. The state is a global
|
||||
// variable, but in the future it is hoped that the state can become local.
|
||||
|
||||
@@ -168,7 +168,7 @@ typedef struct _mp_state_vm_t {
|
||||
// root pointers for extmod
|
||||
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
mp_obj_t term_obj;
|
||||
mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM];
|
||||
mp_obj_t dupterm_arr_obj;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,13 +28,12 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/emitglue.h"
|
||||
#include "py/bc.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_printf DEBUG_printf
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_printf(...) (void)0
|
||||
@@ -42,7 +41,7 @@
|
||||
|
||||
#if MICROPY_EMIT_NATIVE
|
||||
|
||||
// convert a Micro Python object to a valid native value based on type
|
||||
// convert a MicroPython object to a valid native value based on type
|
||||
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
|
||||
DEBUG_printf("mp_convert_obj_to_native(%p, " UINT_FMT ")\n", obj, type);
|
||||
switch (type & 0xf) {
|
||||
@@ -66,7 +65,7 @@ mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
|
||||
|
||||
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM
|
||||
|
||||
// convert a native value to a Micro Python object based on type
|
||||
// convert a native value to a MicroPython object based on type
|
||||
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) {
|
||||
DEBUG_printf("mp_convert_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
|
||||
switch (type & 0xf) {
|
||||
@@ -172,6 +171,8 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
|
||||
mp_obj_new_cell,
|
||||
mp_make_closure_from_raw_code,
|
||||
mp_setup_code_state,
|
||||
mp_small_int_floor_divide,
|
||||
mp_small_int_modulo,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
|
||||
#if (!defined(MICROPY_NLR_SETJMP) || !MICROPY_NLR_SETJMP) && (defined(__thumb2__) || defined(__thumb__) || defined(__arm__))
|
||||
|
||||
@@ -67,7 +66,14 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||
"str lr, [r0, #8] \n" // store lr into nlr_buf
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_6M__)
|
||||
"ldr r1, nlr_push_tail_var \n"
|
||||
"bx r1 \n" // do the rest in C
|
||||
".align 2 \n"
|
||||
"nlr_push_tail_var: .word nlr_push_tail \n"
|
||||
#else
|
||||
"b nlr_push_tail \n" // do the rest in C
|
||||
#endif
|
||||
);
|
||||
|
||||
return 0; // needed to silence compiler warning
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
|
||||
#if !MICROPY_NLR_SETJMP && defined(__x86_64__)
|
||||
|
||||
@@ -34,7 +33,11 @@
|
||||
// x86-64 callee-save registers are:
|
||||
// rbx, rbp, rsp, r12, r13, r14, r15
|
||||
|
||||
#define NLR_OS_WINDOWS (defined(_WIN32) || defined(__CYGWIN__))
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define NLR_OS_WINDOWS 1
|
||||
#else
|
||||
#define NLR_OS_WINDOWS 0
|
||||
#endif
|
||||
|
||||
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
|
||||
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
|
||||
#if !MICROPY_NLR_SETJMP && defined(__i386__)
|
||||
|
||||
@@ -35,7 +33,11 @@
|
||||
// For reference, x86 callee save regs are:
|
||||
// ebx, esi, edi, ebp, esp, eip
|
||||
|
||||
#define NLR_OS_WINDOWS (defined(_WIN32) || defined(__CYGWIN__))
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define NLR_OS_WINDOWS 1
|
||||
#else
|
||||
#define NLR_OS_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if NLR_OS_WINDOWS
|
||||
unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail");
|
||||
@@ -51,7 +53,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||
// by default.
|
||||
// TODE: Better support for various x86 calling conventions
|
||||
// (unfortunately, __attribute__((naked)) is not supported on x86).
|
||||
#ifndef __ZEPHYR__
|
||||
#if !(defined(__ZEPHYR__) || defined(__ANDROID__))
|
||||
"pop %ebp \n" // undo function's prelude
|
||||
#endif
|
||||
"mov 4(%esp), %edx \n" // load nlr_buf
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
|
||||
#if !MICROPY_NLR_SETJMP && defined(__xtensa__)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,12 +29,10 @@
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtype.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/stream.h" // for mp_obj_print
|
||||
@@ -162,7 +160,16 @@ bool mp_obj_is_callable(mp_obj_t o_in) {
|
||||
// comparison returns NotImplemented, == and != are decided by comparing the object
|
||||
// pointer."
|
||||
bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
|
||||
if (o1 == o2) {
|
||||
// Float (and complex) NaN is never equal to anything, not even itself,
|
||||
// so we must have a special check here to cover those cases.
|
||||
if (o1 == o2
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
&& !mp_obj_is_float(o1)
|
||||
#endif
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
&& !MP_OBJ_IS_TYPE(o1, &mp_type_complex)
|
||||
#endif
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (o1 == mp_const_none || o2 == mp_const_none) {
|
||||
@@ -264,20 +271,33 @@ bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value) {
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_float_t mp_obj_get_float(mp_obj_t arg) {
|
||||
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) {
|
||||
mp_float_t val;
|
||||
|
||||
if (arg == mp_const_false) {
|
||||
return 0;
|
||||
val = 0;
|
||||
} else if (arg == mp_const_true) {
|
||||
return 1;
|
||||
val = 1;
|
||||
} else if (MP_OBJ_IS_SMALL_INT(arg)) {
|
||||
return MP_OBJ_SMALL_INT_VALUE(arg);
|
||||
val = MP_OBJ_SMALL_INT_VALUE(arg);
|
||||
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
|
||||
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) {
|
||||
return mp_obj_int_as_float_impl(arg);
|
||||
val = mp_obj_int_as_float_impl(arg);
|
||||
#endif
|
||||
} else if (mp_obj_is_float(arg)) {
|
||||
return mp_obj_float_get(arg);
|
||||
val = mp_obj_float_get(arg);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
mp_float_t mp_obj_get_float(mp_obj_t arg) {
|
||||
mp_float_t val;
|
||||
|
||||
if (!mp_obj_get_float_maybe(arg, &val)) {
|
||||
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
|
||||
mp_raise_TypeError("can't convert to float");
|
||||
} else {
|
||||
@@ -285,6 +305,8 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) {
|
||||
"can't convert %s to float", mp_obj_get_type_str(arg)));
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
@@ -505,7 +527,7 @@ void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flag
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t mp_generic_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT((mp_uint_t)o_in);
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "py/misc.h"
|
||||
#include "py/qstr.h"
|
||||
#include "py/mpprint.h"
|
||||
#include "py/runtime0.h"
|
||||
|
||||
// This is the definition of the opaque MicroPython object type.
|
||||
// All concrete objects have an encoding within this type and the
|
||||
@@ -429,8 +430,8 @@ typedef struct _mp_obj_iter_buf_t {
|
||||
typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind);
|
||||
typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args);
|
||||
typedef mp_obj_t (*mp_unary_op_fun_t)(mp_uint_t op, mp_obj_t);
|
||||
typedef mp_obj_t (*mp_binary_op_fun_t)(mp_uint_t op, mp_obj_t, mp_obj_t);
|
||||
typedef mp_obj_t (*mp_unary_op_fun_t)(mp_unary_op_t op, mp_obj_t);
|
||||
typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t);
|
||||
typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
|
||||
typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
|
||||
typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
|
||||
@@ -615,6 +616,7 @@ extern const mp_obj_type_t mp_type_ZeroDivisionError;
|
||||
#define mp_const_true (MP_OBJ_FROM_PTR(&mp_const_true_obj))
|
||||
#define mp_const_empty_bytes (MP_OBJ_FROM_PTR(&mp_const_empty_bytes_obj))
|
||||
#define mp_const_empty_tuple (MP_OBJ_FROM_PTR(&mp_const_empty_tuple_obj))
|
||||
#define mp_const_notimplemented (MP_OBJ_FROM_PTR(&mp_const_notimplemented_obj))
|
||||
extern const struct _mp_obj_none_t mp_const_none_obj;
|
||||
extern const struct _mp_obj_bool_t mp_const_false_obj;
|
||||
extern const struct _mp_obj_bool_t mp_const_true_obj;
|
||||
@@ -628,7 +630,6 @@ extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj;
|
||||
// General API for objects
|
||||
|
||||
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
|
||||
mp_obj_t mp_obj_new_none(void);
|
||||
static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true : mp_const_false; }
|
||||
mp_obj_t mp_obj_new_cell(mp_obj_t obj);
|
||||
mp_obj_t mp_obj_new_int(mp_int_t value);
|
||||
@@ -684,6 +685,7 @@ mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg);
|
||||
bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value);
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_float_t mp_obj_get_float(mp_obj_t self_in);
|
||||
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value);
|
||||
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
|
||||
#endif
|
||||
//qstr mp_obj_get_qstr(mp_obj_t arg);
|
||||
@@ -694,7 +696,7 @@ mp_obj_t mp_obj_id(mp_obj_t o_in);
|
||||
mp_obj_t mp_obj_len(mp_obj_t o_in);
|
||||
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL
|
||||
mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val);
|
||||
mp_obj_t mp_generic_unary_op(mp_uint_t op, mp_obj_t o_in);
|
||||
mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in);
|
||||
|
||||
// cell
|
||||
mp_obj_t mp_obj_cell_get(mp_obj_t self_in);
|
||||
@@ -734,11 +736,11 @@ mp_int_t mp_float_hash(mp_float_t val);
|
||||
#else
|
||||
static inline mp_int_t mp_float_hash(mp_float_t val) { return (mp_int_t)val; }
|
||||
#endif
|
||||
mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL if op not supported
|
||||
mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL if op not supported
|
||||
|
||||
// complex
|
||||
void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
|
||||
mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in); // can return MP_OBJ_NULL if op not supported
|
||||
mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in); // can return MP_OBJ_NULL if op not supported
|
||||
#else
|
||||
#define mp_obj_is_float(o) (false)
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,8 +29,6 @@
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/objstr.h"
|
||||
@@ -231,7 +229,7 @@ STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args,
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t array_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
STATIC mp_obj_t array_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
mp_obj_array_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->len != 0);
|
||||
@@ -240,7 +238,7 @@ STATIC mp_obj_t array_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t array_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
STATIC mp_obj_t array_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_array_t *lhs = MP_OBJ_TO_PTR(lhs_in);
|
||||
switch (op) {
|
||||
case MP_BINARY_OP_ADD: {
|
||||
@@ -288,7 +286,7 @@ STATIC mp_obj_t array_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in)
|
||||
|
||||
// Otherwise, can only look for a scalar numeric value in an array
|
||||
if (MP_OBJ_IS_INT(rhs_in) || mp_obj_is_float(rhs_in)) {
|
||||
mp_not_implemented("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
|
||||
return mp_const_false;
|
||||
@@ -378,7 +376,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
|
||||
} else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
|
||||
mp_bound_slice_t slice;
|
||||
if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
|
||||
mp_not_implemented("only slices with step=1 (aka None) are supported");
|
||||
mp_raise_NotImplementedError("only slices with step=1 (aka None) are supported");
|
||||
}
|
||||
if (value != MP_OBJ_SENTINEL) {
|
||||
#if MICROPY_PY_ARRAY_SLICE_ASSIGN
|
||||
@@ -409,7 +407,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
|
||||
src_len = bufinfo.len;
|
||||
src_items = bufinfo.buf;
|
||||
} else {
|
||||
mp_not_implemented("array/bytes required on right side");
|
||||
mp_raise_NotImplementedError("array/bytes required on right side");
|
||||
}
|
||||
|
||||
// TODO: check src/dst compat
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
typedef struct _mp_obj_bool_t {
|
||||
@@ -63,7 +61,7 @@ STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, size_
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t bool_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
STATIC mp_obj_t bool_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
if (op == MP_UNARY_OP_LEN) {
|
||||
return MP_OBJ_NULL;
|
||||
}
|
||||
@@ -71,7 +69,7 @@ STATIC mp_obj_t bool_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
return mp_unary_op(op, MP_OBJ_NEW_SMALL_INT(self->value));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t bool_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
STATIC mp_obj_t bool_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_bool_t *self = MP_OBJ_TO_PTR(lhs_in);
|
||||
return mp_binary_op(op, MP_OBJ_NEW_SMALL_INT(self->value), rhs_in);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,10 +28,7 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/parsenum.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
@@ -117,18 +114,20 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, si
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t complex_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
STATIC mp_obj_t complex_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
mp_obj_complex_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->real != 0 || o->imag != 0);
|
||||
case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT(mp_float_hash(o->real) ^ mp_float_hash(o->imag));
|
||||
case MP_UNARY_OP_POSITIVE: return o_in;
|
||||
case MP_UNARY_OP_NEGATIVE: return mp_obj_new_complex(-o->real, -o->imag);
|
||||
case MP_UNARY_OP_ABS:
|
||||
return mp_obj_new_float(MICROPY_FLOAT_C_FUN(sqrt)(o->real*o->real + o->imag*o->imag));
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t complex_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
STATIC mp_obj_t complex_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_complex_t *lhs = MP_OBJ_TO_PTR(lhs_in);
|
||||
return mp_obj_complex_binary_op(op, lhs->real, lhs->imag, rhs_in);
|
||||
}
|
||||
@@ -171,7 +170,7 @@ void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) {
|
||||
*imag = self->imag;
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in) {
|
||||
mp_obj_t mp_obj_complex_binary_op(mp_binary_op_t op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in) {
|
||||
mp_float_t rhs_real, rhs_imag;
|
||||
mp_obj_get_complex(rhs_in, &rhs_real, &rhs_imag); // can be any type, this function will convert to float (if possible)
|
||||
switch (op) {
|
||||
@@ -229,7 +228,6 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t
|
||||
if (abs1 == 0) {
|
||||
if (rhs_imag == 0 && rhs_real >= 0) {
|
||||
lhs_real = (rhs_real == 0);
|
||||
rhs_real = 0;
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,9 +27,6 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/objtype.h"
|
||||
@@ -100,16 +97,22 @@ STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
|
||||
return dict_out;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t dict_unary_op(mp_uint_t op, mp_obj_t self_in) {
|
||||
STATIC mp_obj_t dict_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||
mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(self->map.used != 0);
|
||||
case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(self->map.used);
|
||||
#if MICROPY_PY_SYS_GETSIZEOF
|
||||
case MP_UNARY_OP_SIZEOF: {
|
||||
size_t sz = sizeof(*self) + sizeof(*self->map.table) * self->map.alloc;
|
||||
return MP_OBJ_NEW_SMALL_INT(sz);
|
||||
}
|
||||
#endif
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t dict_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
STATIC mp_obj_t dict_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_dict_t *o = MP_OBJ_TO_PTR(lhs_in);
|
||||
switch (op) {
|
||||
case MP_BINARY_OP_IN: {
|
||||
@@ -476,7 +479,7 @@ STATIC void dict_view_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
|
||||
mp_print_str(print, "])");
|
||||
}
|
||||
|
||||
STATIC mp_obj_t dict_view_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
STATIC mp_obj_t dict_view_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
// only supported for the 'keys' kind until sets and dicts are refactored
|
||||
mp_obj_dict_view_t *o = MP_OBJ_TO_PTR(lhs_in);
|
||||
if (o->kind != MP_DICT_VIEW_KEYS) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/objtuple.h"
|
||||
@@ -38,6 +37,12 @@
|
||||
#include "py/gc.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
// Number of items per traceback entry (file, line, block)
|
||||
#define TRACEBACK_ENTRY_LEN (3)
|
||||
|
||||
// Number of traceback entries to reserve in the emergency exception buffer
|
||||
#define EMG_TRACEBACK_ALLOC (2 * TRACEBACK_ENTRY_LEN)
|
||||
|
||||
// Instance of MemoryError exception - needed by mp_malloc_fail
|
||||
const mp_obj_exception_t mp_const_MemoryError_obj = {{&mp_type_MemoryError}, 0, 0, NULL, (mp_obj_tuple_t*)&mp_const_empty_tuple_obj};
|
||||
|
||||
@@ -127,18 +132,51 @@ STATIC void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_pr
|
||||
|
||||
mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false);
|
||||
mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, 0);
|
||||
if (o == NULL) {
|
||||
// Couldn't allocate heap memory; use local data instead.
|
||||
o = &MP_STATE_VM(mp_emergency_exception_obj);
|
||||
// We can't store any args.
|
||||
o->args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj;
|
||||
} else {
|
||||
o->args = MP_OBJ_TO_PTR(mp_obj_new_tuple(n_args, args));
|
||||
|
||||
// Try to allocate memory for the exception, with fallback to emergency exception object
|
||||
mp_obj_exception_t *o_exc = m_new_obj_maybe(mp_obj_exception_t);
|
||||
if (o_exc == NULL) {
|
||||
o_exc = &MP_STATE_VM(mp_emergency_exception_obj);
|
||||
}
|
||||
o->base.type = type;
|
||||
o->traceback_data = NULL;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
|
||||
// Populate the exception object
|
||||
o_exc->base.type = type;
|
||||
o_exc->traceback_data = NULL;
|
||||
|
||||
mp_obj_tuple_t *o_tuple;
|
||||
if (n_args == 0) {
|
||||
// No args, can use the empty tuple straightaway
|
||||
o_tuple = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj;
|
||||
} else {
|
||||
// Try to allocate memory for the tuple containing the args
|
||||
o_tuple = m_new_obj_var_maybe(mp_obj_tuple_t, mp_obj_t, n_args);
|
||||
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
// If we are called by mp_obj_new_exception_msg_varg then it will have
|
||||
// reserved room (after the traceback data) for a tuple with 1 element.
|
||||
// Otherwise we are free to use the whole buffer after the traceback data.
|
||||
if (o_tuple == NULL && mp_emergency_exception_buf_size >=
|
||||
EMG_TRACEBACK_ALLOC * sizeof(size_t) + sizeof(mp_obj_tuple_t) + n_args * sizeof(mp_obj_t)) {
|
||||
o_tuple = (mp_obj_tuple_t*)
|
||||
((uint8_t*)MP_STATE_VM(mp_emergency_exception_buf) + EMG_TRACEBACK_ALLOC * sizeof(size_t));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (o_tuple == NULL) {
|
||||
// No memory for a tuple, fallback to an empty tuple
|
||||
o_tuple = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj;
|
||||
} else {
|
||||
// Have memory for a tuple so populate it
|
||||
o_tuple->base.type = &mp_type_tuple;
|
||||
o_tuple->len = n_args;
|
||||
memcpy(o_tuple->items, args, n_args * sizeof(mp_obj_t));
|
||||
}
|
||||
}
|
||||
|
||||
// Store the tuple of args in the exception object
|
||||
o_exc->args = o_tuple;
|
||||
|
||||
return MP_OBJ_FROM_PTR(o_exc);
|
||||
}
|
||||
|
||||
// Get exception "value" - that is, first argument, or None
|
||||
@@ -306,87 +344,95 @@ mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg
|
||||
return mp_obj_new_exception_msg_varg(exc_type, msg);
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) {
|
||||
// check that the given type is an exception type
|
||||
assert(exc_type->make_new == mp_obj_exception_make_new);
|
||||
// The following struct and function implement a simple printer that conservatively
|
||||
// allocates memory and truncates the output data if no more memory can be obtained.
|
||||
// It leaves room for a null byte at the end of the buffer.
|
||||
|
||||
// make exception object
|
||||
mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, 0);
|
||||
if (o == NULL) {
|
||||
// Couldn't allocate heap memory; use local data instead.
|
||||
// Unfortunately, we won't be able to format the string...
|
||||
o = &MP_STATE_VM(mp_emergency_exception_obj);
|
||||
o->base.type = exc_type;
|
||||
o->traceback_data = NULL;
|
||||
o->args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj;
|
||||
struct _exc_printer_t {
|
||||
bool allow_realloc;
|
||||
size_t alloc;
|
||||
size_t len;
|
||||
byte *buf;
|
||||
};
|
||||
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
// If the user has provided a buffer, then we try to create a tuple
|
||||
// of length 1, which has a string object and the string data.
|
||||
|
||||
if (mp_emergency_exception_buf_size > (sizeof(mp_obj_tuple_t) + sizeof(mp_obj_str_t) + sizeof(mp_obj_t))) {
|
||||
mp_obj_tuple_t *tuple = (mp_obj_tuple_t *)MP_STATE_VM(mp_emergency_exception_buf);
|
||||
mp_obj_str_t *str = (mp_obj_str_t *)&tuple->items[1];
|
||||
|
||||
tuple->base.type = &mp_type_tuple;
|
||||
tuple->len = 1;
|
||||
tuple->items[0] = MP_OBJ_FROM_PTR(str);
|
||||
|
||||
byte *str_data = (byte *)&str[1];
|
||||
size_t max_len = (byte*)MP_STATE_VM(mp_emergency_exception_buf) + mp_emergency_exception_buf_size
|
||||
- str_data;
|
||||
|
||||
vstr_t vstr;
|
||||
vstr_init_fixed_buf(&vstr, max_len, (char *)str_data);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vstr_vprintf(&vstr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
str->base.type = &mp_type_str;
|
||||
str->hash = qstr_compute_hash(str_data, str->len);
|
||||
str->len = vstr.len;
|
||||
str->data = str_data;
|
||||
|
||||
o->args = tuple;
|
||||
|
||||
size_t offset = &str_data[str->len] - (byte*)MP_STATE_VM(mp_emergency_exception_buf);
|
||||
offset += sizeof(void *) - 1;
|
||||
offset &= ~(sizeof(void *) - 1);
|
||||
|
||||
if ((mp_emergency_exception_buf_size - offset) > (sizeof(o->traceback_data[0]) * 3)) {
|
||||
// We have room to store some traceback.
|
||||
o->traceback_data = (size_t*)((byte *)MP_STATE_VM(mp_emergency_exception_buf) + offset);
|
||||
o->traceback_alloc = ((byte*)MP_STATE_VM(mp_emergency_exception_buf) + mp_emergency_exception_buf_size - (byte *)o->traceback_data) / sizeof(o->traceback_data[0]);
|
||||
o->traceback_len = 0;
|
||||
}
|
||||
}
|
||||
#endif // MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
} else {
|
||||
o->base.type = exc_type;
|
||||
o->traceback_data = NULL;
|
||||
o->args = MP_OBJ_TO_PTR(mp_obj_new_tuple(1, NULL));
|
||||
|
||||
assert(fmt != NULL);
|
||||
{
|
||||
if (strchr(fmt, '%') == NULL) {
|
||||
// no formatting substitutions, avoid allocating vstr.
|
||||
o->args->items[0] = mp_obj_new_str(fmt, strlen(fmt), false);
|
||||
STATIC void exc_add_strn(void *data, const char *str, size_t len) {
|
||||
struct _exc_printer_t *pr = data;
|
||||
if (pr->len + len >= pr->alloc) {
|
||||
// Not enough room for data plus a null byte so try to grow the buffer
|
||||
if (pr->allow_realloc) {
|
||||
size_t new_alloc = pr->alloc + len + 16;
|
||||
byte *new_buf = m_renew_maybe(byte, pr->buf, pr->alloc, new_alloc, true);
|
||||
if (new_buf == NULL) {
|
||||
pr->allow_realloc = false;
|
||||
len = pr->alloc - pr->len - 1;
|
||||
} else {
|
||||
// render exception message and store as .args[0]
|
||||
va_list ap;
|
||||
vstr_t vstr;
|
||||
vstr_init(&vstr, 16);
|
||||
va_start(ap, fmt);
|
||||
vstr_vprintf(&vstr, fmt, ap);
|
||||
va_end(ap);
|
||||
o->args->items[0] = mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
|
||||
pr->alloc = new_alloc;
|
||||
pr->buf = new_buf;
|
||||
}
|
||||
} else {
|
||||
len = pr->alloc - pr->len - 1;
|
||||
}
|
||||
}
|
||||
memcpy(pr->buf + pr->len, str, len);
|
||||
pr->len += len;
|
||||
}
|
||||
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) {
|
||||
assert(fmt != NULL);
|
||||
|
||||
// Check that the given type is an exception type
|
||||
assert(exc_type->make_new == mp_obj_exception_make_new);
|
||||
|
||||
// Try to allocate memory for the message
|
||||
mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t);
|
||||
size_t o_str_alloc = strlen(fmt) + 1;
|
||||
byte *o_str_buf = m_new_maybe(byte, o_str_alloc);
|
||||
|
||||
bool used_emg_buf = false;
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
// If memory allocation failed and there is an emergency buffer then try to use
|
||||
// that buffer to store the string object and its data (at least 16 bytes for
|
||||
// the string data), reserving room at the start for the traceback and 1-tuple.
|
||||
if ((o_str == NULL || o_str_buf == NULL)
|
||||
&& mp_emergency_exception_buf_size >= EMG_TRACEBACK_ALLOC * sizeof(size_t)
|
||||
+ sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t) + sizeof(mp_obj_str_t) + 16) {
|
||||
used_emg_buf = true;
|
||||
o_str = (mp_obj_str_t*)((uint8_t*)MP_STATE_VM(mp_emergency_exception_buf)
|
||||
+ EMG_TRACEBACK_ALLOC * sizeof(size_t) + sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t));
|
||||
o_str_buf = (byte*)&o_str[1];
|
||||
o_str_alloc = (uint8_t*)MP_STATE_VM(mp_emergency_exception_buf)
|
||||
+ mp_emergency_exception_buf_size - o_str_buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (o_str == NULL) {
|
||||
// No memory for the string object so create the exception with no args
|
||||
return mp_obj_exception_make_new(exc_type, 0, 0, NULL);
|
||||
}
|
||||
|
||||
if (o_str_buf == NULL) {
|
||||
// No memory for the string buffer: assume that the fmt string is in ROM
|
||||
// and use that data as the data of the string
|
||||
o_str->len = o_str_alloc - 1; // will be equal to strlen(fmt)
|
||||
o_str->data = (const byte*)fmt;
|
||||
} else {
|
||||
// We have some memory to format the string
|
||||
struct _exc_printer_t exc_pr = {!used_emg_buf, o_str_alloc, 0, o_str_buf};
|
||||
mp_print_t print = {&exc_pr, exc_add_strn};
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
mp_vprintf(&print, fmt, ap);
|
||||
va_end(ap);
|
||||
exc_pr.buf[exc_pr.len] = '\0';
|
||||
o_str->len = exc_pr.len;
|
||||
o_str->data = exc_pr.buf;
|
||||
}
|
||||
|
||||
// Create the string object and call mp_obj_exception_make_new to create the exception
|
||||
o_str->base.type = &mp_type_str;
|
||||
o_str->hash = qstr_compute_hash(o_str->data, o_str->len);
|
||||
mp_obj_t arg = MP_OBJ_FROM_PTR(o_str);
|
||||
return mp_obj_exception_make_new(exc_type, 1, 0, &arg);
|
||||
}
|
||||
|
||||
// return true if the given object is an exception type
|
||||
@@ -443,24 +489,46 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs
|
||||
// if memory allocation fails (eg because gc is locked), just return
|
||||
|
||||
if (self->traceback_data == NULL) {
|
||||
self->traceback_data = m_new_maybe(size_t, 3);
|
||||
self->traceback_data = m_new_maybe(size_t, TRACEBACK_ENTRY_LEN);
|
||||
if (self->traceback_data == NULL) {
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
if (mp_emergency_exception_buf_size >= EMG_TRACEBACK_ALLOC * sizeof(size_t)) {
|
||||
// There is room in the emergency buffer for traceback data
|
||||
size_t *tb = (size_t*)MP_STATE_VM(mp_emergency_exception_buf);
|
||||
self->traceback_data = tb;
|
||||
self->traceback_alloc = EMG_TRACEBACK_ALLOC;
|
||||
} else {
|
||||
// Can't allocate and no room in emergency buffer
|
||||
return;
|
||||
}
|
||||
#else
|
||||
// Can't allocate
|
||||
return;
|
||||
#endif
|
||||
} else {
|
||||
// Allocated the traceback data on the heap
|
||||
self->traceback_alloc = TRACEBACK_ENTRY_LEN;
|
||||
}
|
||||
self->traceback_len = 0;
|
||||
} else if (self->traceback_len + TRACEBACK_ENTRY_LEN > self->traceback_alloc) {
|
||||
#if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
if (self->traceback_data == (size_t*)MP_STATE_VM(mp_emergency_exception_buf)) {
|
||||
// Can't resize the emergency buffer
|
||||
return;
|
||||
}
|
||||
self->traceback_alloc = 3;
|
||||
self->traceback_len = 0;
|
||||
} else if (self->traceback_len + 3 > self->traceback_alloc) {
|
||||
#endif
|
||||
// be conservative with growing traceback data
|
||||
size_t *tb_data = m_renew_maybe(size_t, self->traceback_data, self->traceback_alloc, self->traceback_alloc + 3, true);
|
||||
size_t *tb_data = m_renew_maybe(size_t, self->traceback_data, self->traceback_alloc,
|
||||
self->traceback_alloc + TRACEBACK_ENTRY_LEN, true);
|
||||
if (tb_data == NULL) {
|
||||
return;
|
||||
}
|
||||
self->traceback_data = tb_data;
|
||||
self->traceback_alloc += 3;
|
||||
self->traceback_alloc += TRACEBACK_ENTRY_LEN;
|
||||
}
|
||||
|
||||
size_t *tb_data = &self->traceback_data[self->traceback_len];
|
||||
self->traceback_len += 3;
|
||||
self->traceback_len += TRACEBACK_ENTRY_LEN;
|
||||
tb_data[0] = file;
|
||||
tb_data[1] = line;
|
||||
tb_data[2] = block;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -29,9 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsenum.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
@@ -155,18 +153,26 @@ STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
STATIC mp_obj_t float_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
mp_float_t val = mp_obj_float_get(o_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(val != 0);
|
||||
case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT(mp_float_hash(val));
|
||||
case MP_UNARY_OP_POSITIVE: return o_in;
|
||||
case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val);
|
||||
case MP_UNARY_OP_ABS: {
|
||||
// TODO check for NaN etc
|
||||
if (val < 0) {
|
||||
return mp_obj_new_float(-val);
|
||||
} else {
|
||||
return o_in;
|
||||
}
|
||||
}
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t float_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
STATIC mp_obj_t float_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_float_t lhs_val = mp_obj_float_get(lhs_in);
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) {
|
||||
@@ -239,8 +245,12 @@ STATIC void mp_obj_float_divmod(mp_float_t *x, mp_float_t *y) {
|
||||
*y = mod;
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_in) {
|
||||
mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible)
|
||||
mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t rhs_in) {
|
||||
mp_float_t rhs_val;
|
||||
if (!mp_obj_get_float_maybe(rhs_in, &rhs_val)) {
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case MP_BINARY_OP_ADD:
|
||||
case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;
|
||||
@@ -286,6 +296,13 @@ mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_i
|
||||
if (lhs_val == 0 && rhs_val < 0) {
|
||||
goto zero_division_error;
|
||||
}
|
||||
if (lhs_val < 0 && rhs_val != MICROPY_FLOAT_C_FUN(floor)(rhs_val)) {
|
||||
#if MICROPY_PY_BUILTINS_COMPLEX
|
||||
return mp_obj_complex_binary_op(MP_BINARY_OP_POWER, lhs_val, 0, rhs_in);
|
||||
#else
|
||||
mp_raise_ValueError("complex values not supported");
|
||||
#endif
|
||||
}
|
||||
lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val);
|
||||
break;
|
||||
case MP_BINARY_OP_DIVMOD: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,15 +28,13 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objfun.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/bc.h"
|
||||
#include "py/stackctrl.h"
|
||||
|
||||
#if 0 // print debugging info
|
||||
#if MICROPY_DEBUG_VERBOSE // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_PRINT (0)
|
||||
@@ -480,7 +478,7 @@ typedef mp_uint_t (*inline_asm_fun_2_t)(mp_uint_t, mp_uint_t);
|
||||
typedef mp_uint_t (*inline_asm_fun_3_t)(mp_uint_t, mp_uint_t, mp_uint_t);
|
||||
typedef mp_uint_t (*inline_asm_fun_4_t)(mp_uint_t, mp_uint_t, mp_uint_t, mp_uint_t);
|
||||
|
||||
// convert a Micro Python object to a sensible value for inline asm
|
||||
// convert a MicroPython object to a sensible value for inline asm
|
||||
STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) {
|
||||
// TODO for byte_array, pass pointer to the array
|
||||
if (MP_OBJ_IS_SMALL_INT(obj)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,8 +28,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/bc.h"
|
||||
#include "py/objgenerator.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
// this is a wrapper object that turns something that has a __getitem__ method into an iterator
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,12 +28,10 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsenum.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
|
||||
@@ -314,23 +312,13 @@ int mp_obj_int_sign(mp_obj_t self_in) {
|
||||
}
|
||||
}
|
||||
|
||||
// This must handle int and bool types, and must raise a
|
||||
// TypeError if the argument is not integral
|
||||
mp_obj_t mp_obj_int_abs(mp_obj_t self_in) {
|
||||
mp_int_t val = mp_obj_get_int(self_in);
|
||||
if (val < 0) {
|
||||
val = -val;
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(val);
|
||||
}
|
||||
|
||||
// This is called for operations on SMALL_INT that are not handled by mp_unary_op
|
||||
mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
|
||||
// This is called for operations on SMALL_INT that are not handled by mp_binary_op
|
||||
mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in);
|
||||
}
|
||||
|
||||
@@ -382,7 +370,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
|
||||
|
||||
// This dispatcher function is expected to be independent of the implementation of long int
|
||||
// It handles the extra cases for integer-like arithmetic
|
||||
mp_obj_t mp_obj_int_binary_op_extra_cases(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
if (rhs_in == mp_const_false) {
|
||||
// false acts as 0
|
||||
return mp_binary_op(op, lhs_in, MP_OBJ_NEW_SMALL_INT(0));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -57,10 +57,9 @@ mp_int_t mp_obj_int_hash(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf);
|
||||
void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf);
|
||||
int mp_obj_int_sign(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_int_abs(mp_obj_t self_in);
|
||||
mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in);
|
||||
mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in);
|
||||
mp_obj_t mp_obj_int_binary_op_extra_cases(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in);
|
||||
mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in);
|
||||
mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in);
|
||||
mp_obj_t mp_obj_int_binary_op_extra_cases(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in);
|
||||
mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus);
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_OBJINT_H
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,10 +28,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
@@ -94,31 +92,7 @@ int mp_obj_int_sign(mp_obj_t self_in) {
|
||||
}
|
||||
}
|
||||
|
||||
// This must handle int and bool types, and must raise a
|
||||
// TypeError if the argument is not integral
|
||||
mp_obj_t mp_obj_int_abs(mp_obj_t self_in) {
|
||||
if (MP_OBJ_IS_TYPE(self_in, &mp_type_int)) {
|
||||
mp_obj_int_t *self = self_in;
|
||||
self = mp_obj_new_int_from_ll(self->val);
|
||||
if (self->val < 0) {
|
||||
// TODO could overflow long long
|
||||
self->val = -self->val;
|
||||
}
|
||||
return self;
|
||||
} else {
|
||||
mp_int_t val = mp_obj_get_int(self_in);
|
||||
if (val == MP_SMALL_INT_MIN) {
|
||||
return mp_obj_new_int_from_ll(-val);
|
||||
} else {
|
||||
if (val < 0) {
|
||||
val = -val;
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
mp_obj_int_t *o = o_in;
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->val != 0);
|
||||
@@ -130,11 +104,21 @@ mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
case MP_UNARY_OP_POSITIVE: return o_in;
|
||||
case MP_UNARY_OP_NEGATIVE: return mp_obj_new_int_from_ll(-o->val);
|
||||
case MP_UNARY_OP_INVERT: return mp_obj_new_int_from_ll(~o->val);
|
||||
case MP_UNARY_OP_ABS: {
|
||||
mp_obj_int_t *self = MP_OBJ_TO_PTR(o_in);
|
||||
if (self->val >= 0) {
|
||||
return o_in;
|
||||
}
|
||||
self = mp_obj_new_int_from_ll(self->val);
|
||||
// TODO could overflow long long
|
||||
self->val = -self->val;
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
long long lhs_val;
|
||||
long long rhs_val;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -28,11 +28,9 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsenumbase.h"
|
||||
#include "py/smallint.h"
|
||||
#include "py/objint.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
@@ -141,28 +139,7 @@ int mp_obj_int_sign(mp_obj_t self_in) {
|
||||
}
|
||||
}
|
||||
|
||||
// This must handle int and bool types, and must raise a
|
||||
// TypeError if the argument is not integral
|
||||
mp_obj_t mp_obj_int_abs(mp_obj_t self_in) {
|
||||
if (MP_OBJ_IS_TYPE(self_in, &mp_type_int)) {
|
||||
mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_int_t *self2 = mp_obj_int_new_mpz();
|
||||
mpz_abs_inpl(&self2->mpz, &self->mpz);
|
||||
return MP_OBJ_FROM_PTR(self2);
|
||||
} else {
|
||||
mp_int_t val = mp_obj_get_int(self_in);
|
||||
if (val == MP_SMALL_INT_MIN) {
|
||||
return mp_obj_new_int_from_ll(-val);
|
||||
} else {
|
||||
if (val < 0) {
|
||||
val = -val;
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
|
||||
mp_obj_int_t *o = MP_OBJ_TO_PTR(o_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(!mpz_is_zero(&o->mpz));
|
||||
@@ -170,11 +147,20 @@ mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in) {
|
||||
case MP_UNARY_OP_POSITIVE: return o_in;
|
||||
case MP_UNARY_OP_NEGATIVE: { mp_obj_int_t *o2 = mp_obj_int_new_mpz(); mpz_neg_inpl(&o2->mpz, &o->mpz); return MP_OBJ_FROM_PTR(o2); }
|
||||
case MP_UNARY_OP_INVERT: { mp_obj_int_t *o2 = mp_obj_int_new_mpz(); mpz_not_inpl(&o2->mpz, &o->mpz); return MP_OBJ_FROM_PTR(o2); }
|
||||
case MP_UNARY_OP_ABS: {
|
||||
mp_obj_int_t *self = MP_OBJ_TO_PTR(o_in);
|
||||
if (self->mpz.neg == 0) {
|
||||
return o_in;
|
||||
}
|
||||
mp_obj_int_t *self2 = mp_obj_int_new_mpz();
|
||||
mpz_abs_inpl(&self2->mpz, &self->mpz);
|
||||
return MP_OBJ_FROM_PTR(self2);
|
||||
}
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
const mpz_t *zlhs;
|
||||
const mpz_t *zrhs;
|
||||
mpz_t z_int;
|
||||
@@ -221,7 +207,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||
return mp_obj_new_float(flhs / frhs);
|
||||
#endif
|
||||
|
||||
} else if (op <= MP_BINARY_OP_INPLACE_POWER) {
|
||||
} else if (op >= MP_BINARY_OP_INPLACE_OR) {
|
||||
mp_obj_int_t *res = mp_obj_int_new_mpz();
|
||||
|
||||
switch (op) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,9 +27,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime0.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
|
||||
@@ -87,28 +85,22 @@ STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_
|
||||
}
|
||||
}
|
||||
|
||||
// Don't pass MP_BINARY_OP_NOT_EQUAL here
|
||||
STATIC bool list_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t another_in) {
|
||||
mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_list));
|
||||
if (!MP_OBJ_IS_TYPE(another_in, &mp_type_list)) {
|
||||
return false;
|
||||
}
|
||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_list_t *another = MP_OBJ_TO_PTR(another_in);
|
||||
|
||||
return mp_seq_cmp_objs(op, self->items, self->len, another->items, another->len);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t list_unary_op(mp_uint_t op, mp_obj_t self_in) {
|
||||
STATIC mp_obj_t list_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(self->len != 0);
|
||||
case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(self->len);
|
||||
#if MICROPY_PY_SYS_GETSIZEOF
|
||||
case MP_UNARY_OP_SIZEOF: {
|
||||
size_t sz = sizeof(*self) + sizeof(mp_obj_t) * self->alloc;
|
||||
return MP_OBJ_NEW_SMALL_INT(sz);
|
||||
}
|
||||
#endif
|
||||
default: return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t list_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
mp_obj_list_t *o = MP_OBJ_TO_PTR(lhs);
|
||||
switch (op) {
|
||||
case MP_BINARY_OP_ADD: {
|
||||
@@ -140,8 +132,18 @@ STATIC mp_obj_t list_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
case MP_BINARY_OP_LESS:
|
||||
case MP_BINARY_OP_LESS_EQUAL:
|
||||
case MP_BINARY_OP_MORE:
|
||||
case MP_BINARY_OP_MORE_EQUAL:
|
||||
return mp_obj_new_bool(list_cmp_helper(op, lhs, rhs));
|
||||
case MP_BINARY_OP_MORE_EQUAL: {
|
||||
if (!MP_OBJ_IS_TYPE(rhs, &mp_type_list)) {
|
||||
if (op == MP_BINARY_OP_EQUAL) {
|
||||
return mp_const_false;
|
||||
}
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
|
||||
mp_obj_list_t *another = MP_OBJ_TO_PTR(rhs);
|
||||
bool res = mp_seq_cmp_objs(op, o->items, o->len, another->items, another->len);
|
||||
return mp_obj_new_bool(res);
|
||||
}
|
||||
|
||||
default:
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
@@ -156,7 +158,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_bound_slice_t slice;
|
||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
|
||||
mp_not_implemented("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
|
||||
mp_int_t len_adj = slice.start - slice.stop;
|
||||
@@ -196,7 +198,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
||||
mp_obj_get_array(value, &value_len, &value_items);
|
||||
mp_bound_slice_t slice_out;
|
||||
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) {
|
||||
mp_not_implemented("");
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start);
|
||||
//printf("Len adj: %d\n", len_adj);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,8 +27,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/objmodule.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objstr.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -26,9 +26,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime0.h"
|
||||
|
||||
typedef struct _mp_obj_none_t {
|
||||
mp_obj_base_t base;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user