Skip to content

Commit 9f923a5

Browse files
committed
py/parse: Generate const int variables for annotated assignments.
This commit extends the parser's behaviour to also recognise constant integer assignments even when the assignment itself has an "int" type annotation. For assignments like "var = const(1)" the compiler generates an optimised constant load bytecode instruction, whilst before this change assignments like "var: int = const(1)" would generate a sequence of bytecode instructions to create a new integer object, create a variable, and perform the assignment. This fixes #15608. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 05342b0 commit 9f923a5

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

py/parse.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,15 @@ static bool fold_logical_constants(parser_t *parser, uint8_t rule_id, size_t *nu
705705
return false;
706706
}
707707

708+
#if MICROPY_COMP_CONST
709+
static bool is_const_atom_expr_normal(mp_parse_node_t node) {
710+
return MP_PARSE_NODE_IS_STRUCT_KIND(node, RULE_atom_expr_normal)
711+
&& MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t *)node)->nodes[0])
712+
&& MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t *)node)->nodes[0]) == MP_QSTR_const
713+
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t *)node)->nodes[1], RULE_trailer_paren);
714+
}
715+
#endif
716+
708717
static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
709718
// this code does folding of arbitrary integer expressions, eg 1 + 2 * 3 + 4
710719
// it does not do partial folding, eg 1 + 2 + x -> 3 + x
@@ -797,21 +806,26 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
797806
if (!MP_PARSE_NODE_IS_NULL(pn1)
798807
&& !(MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_expr_stmt_augassign)
799808
|| MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_expr_stmt_assign_list))) {
800-
// this node is of the form <x> = <y>
809+
// this node is of the form <x> = <y> or <x> : int = <y>
801810
mp_parse_node_t pn0 = peek_result(parser, 1);
802811
if (MP_PARSE_NODE_IS_ID(pn0)
803-
&& MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_atom_expr_normal)
804-
&& MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t *)pn1)->nodes[0])
805-
&& MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t *)pn1)->nodes[0]) == MP_QSTR_const
806-
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t *)pn1)->nodes[1], RULE_trailer_paren)
807-
) {
812+
&& ((MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_annassign) &&
813+
MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t *)pn1)->nodes[0]) &&
814+
MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t *)pn1)->nodes[0]) == MP_QSTR_int &&
815+
is_const_atom_expr_normal(((mp_parse_node_struct_t *)pn1)->nodes[1]))
816+
|| is_const_atom_expr_normal(pn1))) {
808817
// code to assign dynamic constants: id = const(value)
809818

810819
// get the id
811820
qstr id = MP_PARSE_NODE_LEAF_ARG(pn0);
812821

813822
// get the value
814-
mp_parse_node_t pn_value = ((mp_parse_node_struct_t *)((mp_parse_node_struct_t *)pn1)->nodes[1])->nodes[0];
823+
mp_parse_node_t pn_value;
824+
if (MP_PARSE_NODE_IS_STRUCT_KIND(pn1, RULE_annassign)) {
825+
pn_value = ((mp_parse_node_struct_t *)(((mp_parse_node_struct_t *)(((mp_parse_node_struct_t *)pn1)->nodes[1]))->nodes[1]))->nodes[0];
826+
} else {
827+
pn_value = ((mp_parse_node_struct_t *)((mp_parse_node_struct_t *)pn1)->nodes[1])->nodes[0];
828+
}
815829
if (!mp_parse_node_is_const(pn_value)) {
816830
mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
817831
MP_ERROR_TEXT("not a constant"));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy