py/parse: Allow const types other than int to optimise as true/false.

Allows optimisation of cases like:

    import micropython
    _DEBUG = micropython.const(False)
    if _DEBUG:
        print('Debugging info')

Previously the 'if' statement was only optimised out if the type of the
const() argument was integer.

The change is implemented in a way that makes the compiler slightly smaller
(-16 bytes on PYBV11) but compilation will also be very slightly slower.

As a bonus, if const support is enabled then the compiler can now optimise
const truthy/falsey expressions of other types, like:

    while "something":
        pass

... unclear if that is useful, but perhaps it could be.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
Angus Gratton
2022-07-27 12:52:48 +10:00
committed by Damien George
parent f91ebf6fa9
commit 25ff5b52d9
3 changed files with 247 additions and 10 deletions

View File

@@ -334,16 +334,6 @@ STATIC uint8_t peek_rule(parser_t *parser, size_t n) {
}
#endif
bool mp_parse_node_is_const_false(mp_parse_node_t pn) {
return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_FALSE)
|| (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) == 0);
}
bool mp_parse_node_is_const_true(mp_parse_node_t pn) {
return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_TRUE)
|| (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) != 0);
}
bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) {
if (MP_PARSE_NODE_IS_SMALL_INT(pn)) {
*o = MP_OBJ_NEW_SMALL_INT(MP_PARSE_NODE_LEAF_SMALL_INT(pn));
@@ -427,6 +417,24 @@ STATIC mp_obj_t mp_parse_node_convert_to_obj(mp_parse_node_t pn) {
}
#endif
STATIC bool parse_node_is_const_bool(mp_parse_node_t pn, bool value) {
// Returns true if 'pn' is a constant whose boolean value is equivalent to 'value'
#if MICROPY_COMP_CONST_TUPLE || MICROPY_COMP_CONST
return mp_parse_node_is_const(pn) && mp_obj_is_true(mp_parse_node_convert_to_obj(pn)) == value;
#else
return MP_PARSE_NODE_IS_TOKEN_KIND(pn, value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE)
|| (MP_PARSE_NODE_IS_SMALL_INT(pn) && !!MP_PARSE_NODE_LEAF_SMALL_INT(pn) == value);
#endif
}
bool mp_parse_node_is_const_false(mp_parse_node_t pn) {
return parse_node_is_const_bool(pn, false);
}
bool mp_parse_node_is_const_true(mp_parse_node_t pn) {
return parse_node_is_const_bool(pn, true);
}
size_t mp_parse_node_extract_list(mp_parse_node_t *pn, size_t pn_kind, mp_parse_node_t **nodes) {
if (MP_PARSE_NODE_IS_NULL(*pn)) {
*nodes = NULL;