@@ -336,18 +336,34 @@ static uint8_t peek_rule(parser_t *parser, size_t n) {
336
336
}
337
337
#endif
338
338
339
- bool mp_parse_node_get_int_maybe (mp_parse_node_t pn , mp_obj_t * o ) {
339
+ #if MICROPY_COMP_CONST_FOLDING || MICROPY_EMIT_INLINE_ASM
340
+ static bool mp_parse_node_get_number_maybe (mp_parse_node_t pn , mp_obj_t * o ) {
340
341
if (MP_PARSE_NODE_IS_SMALL_INT (pn )) {
341
342
* o = MP_OBJ_NEW_SMALL_INT (MP_PARSE_NODE_LEAF_SMALL_INT (pn ));
342
343
return true;
343
344
} else if (MP_PARSE_NODE_IS_STRUCT_KIND (pn , RULE_const_object )) {
344
345
mp_parse_node_struct_t * pns = (mp_parse_node_struct_t * )pn ;
345
346
* o = mp_parse_node_extract_const_object (pns );
346
- return mp_obj_is_int (* o );
347
+ return mp_obj_is_int (* o )
348
+ #if MICROPY_COMP_CONST_FLOAT
349
+ || mp_obj_is_float (* o )
350
+ #endif
351
+ ;
347
352
} else {
348
353
return false;
349
354
}
350
355
}
356
+ #endif
357
+
358
+ #if MICROPY_EMIT_INLINE_ASM
359
+ bool mp_parse_node_get_int_maybe (mp_parse_node_t pn , mp_obj_t * o ) {
360
+ return mp_parse_node_get_number_maybe (pn , o )
361
+ #if MICROPY_COMP_CONST_FLOAT
362
+ && mp_obj_is_int (* o )
363
+ #endif
364
+ ;
365
+ }
366
+ #endif
351
367
352
368
#if MICROPY_COMP_CONST_TUPLE || MICROPY_COMP_CONST
353
369
static bool mp_parse_node_is_const (mp_parse_node_t pn ) {
@@ -642,12 +658,32 @@ static const mp_rom_map_elem_t mp_constants_table[] = {
642
658
#if MICROPY_PY_UCTYPES
643
659
{ MP_ROM_QSTR (MP_QSTR_uctypes ), MP_ROM_PTR (& mp_module_uctypes ) },
644
660
#endif
661
+ #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH && MICROPY_COMP_CONST_FLOAT
662
+ { MP_ROM_QSTR (MP_QSTR_math ), MP_ROM_PTR (& mp_module_math ) },
663
+ #endif
645
664
// Extra constants as defined by a port
646
665
MICROPY_PORT_CONSTANTS
647
666
};
648
667
static MP_DEFINE_CONST_MAP (mp_constants_map , mp_constants_table ) ;
649
668
#endif
650
669
670
+ static bool binary_op_maybe (mp_binary_op_t op , mp_obj_t lhs , mp_obj_t rhs , mp_obj_t * res ) {
671
+ nlr_buf_t nlr ;
672
+ if (nlr_push (& nlr ) == 0 ) {
673
+ mp_obj_t tmp = mp_binary_op (op , lhs , rhs );
674
+ #if MICROPY_PY_BUILTINS_COMPLEX
675
+ if (mp_obj_is_type (tmp , & mp_type_complex )) {
676
+ return false;
677
+ }
678
+ #endif
679
+ * res = tmp ;
680
+ nlr_pop ();
681
+ return true;
682
+ } else {
683
+ return false;
684
+ }
685
+ }
686
+
651
687
static bool fold_logical_constants (parser_t * parser , uint8_t rule_id , size_t * num_args ) {
652
688
if (rule_id == RULE_or_test
653
689
|| rule_id == RULE_and_test ) {
@@ -706,7 +742,7 @@ static bool fold_logical_constants(parser_t *parser, uint8_t rule_id, size_t *nu
706
742
}
707
743
708
744
static bool fold_constants (parser_t * parser , uint8_t rule_id , size_t num_args ) {
709
- // this code does folding of arbitrary integer expressions, eg 1 + 2 * 3 + 4
745
+ // this code does folding of arbitrary numeric expressions, eg 1 + 2 * 3 + 4
710
746
// it does not do partial folding, eg 1 + 2 + x -> 3 + x
711
747
712
748
mp_obj_t arg0 ;
@@ -716,7 +752,7 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
716
752
|| rule_id == RULE_power ) {
717
753
// folding for binary ops: | ^ & **
718
754
mp_parse_node_t pn = peek_result (parser , num_args - 1 );
719
- if (!mp_parse_node_get_int_maybe (pn , & arg0 )) {
755
+ if (!mp_parse_node_get_number_maybe (pn , & arg0 )) {
720
756
return false;
721
757
}
722
758
mp_binary_op_t op ;
@@ -732,58 +768,61 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
732
768
for (ssize_t i = num_args - 2 ; i >= 0 ; -- i ) {
733
769
pn = peek_result (parser , i );
734
770
mp_obj_t arg1 ;
735
- if (!mp_parse_node_get_int_maybe (pn , & arg1 )) {
771
+ if (!mp_parse_node_get_number_maybe (pn , & arg1 )) {
736
772
return false;
737
773
}
774
+ #if !MICROPY_COMP_CONST_FLOAT
738
775
if (op == MP_BINARY_OP_POWER && mp_obj_int_sign (arg1 ) < 0 ) {
739
776
// ** can't have negative rhs
740
777
return false;
741
778
}
742
- arg0 = mp_binary_op (op , arg0 , arg1 );
779
+ #endif
780
+ if (!binary_op_maybe (op , arg0 , arg1 , & arg0 )) {
781
+ return false;
782
+ }
743
783
}
744
784
} else if (rule_id == RULE_shift_expr
745
785
|| rule_id == RULE_arith_expr
746
786
|| rule_id == RULE_term ) {
747
787
// folding for binary ops: << >> + - * @ / % //
748
788
mp_parse_node_t pn = peek_result (parser , num_args - 1 );
749
- if (!mp_parse_node_get_int_maybe (pn , & arg0 )) {
789
+ if (!mp_parse_node_get_number_maybe (pn , & arg0 )) {
750
790
return false;
751
791
}
752
792
for (ssize_t i = num_args - 2 ; i >= 1 ; i -= 2 ) {
753
793
pn = peek_result (parser , i - 1 );
754
794
mp_obj_t arg1 ;
755
- if (!mp_parse_node_get_int_maybe (pn , & arg1 )) {
795
+ if (!mp_parse_node_get_number_maybe (pn , & arg1 )) {
756
796
return false;
757
797
}
758
798
mp_token_kind_t tok = MP_PARSE_NODE_LEAF_ARG (peek_result (parser , i ));
759
- if (tok == MP_TOKEN_OP_AT || tok == MP_TOKEN_OP_SLASH ) {
760
- // Can't fold @ or /
799
+ if (tok == MP_TOKEN_OP_AT ) {
800
+ // Can't fold @
801
+ return false;
802
+ }
803
+ #if !MICROPY_COMP_CONST_FLOAT
804
+ if (tok == MP_TOKEN_OP_SLASH ) {
805
+ // Can't fold /
761
806
return false;
762
807
}
808
+ #endif
763
809
mp_binary_op_t op = MP_BINARY_OP_LSHIFT + (tok - MP_TOKEN_OP_DBL_LESS );
764
- int rhs_sign = mp_obj_int_sign (arg1 );
765
- if (op <= MP_BINARY_OP_RSHIFT ) {
766
- // << and >> can't have negative rhs
767
- if (rhs_sign < 0 ) {
768
- return false;
769
- }
770
- } else if (op >= MP_BINARY_OP_FLOOR_DIVIDE ) {
771
- // % and // can't have zero rhs
772
- if (rhs_sign == 0 ) {
773
- return false;
774
- }
810
+ if (!binary_op_maybe (op , arg0 , arg1 , & arg0 )) {
811
+ return false;
775
812
}
776
- arg0 = mp_binary_op (op , arg0 , arg1 );
777
813
}
778
814
} else if (rule_id == RULE_factor_2 ) {
779
815
// folding for unary ops: + - ~
780
816
mp_parse_node_t pn = peek_result (parser , 0 );
781
- if (!mp_parse_node_get_int_maybe (pn , & arg0 )) {
817
+ if (!mp_parse_node_get_number_maybe (pn , & arg0 )) {
782
818
return false;
783
819
}
784
820
mp_token_kind_t tok = MP_PARSE_NODE_LEAF_ARG (peek_result (parser , 1 ));
785
821
mp_unary_op_t op ;
786
822
if (tok == MP_TOKEN_OP_TILDE ) {
823
+ if (!mp_obj_is_int (arg0 )) {
824
+ return false;
825
+ }
787
826
op = MP_UNARY_OP_INVERT ;
788
827
} else {
789
828
assert (tok == MP_TOKEN_OP_PLUS || tok == MP_TOKEN_OP_MINUS ); // should be
@@ -855,7 +894,7 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
855
894
return false;
856
895
}
857
896
// id1.id2
858
- // look it up in constant table, see if it can be replaced with an integer
897
+ // look it up in constant table, see if it can be replaced with an integer or a float
859
898
mp_parse_node_struct_t * pns1 = (mp_parse_node_struct_t * )pn1 ;
860
899
assert (MP_PARSE_NODE_IS_ID (pns1 -> nodes [0 ]));
861
900
qstr q_base = MP_PARSE_NODE_LEAF_ARG (pn0 );
@@ -866,7 +905,7 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) {
866
905
}
867
906
mp_obj_t dest [2 ];
868
907
mp_load_method_maybe (elem -> value , q_attr , dest );
869
- if (!(dest [0 ] != MP_OBJ_NULL && mp_obj_is_int (dest [0 ]) && dest [1 ] == MP_OBJ_NULL )) {
908
+ if (!(dest [0 ] != MP_OBJ_NULL && ( mp_obj_is_int (dest [0 ]) || mp_obj_is_float ( dest [ 0 ]) ) && dest [1 ] == MP_OBJ_NULL )) {
870
909
return false;
871
910
}
872
911
arg0 = dest [0 ];
0 commit comments