@@ -1460,10 +1460,14 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
14601460
14611461 EMIT (label_assign , continue_label );
14621462
1463- // compile: if var < end: goto top
1463+ // compile: if var <cond> end: goto top
14641464 compile_node (comp , pn_var );
14651465 compile_node (comp , pn_end );
1466- EMIT (compare_op , RT_COMPARE_OP_LESS );
1466+ if (MP_PARSE_NODE_LEAF_ARG (pn_step ) >= 0 ) {
1467+ EMIT (compare_op , RT_COMPARE_OP_LESS );
1468+ } else {
1469+ EMIT (compare_op , RT_COMPARE_OP_MORE );
1470+ }
14671471 EMIT (pop_jump_if_true , top_label );
14681472
14691473 // break/continue apply to outer loop (if any) in the else block
@@ -1482,14 +1486,19 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
14821486 // for viper it will be much, much faster
14831487 if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_STRUCT_KIND (pns -> nodes [1 ], PN_power )) {
14841488 mp_parse_node_struct_t * pns_it = (mp_parse_node_struct_t * )pns -> nodes [1 ];
1485- if (MP_PARSE_NODE_IS_ID (pns_it -> nodes [0 ]) && MP_PARSE_NODE_LEAF_ARG (pns_it -> nodes [0 ]) == MP_QSTR_range && MP_PARSE_NODE_IS_STRUCT_KIND (pns_it -> nodes [1 ], PN_trailer_paren ) && MP_PARSE_NODE_IS_NULL (pns_it -> nodes [2 ])) {
1489+ if (MP_PARSE_NODE_IS_ID (pns_it -> nodes [0 ])
1490+ && MP_PARSE_NODE_LEAF_ARG (pns_it -> nodes [0 ]) == MP_QSTR_range
1491+ && MP_PARSE_NODE_IS_STRUCT_KIND (pns_it -> nodes [1 ], PN_trailer_paren )
1492+ && MP_PARSE_NODE_IS_NULL (pns_it -> nodes [2 ])) {
14861493 mp_parse_node_t pn_range_args = ((mp_parse_node_struct_t * )pns_it -> nodes [1 ])-> nodes [0 ];
14871494 mp_parse_node_t * args ;
14881495 int n_args = list_get (& pn_range_args , PN_arglist , & args );
1496+ mp_parse_node_t pn_range_start ;
1497+ mp_parse_node_t pn_range_end ;
1498+ mp_parse_node_t pn_range_step ;
1499+ bool optimize = false;
14891500 if (1 <= n_args && n_args <= 3 ) {
1490- mp_parse_node_t pn_range_start ;
1491- mp_parse_node_t pn_range_end ;
1492- mp_parse_node_t pn_range_step ;
1501+ optimize = true;
14931502 if (n_args == 1 ) {
14941503 pn_range_start = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , 0 );
14951504 pn_range_end = args [0 ];
@@ -1502,7 +1511,13 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
15021511 pn_range_start = args [0 ];
15031512 pn_range_end = args [1 ];
15041513 pn_range_step = args [2 ];
1514+ // We need to know sign of step. This is possible only if it's constant
1515+ if (!MP_PARSE_NODE_IS_SMALL_INT (pn_range_step )) {
1516+ optimize = false;
1517+ }
15051518 }
1519+ }
1520+ if (optimize ) {
15061521 compile_for_stmt_optimised_range (comp , pns -> nodes [0 ], pn_range_start , pn_range_end , pn_range_step , pns -> nodes [2 ], pns -> nodes [3 ]);
15071522 return ;
15081523 }
0 commit comments