diff --git a/py/objdict.c b/py/objdict.c index 55a612913..93ff1af90 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -43,6 +43,14 @@ static mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp return rt_build_map(0); } +static mp_obj_t dict_unary_op(int op, mp_obj_t self_in) { + mp_obj_dict_t *self = self_in; + switch (op) { + case RT_UNARY_OP_NOT: if (self->map.used == 0) { return mp_const_true; } else { return mp_const_false; } + default: return MP_OBJ_NULL; // op not supported for None + } +} + static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_dict_t *o = lhs_in; switch (op) { @@ -436,6 +444,7 @@ const mp_obj_type_t dict_type = { "dict", .print = dict_print, .make_new = dict_make_new, + .unary_op = dict_unary_op, .binary_op = dict_binary_op, .getiter = dict_getiter, .methods = dict_type_methods, diff --git a/py/objlist.c b/py/objlist.c index 2e9a8705f..1e8930eee 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -119,6 +119,14 @@ static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) { return true; } +static mp_obj_t list_unary_op(int op, mp_obj_t self_in) { + mp_obj_list_t *self = self_in; + switch (op) { + case RT_UNARY_OP_NOT: if (self->len == 0) { return mp_const_true; } else { return mp_const_false; } + default: return MP_OBJ_NULL; // op not supported for None + } +} + static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_list_t *o = lhs; switch (op) { @@ -395,6 +403,7 @@ const mp_obj_type_t list_type = { "list", .print = list_print, .make_new = list_make_new, + .unary_op = list_unary_op, .binary_op = list_binary_op, .getiter = list_getiter, .methods = list_type_methods, diff --git a/py/objnone.c b/py/objnone.c index ecc7c4b4e..4151403b2 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -6,19 +6,28 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" +#include "runtime0.h" typedef struct _mp_obj_none_t { mp_obj_base_t base; } mp_obj_none_t; -void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { +static void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { print(env, "None"); } +static mp_obj_t none_unary_op(int op, mp_obj_t o_in) { + switch (op) { + case RT_UNARY_OP_NOT: return mp_const_true; + default: return MP_OBJ_NULL; // op not supported for None + } +} + const mp_obj_type_t none_type = { { &mp_const_type }, "NoneType", .print = none_print, + .unary_op = none_unary_op, }; static const mp_obj_none_t none_obj = {{&none_type}}; diff --git a/py/objtuple.c b/py/objtuple.c index ec35ef855..754fe4b66 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -73,6 +73,14 @@ static mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m } } +static mp_obj_t tuple_unary_op(int op, mp_obj_t self_in) { + mp_obj_tuple_t *self = self_in; + switch (op) { + case RT_UNARY_OP_NOT: if (self->len == 0) { return mp_const_true; } else { return mp_const_false; } + default: return MP_OBJ_NULL; // op not supported for None + } +} + static mp_obj_t tuple_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_tuple_t *o = lhs; switch (op) { @@ -97,6 +105,7 @@ const mp_obj_type_t tuple_type = { "tuple", .print = tuple_print, .make_new = tuple_make_new, + .unary_op = tuple_unary_op, .binary_op = tuple_binary_op, .getiter = tuple_getiter, }; diff --git a/py/runtime.c b/py/runtime.c index 8ad98d5f1..ba80480ae 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -481,7 +481,7 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) { if (MP_OBJ_IS_SMALL_INT(arg)) { mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(arg); switch (op) { - case RT_UNARY_OP_NOT: if (val != 0) { return mp_const_true;} else { return mp_const_false; } + case RT_UNARY_OP_NOT: if (val == 0) { return mp_const_true;} else { return mp_const_false; } case RT_UNARY_OP_POSITIVE: break; case RT_UNARY_OP_NEGATIVE: val = -val; break; case RT_UNARY_OP_INVERT: val = ~val; break; diff --git a/tests/basics/unary_op.py b/tests/basics/unary_op.py new file mode 100644 index 000000000..9846285d5 --- /dev/null +++ b/tests/basics/unary_op.py @@ -0,0 +1,12 @@ +print(not None) +print(not False) +print(not True) +print(not 0) +print(not 1) +print(not -1) +print(not ()) +print(not (1,)) +print(not []) +print(not [1,]) +print(not {}) +print(not {1:1})