1717#include "obj.h"
1818#include "compile.h"
1919#include "runtime.h"
20+ #include "builtin.h"
2021#include "smallint.h"
2122
2223// TODO need to mangle __attr names
@@ -100,17 +101,44 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
100101 pns -> nodes [i ] = fold_constants (pns -> nodes [i ]);
101102 }
102103
104+ // now try to fold this parse node
103105 switch (MP_PARSE_NODE_STRUCT_KIND (pns )) {
106+ case PN_atom_paren :
107+ if (n == 1 && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [0 ])) {
108+ // (int)
109+ pn = pns -> nodes [0 ];
110+ }
111+ break ;
112+
113+ case PN_expr :
114+ if (n == 2 && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [1 ])) {
115+ // int | int
116+ machine_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [0 ]);
117+ machine_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [1 ]);
118+ pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 | arg1 );
119+ }
120+ break ;
121+
122+ case PN_and_expr :
123+ if (n == 2 && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [1 ])) {
124+ // int & int
125+ machine_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [0 ]);
126+ machine_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [1 ]);
127+ pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 & arg1 );
128+ }
129+ break ;
130+
104131 case PN_shift_expr :
105132 if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [2 ])) {
106- int arg0 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [0 ]);
107- int arg1 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [2 ]);
133+ machine_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [0 ]);
134+ machine_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [2 ]);
108135 if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_DBL_LESS )) {
109- #if MICROPY_EMIT_CPYTHON
110- // can overflow; enabled only to compare with CPython
111- pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 << arg1 );
112- #endif
136+ // int << int
137+ if (!( arg1 >= BITS_PER_WORD || arg0 > ( MP_SMALL_INT_MAX >> arg1 ) || arg0 < ( MP_SMALL_INT_MIN >> arg1 ))) {
138+ pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 << arg1 );
139+ }
113140 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_DBL_MORE )) {
141+ // int >> int
114142 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 >> arg1 );
115143 } else {
116144 // shouldn't happen
@@ -125,14 +153,17 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
125153 machine_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [0 ]);
126154 machine_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [2 ]);
127155 if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_PLUS )) {
156+ // int + int
128157 arg0 += arg1 ;
129158 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_MINUS )) {
159+ // int - int
130160 arg0 -= arg1 ;
131161 } else {
132162 // shouldn't happen
133163 assert (0 );
134164 }
135165 if (MP_PARSE_FITS_SMALL_INT (arg0 )) {
166+ //printf("%ld + %ld\n", arg0, arg1);
136167 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 );
137168 }
138169 }
@@ -143,18 +174,22 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
143174 machine_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [0 ]);
144175 machine_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [2 ]);
145176 if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_STAR )) {
177+ // int * int
146178 if (!mp_small_int_mul_overflow (arg0 , arg1 )) {
147179 arg0 *= arg1 ;
148180 if (MP_PARSE_FITS_SMALL_INT (arg0 )) {
149181 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg0 );
150182 }
151183 }
152184 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_SLASH )) {
153- ; // pass
185+ // int / int
186+ // pass
154187 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_PERCENT )) {
188+ // int%int
155189 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , mp_small_int_modulo (arg0 , arg1 ));
156190 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [1 ], MP_TOKEN_OP_DBL_SLASH )) {
157191 if (arg1 != 0 ) {
192+ // int // int
158193 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , mp_small_int_floor_divide (arg0 , arg1 ));
159194 }
160195 } else {
@@ -168,10 +203,13 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
168203 if (MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [1 ])) {
169204 machine_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT (pns -> nodes [1 ]);
170205 if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [0 ], MP_TOKEN_OP_PLUS )) {
206+ // +int
171207 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , arg );
172208 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [0 ], MP_TOKEN_OP_MINUS )) {
209+ // -int
173210 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , - arg );
174211 } else if (MP_PARSE_NODE_IS_TOKEN_KIND (pns -> nodes [0 ], MP_TOKEN_OP_TILDE )) {
212+ // ~int
175213 pn = mp_parse_node_new_leaf (MP_PARSE_NODE_SMALL_INT , ~arg );
176214 } else {
177215 // shouldn't happen
@@ -184,7 +222,7 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
184222 if (0 ) {
185223#if MICROPY_EMIT_CPYTHON
186224 } else if (MP_PARSE_NODE_IS_SMALL_INT (pns -> nodes [0 ]) && MP_PARSE_NODE_IS_NULL (pns -> nodes [1 ]) && !MP_PARSE_NODE_IS_NULL (pns -> nodes [2 ])) {
187- // int** x
225+ // int ** x
188226 // can overflow; enabled only to compare with CPython
189227 mp_parse_node_struct_t * pns2 = (mp_parse_node_struct_t * )pns -> nodes [2 ];
190228 if (MP_PARSE_NODE_IS_SMALL_INT (pns2 -> nodes [0 ])) {
@@ -3121,7 +3159,16 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
31213159 for (int i = 0 ; i < num ; i ++ ) {
31223160 assert (MP_PARSE_NODE_IS_STRUCT (nodes [i ]));
31233161 mp_parse_node_struct_t * pns2 = (mp_parse_node_struct_t * )nodes [i ];
3124- assert (MP_PARSE_NODE_STRUCT_KIND (pns2 ) == PN_expr_stmt );
3162+ if (MP_PARSE_NODE_STRUCT_KIND (pns2 ) == PN_pass_stmt ) {
3163+ // no instructions
3164+ continue ;
3165+ } else if (MP_PARSE_NODE_STRUCT_KIND (pns2 ) == PN_expr_stmt ) {
3166+ // an instruction; fall through
3167+ } else {
3168+ // not an instruction; error
3169+ compile_syntax_error (comp , nodes [i ], "inline assembler expecting an instruction" );
3170+ return ;
3171+ }
31253172 assert (MP_PARSE_NODE_IS_STRUCT (pns2 -> nodes [0 ]));
31263173 assert (MP_PARSE_NODE_IS_NULL (pns2 -> nodes [1 ]));
31273174 pns2 = (mp_parse_node_struct_t * )pns2 -> nodes [0 ];
@@ -3152,7 +3199,10 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
31523199 }
31533200
31543201 if (comp -> pass > PASS_1 ) {
3155- EMIT_INLINE_ASM (end_pass );
3202+ bool success = EMIT_INLINE_ASM (end_pass );
3203+ if (!success ) {
3204+ comp -> had_error = true;
3205+ }
31563206 }
31573207}
31583208#endif
@@ -3330,7 +3380,9 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
33303380 comp -> emit_inline_asm = emit_inline_thumb ;
33313381 comp -> emit_inline_asm_method_table = & emit_inline_thumb_method_table ;
33323382 compile_scope_inline_asm (comp , s , PASS_2 );
3333- compile_scope_inline_asm (comp , s , PASS_3 );
3383+ if (!comp -> had_error ) {
3384+ compile_scope_inline_asm (comp , s , PASS_3 );
3385+ }
33343386#endif
33353387
33363388 } else {
@@ -3374,7 +3426,9 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
33743426
33753427 // compile pass 2 and pass 3
33763428 compile_scope (comp , s , PASS_2 );
3377- compile_scope (comp , s , PASS_3 );
3429+ if (!comp -> had_error ) {
3430+ compile_scope (comp , s , PASS_3 );
3431+ }
33783432 }
33793433 }
33803434
0 commit comments