summaryrefslogtreecommitdiffstatshomepage
path: root/py/parse.c
diff options
context:
space:
mode:
authorAngus Gratton <angus@redyak.com.au>2022-07-27 12:52:48 +1000
committerDamien George <damien@micropython.org>2022-09-23 16:04:13 +1000
commit25ff5b52d9786beff0b90a268af813b223f31f57 (patch)
tree83fdfa31be7243de58f1e555149305eecd10ffd6 /py/parse.c
parentf91ebf6fa972a593ede25d33740e693d99dbbc3f (diff)
downloadmicropython-25ff5b52d9786beff0b90a268af813b223f31f57.tar.gz
micropython-25ff5b52d9786beff0b90a268af813b223f31f57.zip
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>
Diffstat (limited to 'py/parse.c')
-rw-r--r--py/parse.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/py/parse.c b/py/parse.c
index d58098af2e..62de3282b3 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -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;