@@ -115,17 +115,77 @@ STATIC const mp_map_t mp_constants_map = {
115115 .table = (mp_map_elem_t * )mp_constants_table ,
116116};
117117
118- STATIC mp_parse_node_t fold_constants (mp_parse_node_t pn ) {
119- if (MP_PARSE_NODE_IS_STRUCT (pn )) {
118+ // this function is essentially a simple preprocessor
119+ STATIC mp_parse_node_t fold_constants (compiler_t * comp , mp_parse_node_t pn , mp_map_t * consts ) {
120+ if (0 ) {
121+ // dummy
122+ #if MICROPY_ENABLE_CONST
123+ } else if (MP_PARSE_NODE_IS_ID (pn )) {
124+ // lookup identifier in table of dynamic constants
125+ qstr qst = MP_PARSE_NODE_LEAF_ARG (pn );
126+ mp_map_elem_t * elem = mp_map_lookup (consts , MP_OBJ_NEW_QSTR (qst ), MP_MAP_LOOKUP );
127+ if (elem != NULL ) {
128+ pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , MP_OBJ_SMALL_INT_VALUE (elem -> value ));
129+ }
130+ #endif
131+ } else if (MP_PARSE_NODE_IS_STRUCT (pn )) {
120132 mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
121- int n = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
122133
123- // fold arguments first
134+ // fold some parse nodes before folding their arguments
135+ switch (MP_PARSE_NODE_STRUCT_KIND (pns )) {
136+ #if MICROPY_ENABLE_CONST
137+ case PN_expr_stmt :
138+ if (!MP_PARSE_NODE_IS_NULL (pns -> nodes [1 ])) {
139+ mp_parse_node_struct_t * pns1 = (mp_parse_node_struct_t * )pns -> nodes [1 ];
140+ if (MP_PARSE_NODE_STRUCT_KIND (pns1 ) == PN_expr_stmt_assign ) {
141+ if (MP_PARSE_NODE_IS_ID (pns -> nodes [0 ])
142+ && MP_PARSE_NODE_IS_STRUCT_KIND (pns1 -> nodes [0 ], PN_power )
143+ && MP_PARSE_NODE_IS_ID (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [0 ])
144+ && MP_PARSE_NODE_LEAF_ARG (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [0 ]) == MP_QSTR_const
145+ && MP_PARSE_NODE_IS_STRUCT_KIND (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [1 ], PN_trailer_paren )
146+ && MP_PARSE_NODE_IS_NULL (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [2 ])
147+ ) {
148+ // code to assign dynamic constants: id = const(value)
149+
150+ // get the id
151+ qstr id_qstr = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
152+
153+ // get the value
154+ mp_parse_node_t pn_value = ((mp_parse_node_struct_t * )((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [1 ])-> nodes [0 ];
155+ pn_value = fold_constants (comp , pn_value , consts );
156+ if (!MP_PARSE_NODE_IS_SMALL_INT (pn_value )) {
157+ compile_syntax_error (comp , (mp_parse_node_t )pns , "constant must be an integer" );
158+ break ;
159+ }
160+ machine_int_t value = MP_PARSE_NODE_LEAF_SMALL_INT (pn_value );
161+
162+ // store the value in the table of dynamic constants
163+ mp_map_elem_t * elem = mp_map_lookup (consts , MP_OBJ_NEW_QSTR (id_qstr ), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND );
164+ if (elem -> value != MP_OBJ_NULL ) {
165+ compile_syntax_error (comp , (mp_parse_node_t )pns , "constant redefined" );
166+ break ;
167+ }
168+ elem -> value = MP_OBJ_NEW_SMALL_INT (value );
169+
170+ // replace const(value) with value
171+ pns1 -> nodes [0 ] = pn_value ;
172+
173+ // finished folding this assignment
174+ return pn ;
175+ }
176+ }
177+ }
178+ break ;
179+ #endif
180+ }
181+
182+ // fold arguments
183+ int n = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
124184 for (int i = 0 ; i < n ; i ++ ) {
125- pns -> nodes [i ] = fold_constants (pns -> nodes [i ]);
185+ pns -> nodes [i ] = fold_constants (comp , pns -> nodes [i ], consts );
126186 }
127187
128- // now try to fold this parse node
188+ // try to fold this parse node
129189 switch (MP_PARSE_NODE_STRUCT_KIND (pns )) {
130190 case PN_atom_paren :
131191 if (n == 1 && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [0 ])) {
@@ -2045,36 +2105,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
20452105 c_assign (comp , ((mp_parse_node_struct_t * )pns1 -> nodes [i ])-> nodes [0 ], ASSIGN_STORE ); // middle store
20462106 }
20472107 } else if (kind == PN_expr_stmt_assign ) {
2048- if (0 ) {
2049- // dummy
2050- #if 0
2051- // code to compile constants: id = const(...)
2052- } else if (MP_PARSE_NODE_IS_ID (pns -> nodes [0 ])
2053- && MP_PARSE_NODE_IS_STRUCT_KIND (pns1 -> nodes [0 ], PN_power )
2054- && MP_PARSE_NODE_IS_ID (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [0 ])
2055- && MP_PARSE_NODE_LEAF_ARG (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [0 ]) == MP_QSTR_const
2056- && MP_PARSE_NODE_IS_STRUCT_KIND (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [1 ], PN_trailer_paren )
2057- && MP_PARSE_NODE_IS_NULL (((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [2 ])
2058- ) {
2059- if (comp -> pass == MP_PASS_SCOPE ) {
2060- qstr const_id = MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]);
2061-
2062- if (!MP_PARSE_NODE_IS_SMALL_INT (((mp_parse_node_struct_t * )((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [1 ])-> nodes [0 ])) {
2063- compile_syntax_error (comp , (mp_parse_node_t )pns , "constant must be an integer" );
2064- }
2065- machine_int_t value = MP_PARSE_NODE_LEAF_SMALL_INT (((mp_parse_node_struct_t * )((mp_parse_node_struct_t * )pns1 -> nodes [0 ])-> nodes [1 ])-> nodes [0 ]);
2066-
2067- printf ("assign const: %s = %ld\n" , qstr_str (const_id ), value );
2068- mp_map_elem_t * elem = mp_map_lookup (& comp -> module_consts , MP_OBJ_NEW_QSTR (const_id ), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND );
2069- if (elem -> value != MP_OBJ_NULL ) {
2070- compile_syntax_error (comp , (mp_parse_node_t )pns , "constant redefined" );
2071- }
2072- elem -> value = MP_OBJ_NEW_SMALL_INT (value );
2073- }
2074- goto no_optimisation ;
2075-
2076- #endif
2077- } else if (MP_PARSE_NODE_IS_STRUCT_KIND (pns1 -> nodes [0 ], PN_testlist_star_expr )
2108+ if (MP_PARSE_NODE_IS_STRUCT_KIND (pns1 -> nodes [0 ], PN_testlist_star_expr )
20782109 && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [0 ], PN_testlist_star_expr )
20792110 && MP_PARSE_NODE_STRUCT_NUM_NODES ((mp_parse_node_struct_t * )pns1 -> nodes [0 ]) == 2
20802111 && MP_PARSE_NODE_STRUCT_NUM_NODES ((mp_parse_node_struct_t * )pns -> nodes [0 ]) == 2 ) {
@@ -3424,7 +3455,10 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
34243455 comp -> is_repl = is_repl ;
34253456
34263457 // optimise constants
3427- pn = fold_constants (pn );
3458+ mp_map_t consts ;
3459+ mp_map_init (& consts , 0 );
3460+ pn = fold_constants (comp , pn , & consts );
3461+ mp_map_deinit (& consts );
34283462
34293463 // set the outer scope
34303464 scope_t * module_scope = scope_new_and_link (comp , SCOPE_MODULE , pn , emit_opt );
0 commit comments