diff options
author | Damien George <damien.p.george@gmail.com> | 2014-01-28 23:27:35 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-01-28 23:27:35 +0000 |
commit | e4b6a079b3422e83a5fb082ba0e166ed1b48ecdf (patch) | |
tree | 534926f93ce82967398a08ab24ec269a5f87e659 | |
parent | b40892d266c05613f3e32f12ca3a7c4b03270fb7 (diff) | |
download | micropython-e4b6a079b3422e83a5fb082ba0e166ed1b48ecdf.tar.gz micropython-e4b6a079b3422e83a5fb082ba0e166ed1b48ecdf.zip |
py: Implement 'not' in compiler, and improve rt_is_true.
-rw-r--r-- | py/compile.c | 14 | ||||
-rw-r--r-- | py/runtime.c | 27 | ||||
-rw-r--r-- | py/runtime0.h | 2 |
3 files changed, 26 insertions, 17 deletions
diff --git a/py/compile.c b/py/compile.c index e1b62a11bf..ebd2abb5c4 100644 --- a/py/compile.c +++ b/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) { compile_node(comp, pns->nodes[0]); +#if MICROPY_EMIT_CPYTHON 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) { diff --git a/py/runtime.c b/py/runtime.c index 27c0da3b89..39f297fce0 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -315,23 +315,18 @@ int rt_is_true(mp_obj_t arg) { return 0; } else if (arg == mp_const_true) { 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 { - assert(0); - return 0; + mp_obj_t len = mp_obj_len_maybe(arg); + 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; + } } } diff --git a/py/runtime0.h b/py/runtime0.h index 4fdcdc3cc9..b7b5afaeb6 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -1,5 +1,5 @@ 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_NEGATIVE, RT_UNARY_OP_INVERT, |