diff options
-rw-r--r-- | py/builtin.c | 8 | ||||
-rw-r--r-- | py/mpconfig.h | 11 | ||||
-rw-r--r-- | py/obj.h | 1 | ||||
-rw-r--r-- | py/objfun.c | 40 | ||||
-rw-r--r-- | py/objgenerator.c | 3 | ||||
-rw-r--r-- | tests/basics/builtin-minmax.py | 15 | ||||
-rw-r--r-- | tests/float/builtin-float-minmax.py | 26 | ||||
-rw-r--r-- | unix/mpconfigport.h | 3 |
8 files changed, 100 insertions, 7 deletions
diff --git a/py/builtin.c b/py/builtin.c index 250a3558e8..b586792020 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -245,7 +245,7 @@ STATIC mp_obj_t mp_builtin_max(uint n_args, const mp_obj_t *args) { mp_obj_t max_obj = NULL; mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (max_obj == NULL || mp_binary_op(MP_BINARY_OP_LESS, max_obj, item)) { + if (max_obj == NULL || (mp_binary_op(MP_BINARY_OP_LESS, max_obj, item) == mp_const_true)) { max_obj = item; } } @@ -257,7 +257,7 @@ STATIC mp_obj_t mp_builtin_max(uint n_args, const mp_obj_t *args) { // given many args mp_obj_t max_obj = args[0]; for (int i = 1; i < n_args; i++) { - if (mp_binary_op(MP_BINARY_OP_LESS, max_obj, args[i])) { + if (mp_binary_op(MP_BINARY_OP_LESS, max_obj, args[i]) == mp_const_true) { max_obj = args[i]; } } @@ -274,7 +274,7 @@ STATIC mp_obj_t mp_builtin_min(uint n_args, const mp_obj_t *args) { mp_obj_t min_obj = NULL; mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (min_obj == NULL || mp_binary_op(MP_BINARY_OP_LESS, item, min_obj)) { + if (min_obj == NULL || (mp_binary_op(MP_BINARY_OP_LESS, item, min_obj) == mp_const_true)) { min_obj = item; } } @@ -286,7 +286,7 @@ STATIC mp_obj_t mp_builtin_min(uint n_args, const mp_obj_t *args) { // given many args mp_obj_t min_obj = args[0]; for (int i = 1; i < n_args; i++) { - if (mp_binary_op(MP_BINARY_OP_LESS, args[i], min_obj)) { + if (mp_binary_op(MP_BINARY_OP_LESS, args[i], min_obj) == mp_const_true) { min_obj = args[i]; } } diff --git a/py/mpconfig.h b/py/mpconfig.h index 04d4a7ddc9..8a2e96cc4a 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -94,6 +94,17 @@ typedef long long mp_longint_impl_t; #define MICROPY_ENABLE_DOC_STRING (0) #endif +// Exception messages are short static strings (TODO) +#define MICROPY_ERROR_REPORTING_TERSE (1) +// Exception messages provide basic error details +#define MICROPY_ERROR_REPORTING_NORMAL (2) +// Exception messages provide full info, e.g. object names +#define MICROPY_ERROR_REPORTING_DETAILED (3) + +#ifndef MICROPY_ERROR_REPORTING +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL) +#endif + // Float and complex implementation #define MICROPY_FLOAT_IMPL_NONE (0) #define MICROPY_FLOAT_IMPL_FLOAT (1) @@ -508,6 +508,7 @@ typedef struct _mp_obj_fun_native_t { // need this so we can define const object bool mp_obj_fun_prepare_simple_args(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args, uint *out_args1_len, const mp_obj_t **out_args1, uint *out_args2_len, const mp_obj_t **out_args2); +const char *mp_obj_code_get_name(const byte *code_info); mp_obj_t mp_identity(mp_obj_t self); MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj); diff --git a/py/objfun.c b/py/objfun.c index d828b6d084..7a1c3ff15a 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -126,6 +126,23 @@ mp_obj_t mp_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var /******************************************************************************/ /* byte code functions */ +const char *mp_obj_code_get_name(const byte *code_info) { + qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); + return qstr_str(block_name); +} + +const char *mp_obj_fun_get_name(mp_obj_fun_bc_t *o) { + const byte *code_info = o->bytecode; + return mp_obj_code_get_name(code_info); +} + +#if MICROPY_CPYTHON_COMPAT +STATIC void fun_bc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { + mp_obj_fun_bc_t *o = o_in; + print(env, "<function %s at 0x%x>", mp_obj_fun_get_name(o), o); +} +#endif + #if DEBUG_PRINT STATIC void dump_args(const mp_obj_t *a, int sz) { DEBUG_printf("%p: ", a); @@ -139,8 +156,18 @@ STATIC void dump_args(const mp_obj_t *a, int sz) { #endif STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, uint expected, uint given) { +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + // Generic message, to be reused for other argument issues + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, + "argument num/types mismatch")); +#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", expected, given)); +#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "%s() takes %d positional arguments but %d were given", + mp_obj_fun_get_name(f), expected, given)); +#endif } // If it's possible to call a function without allocating new argument array, @@ -155,6 +182,8 @@ STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, uint expected, ui bool mp_obj_fun_prepare_simple_args(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args, uint *out_args1_len, const mp_obj_t **out_args1, uint *out_args2_len, const mp_obj_t **out_args2) { mp_obj_fun_bc_t *self = self_in; + DEBUG_printf("mp_obj_fun_prepare_simple_args: given: %d pos, %d kw, expected: %d pos (%d default)\n", + n_args, n_kw, self->n_pos_args, self->n_def_args); assert(n_kw == 0); assert(self->n_kwonly_args == 0); @@ -167,8 +196,12 @@ bool mp_obj_fun_prepare_simple_args(mp_obj_t self_in, uint n_args, uint n_kw, co if (n_args > self->n_pos_args) { goto arg_error; } else { - extra_args -= self->n_pos_args - n_args; - n_extra_args += self->n_pos_args - n_args; + if (n_args >= self->n_pos_args - self->n_def_args) { + extra_args -= self->n_pos_args - n_args; + n_extra_args += self->n_pos_args - n_args; + } else { + fun_pos_args_mismatch(self, self->n_pos_args - self->n_def_args, n_args); + } } *out_args1 = args; *out_args1_len = n_args; @@ -335,6 +368,9 @@ continue2:; const mp_obj_type_t mp_type_fun_bc = { { &mp_type_type }, .name = MP_QSTR_function, +#if MICROPY_CPYTHON_COMPAT + .print = fun_bc_print, +#endif .call = fun_bc_call, .binary_op = fun_binary_op, }; diff --git a/py/objgenerator.c b/py/objgenerator.c index 895c03cc23..d02f838afe 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -68,7 +68,8 @@ typedef struct _mp_obj_gen_instance_t { } mp_obj_gen_instance_t; void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - print(env, "<generator object 'fun-name' at %p>", self_in); + mp_obj_gen_instance_t *self = self_in; + print(env, "<generator object '%s' at %p>", mp_obj_code_get_name(self->code_info), self_in); } mp_obj_t gen_instance_getiter(mp_obj_t self_in) { diff --git a/tests/basics/builtin-minmax.py b/tests/basics/builtin-minmax.py new file mode 100644 index 0000000000..8ee4bbca7d --- /dev/null +++ b/tests/basics/builtin-minmax.py @@ -0,0 +1,15 @@ +# test builtin min and max functions + +print(min(0,1)) +print(min(1,0)) +print(min(0,-1)) +print(min(-1,0)) + +print(max(0,1)) +print(max(1,0)) +print(max(0,-1)) +print(max(-1,0)) + +print(min([1,2,4,0,-1,2])) +print(max([1,2,4,0,-1,2])) + diff --git a/tests/float/builtin-float-minmax.py b/tests/float/builtin-float-minmax.py new file mode 100644 index 0000000000..ce45a768a5 --- /dev/null +++ b/tests/float/builtin-float-minmax.py @@ -0,0 +1,26 @@ +# test builtin min and max functions with float args + +print(min(0,1.0)) +print(min(1.0,0)) +print(min(0,-1.0)) +print(min(-1.0,0)) + +print(max(0,1.0)) +print(max(1.0,0)) +print(max(0,-1.0)) +print(max(-1.0,0)) + +print(min(1.5,-1.5)) +print(min(-1.5,1.5)) + +print(max(1.5,-1.5)) +print(max(-1.5,1.5)) + +print(min([1,2.9,4,0,-1,2])) +print(max([1,2.9,4,0,-1,2])) + +print(min([1,2.9,4,6.5,-1,2])) +print(max([1,2.9,4,6.5,-1,2])) +print(min([1,2.9,4,-6.5,-1,2])) +print(max([1,2.9,4,-6.5,-1,2])) + diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index 2d252427f0..b777cfbe31 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -16,6 +16,9 @@ #define MICROPY_USE_COMPUTED_GOTO (1) #define MICROPY_MOD_SYS_STDFILES (1) #define MICROPY_ENABLE_MOD_CMATH (1) +// Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc. +// names in exception messages (may require more RAM). +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_DETAILED) extern const struct _mp_obj_module_t mp_module_time; extern const struct _mp_obj_module_t mp_module_socket; |