py: Implement 'not' in compiler, and improve rt_is_true.
This commit is contained in:
parent
b40892d266
commit
e4b6a079b3
14
py/compile.c
14
py/compile.c
|
@ -1912,7 +1912,21 @@ void compile_and_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||||
|
|
||||||
void compile_not_test_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
void compile_not_test_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||||
compile_node(comp, pns->nodes[0]);
|
compile_node(comp, pns->nodes[0]);
|
||||||
|
#if MICROPY_EMIT_CPYTHON
|
||||||
EMIT_ARG(unary_op, RT_UNARY_OP_NOT);
|
EMIT_ARG(unary_op, RT_UNARY_OP_NOT);
|
||||||
|
#else
|
||||||
|
// eliminate use of NOT byte code
|
||||||
|
int l_load_false = comp_next_label(comp);
|
||||||
|
int l_done = comp_next_label(comp);
|
||||||
|
int stack_size = EMIT(get_stack_size);
|
||||||
|
EMIT_ARG(pop_jump_if_true, l_load_false);
|
||||||
|
EMIT_ARG(load_const_tok, MP_TOKEN_KW_TRUE);
|
||||||
|
EMIT_ARG(jump, l_done);
|
||||||
|
EMIT_ARG(label_assign, l_load_false);
|
||||||
|
EMIT_ARG(load_const_tok, MP_TOKEN_KW_FALSE);
|
||||||
|
EMIT_ARG(label_assign, l_done);
|
||||||
|
EMIT_ARG(set_stack_size, stack_size); // force stack size since it counts 1 pop and 2 pushes statically, but really it's 1 pop and 1 push dynamically
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
||||||
|
|
27
py/runtime.c
27
py/runtime.c
|
@ -315,23 +315,18 @@ int rt_is_true(mp_obj_t arg) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (arg == mp_const_true) {
|
} else if (arg == mp_const_true) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (MP_OBJ_IS_STR(arg)) {
|
|
||||||
return mp_obj_str_get_len(arg) != 0;
|
|
||||||
} else if (MP_OBJ_IS_TYPE(arg, &list_type)) {
|
|
||||||
uint len;
|
|
||||||
mp_obj_t *dummy;
|
|
||||||
mp_obj_list_get(arg, &len, &dummy);
|
|
||||||
return len != 0;
|
|
||||||
} else if (MP_OBJ_IS_TYPE(arg, &tuple_type)) {
|
|
||||||
uint len;
|
|
||||||
mp_obj_t *dummy;
|
|
||||||
mp_obj_tuple_get(arg, &len, &dummy);
|
|
||||||
return len != 0;
|
|
||||||
} else if (MP_OBJ_IS_TYPE(arg, &dict_type)) {
|
|
||||||
return mp_obj_dict_len(arg) != 0;
|
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
mp_obj_t len = mp_obj_len_maybe(arg);
|
||||||
return 0;
|
if (len != MP_OBJ_NULL) {
|
||||||
|
// obj has a length, truth determined if len != 0
|
||||||
|
return len != MP_OBJ_NEW_SMALL_INT(0);
|
||||||
|
} else {
|
||||||
|
// TODO check for __bool__ method
|
||||||
|
// TODO check floats and complex numbers
|
||||||
|
|
||||||
|
// any other obj is true (TODO is that correct?)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RT_UNARY_OP_NOT,
|
RT_UNARY_OP_NOT, // TODO remove this op since it's no longer needed
|
||||||
RT_UNARY_OP_POSITIVE,
|
RT_UNARY_OP_POSITIVE,
|
||||||
RT_UNARY_OP_NEGATIVE,
|
RT_UNARY_OP_NEGATIVE,
|
||||||
RT_UNARY_OP_INVERT,
|
RT_UNARY_OP_INVERT,
|
||||||
|
|
Loading…
Reference in New Issue