|
33 | 33 | #include "py/scope.h" |
34 | 34 | #include "py/emit.h" |
35 | 35 | #include "py/compile.h" |
36 | | -#include "py/smallint.h" |
37 | 36 | #include "py/runtime.h" |
38 | | -#include "py/builtin.h" |
39 | 37 |
|
40 | 38 | // TODO need to mangle __attr names |
41 | 39 |
|
@@ -124,238 +122,6 @@ STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const cha |
124 | 122 | } |
125 | 123 | } |
126 | 124 |
|
127 | | -#if MICROPY_COMP_MODULE_CONST |
128 | | -STATIC const mp_map_elem_t mp_constants_table[] = { |
129 | | - #if MICROPY_PY_UCTYPES |
130 | | - { MP_OBJ_NEW_QSTR(MP_QSTR_uctypes), (mp_obj_t)&mp_module_uctypes }, |
131 | | - #endif |
132 | | - // Extra constants as defined by a port |
133 | | - MICROPY_PORT_CONSTANTS |
134 | | -}; |
135 | | -STATIC MP_DEFINE_CONST_MAP(mp_constants_map, mp_constants_table); |
136 | | -#endif |
137 | | - |
138 | | -// this function is essentially a simple preprocessor |
139 | | -STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_map_t *consts) { |
140 | | - if (0) { |
141 | | - // dummy |
142 | | -#if MICROPY_COMP_CONST |
143 | | - } else if (MP_PARSE_NODE_IS_ID(pn)) { |
144 | | - // lookup identifier in table of dynamic constants |
145 | | - qstr qst = MP_PARSE_NODE_LEAF_ARG(pn); |
146 | | - mp_map_elem_t *elem = mp_map_lookup(consts, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); |
147 | | - if (elem != NULL) { |
148 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, MP_OBJ_SMALL_INT_VALUE(elem->value)); |
149 | | - } |
150 | | -#endif |
151 | | - } else if (MP_PARSE_NODE_IS_STRUCT(pn)) { |
152 | | - mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; |
153 | | - |
154 | | - // fold some parse nodes before folding their arguments |
155 | | - switch (MP_PARSE_NODE_STRUCT_KIND(pns)) { |
156 | | -#if MICROPY_COMP_CONST |
157 | | - case PN_expr_stmt: |
158 | | - if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) { |
159 | | - if (!(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_expr_stmt_augassign) |
160 | | - || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_expr_stmt_assign_list))) { |
161 | | - // this node is of the form <x> = <y> |
162 | | - if (MP_PARSE_NODE_IS_ID(pns->nodes[0]) |
163 | | - && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power) |
164 | | - && MP_PARSE_NODE_IS_ID(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[0]) |
165 | | - && MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[0]) == MP_QSTR_const |
166 | | - && MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[1], PN_trailer_paren) |
167 | | - && MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns->nodes[1])->nodes[2]) |
168 | | - ) { |
169 | | - // code to assign dynamic constants: id = const(value) |
170 | | - |
171 | | - // get the id |
172 | | - qstr id_qstr = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); |
173 | | - |
174 | | - // get the value |
175 | | - mp_parse_node_t pn_value = ((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns->nodes[1])->nodes[1])->nodes[0]; |
176 | | - pn_value = fold_constants(comp, pn_value, consts); |
177 | | - if (!MP_PARSE_NODE_IS_SMALL_INT(pn_value)) { |
178 | | - compile_syntax_error(comp, (mp_parse_node_t)pns, "constant must be an integer"); |
179 | | - break; |
180 | | - } |
181 | | - mp_int_t value = MP_PARSE_NODE_LEAF_SMALL_INT(pn_value); |
182 | | - |
183 | | - // store the value in the table of dynamic constants |
184 | | - mp_map_elem_t *elem = mp_map_lookup(consts, MP_OBJ_NEW_QSTR(id_qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); |
185 | | - if (elem->value != MP_OBJ_NULL) { |
186 | | - compile_syntax_error(comp, (mp_parse_node_t)pns, "constant redefined"); |
187 | | - break; |
188 | | - } |
189 | | - elem->value = MP_OBJ_NEW_SMALL_INT(value); |
190 | | - |
191 | | - // replace const(value) with value |
192 | | - pns->nodes[1] = pn_value; |
193 | | - |
194 | | - // finished folding this assignment |
195 | | - return pn; |
196 | | - } |
197 | | - } |
198 | | - } |
199 | | - break; |
200 | | -#endif |
201 | | - case PN_string: |
202 | | - case PN_bytes: |
203 | | - case PN_const_object: |
204 | | - return pn; |
205 | | - } |
206 | | - |
207 | | - // fold arguments |
208 | | - int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); |
209 | | - for (int i = 0; i < n; i++) { |
210 | | - pns->nodes[i] = fold_constants(comp, pns->nodes[i], consts); |
211 | | - } |
212 | | - |
213 | | - // try to fold this parse node |
214 | | - switch (MP_PARSE_NODE_STRUCT_KIND(pns)) { |
215 | | - case PN_atom_paren: |
216 | | - if (n == 1 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0])) { |
217 | | - // (int) |
218 | | - pn = pns->nodes[0]; |
219 | | - } |
220 | | - break; |
221 | | - |
222 | | - case PN_expr: |
223 | | - if (n == 2 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) { |
224 | | - // int | int |
225 | | - mp_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[0]); |
226 | | - mp_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[1]); |
227 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 | arg1); |
228 | | - } |
229 | | - break; |
230 | | - |
231 | | - case PN_and_expr: |
232 | | - if (n == 2 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) { |
233 | | - // int & int |
234 | | - mp_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[0]); |
235 | | - mp_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[1]); |
236 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 & arg1); |
237 | | - } |
238 | | - break; |
239 | | - |
240 | | - case PN_shift_expr: |
241 | | - if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { |
242 | | - mp_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[0]); |
243 | | - mp_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[2]); |
244 | | - if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_LESS)) { |
245 | | - // int << int |
246 | | - if (!(arg1 >= (mp_int_t)BITS_PER_WORD || arg0 > (MP_SMALL_INT_MAX >> arg1) || arg0 < (MP_SMALL_INT_MIN >> arg1))) { |
247 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 << arg1); |
248 | | - } |
249 | | - } else { |
250 | | - assert(MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_MORE)); // should be |
251 | | - // int >> int |
252 | | - if (arg1 >= (mp_int_t)BITS_PER_WORD) { |
253 | | - // Shifting to big amounts is underfined behavior |
254 | | - // in C and is CPU-dependent; propagate sign bit. |
255 | | - arg1 = BITS_PER_WORD - 1; |
256 | | - } |
257 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 >> arg1); |
258 | | - } |
259 | | - } |
260 | | - break; |
261 | | - |
262 | | - case PN_arith_expr: |
263 | | - // overflow checking here relies on SMALL_INT being strictly smaller than mp_int_t |
264 | | - if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { |
265 | | - mp_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[0]); |
266 | | - mp_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[2]); |
267 | | - if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PLUS)) { |
268 | | - // int + int |
269 | | - arg0 += arg1; |
270 | | - } else { |
271 | | - assert(MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_MINUS)); // should be |
272 | | - // int - int |
273 | | - arg0 -= arg1; |
274 | | - } |
275 | | - if (MP_SMALL_INT_FITS(arg0)) { |
276 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0); |
277 | | - } |
278 | | - } |
279 | | - break; |
280 | | - |
281 | | - case PN_term: |
282 | | - if (n == 3 && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) { |
283 | | - mp_int_t arg0 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[0]); |
284 | | - mp_int_t arg1 = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[2]); |
285 | | - if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_STAR)) { |
286 | | - // int * int |
287 | | - if (!mp_small_int_mul_overflow(arg0, arg1)) { |
288 | | - arg0 *= arg1; |
289 | | - if (MP_SMALL_INT_FITS(arg0)) { |
290 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0); |
291 | | - } |
292 | | - } |
293 | | - } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_SLASH)) { |
294 | | - // int / int |
295 | | - // pass |
296 | | - } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PERCENT)) { |
297 | | - // int%int |
298 | | - if (arg1 != 0) { |
299 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, mp_small_int_modulo(arg0, arg1)); |
300 | | - } |
301 | | - } else { |
302 | | - assert(MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_SLASH)); // should be |
303 | | - if (arg1 != 0) { |
304 | | - // int // int |
305 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, mp_small_int_floor_divide(arg0, arg1)); |
306 | | - } |
307 | | - } |
308 | | - } |
309 | | - break; |
310 | | - |
311 | | - case PN_factor_2: |
312 | | - if (MP_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) { |
313 | | - mp_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT(pns->nodes[1]); |
314 | | - if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_PLUS)) { |
315 | | - // +int |
316 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg); |
317 | | - } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_MINUS)) { |
318 | | - // -int |
319 | | - arg = -arg; |
320 | | - if (MP_SMALL_INT_FITS(arg)) { |
321 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg); |
322 | | - } |
323 | | - } else { |
324 | | - assert(MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], MP_TOKEN_OP_TILDE)); // should be |
325 | | - // ~int |
326 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, ~arg); |
327 | | - } |
328 | | - } |
329 | | - break; |
330 | | - |
331 | | - case PN_power: |
332 | | - if (0) { |
333 | | -#if MICROPY_COMP_MODULE_CONST |
334 | | - } else if (MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_trailer_period) && MP_PARSE_NODE_IS_NULL(pns->nodes[2])) { |
335 | | - // id.id |
336 | | - // look it up in constant table, see if it can be replaced with an integer |
337 | | - mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1]; |
338 | | - assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0])); |
339 | | - qstr q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); |
340 | | - qstr q_attr = MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]); |
341 | | - mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&mp_constants_map, MP_OBJ_NEW_QSTR(q_base), MP_MAP_LOOKUP); |
342 | | - if (elem != NULL) { |
343 | | - mp_obj_t dest[2]; |
344 | | - mp_load_method_maybe(elem->value, q_attr, dest); |
345 | | - if (MP_OBJ_IS_SMALL_INT(dest[0]) && dest[1] == NULL) { |
346 | | - mp_int_t val = MP_OBJ_SMALL_INT_VALUE(dest[0]); |
347 | | - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, val); |
348 | | - } |
349 | | - } |
350 | | -#endif |
351 | | - } |
352 | | - break; |
353 | | - } |
354 | | - } |
355 | | - |
356 | | - return pn; |
357 | | -} |
358 | | - |
359 | 125 | STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_arglist, bool is_method_call, int n_positional_extra); |
360 | 126 | STATIC void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_kind_t kind); |
361 | 127 | STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn); |
@@ -3332,13 +3098,6 @@ mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt |
3332 | 3098 | // create the module scope |
3333 | 3099 | scope_t *module_scope = scope_new_and_link(comp, SCOPE_MODULE, parse_tree->root, emit_opt); |
3334 | 3100 |
|
3335 | | - // optimise constants (scope must be set for error messages to work) |
3336 | | - comp->scope_cur = module_scope; |
3337 | | - mp_map_t consts; |
3338 | | - mp_map_init(&consts, 0); |
3339 | | - module_scope->pn = fold_constants(comp, module_scope->pn, &consts); |
3340 | | - mp_map_deinit(&consts); |
3341 | | - |
3342 | 3101 | // create standard emitter; it's used at least for MP_PASS_SCOPE |
3343 | 3102 | emit_t *emit_bc = emit_bc_new(); |
3344 | 3103 |
|
|
0 commit comments