Numworks Epsilon  1.4.1
Graphing Calculator Operating System
compile.c
Go to the documentation of this file.
1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2013-2015 Damien P. George
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32 
33 #include "py/scope.h"
34 #include "py/emit.h"
35 #include "py/compile.h"
36 #include "py/runtime.h"
37 #include "py/asmbase.h"
38 
39 #if MICROPY_ENABLE_COMPILER
40 
41 // TODO need to mangle __attr names
42 
43 #define INVALID_LABEL (0xffff)
44 
45 typedef enum {
46 // define rules with a compile function
47 #define DEF_RULE(rule, comp, kind, ...) PN_##rule,
48 #define DEF_RULE_NC(rule, kind, ...)
49 #include "py/grammar.h"
50 #undef DEF_RULE
51 #undef DEF_RULE_NC
52  PN_const_object, // special node for a constant, generic Python object
53 // define rules without a compile function
54 #define DEF_RULE(rule, comp, kind, ...)
55 #define DEF_RULE_NC(rule, kind, ...) PN_##rule,
56 #include "py/grammar.h"
57 #undef DEF_RULE
58 #undef DEF_RULE_NC
59 } pn_kind_t;
60 
61 #define NEED_METHOD_TABLE MICROPY_EMIT_NATIVE
62 
63 #if NEED_METHOD_TABLE
64 
65 // we need a method table to do the lookup for the emitter functions
66 #define EMIT(fun) (comp->emit_method_table->fun(comp->emit))
67 #define EMIT_ARG(fun, ...) (comp->emit_method_table->fun(comp->emit, __VA_ARGS__))
68 #define EMIT_LOAD_FAST(qst, local_num) (comp->emit_method_table->load_id.fast(comp->emit, qst, local_num))
69 #define EMIT_LOAD_GLOBAL(qst) (comp->emit_method_table->load_id.global(comp->emit, qst))
70 
71 #else
72 
73 // if we only have the bytecode emitter enabled then we can do a direct call to the functions
74 #define EMIT(fun) (mp_emit_bc_##fun(comp->emit))
75 #define EMIT_ARG(fun, ...) (mp_emit_bc_##fun(comp->emit, __VA_ARGS__))
76 #define EMIT_LOAD_FAST(qst, local_num) (mp_emit_bc_load_fast(comp->emit, qst, local_num))
77 #define EMIT_LOAD_GLOBAL(qst) (mp_emit_bc_load_global(comp->emit, qst))
78 
79 #endif
80 
81 #if MICROPY_EMIT_NATIVE
82 // define a macro to access external native emitter
83 #if MICROPY_EMIT_X64
84 #define NATIVE_EMITTER(f) emit_native_x64_##f
85 #elif MICROPY_EMIT_X86
86 #define NATIVE_EMITTER(f) emit_native_x86_##f
87 #elif MICROPY_EMIT_THUMB
88 #define NATIVE_EMITTER(f) emit_native_thumb_##f
89 #elif MICROPY_EMIT_ARM
90 #define NATIVE_EMITTER(f) emit_native_arm_##f
91 #elif MICROPY_EMIT_XTENSA
92 #define NATIVE_EMITTER(f) emit_native_xtensa_##f
93 #else
94 #error "unknown native emitter"
95 #endif
96 #endif
97 
98 #if MICROPY_EMIT_INLINE_ASM
99 // define macros for inline assembler
100 #if MICROPY_EMIT_INLINE_THUMB
101 #define ASM_DECORATOR_QSTR MP_QSTR_asm_thumb
102 #define ASM_EMITTER(f) emit_inline_thumb_##f
103 #elif MICROPY_EMIT_INLINE_XTENSA
104 #define ASM_DECORATOR_QSTR MP_QSTR_asm_xtensa
105 #define ASM_EMITTER(f) emit_inline_xtensa_##f
106 #else
107 #error "unknown asm emitter"
108 #endif
109 #endif
110 
111 #define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
112 #define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
113 
114 // elements in this struct are ordered to make it compact
115 typedef struct _compiler_t {
116  qstr source_file;
117 
118  uint8_t is_repl;
119  uint8_t pass; // holds enum type pass_kind_t
120  uint8_t have_star;
121 
122  // try to keep compiler clean from nlr
123  mp_obj_t compile_error; // set to an exception object if there's an error
124  size_t compile_error_line; // set to best guess of line of error
125 
126  uint next_label;
127 
128  uint16_t num_dict_params;
129  uint16_t num_default_params;
130 
131  uint16_t break_label; // highest bit set indicates we are breaking out of a for loop
132  uint16_t continue_label;
133  uint16_t cur_except_level; // increased for SETUP_EXCEPT, SETUP_FINALLY; decreased for POP_BLOCK, POP_EXCEPT
134  uint16_t break_continue_except_level;
135 
136  scope_t *scope_head;
137  scope_t *scope_cur;
138 
139  emit_t *emit; // current emitter
140  #if NEED_METHOD_TABLE
141  const emit_method_table_t *emit_method_table; // current emit method table
142  #endif
143 
144  #if MICROPY_EMIT_INLINE_ASM
145  emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
146  const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm
147  #endif
148 } compiler_t;
149 
150 STATIC void compile_error_set_line(compiler_t *comp, mp_parse_node_t pn) {
151  // if the line of the error is unknown then try to update it from the pn
152  if (comp->compile_error_line == 0 && MP_PARSE_NODE_IS_STRUCT(pn)) {
153  comp->compile_error_line = ((mp_parse_node_struct_t*)pn)->source_line;
154  }
155 }
156 
157 STATIC void compile_syntax_error(compiler_t *comp, mp_parse_node_t pn, const char *msg) {
158  // only register the error if there has been no other error
159  if (comp->compile_error == MP_OBJ_NULL) {
160  comp->compile_error = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg);
161  compile_error_set_line(comp, pn);
162  }
163 }
164 
165 STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_arglist, bool is_method_call, int n_positional_extra);
166 STATIC void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_kind_t kind);
167 STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn);
168 
169 STATIC uint comp_next_label(compiler_t *comp) {
170  return comp->next_label++;
171 }
172 
173 STATIC void compile_increase_except_level(compiler_t *comp) {
174  comp->cur_except_level += 1;
175  if (comp->cur_except_level > comp->scope_cur->exc_stack_size) {
176  comp->scope_cur->exc_stack_size = comp->cur_except_level;
177  }
178 }
179 
180 STATIC void compile_decrease_except_level(compiler_t *comp) {
181  assert(comp->cur_except_level > 0);
182  comp->cur_except_level -= 1;
183 }
184 
185 STATIC scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) {
186  scope_t *scope = scope_new(kind, pn, comp->source_file, emit_options);
187  scope->parent = comp->scope_cur;
188  scope->next = NULL;
189  if (comp->scope_head == NULL) {
190  comp->scope_head = scope;
191  } else {
192  scope_t *s = comp->scope_head;
193  while (s->next != NULL) {
194  s = s->next;
195  }
196  s->next = scope;
197  }
198  return scope;
199 }
200 
201 typedef void (*apply_list_fun_t)(compiler_t *comp, mp_parse_node_t pn);
202 
203 STATIC void apply_to_single_or_list(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_list_kind, apply_list_fun_t f) {
204  if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, pn_list_kind)) {
206  int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
207  for (int i = 0; i < num_nodes; i++) {
208  f(comp, pns->nodes[i]);
209  }
210  } else if (!MP_PARSE_NODE_IS_NULL(pn)) {
211  f(comp, pn);
212  }
213 }
214 
215 STATIC void compile_generic_all_nodes(compiler_t *comp, mp_parse_node_struct_t *pns) {
216  int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
217  for (int i = 0; i < num_nodes; i++) {
218  compile_node(comp, pns->nodes[i]);
219  if (comp->compile_error != MP_OBJ_NULL) {
220  // add line info for the error in case it didn't have a line number
221  compile_error_set_line(comp, pns->nodes[i]);
222  return;
223  }
224  }
225 }
226 
227 STATIC void compile_load_id(compiler_t *comp, qstr qst) {
228  if (comp->pass == MP_PASS_SCOPE) {
229  mp_emit_common_get_id_for_load(comp->scope_cur, qst);
230  } else {
231  #if NEED_METHOD_TABLE
232  mp_emit_common_id_op(comp->emit, &comp->emit_method_table->load_id, comp->scope_cur, qst);
233  #else
234  mp_emit_common_id_op(comp->emit, &mp_emit_bc_method_table_load_id_ops, comp->scope_cur, qst);
235  #endif
236  }
237 }
238 
239 STATIC void compile_store_id(compiler_t *comp, qstr qst) {
240  if (comp->pass == MP_PASS_SCOPE) {
241  mp_emit_common_get_id_for_modification(comp->scope_cur, qst);
242  } else {
243  #if NEED_METHOD_TABLE
244  mp_emit_common_id_op(comp->emit, &comp->emit_method_table->store_id, comp->scope_cur, qst);
245  #else
246  mp_emit_common_id_op(comp->emit, &mp_emit_bc_method_table_store_id_ops, comp->scope_cur, qst);
247  #endif
248  }
249 }
250 
251 STATIC void compile_delete_id(compiler_t *comp, qstr qst) {
252  if (comp->pass == MP_PASS_SCOPE) {
253  mp_emit_common_get_id_for_modification(comp->scope_cur, qst);
254  } else {
255  #if NEED_METHOD_TABLE
256  mp_emit_common_id_op(comp->emit, &comp->emit_method_table->delete_id, comp->scope_cur, qst);
257  #else
258  mp_emit_common_id_op(comp->emit, &mp_emit_bc_method_table_delete_id_ops, comp->scope_cur, qst);
259  #endif
260  }
261 }
262 
263 STATIC void c_tuple(compiler_t *comp, mp_parse_node_t pn, mp_parse_node_struct_t *pns_list) {
264  int total = 0;
265  if (!MP_PARSE_NODE_IS_NULL(pn)) {
266  compile_node(comp, pn);
267  total += 1;
268  }
269  if (pns_list != NULL) {
270  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
271  for (int i = 0; i < n; i++) {
272  compile_node(comp, pns_list->nodes[i]);
273  }
274  total += n;
275  }
276  EMIT_ARG(build_tuple, total);
277 }
278 
279 STATIC void compile_generic_tuple(compiler_t *comp, mp_parse_node_struct_t *pns) {
280  // a simple tuple expression
281  c_tuple(comp, MP_PARSE_NODE_NULL, pns);
282 }
283 
284 STATIC void c_if_cond(compiler_t *comp, mp_parse_node_t pn, bool jump_if, int label) {
286  if (jump_if == false) {
287  EMIT_ARG(jump, label);
288  }
289  return;
290  } else if (mp_parse_node_is_const_true(pn)) {
291  if (jump_if == true) {
292  EMIT_ARG(jump, label);
293  }
294  return;
295  } else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
297  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
298  if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
299  if (jump_if == false) {
300  and_or_logic1:;
301  uint label2 = comp_next_label(comp);
302  for (int i = 0; i < n - 1; i++) {
303  c_if_cond(comp, pns->nodes[i], !jump_if, label2);
304  }
305  c_if_cond(comp, pns->nodes[n - 1], jump_if, label);
306  EMIT_ARG(label_assign, label2);
307  } else {
308  and_or_logic2:
309  for (int i = 0; i < n; i++) {
310  c_if_cond(comp, pns->nodes[i], jump_if, label);
311  }
312  }
313  return;
314  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
315  if (jump_if == false) {
316  goto and_or_logic2;
317  } else {
318  goto and_or_logic1;
319  }
320  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
321  c_if_cond(comp, pns->nodes[0], !jump_if, label);
322  return;
323  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_atom_paren) {
324  // cond is something in parenthesis
325  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
326  // empty tuple, acts as false for the condition
327  if (jump_if == false) {
328  EMIT_ARG(jump, label);
329  }
330  } else {
331  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp));
332  // non-empty tuple, acts as true for the condition
333  if (jump_if == true) {
334  EMIT_ARG(jump, label);
335  }
336  }
337  return;
338  }
339  }
340 
341  // nothing special, fall back to default compiling for node and jump
342  compile_node(comp, pn);
343  EMIT_ARG(pop_jump_if, jump_if, label);
344 }
345 
346 typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
347 STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t kind);
348 
349 STATIC void c_assign_atom_expr(compiler_t *comp, mp_parse_node_struct_t *pns, assign_kind_t assign_kind) {
350  if (assign_kind != ASSIGN_AUG_STORE) {
351  compile_node(comp, pns->nodes[0]);
352  }
353 
354  if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
356  if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_atom_expr_trailers) {
357  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1);
358  if (assign_kind != ASSIGN_AUG_STORE) {
359  for (int i = 0; i < n - 1; i++) {
360  compile_node(comp, pns1->nodes[i]);
361  }
362  }
363  assert(MP_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
364  pns1 = (mp_parse_node_struct_t*)pns1->nodes[n - 1];
365  }
366  if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
367  if (assign_kind == ASSIGN_AUG_STORE) {
368  EMIT(rot_three);
369  EMIT(store_subscr);
370  } else {
371  compile_node(comp, pns1->nodes[0]);
372  if (assign_kind == ASSIGN_AUG_LOAD) {
373  EMIT(dup_top_two);
374  EMIT(load_subscr);
375  } else {
376  EMIT(store_subscr);
377  }
378  }
379  } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
380  assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
381  if (assign_kind == ASSIGN_AUG_LOAD) {
382  EMIT(dup_top);
383  EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
384  } else {
385  if (assign_kind == ASSIGN_AUG_STORE) {
386  EMIT(rot_two);
387  }
388  EMIT_ARG(store_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
389  }
390  } else {
391  goto cannot_assign;
392  }
393  } else {
394  goto cannot_assign;
395  }
396 
397  return;
398 
399 cannot_assign:
400  compile_syntax_error(comp, (mp_parse_node_t)pns, "can't assign to expression");
401 }
402 
403 // we need to allow for a caller passing in 1 initial node (node_head) followed by an array of nodes (nodes_tail)
404 STATIC void c_assign_tuple(compiler_t *comp, mp_parse_node_t node_head, uint num_tail, mp_parse_node_t *nodes_tail) {
405  uint num_head = (node_head == MP_PARSE_NODE_NULL) ? 0 : 1;
406 
407  // look for star expression
408  uint have_star_index = -1;
409  if (num_head != 0 && MP_PARSE_NODE_IS_STRUCT_KIND(node_head, PN_star_expr)) {
410  EMIT_ARG(unpack_ex, 0, num_tail);
411  have_star_index = 0;
412  }
413  for (uint i = 0; i < num_tail; i++) {
414  if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes_tail[i], PN_star_expr)) {
415  if (have_star_index == (uint)-1) {
416  EMIT_ARG(unpack_ex, num_head + i, num_tail - i - 1);
417  have_star_index = num_head + i;
418  } else {
419  compile_syntax_error(comp, nodes_tail[i], "multiple *x in assignment");
420  return;
421  }
422  }
423  }
424  if (have_star_index == (uint)-1) {
425  EMIT_ARG(unpack_sequence, num_head + num_tail);
426  }
427  if (num_head != 0) {
428  if (0 == have_star_index) {
429  c_assign(comp, ((mp_parse_node_struct_t*)node_head)->nodes[0], ASSIGN_STORE);
430  } else {
431  c_assign(comp, node_head, ASSIGN_STORE);
432  }
433  }
434  for (uint i = 0; i < num_tail; i++) {
435  if (num_head + i == have_star_index) {
436  c_assign(comp, ((mp_parse_node_struct_t*)nodes_tail[i])->nodes[0], ASSIGN_STORE);
437  } else {
438  c_assign(comp, nodes_tail[i], ASSIGN_STORE);
439  }
440  }
441 }
442 
443 // assigns top of stack to pn
444 STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) {
446  if (MP_PARSE_NODE_IS_LEAF(pn)) {
447  if (MP_PARSE_NODE_IS_ID(pn)) {
448  qstr arg = MP_PARSE_NODE_LEAF_ARG(pn);
449  switch (assign_kind) {
450  case ASSIGN_STORE:
451  case ASSIGN_AUG_STORE:
452  compile_store_id(comp, arg);
453  break;
454  case ASSIGN_AUG_LOAD:
455  default:
456  compile_load_id(comp, arg);
457  break;
458  }
459  } else {
460  goto cannot_assign;
461  }
462  } else {
463  // pn must be a struct
465  switch (MP_PARSE_NODE_STRUCT_KIND(pns)) {
466  case PN_atom_expr_normal:
467  // lhs is an index or attribute
468  c_assign_atom_expr(comp, pns, assign_kind);
469  break;
470 
471  case PN_testlist_star_expr:
472  case PN_exprlist:
473  // lhs is a tuple
474  if (assign_kind != ASSIGN_STORE) {
475  goto cannot_assign;
476  }
477  c_assign_tuple(comp, MP_PARSE_NODE_NULL, MP_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
478  break;
479 
480  case PN_atom_paren:
481  // lhs is something in parenthesis
482  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
483  // empty tuple
484  goto cannot_assign;
485  } else {
486  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp));
487  if (assign_kind != ASSIGN_STORE) {
488  goto cannot_assign;
489  }
490  pns = (mp_parse_node_struct_t*)pns->nodes[0];
491  goto testlist_comp;
492  }
493  break;
494 
495  case PN_atom_bracket:
496  // lhs is something in brackets
497  if (assign_kind != ASSIGN_STORE) {
498  goto cannot_assign;
499  }
500  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
501  // empty list, assignment allowed
502  c_assign_tuple(comp, MP_PARSE_NODE_NULL, 0, NULL);
503  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
504  pns = (mp_parse_node_struct_t*)pns->nodes[0];
505  goto testlist_comp;
506  } else {
507  // brackets around 1 item
508  c_assign_tuple(comp, pns->nodes[0], 0, NULL);
509  }
510  break;
511 
512  default:
513  goto cannot_assign;
514  }
515  return;
516 
517  testlist_comp:
518  // lhs is a sequence
519  if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
521  if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
522  // sequence of one item, with trailing comma
524  c_assign_tuple(comp, pns->nodes[0], 0, NULL);
525  } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
526  // sequence of many items
528  c_assign_tuple(comp, pns->nodes[0], n, pns2->nodes);
529  } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
530  goto cannot_assign;
531  } else {
532  // sequence with 2 items
533  goto sequence_with_2_items;
534  }
535  } else {
536  // sequence with 2 items
537  sequence_with_2_items:
538  c_assign_tuple(comp, MP_PARSE_NODE_NULL, 2, pns->nodes);
539  }
540  return;
541  }
542  return;
543 
544  cannot_assign:
545  compile_syntax_error(comp, pn, "can't assign to expression");
546 }
547 
548 // stuff for lambda and comprehensions and generators:
549 // if n_pos_defaults > 0 then there is a tuple on the stack with the positional defaults
550 // if n_kw_defaults > 0 then there is a dictionary on the stack with the keyword defaults
551 // if both exist, the tuple is above the dictionary (ie the first pop gets the tuple)
552 STATIC void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_pos_defaults, int n_kw_defaults) {
553  assert(n_pos_defaults >= 0);
554  assert(n_kw_defaults >= 0);
555 
556  // set flags
557  if (n_kw_defaults > 0) {
558  this_scope->scope_flags |= MP_SCOPE_FLAG_DEFKWARGS;
559  }
560  this_scope->num_def_pos_args = n_pos_defaults;
561 
562  // make closed over variables, if any
563  // ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython)
564  int nfree = 0;
565  if (comp->scope_cur->kind != SCOPE_MODULE) {
566  for (int i = 0; i < comp->scope_cur->id_info_len; i++) {
567  id_info_t *id = &comp->scope_cur->id_info[i];
568  if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
569  for (int j = 0; j < this_scope->id_info_len; j++) {
570  id_info_t *id2 = &this_scope->id_info[j];
571  if (id2->kind == ID_INFO_KIND_FREE && id->qst == id2->qst) {
572  // in MicroPython we load closures using LOAD_FAST
573  EMIT_LOAD_FAST(id->qst, id->local_num);
574  nfree += 1;
575  }
576  }
577  }
578  }
579  }
580 
581  // make the function/closure
582  if (nfree == 0) {
583  EMIT_ARG(make_function, this_scope, n_pos_defaults, n_kw_defaults);
584  } else {
585  EMIT_ARG(make_closure, this_scope, nfree, n_pos_defaults, n_kw_defaults);
586  }
587 }
588 
589 STATIC void compile_funcdef_lambdef_param(compiler_t *comp, mp_parse_node_t pn) {
590  // For efficiency of the code below we extract the parse-node kind here
591  int pn_kind;
592  if (MP_PARSE_NODE_IS_ID(pn)) {
593  pn_kind = -1;
594  } else {
597  }
598 
599  if (pn_kind == PN_typedargslist_star || pn_kind == PN_varargslist_star) {
600  comp->have_star = true;
601  /* don't need to distinguish bare from named star
602  mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
603  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
604  // bare star
605  } else {
606  // named star
607  }
608  */
609 
610  } else if (pn_kind == PN_typedargslist_dbl_star || pn_kind == PN_varargslist_dbl_star) {
611  // named double star
612  // TODO do we need to do anything with this?
613 
614  } else {
615  mp_parse_node_t pn_id;
616  mp_parse_node_t pn_equal;
617  if (pn_kind == -1) {
618  // this parameter is just an id
619 
620  pn_id = pn;
621  pn_equal = MP_PARSE_NODE_NULL;
622 
623  } else if (pn_kind == PN_typedargslist_name) {
624  // this parameter has a colon and/or equal specifier
625 
627  pn_id = pns->nodes[0];
628  //pn_colon = pns->nodes[1]; // unused
629  pn_equal = pns->nodes[2];
630 
631  } else {
632  assert(pn_kind == PN_varargslist_name); // should be
633  // this parameter has an equal specifier
634 
636  pn_id = pns->nodes[0];
637  pn_equal = pns->nodes[1];
638  }
639 
640  if (MP_PARSE_NODE_IS_NULL(pn_equal)) {
641  // this parameter does not have a default value
642 
643  // check for non-default parameters given after default parameters (allowed by parser, but not syntactically valid)
644  if (!comp->have_star && comp->num_default_params != 0) {
645  compile_syntax_error(comp, pn, "non-default argument follows default argument");
646  return;
647  }
648 
649  } else {
650  // this parameter has a default value
651  // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
652 
653  if (comp->have_star) {
654  comp->num_dict_params += 1;
655  // in MicroPython we put the default dict parameters into a dictionary using the bytecode
656  if (comp->num_dict_params == 1) {
657  // in MicroPython we put the default positional parameters into a tuple using the bytecode
658  // we need to do this here before we start building the map for the default keywords
659  if (comp->num_default_params > 0) {
660  EMIT_ARG(build_tuple, comp->num_default_params);
661  } else {
662  EMIT(load_null); // sentinel indicating empty default positional args
663  }
664  // first default dict param, so make the map
665  EMIT_ARG(build_map, 0);
666  }
667 
668  // compile value then key, then store it to the dict
669  compile_node(comp, pn_equal);
670  EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pn_id));
671  EMIT(store_map);
672  } else {
673  comp->num_default_params += 1;
674  compile_node(comp, pn_equal);
675  }
676  }
677  }
678 }
679 
680 STATIC void compile_funcdef_lambdef(compiler_t *comp, scope_t *scope, mp_parse_node_t pn_params, pn_kind_t pn_list_kind) {
681  // When we call compile_funcdef_lambdef_param below it can compile an arbitrary
682  // expression for default arguments, which may contain a lambda. The lambda will
683  // call here in a nested way, so we must save and restore the relevant state.
684  bool orig_have_star = comp->have_star;
685  uint16_t orig_num_dict_params = comp->num_dict_params;
686  uint16_t orig_num_default_params = comp->num_default_params;
687 
688  // compile default parameters
689  comp->have_star = false;
690  comp->num_dict_params = 0;
691  comp->num_default_params = 0;
692  apply_to_single_or_list(comp, pn_params, pn_list_kind, compile_funcdef_lambdef_param);
693 
694  if (comp->compile_error != MP_OBJ_NULL) {
695  return;
696  }
697 
698  // in MicroPython we put the default positional parameters into a tuple using the bytecode
699  // the default keywords args may have already made the tuple; if not, do it now
700  if (comp->num_default_params > 0 && comp->num_dict_params == 0) {
701  EMIT_ARG(build_tuple, comp->num_default_params);
702  EMIT(load_null); // sentinel indicating empty default keyword args
703  }
704 
705  // make the function
706  close_over_variables_etc(comp, scope, comp->num_default_params, comp->num_dict_params);
707 
708  // restore state
709  comp->have_star = orig_have_star;
710  comp->num_dict_params = orig_num_dict_params;
711  comp->num_default_params = orig_num_default_params;
712 }
713 
714 // leaves function object on stack
715 // returns function name
716 STATIC qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
717  if (comp->pass == MP_PASS_SCOPE) {
718  // create a new scope for this function
719  scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options);
720  // store the function scope so the compiling function can use it at each pass
721  pns->nodes[4] = (mp_parse_node_t)s;
722  }
723 
724  // get the scope for this function
725  scope_t *fscope = (scope_t*)pns->nodes[4];
726 
727  // compile the function definition
728  compile_funcdef_lambdef(comp, fscope, pns->nodes[1], PN_typedargslist);
729 
730  // return its name (the 'f' in "def f(...):")
731  return fscope->simple_name;
732 }
733 
734 // leaves class object on stack
735 // returns class name
736 STATIC qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
737  if (comp->pass == MP_PASS_SCOPE) {
738  // create a new scope for this class
739  scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (mp_parse_node_t)pns, emit_options);
740  // store the class scope so the compiling function can use it at each pass
741  pns->nodes[3] = (mp_parse_node_t)s;
742  }
743 
744  EMIT(load_build_class);
745 
746  // scope for this class
747  scope_t *cscope = (scope_t*)pns->nodes[3];
748 
749  // compile the class
750  close_over_variables_etc(comp, cscope, 0, 0);
751 
752  // get its name
753  EMIT_ARG(load_const_str, cscope->simple_name);
754 
755  // nodes[1] has parent classes, if any
756  // empty parenthesis (eg class C():) gets here as an empty PN_classdef_2 and needs special handling
757  mp_parse_node_t parents = pns->nodes[1];
758  if (MP_PARSE_NODE_IS_STRUCT_KIND(parents, PN_classdef_2)) {
759  parents = MP_PARSE_NODE_NULL;
760  }
761  compile_trailer_paren_helper(comp, parents, false, 2);
762 
763  // return its name (the 'C' in class C(...):")
764  return cscope->simple_name;
765 }
766 
767 // returns true if it was a built-in decorator (even if the built-in had an error)
768 STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_node_t *name_nodes, uint *emit_options) {
769  if (MP_PARSE_NODE_LEAF_ARG(name_nodes[0]) != MP_QSTR_micropython) {
770  return false;
771  }
772 
773  if (name_len != 2) {
774  compile_syntax_error(comp, name_nodes[0], "invalid micropython decorator");
775  return true;
776  }
777 
778  qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
779  if (attr == MP_QSTR_bytecode) {
780  *emit_options = MP_EMIT_OPT_BYTECODE;
781 #if MICROPY_EMIT_NATIVE
782  } else if (attr == MP_QSTR_native) {
783  *emit_options = MP_EMIT_OPT_NATIVE_PYTHON;
784  } else if (attr == MP_QSTR_viper) {
785  *emit_options = MP_EMIT_OPT_VIPER;
786 #endif
787  #if MICROPY_EMIT_INLINE_ASM
788  } else if (attr == ASM_DECORATOR_QSTR) {
789  *emit_options = MP_EMIT_OPT_ASM;
790  #endif
791  } else {
792  compile_syntax_error(comp, name_nodes[1], "invalid micropython decorator");
793  }
794 
795  return true;
796 }
797 
798 STATIC void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
799  // get the list of decorators
800  mp_parse_node_t *nodes;
801  int n = mp_parse_node_extract_list(&pns->nodes[0], PN_decorators, &nodes);
802 
803  // inherit emit options for this function/class definition
804  uint emit_options = comp->scope_cur->emit_options;
805 
806  // compile each decorator
807  int num_built_in_decorators = 0;
808  for (int i = 0; i < n; i++) {
809  assert(MP_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
810  mp_parse_node_struct_t *pns_decorator = (mp_parse_node_struct_t*)nodes[i];
811 
812  // nodes[0] contains the decorator function, which is a dotted name
813  mp_parse_node_t *name_nodes;
814  int name_len = mp_parse_node_extract_list(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
815 
816  // check for built-in decorators
817  if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
818  // this was a built-in
819  num_built_in_decorators += 1;
820 
821  } else {
822  // not a built-in, compile normally
823 
824  // compile the decorator function
825  compile_node(comp, name_nodes[0]);
826  for (int j = 1; j < name_len; j++) {
827  assert(MP_PARSE_NODE_IS_ID(name_nodes[j])); // should be
828  EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(name_nodes[j]));
829  }
830 
831  // nodes[1] contains arguments to the decorator function, if any
832  if (!MP_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
833  // call the decorator function with the arguments in nodes[1]
834  compile_node(comp, pns_decorator->nodes[1]);
835  }
836  }
837  }
838 
839  // compile the body (funcdef, async funcdef or classdef) and get its name
841  qstr body_name = 0;
842  if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
843  body_name = compile_funcdef_helper(comp, pns_body, emit_options);
844  #if MICROPY_PY_ASYNC_AWAIT
845  } else if (MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_async_funcdef) {
846  assert(MP_PARSE_NODE_IS_STRUCT(pns_body->nodes[0]));
847  mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t*)pns_body->nodes[0];
848  body_name = compile_funcdef_helper(comp, pns0, emit_options);
849  scope_t *fscope = (scope_t*)pns0->nodes[4];
851  #endif
852  } else {
853  assert(MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef); // should be
854  body_name = compile_classdef_helper(comp, pns_body, emit_options);
855  }
856 
857  // call each decorator
858  for (int i = 0; i < n - num_built_in_decorators; i++) {
859  EMIT_ARG(call_function, 1, 0, 0);
860  }
861 
862  // store func/class object into name
863  compile_store_id(comp, body_name);
864 }
865 
866 STATIC void compile_funcdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
867  qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
868  // store function object into function name
869  compile_store_id(comp, fname);
870 }
871 
872 STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
873  if (MP_PARSE_NODE_IS_ID(pn)) {
874  compile_delete_id(comp, MP_PARSE_NODE_LEAF_ARG(pn));
875  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_expr_normal)) {
877 
878  compile_node(comp, pns->nodes[0]); // base of the atom_expr_normal node
879 
880  if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
882  if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_atom_expr_trailers) {
883  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1);
884  for (int i = 0; i < n - 1; i++) {
885  compile_node(comp, pns1->nodes[i]);
886  }
887  assert(MP_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
888  pns1 = (mp_parse_node_struct_t*)pns1->nodes[n - 1];
889  }
890  if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
891  compile_node(comp, pns1->nodes[0]);
892  EMIT(delete_subscr);
893  } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
894  assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
895  EMIT_ARG(delete_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
896  } else {
897  goto cannot_delete;
898  }
899  } else {
900  goto cannot_delete;
901  }
902 
903  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
904  pn = ((mp_parse_node_struct_t*)pn)->nodes[0];
905  if (MP_PARSE_NODE_IS_NULL(pn)) {
906  goto cannot_delete;
907  } else {
908  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp));
910  // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
911 
912  if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
914  if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
915  // sequence of one item, with trailing comma
917  c_del_stmt(comp, pns->nodes[0]);
918  } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
919  // sequence of many items
920  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1);
921  c_del_stmt(comp, pns->nodes[0]);
922  for (int i = 0; i < n; i++) {
923  c_del_stmt(comp, pns1->nodes[i]);
924  }
925  } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
926  goto cannot_delete;
927  } else {
928  // sequence with 2 items
929  goto sequence_with_2_items;
930  }
931  } else {
932  // sequence with 2 items
933  sequence_with_2_items:
934  c_del_stmt(comp, pns->nodes[0]);
935  c_del_stmt(comp, pns->nodes[1]);
936  }
937  }
938  } else {
939  // some arbitrary statement that we can't delete (eg del 1)
940  goto cannot_delete;
941  }
942 
943  return;
944 
945 cannot_delete:
946  compile_syntax_error(comp, (mp_parse_node_t)pn, "can't delete expression");
947 }
948 
949 STATIC void compile_del_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
950  apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
951 }
952 
953 STATIC void compile_break_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
954  if (comp->break_label == INVALID_LABEL) {
955  compile_syntax_error(comp, (mp_parse_node_t)pns, "'break' outside loop");
956  }
957  assert(comp->cur_except_level >= comp->break_continue_except_level);
958  EMIT_ARG(break_loop, comp->break_label, comp->cur_except_level - comp->break_continue_except_level);
959 }
960 
961 STATIC void compile_continue_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
962  if (comp->continue_label == INVALID_LABEL) {
963  compile_syntax_error(comp, (mp_parse_node_t)pns, "'continue' outside loop");
964  }
965  assert(comp->cur_except_level >= comp->break_continue_except_level);
966  EMIT_ARG(continue_loop, comp->continue_label, comp->cur_except_level - comp->break_continue_except_level);
967 }
968 
969 STATIC void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
970  if (comp->scope_cur->kind != SCOPE_FUNCTION) {
971  compile_syntax_error(comp, (mp_parse_node_t)pns, "'return' outside function");
972  return;
973  }
974  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
975  // no argument to 'return', so return None
976  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
977  } else if (MICROPY_COMP_RETURN_IF_EXPR
978  && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
979  // special case when returning an if-expression; to match CPython optimisation
980  mp_parse_node_struct_t *pns_test_if_expr = (mp_parse_node_struct_t*)pns->nodes[0];
981  mp_parse_node_struct_t *pns_test_if_else = (mp_parse_node_struct_t*)pns_test_if_expr->nodes[1];
982 
983  uint l_fail = comp_next_label(comp);
984  c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
985  compile_node(comp, pns_test_if_expr->nodes[0]); // success value
986  EMIT(return_value);
987  EMIT_ARG(label_assign, l_fail);
988  compile_node(comp, pns_test_if_else->nodes[1]); // failure value
989  } else {
990  compile_node(comp, pns->nodes[0]);
991  }
992  EMIT(return_value);
993 }
994 
995 STATIC void compile_yield_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
996  compile_node(comp, pns->nodes[0]);
997  EMIT(pop_top);
998 }
999 
1000 STATIC void compile_raise_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1001  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1002  // raise
1003  EMIT_ARG(raise_varargs, 0);
1004  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1005  // raise x from y
1006  pns = (mp_parse_node_struct_t*)pns->nodes[0];
1007  compile_node(comp, pns->nodes[0]);
1008  compile_node(comp, pns->nodes[1]);
1009  EMIT_ARG(raise_varargs, 2);
1010  } else {
1011  // raise x
1012  compile_node(comp, pns->nodes[0]);
1013  EMIT_ARG(raise_varargs, 1);
1014  }
1015 }
1016 
1017 // q_base holds the base of the name
1018 // eg a -> q_base=a
1019 // a.b.c -> q_base=a
1020 STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
1021  bool is_as = false;
1022  if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1024  // a name of the form x as y; unwrap it
1025  *q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1026  pn = pns->nodes[0];
1027  is_as = true;
1028  }
1029  if (MP_PARSE_NODE_IS_NULL(pn)) {
1030  // empty name (eg, from . import x)
1031  *q_base = MP_QSTR_;
1032  EMIT_ARG(import_name, MP_QSTR_); // import the empty string
1033  } else if (MP_PARSE_NODE_IS_ID(pn)) {
1034  // just a simple name
1035  qstr q_full = MP_PARSE_NODE_LEAF_ARG(pn);
1036  if (!is_as) {
1037  *q_base = q_full;
1038  }
1039  EMIT_ARG(import_name, q_full);
1040  } else {
1041  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_name)); // should be
1043  {
1044  // a name of the form a.b.c
1045  if (!is_as) {
1046  *q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1047  }
1048  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
1049  int len = n - 1;
1050  for (int i = 0; i < n; i++) {
1051  len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1052  }
1053  byte *q_ptr;
1054  byte *str_dest = qstr_build_start(len, &q_ptr);
1055  for (int i = 0; i < n; i++) {
1056  if (i > 0) {
1057  *str_dest++ = '.';
1058  }
1059  size_t str_src_len;
1060  const byte *str_src = qstr_data(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]), &str_src_len);
1061  memcpy(str_dest, str_src, str_src_len);
1062  str_dest += str_src_len;
1063  }
1064  qstr q_full = qstr_build_end(q_ptr);
1065  EMIT_ARG(import_name, q_full);
1066  if (is_as) {
1067  for (int i = 1; i < n; i++) {
1068  EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1069  }
1070  }
1071  }
1072  }
1073 }
1074 
1075 STATIC void compile_dotted_as_name(compiler_t *comp, mp_parse_node_t pn) {
1076  EMIT_ARG(load_const_small_int, 0); // level 0 import
1077  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); // not importing from anything
1078  qstr q_base;
1079  do_import_name(comp, pn, &q_base);
1080  compile_store_id(comp, q_base);
1081 }
1082 
1083 STATIC void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) {
1084  apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1085 }
1086 
1087 STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
1088  mp_parse_node_t pn_import_source = pns->nodes[0];
1089 
1090  // extract the preceding .'s (if any) for a relative import, to compute the import level
1091  uint import_level = 0;
1092  do {
1093  mp_parse_node_t pn_rel;
1094  if (MP_PARSE_NODE_IS_TOKEN(pn_import_source) || MP_PARSE_NODE_IS_STRUCT_KIND(pn_import_source, PN_one_or_more_period_or_ellipsis)) {
1095  // This covers relative imports with dots only like "from .. import"
1096  pn_rel = pn_import_source;
1097  pn_import_source = MP_PARSE_NODE_NULL;
1098  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_import_source, PN_import_from_2b)) {
1099  // This covers relative imports starting with dot(s) like "from .foo import"
1100  mp_parse_node_struct_t *pns_2b = (mp_parse_node_struct_t*)pn_import_source;
1101  pn_rel = pns_2b->nodes[0];
1102  pn_import_source = pns_2b->nodes[1];
1103  assert(!MP_PARSE_NODE_IS_NULL(pn_import_source)); // should not be
1104  } else {
1105  // Not a relative import
1106  break;
1107  }
1108 
1109  // get the list of . and/or ...'s
1110  mp_parse_node_t *nodes;
1111  int n = mp_parse_node_extract_list(&pn_rel, PN_one_or_more_period_or_ellipsis, &nodes);
1112 
1113  // count the total number of .'s
1114  for (int i = 0; i < n; i++) {
1116  import_level++;
1117  } else {
1118  // should be an MP_TOKEN_ELLIPSIS
1119  import_level += 3;
1120  }
1121  }
1122  } while (0);
1123 
1125  EMIT_ARG(load_const_small_int, import_level);
1126 
1127  // build the "fromlist" tuple
1128  EMIT_ARG(load_const_str, MP_QSTR__star_);
1129  EMIT_ARG(build_tuple, 1);
1130 
1131  // do the import
1132  qstr dummy_q;
1133  do_import_name(comp, pn_import_source, &dummy_q);
1134  EMIT(import_star);
1135 
1136  } else {
1137  EMIT_ARG(load_const_small_int, import_level);
1138 
1139  // build the "fromlist" tuple
1140  mp_parse_node_t *pn_nodes;
1141  int n = mp_parse_node_extract_list(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1142  for (int i = 0; i < n; i++) {
1143  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1144  mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pn_nodes[i];
1145  qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1146  EMIT_ARG(load_const_str, id2);
1147  }
1148  EMIT_ARG(build_tuple, n);
1149 
1150  // do the import
1151  qstr dummy_q;
1152  do_import_name(comp, pn_import_source, &dummy_q);
1153  for (int i = 0; i < n; i++) {
1154  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1155  mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pn_nodes[i];
1156  qstr id2 = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1157  EMIT_ARG(import_from, id2);
1158  if (MP_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
1159  compile_store_id(comp, id2);
1160  } else {
1161  compile_store_id(comp, MP_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
1162  }
1163  }
1164  EMIT(pop_top);
1165  }
1166 }
1167 
1168 STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qst) {
1169  bool added;
1170  id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
1171  if (!added && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) {
1172  compile_syntax_error(comp, pn, "identifier redefined as global");
1173  return;
1174  }
1176 
1177  // if the id exists in the global scope, set its kind to EXPLICIT_GLOBAL
1178  id_info = scope_find_global(comp->scope_cur, qst);
1179  if (id_info != NULL) {
1181  }
1182 }
1183 
1184 STATIC void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1185  if (comp->pass == MP_PASS_SCOPE) {
1186  mp_parse_node_t *nodes;
1187  int n = mp_parse_node_extract_list(&pns->nodes[0], PN_name_list, &nodes);
1188  for (int i = 0; i < n; i++) {
1189  compile_declare_global(comp, (mp_parse_node_t)pns, MP_PARSE_NODE_LEAF_ARG(nodes[i]));
1190  }
1191  }
1192 }
1193 
1194 STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr qst) {
1195  bool added;
1196  id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
1197  if (added) {
1198  scope_find_local_and_close_over(comp->scope_cur, id_info, qst);
1199  if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
1200  compile_syntax_error(comp, pn, "no binding for nonlocal found");
1201  }
1202  } else if (id_info->kind != ID_INFO_KIND_FREE) {
1203  compile_syntax_error(comp, pn, "identifier redefined as nonlocal");
1204  }
1205 }
1206 
1207 STATIC void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1208  if (comp->pass == MP_PASS_SCOPE) {
1209  if (comp->scope_cur->kind == SCOPE_MODULE) {
1210  compile_syntax_error(comp, (mp_parse_node_t)pns, "can't declare nonlocal in outer code");
1211  return;
1212  }
1213  mp_parse_node_t *nodes;
1214  int n = mp_parse_node_extract_list(&pns->nodes[0], PN_name_list, &nodes);
1215  for (int i = 0; i < n; i++) {
1216  compile_declare_nonlocal(comp, (mp_parse_node_t)pns, MP_PARSE_NODE_LEAF_ARG(nodes[i]));
1217  }
1218  }
1219 }
1220 
1221 STATIC void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1222  // with optimisations enabled we don't compile assertions
1223  if (MP_STATE_VM(mp_optimise_value) != 0) {
1224  return;
1225  }
1226 
1227  uint l_end = comp_next_label(comp);
1228  c_if_cond(comp, pns->nodes[0], true, l_end);
1229  EMIT_LOAD_GLOBAL(MP_QSTR_AssertionError); // we load_global instead of load_id, to be consistent with CPython
1230  if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1231  // assertion message
1232  compile_node(comp, pns->nodes[1]);
1233  EMIT_ARG(call_function, 1, 0, 0);
1234  }
1235  EMIT_ARG(raise_varargs, 1);
1236  EMIT_ARG(label_assign, l_end);
1237 }
1238 
1239 STATIC void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1240  uint l_end = comp_next_label(comp);
1241 
1242  // optimisation: don't emit anything when "if False"
1243  if (!mp_parse_node_is_const_false(pns->nodes[0])) {
1244  uint l_fail = comp_next_label(comp);
1245  c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1246 
1247  compile_node(comp, pns->nodes[1]); // if block
1248 
1249  // optimisation: skip everything else when "if True"
1250  if (mp_parse_node_is_const_true(pns->nodes[0])) {
1251  goto done;
1252  }
1253 
1254  if (
1255  // optimisation: don't jump over non-existent elif/else blocks
1256  !(MP_PARSE_NODE_IS_NULL(pns->nodes[2]) && MP_PARSE_NODE_IS_NULL(pns->nodes[3]))
1257  // optimisation: don't jump if last instruction was return
1258  && !EMIT(last_emit_was_return_value)
1259  ) {
1260  // jump over elif/else blocks
1261  EMIT_ARG(jump, l_end);
1262  }
1263 
1264  EMIT_ARG(label_assign, l_fail);
1265  }
1266 
1267  // compile elif blocks (if any)
1268  mp_parse_node_t *pn_elif;
1269  int n_elif = mp_parse_node_extract_list(&pns->nodes[2], PN_if_stmt_elif_list, &pn_elif);
1270  for (int i = 0; i < n_elif; i++) {
1271  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_elif[i], PN_if_stmt_elif)); // should be
1272  mp_parse_node_struct_t *pns_elif = (mp_parse_node_struct_t*)pn_elif[i];
1273 
1274  // optimisation: don't emit anything when "if False"
1275  if (!mp_parse_node_is_const_false(pns_elif->nodes[0])) {
1276  uint l_fail = comp_next_label(comp);
1277  c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1278 
1279  compile_node(comp, pns_elif->nodes[1]); // elif block
1280 
1281  // optimisation: skip everything else when "elif True"
1282  if (mp_parse_node_is_const_true(pns_elif->nodes[0])) {
1283  goto done;
1284  }
1285 
1286  // optimisation: don't jump if last instruction was return
1287  if (!EMIT(last_emit_was_return_value)) {
1288  EMIT_ARG(jump, l_end);
1289  }
1290  EMIT_ARG(label_assign, l_fail);
1291  }
1292  }
1293 
1294  // compile else block
1295  compile_node(comp, pns->nodes[3]); // can be null
1296 
1297 done:
1298  EMIT_ARG(label_assign, l_end);
1299 }
1300 
1301 #define START_BREAK_CONTINUE_BLOCK \
1302  uint16_t old_break_label = comp->break_label; \
1303  uint16_t old_continue_label = comp->continue_label; \
1304  uint16_t old_break_continue_except_level = comp->break_continue_except_level; \
1305  uint break_label = comp_next_label(comp); \
1306  uint continue_label = comp_next_label(comp); \
1307  comp->break_label = break_label; \
1308  comp->continue_label = continue_label; \
1309  comp->break_continue_except_level = comp->cur_except_level;
1310 
1311 #define END_BREAK_CONTINUE_BLOCK \
1312  comp->break_label = old_break_label; \
1313  comp->continue_label = old_continue_label; \
1314  comp->break_continue_except_level = old_break_continue_except_level;
1315 
1316 STATIC void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1317  START_BREAK_CONTINUE_BLOCK
1318 
1319  if (!mp_parse_node_is_const_false(pns->nodes[0])) { // optimisation: don't emit anything for "while False"
1320  uint top_label = comp_next_label(comp);
1321  if (!mp_parse_node_is_const_true(pns->nodes[0])) { // optimisation: don't jump to cond for "while True"
1322  EMIT_ARG(jump, continue_label);
1323  }
1324  EMIT_ARG(label_assign, top_label);
1325  compile_node(comp, pns->nodes[1]); // body
1326  EMIT_ARG(label_assign, continue_label);
1327  c_if_cond(comp, pns->nodes[0], true, top_label); // condition
1328  }
1329 
1330  // break/continue apply to outer loop (if any) in the else block
1331  END_BREAK_CONTINUE_BLOCK
1332 
1333  compile_node(comp, pns->nodes[2]); // else
1334 
1335  EMIT_ARG(label_assign, break_label);
1336 }
1337 
1338 // This function compiles an optimised for-loop of the form:
1339 // for <var> in range(<start>, <end>, <step>):
1340 // <body>
1341 // else:
1342 // <else>
1343 // <var> must be an identifier and <step> must be a small-int.
1344 //
1345 // Semantics of for-loop require:
1346 // - final failing value should not be stored in the loop variable
1347 // - if the loop never runs, the loop variable should never be assigned
1348 // - assignments to <var>, <end> or <step> in the body do not alter the loop
1349 // (<step> is a constant for us, so no need to worry about it changing)
1350 //
1351 // If <end> is a small-int, then the stack during the for-loop contains just
1352 // the current value of <var>. Otherwise, the stack contains <end> then the
1353 // current value of <var>.
1354 STATIC void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, mp_parse_node_t pn_start, mp_parse_node_t pn_end, mp_parse_node_t pn_step, mp_parse_node_t pn_body, mp_parse_node_t pn_else) {
1355  START_BREAK_CONTINUE_BLOCK
1356 
1357  uint top_label = comp_next_label(comp);
1358  uint entry_label = comp_next_label(comp);
1359 
1360  // put the end value on the stack if it's not a small-int constant
1361  bool end_on_stack = !MP_PARSE_NODE_IS_SMALL_INT(pn_end);
1362  if (end_on_stack) {
1363  compile_node(comp, pn_end);
1364  }
1365 
1366  // compile: start
1367  compile_node(comp, pn_start);
1368 
1369  EMIT_ARG(jump, entry_label);
1370  EMIT_ARG(label_assign, top_label);
1371 
1372  // duplicate next value and store it to var
1373  EMIT(dup_top);
1374  c_assign(comp, pn_var, ASSIGN_STORE);
1375 
1376  // compile body
1377  compile_node(comp, pn_body);
1378 
1379  EMIT_ARG(label_assign, continue_label);
1380 
1381  // compile: var + step
1382  compile_node(comp, pn_step);
1383  EMIT_ARG(binary_op, MP_BINARY_OP_INPLACE_ADD);
1384 
1385  EMIT_ARG(label_assign, entry_label);
1386 
1387  // compile: if var <cond> end: goto top
1388  if (end_on_stack) {
1389  EMIT(dup_top_two);
1390  EMIT(rot_two);
1391  } else {
1392  EMIT(dup_top);
1393  compile_node(comp, pn_end);
1394  }
1396  if (MP_PARSE_NODE_LEAF_SMALL_INT(pn_step) >= 0) {
1397  EMIT_ARG(binary_op, MP_BINARY_OP_LESS);
1398  } else {
1399  EMIT_ARG(binary_op, MP_BINARY_OP_MORE);
1400  }
1401  EMIT_ARG(pop_jump_if, true, top_label);
1402 
1403  // break/continue apply to outer loop (if any) in the else block
1404  END_BREAK_CONTINUE_BLOCK
1405 
1406  // Compile the else block. We must pop the iterator variables before
1407  // executing the else code because it may contain break/continue statements.
1408  uint end_label = 0;
1409  if (!MP_PARSE_NODE_IS_NULL(pn_else)) {
1410  // discard final value of "var", and possible "end" value
1411  EMIT(pop_top);
1412  if (end_on_stack) {
1413  EMIT(pop_top);
1414  }
1415  compile_node(comp, pn_else);
1416  end_label = comp_next_label(comp);
1417  EMIT_ARG(jump, end_label);
1418  EMIT_ARG(adjust_stack_size, 1 + end_on_stack);
1419  }
1420 
1421  EMIT_ARG(label_assign, break_label);
1422 
1423  // discard final value of var that failed the loop condition
1424  EMIT(pop_top);
1425 
1426  // discard <end> value if it's on the stack
1427  if (end_on_stack) {
1428  EMIT(pop_top);
1429  }
1430 
1431  if (!MP_PARSE_NODE_IS_NULL(pn_else)) {
1432  EMIT_ARG(label_assign, end_label);
1433  }
1434 }
1435 
1436 STATIC void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1437  // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
1438  // this is actually slower, but uses no heap memory
1439  // for viper it will be much, much faster
1440  if (/*comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_atom_expr_normal)) {
1442  if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0])
1443  && MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == MP_QSTR_range
1444  && MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)pns_it->nodes[1]) == PN_trailer_paren) {
1445  mp_parse_node_t pn_range_args = ((mp_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
1447  int n_args = mp_parse_node_extract_list(&pn_range_args, PN_arglist, &args);
1448  mp_parse_node_t pn_range_start;
1449  mp_parse_node_t pn_range_end;
1450  mp_parse_node_t pn_range_step;
1451  bool optimize = false;
1452  if (1 <= n_args && n_args <= 3) {
1453  optimize = true;
1454  if (n_args == 1) {
1455  pn_range_start = mp_parse_node_new_small_int(0);
1456  pn_range_end = args[0];
1457  pn_range_step = mp_parse_node_new_small_int(1);
1458  } else if (n_args == 2) {
1459  pn_range_start = args[0];
1460  pn_range_end = args[1];
1461  pn_range_step = mp_parse_node_new_small_int(1);
1462  } else {
1463  pn_range_start = args[0];
1464  pn_range_end = args[1];
1465  pn_range_step = args[2];
1466  // the step must be a non-zero constant integer to do the optimisation
1467  if (!MP_PARSE_NODE_IS_SMALL_INT(pn_range_step)
1468  || MP_PARSE_NODE_LEAF_SMALL_INT(pn_range_step) == 0) {
1469  optimize = false;
1470  }
1471  }
1472  // arguments must be able to be compiled as standard expressions
1473  if (optimize && MP_PARSE_NODE_IS_STRUCT(pn_range_start)) {
1474  int k = MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)pn_range_start);
1475  if (k == PN_arglist_star || k == PN_arglist_dbl_star || k == PN_argument) {
1476  optimize = false;
1477  }
1478  }
1479  if (optimize && MP_PARSE_NODE_IS_STRUCT(pn_range_end)) {
1480  int k = MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)pn_range_end);
1481  if (k == PN_arglist_star || k == PN_arglist_dbl_star || k == PN_argument) {
1482  optimize = false;
1483  }
1484  }
1485  }
1486  if (optimize) {
1487  compile_for_stmt_optimised_range(comp, pns->nodes[0], pn_range_start, pn_range_end, pn_range_step, pns->nodes[2], pns->nodes[3]);
1488  return;
1489  }
1490  }
1491  }
1492 
1493  START_BREAK_CONTINUE_BLOCK
1494  comp->break_label |= MP_EMIT_BREAK_FROM_FOR;
1495 
1496  uint pop_label = comp_next_label(comp);
1497 
1498  compile_node(comp, pns->nodes[1]); // iterator
1499  EMIT_ARG(get_iter, true);
1500  EMIT_ARG(label_assign, continue_label);
1501  EMIT_ARG(for_iter, pop_label);
1502  c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1503  compile_node(comp, pns->nodes[2]); // body
1504  if (!EMIT(last_emit_was_return_value)) {
1505  EMIT_ARG(jump, continue_label);
1506  }
1507  EMIT_ARG(label_assign, pop_label);
1508  EMIT(for_iter_end);
1509 
1510  // break/continue apply to outer loop (if any) in the else block
1511  END_BREAK_CONTINUE_BLOCK
1512 
1513  compile_node(comp, pns->nodes[3]); // else (may be empty)
1514 
1515  EMIT_ARG(label_assign, break_label);
1516 }
1517 
1518 STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_excepts, mp_parse_node_t pn_else) {
1519  // setup code
1520  uint l1 = comp_next_label(comp);
1521  uint success_label = comp_next_label(comp);
1522 
1523  EMIT_ARG(setup_except, l1);
1524  compile_increase_except_level(comp);
1525 
1526  compile_node(comp, pn_body); // body
1527  EMIT(pop_block);
1528  EMIT_ARG(jump, success_label); // jump over exception handler
1529 
1530  EMIT_ARG(label_assign, l1); // start of exception handler
1531  EMIT(start_except_handler);
1532 
1533  // at this point the top of the stack contains the exception instance that was raised
1534 
1535  uint l2 = comp_next_label(comp);
1536 
1537  for (int i = 0; i < n_except; i++) {
1538  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1539  mp_parse_node_struct_t *pns_except = (mp_parse_node_struct_t*)pn_excepts[i];
1540 
1541  qstr qstr_exception_local = 0;
1542  uint end_finally_label = comp_next_label(comp);
1543 
1544  if (MP_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1545  // this is a catch all exception handler
1546  if (i + 1 != n_except) {
1547  compile_syntax_error(comp, pn_excepts[i], "default 'except' must be last");
1548  compile_decrease_except_level(comp);
1549  return;
1550  }
1551  } else {
1552  // this exception handler requires a match to a certain type of exception
1553  mp_parse_node_t pns_exception_expr = pns_except->nodes[0];
1554  if (MP_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1555  mp_parse_node_struct_t *pns3 = (mp_parse_node_struct_t*)pns_exception_expr;
1556  if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1557  // handler binds the exception to a local
1558  pns_exception_expr = pns3->nodes[0];
1559  qstr_exception_local = MP_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1560  }
1561  }
1562  EMIT(dup_top);
1563  compile_node(comp, pns_exception_expr);
1564  EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH);
1565  EMIT_ARG(pop_jump_if, false, end_finally_label);
1566  }
1567 
1568  // either discard or store the exception instance
1569  if (qstr_exception_local == 0) {
1570  EMIT(pop_top);
1571  } else {
1572  compile_store_id(comp, qstr_exception_local);
1573  }
1574 
1575  uint l3 = 0;
1576  if (qstr_exception_local != 0) {
1577  l3 = comp_next_label(comp);
1578  EMIT_ARG(setup_finally, l3);
1579  compile_increase_except_level(comp);
1580  }
1581  compile_node(comp, pns_except->nodes[1]);
1582  if (qstr_exception_local != 0) {
1583  EMIT(pop_block);
1584  }
1585  EMIT(pop_except);
1586  if (qstr_exception_local != 0) {
1587  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
1588  EMIT_ARG(label_assign, l3);
1589  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
1590  compile_store_id(comp, qstr_exception_local);
1591  compile_delete_id(comp, qstr_exception_local);
1592 
1593  compile_decrease_except_level(comp);
1594  EMIT(end_finally);
1595  }
1596  EMIT_ARG(jump, l2);
1597  EMIT_ARG(label_assign, end_finally_label);
1598  EMIT_ARG(adjust_stack_size, 1); // stack adjust for the exception instance
1599  }
1600 
1601  compile_decrease_except_level(comp);
1602  EMIT(end_finally);
1603  EMIT(end_except_handler);
1604 
1605  EMIT_ARG(label_assign, success_label);
1606  compile_node(comp, pn_else); // else block, can be null
1607  EMIT_ARG(label_assign, l2);
1608 }
1609 
1610 STATIC void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_except, mp_parse_node_t pn_else, mp_parse_node_t pn_finally) {
1611  uint l_finally_block = comp_next_label(comp);
1612 
1613  EMIT_ARG(setup_finally, l_finally_block);
1614  compile_increase_except_level(comp);
1615 
1616  if (n_except == 0) {
1617  assert(MP_PARSE_NODE_IS_NULL(pn_else));
1618  EMIT_ARG(adjust_stack_size, 3); // stack adjust for possible UNWIND_JUMP state
1619  compile_node(comp, pn_body);
1620  EMIT_ARG(adjust_stack_size, -3);
1621  } else {
1622  compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1623  }
1624  EMIT(pop_block);
1625  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
1626  EMIT_ARG(label_assign, l_finally_block);
1627  compile_node(comp, pn_finally);
1628 
1629  compile_decrease_except_level(comp);
1630  EMIT(end_finally);
1631 }
1632 
1633 STATIC void compile_try_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1634  assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should be
1635  {
1637  if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1638  // just try-finally
1639  compile_try_finally(comp, pns->nodes[0], 0, NULL, MP_PARSE_NODE_NULL, pns2->nodes[0]);
1640  } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1641  // try-except and possibly else and/or finally
1642  mp_parse_node_t *pn_excepts;
1643  int n_except = mp_parse_node_extract_list(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1644  if (MP_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1645  // no finally
1646  compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1647  } else {
1648  // have finally
1649  compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((mp_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1650  }
1651  } else {
1652  // just try-except
1653  mp_parse_node_t *pn_excepts;
1654  int n_except = mp_parse_node_extract_list(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1655  compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, MP_PARSE_NODE_NULL);
1656  }
1657  }
1658 }
1659 
1660 STATIC void compile_with_stmt_helper(compiler_t *comp, int n, mp_parse_node_t *nodes, mp_parse_node_t body) {
1661  if (n == 0) {
1662  // no more pre-bits, compile the body of the with
1663  compile_node(comp, body);
1664  } else {
1665  uint l_end = comp_next_label(comp);
1666  if (MICROPY_EMIT_NATIVE && comp->scope_cur->emit_options != MP_EMIT_OPT_BYTECODE) {
1667  // we need to allocate an extra label for the native emitter
1668  // it will use l_end+1 as an auxiliary label
1669  comp_next_label(comp);
1670  }
1671  if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1672  // this pre-bit is of the form "a as b"
1674  compile_node(comp, pns->nodes[0]);
1675  EMIT_ARG(setup_with, l_end);
1676  c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1677  } else {
1678  // this pre-bit is just an expression
1679  compile_node(comp, nodes[0]);
1680  EMIT_ARG(setup_with, l_end);
1681  EMIT(pop_top);
1682  }
1683  compile_increase_except_level(comp);
1684  // compile additional pre-bits and the body
1685  compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1686  // finish this with block
1687  EMIT_ARG(with_cleanup, l_end);
1688  compile_decrease_except_level(comp);
1689  EMIT(end_finally);
1690  }
1691 }
1692 
1693 STATIC void compile_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1694  // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1695  mp_parse_node_t *nodes;
1696  int n = mp_parse_node_extract_list(&pns->nodes[0], PN_with_stmt_list, &nodes);
1697  assert(n > 0);
1698 
1699  // compile in a nested fashion
1700  compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1701 }
1702 
1703 STATIC void compile_yield_from(compiler_t *comp) {
1704  EMIT_ARG(get_iter, false);
1705  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
1706  EMIT(yield_from);
1707 }
1708 
1709 #if MICROPY_PY_ASYNC_AWAIT
1710 STATIC void compile_await_object_method(compiler_t *comp, qstr method) {
1711  EMIT_ARG(load_method, method, false);
1712  EMIT_ARG(call_method, 0, 0, 0);
1713  compile_yield_from(comp);
1714 }
1715 
1716 STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1717  // comp->break_label |= MP_EMIT_BREAK_FROM_FOR;
1718 
1719  qstr context = MP_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1720  uint while_else_label = comp_next_label(comp);
1721  uint try_exception_label = comp_next_label(comp);
1722  uint try_else_label = comp_next_label(comp);
1723  uint try_finally_label = comp_next_label(comp);
1724 
1725  compile_node(comp, pns->nodes[1]); // iterator
1726  compile_await_object_method(comp, MP_QSTR___aiter__);
1727  compile_store_id(comp, context);
1728 
1729  START_BREAK_CONTINUE_BLOCK
1730 
1731  EMIT_ARG(label_assign, continue_label);
1732 
1733  EMIT_ARG(setup_except, try_exception_label);
1734  compile_increase_except_level(comp);
1735 
1736  compile_load_id(comp, context);
1737  compile_await_object_method(comp, MP_QSTR___anext__);
1738  c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1739  EMIT(pop_block);
1740  EMIT_ARG(jump, try_else_label);
1741 
1742  EMIT_ARG(label_assign, try_exception_label);
1743  EMIT(start_except_handler);
1744  EMIT(dup_top);
1745  EMIT_LOAD_GLOBAL(MP_QSTR_StopAsyncIteration);
1746  EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH);
1747  EMIT_ARG(pop_jump_if, false, try_finally_label);
1748  EMIT(pop_top); // pop exception instance
1749  EMIT(pop_except);
1750  EMIT_ARG(jump, while_else_label);
1751 
1752  EMIT_ARG(label_assign, try_finally_label);
1753  EMIT_ARG(adjust_stack_size, 1); // if we jump here, the exc is on the stack
1754  compile_decrease_except_level(comp);
1755  EMIT(end_finally);
1756  EMIT(end_except_handler);
1757 
1758  EMIT_ARG(label_assign, try_else_label);
1759  compile_node(comp, pns->nodes[2]); // body
1760 
1761  EMIT_ARG(jump, continue_label);
1762  // break/continue apply to outer loop (if any) in the else block
1763  END_BREAK_CONTINUE_BLOCK
1764 
1765  EMIT_ARG(label_assign, while_else_label);
1766  compile_node(comp, pns->nodes[3]); // else
1767 
1768  EMIT_ARG(label_assign, break_label);
1769 }
1770 
1771 STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_node_t *nodes, mp_parse_node_t body) {
1772  if (n == 0) {
1773  // no more pre-bits, compile the body of the with
1774  compile_node(comp, body);
1775  } else {
1776  uint try_exception_label = comp_next_label(comp);
1777  uint no_reraise_label = comp_next_label(comp);
1778  uint try_else_label = comp_next_label(comp);
1779  uint end_label = comp_next_label(comp);
1780  qstr context;
1781 
1782  if (MP_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1783  // this pre-bit is of the form "a as b"
1785  compile_node(comp, pns->nodes[0]);
1786  context = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1787  compile_store_id(comp, context);
1788  compile_load_id(comp, context);
1789  compile_await_object_method(comp, MP_QSTR___aenter__);
1790  c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1791  } else {
1792  // this pre-bit is just an expression
1793  compile_node(comp, nodes[0]);
1794  context = MP_PARSE_NODE_LEAF_ARG(nodes[0]);
1795  compile_store_id(comp, context);
1796  compile_load_id(comp, context);
1797  compile_await_object_method(comp, MP_QSTR___aenter__);
1798  EMIT(pop_top);
1799  }
1800 
1801  compile_load_id(comp, context);
1802  EMIT_ARG(load_method, MP_QSTR___aexit__, false);
1803 
1804  EMIT_ARG(setup_except, try_exception_label);
1805  compile_increase_except_level(comp);
1806  // compile additional pre-bits and the body
1807  compile_async_with_stmt_helper(comp, n - 1, nodes + 1, body);
1808  // finish this with block
1809  EMIT(pop_block);
1810  EMIT_ARG(jump, try_else_label); // jump over exception handler
1811 
1812  EMIT_ARG(label_assign, try_exception_label); // start of exception handler
1813  EMIT(start_except_handler);
1814 
1815  // at this point the stack contains: ..., __aexit__, self, exc
1816  EMIT(dup_top);
1817  #if MICROPY_CPYTHON_COMPAT
1818  EMIT_ARG(load_attr, MP_QSTR___class__); // get type(exc)
1819  #else
1820  compile_load_id(comp, MP_QSTR_type);
1821  EMIT(rot_two);
1822  EMIT_ARG(call_function, 1, 0, 0); // get type(exc)
1823  #endif
1824  EMIT(rot_two);
1825  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); // dummy traceback value
1826  // at this point the stack contains: ..., __aexit__, self, type(exc), exc, None
1827  EMIT_ARG(call_method, 3, 0, 0);
1828 
1829  compile_yield_from(comp);
1830  EMIT_ARG(pop_jump_if, true, no_reraise_label);
1831  EMIT_ARG(raise_varargs, 0);
1832 
1833  EMIT_ARG(label_assign, no_reraise_label);
1834  EMIT(pop_except);
1835  EMIT_ARG(jump, end_label);
1836 
1837  EMIT_ARG(adjust_stack_size, 3); // adjust for __aexit__, self, exc
1838  compile_decrease_except_level(comp);
1839  EMIT(end_finally);
1840  EMIT(end_except_handler);
1841 
1842  EMIT_ARG(label_assign, try_else_label); // start of try-else handler
1843  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
1844  EMIT(dup_top);
1845  EMIT(dup_top);
1846  EMIT_ARG(call_method, 3, 0, 0);
1847  compile_yield_from(comp);
1848  EMIT(pop_top);
1849 
1850  EMIT_ARG(label_assign, end_label);
1851 
1852  }
1853 }
1854 
1855 STATIC void compile_async_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1856  // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1857  mp_parse_node_t *nodes;
1858  int n = mp_parse_node_extract_list(&pns->nodes[0], PN_with_stmt_list, &nodes);
1859  assert(n > 0);
1860 
1861  // compile in a nested fashion
1862  compile_async_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1863 }
1864 
1865 STATIC void compile_async_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1868  if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_funcdef) {
1869  // async def
1870  compile_funcdef(comp, pns0);
1871  scope_t *fscope = (scope_t*)pns0->nodes[4];
1873  } else if (MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_for_stmt) {
1874  // async for
1875  compile_async_for_stmt(comp, pns0);
1876  } else {
1877  // async with
1878  assert(MP_PARSE_NODE_STRUCT_KIND(pns0) == PN_with_stmt);
1879  compile_async_with_stmt(comp, pns0);
1880  }
1881 }
1882 #endif
1883 
1884 STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
1885  if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1886  if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
1887  // for REPL, evaluate then print the expression
1888  compile_load_id(comp, MP_QSTR___repl_print__);
1889  compile_node(comp, pns->nodes[0]);
1890  EMIT_ARG(call_function, 1, 0, 0);
1891  EMIT(pop_top);
1892 
1893  } else {
1894  // for non-REPL, evaluate then discard the expression
1895  if ((MP_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !MP_PARSE_NODE_IS_ID(pns->nodes[0]))
1896  || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_const_object)) {
1897  // do nothing with a lonely constant
1898  } else {
1899  compile_node(comp, pns->nodes[0]); // just an expression
1900  EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1901  }
1902  }
1903  } else if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1905  int kind = MP_PARSE_NODE_STRUCT_KIND(pns1);
1906  if (kind == PN_expr_stmt_augassign) {
1907  c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1908  compile_node(comp, pns1->nodes[1]); // rhs
1909  assert(MP_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1910  mp_binary_op_t op;
1911  switch (MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1923  case MP_TOKEN_DEL_DBL_STAR_EQUAL: default: op = MP_BINARY_OP_INPLACE_POWER; break;
1924  }
1925  EMIT_ARG(binary_op, op);
1926  c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1927  } else if (kind == PN_expr_stmt_assign_list) {
1928  int rhs = MP_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1929  compile_node(comp, pns1->nodes[rhs]); // rhs
1930  // following CPython, we store left-most first
1931  if (rhs > 0) {
1932  EMIT(dup_top);
1933  }
1934  c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1935  for (int i = 0; i < rhs; i++) {
1936  if (i + 1 < rhs) {
1937  EMIT(dup_top);
1938  }
1939  c_assign(comp, pns1->nodes[i], ASSIGN_STORE); // middle store
1940  }
1941  } else {
1942  plain_assign:
1944  && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
1945  && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1948  // optimisation for a, b = c, d
1951  if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
1952  || MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)) {
1953  // can't optimise when it's a star expression on the lhs
1954  goto no_optimisation;
1955  }
1956  compile_node(comp, pns10->nodes[0]); // rhs
1957  compile_node(comp, pns10->nodes[1]); // rhs
1958  EMIT(rot_two);
1959  c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1960  c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1962  && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_testlist_star_expr)
1963  && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1966  // optimisation for a, b, c = d, e, f
1969  if (MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[0], PN_star_expr)
1970  || MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[1], PN_star_expr)
1971  || MP_PARSE_NODE_IS_STRUCT_KIND(pns0->nodes[2], PN_star_expr)) {
1972  // can't optimise when it's a star expression on the lhs
1973  goto no_optimisation;
1974  }
1975  compile_node(comp, pns10->nodes[0]); // rhs
1976  compile_node(comp, pns10->nodes[1]); // rhs
1977  compile_node(comp, pns10->nodes[2]); // rhs
1978  EMIT(rot_three);
1979  EMIT(rot_two);
1980  c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1981  c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1982  c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1983  } else {
1984  no_optimisation:
1985  compile_node(comp, pns->nodes[1]); // rhs
1986  c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1987  }
1988  }
1989  } else {
1990  goto plain_assign;
1991  }
1992 }
1993 
1994 STATIC void c_binary_op(compiler_t *comp, mp_parse_node_struct_t *pns, mp_binary_op_t binary_op) {
1995  int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
1996  compile_node(comp, pns->nodes[0]);
1997  for (int i = 1; i < num_nodes; i += 1) {
1998  compile_node(comp, pns->nodes[i]);
1999  EMIT_ARG(binary_op, binary_op);
2000  }
2001 }
2002 
2003 STATIC void compile_test_if_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
2004  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
2005  mp_parse_node_struct_t *pns_test_if_else = (mp_parse_node_struct_t*)pns->nodes[1];
2006 
2007  uint l_fail = comp_next_label(comp);
2008  uint l_end = comp_next_label(comp);
2009  c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
2010  compile_node(comp, pns->nodes[0]); // success value
2011  EMIT_ARG(jump, l_end);
2012  EMIT_ARG(label_assign, l_fail);
2013  EMIT_ARG(adjust_stack_size, -1); // adjust stack size
2014  compile_node(comp, pns_test_if_else->nodes[1]); // failure value
2015  EMIT_ARG(label_assign, l_end);
2016 }
2017 
2018 STATIC void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
2019  if (comp->pass == MP_PASS_SCOPE) {
2020  // create a new scope for this lambda
2021  scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (mp_parse_node_t)pns, comp->scope_cur->emit_options);
2022  // store the lambda scope so the compiling function (this one) can use it at each pass
2023  pns->nodes[2] = (mp_parse_node_t)s;
2024  }
2025 
2026  // get the scope for this lambda
2027  scope_t *this_scope = (scope_t*)pns->nodes[2];
2028 
2029  // compile the lambda definition
2030  compile_funcdef_lambdef(comp, this_scope, pns->nodes[0], PN_varargslist);
2031 }
2032 
2033 STATIC void compile_or_and_test(compiler_t *comp, mp_parse_node_struct_t *pns, bool cond) {
2034  uint l_end = comp_next_label(comp);
2035  int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
2036  for (int i = 0; i < n; i += 1) {
2037  compile_node(comp, pns->nodes[i]);
2038  if (i + 1 < n) {
2039  EMIT_ARG(jump_if_or_pop, cond, l_end);
2040  }
2041  }
2042  EMIT_ARG(label_assign, l_end);
2043 }
2044 
2045 STATIC void compile_or_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
2046  compile_or_and_test(comp, pns, true);
2047 }
2048 
2049 STATIC void compile_and_test(compiler_t *comp, mp_parse_node_struct_t *pns) {
2050  compile_or_and_test(comp, pns, false);
2051 }
2052 
2053 STATIC void compile_not_test_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
2054  compile_node(comp, pns->nodes[0]);
2055  EMIT_ARG(unary_op, MP_UNARY_OP_NOT);
2056 }
2057 
2058 STATIC void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
2059  int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
2060  compile_node(comp, pns->nodes[0]);
2061  bool multi = (num_nodes > 3);
2062  uint l_fail = 0;
2063  if (multi) {
2064  l_fail = comp_next_label(comp);
2065  }
2066  for (int i = 1; i + 1 < num_nodes; i += 2) {
2067  compile_node(comp, pns->nodes[i + 1]);
2068  if (i + 2 < num_nodes) {
2069  EMIT(dup_top);
2070  EMIT(rot_three);
2071  }
2072  if (MP_PARSE_NODE_IS_TOKEN(pns->nodes[i])) {
2073  mp_binary_op_t op;
2074  switch (MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])) {
2075  case MP_TOKEN_OP_LESS: op = MP_BINARY_OP_LESS; break;
2076  case MP_TOKEN_OP_MORE: op = MP_BINARY_OP_MORE; break;
2077  case MP_TOKEN_OP_DBL_EQUAL: op = MP_BINARY_OP_EQUAL; break;
2081  case MP_TOKEN_KW_IN: default: op = MP_BINARY_OP_IN; break;
2082  }
2083  EMIT_ARG(binary_op, op);
2084  } else {
2085  assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[i])); // should be
2087  int kind = MP_PARSE_NODE_STRUCT_KIND(pns2);
2088  if (kind == PN_comp_op_not_in) {
2089  EMIT_ARG(binary_op, MP_BINARY_OP_NOT_IN);
2090  } else {
2091  assert(kind == PN_comp_op_is); // should be
2092  if (MP_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
2093  EMIT_ARG(binary_op, MP_BINARY_OP_IS);
2094  } else {
2095  EMIT_ARG(binary_op, MP_BINARY_OP_IS_NOT);
2096  }
2097  }
2098  }
2099  if (i + 2 < num_nodes) {
2100  EMIT_ARG(jump_if_or_pop, false, l_fail);
2101  }
2102  }
2103  if (multi) {
2104  uint l_end = comp_next_label(comp);
2105  EMIT_ARG(jump, l_end);
2106  EMIT_ARG(label_assign, l_fail);
2107  EMIT_ARG(adjust_stack_size, 1);
2108  EMIT(rot_two);
2109  EMIT(pop_top);
2110  EMIT_ARG(label_assign, l_end);
2111  }
2112 }
2113 
2114 STATIC void compile_star_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
2115  compile_syntax_error(comp, (mp_parse_node_t)pns, "*x must be assignment target");
2116 }
2117 
2118 STATIC void compile_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
2119  c_binary_op(comp, pns, MP_BINARY_OP_OR);
2120 }
2121 
2122 STATIC void compile_xor_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
2123  c_binary_op(comp, pns, MP_BINARY_OP_XOR);
2124 }
2125 
2126 STATIC void compile_and_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
2127  c_binary_op(comp, pns, MP_BINARY_OP_AND);
2128 }
2129 
2130 STATIC void compile_term(compiler_t *comp, mp_parse_node_struct_t *pns) {
2131  int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
2132  compile_node(comp, pns->nodes[0]);
2133  for (int i = 1; i + 1 < num_nodes; i += 2) {
2134  compile_node(comp, pns->nodes[i + 1]);
2135  mp_binary_op_t op;
2137  switch (tok) {
2138  case MP_TOKEN_OP_PLUS: op = MP_BINARY_OP_ADD; break;
2139  case MP_TOKEN_OP_MINUS: op = MP_BINARY_OP_SUBTRACT; break;
2140  case MP_TOKEN_OP_STAR: op = MP_BINARY_OP_MULTIPLY; break;
2142  case MP_TOKEN_OP_SLASH: op = MP_BINARY_OP_TRUE_DIVIDE; break;
2143  case MP_TOKEN_OP_PERCENT: op = MP_BINARY_OP_MODULO; break;
2144  case MP_TOKEN_OP_DBL_LESS: op = MP_BINARY_OP_LSHIFT; break;
2145  default:
2147  op = MP_BINARY_OP_RSHIFT;
2148  break;
2149  }
2150  EMIT_ARG(binary_op, op);
2151  }
2152 }
2153 
2154 STATIC void compile_factor_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
2155  compile_node(comp, pns->nodes[1]);
2156  mp_unary_op_t op;
2158  switch (tok) {
2159  case MP_TOKEN_OP_PLUS: op = MP_UNARY_OP_POSITIVE; break;
2160  case MP_TOKEN_OP_MINUS: op = MP_UNARY_OP_NEGATIVE; break;
2161  default:
2163  op = MP_UNARY_OP_INVERT;
2164  break;
2165  }
2166  EMIT_ARG(unary_op, op);
2167 }
2168 
2169 STATIC void compile_atom_expr_normal(compiler_t *comp, mp_parse_node_struct_t *pns) {
2170  // compile the subject of the expression
2171  compile_node(comp, pns->nodes[0]);
2172 
2173  // compile_atom_expr_await may call us with a NULL node
2174  if (MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2175  return;
2176  }
2177 
2178  // get the array of trailers (known to be an array of PARSE_NODE_STRUCT)
2179  size_t num_trail = 1;
2180  mp_parse_node_struct_t **pns_trail = (mp_parse_node_struct_t**)&pns->nodes[1];
2181  if (MP_PARSE_NODE_STRUCT_KIND(pns_trail[0]) == PN_atom_expr_trailers) {
2182  num_trail = MP_PARSE_NODE_STRUCT_NUM_NODES(pns_trail[0]);
2183  pns_trail = (mp_parse_node_struct_t**)&pns_trail[0]->nodes[0];
2184  }
2185 
2186  // the current index into the array of trailers
2187  size_t i = 0;
2188 
2189  // handle special super() call
2190  if (comp->scope_cur->kind == SCOPE_FUNCTION
2191  && MP_PARSE_NODE_IS_ID(pns->nodes[0])
2192  && MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]) == MP_QSTR_super
2193  && MP_PARSE_NODE_STRUCT_KIND(pns_trail[0]) == PN_trailer_paren
2194  && MP_PARSE_NODE_IS_NULL(pns_trail[0]->nodes[0])) {
2195  // at this point we have matched "super()" within a function
2196 
2197  // load the class for super to search for a parent
2198  compile_load_id(comp, MP_QSTR___class__);
2199 
2200  // look for first argument to function (assumes it's "self")
2201  bool found = false;
2202  id_info_t *id = &comp->scope_cur->id_info[0];
2203  for (size_t n = comp->scope_cur->id_info_len; n > 0; --n, ++id) {
2204  if (id->flags & ID_FLAG_IS_PARAM) {
2205  // first argument found; load it
2206  compile_load_id(comp, id->qst);
2207  found = true;
2208  break;
2209  }
2210  }
2211  if (!found) {
2212  compile_syntax_error(comp, (mp_parse_node_t)pns_trail[0],
2213  "super() can't find self"); // really a TypeError
2214  return;
2215  }
2216 
2217  if (num_trail >= 3
2218  && MP_PARSE_NODE_STRUCT_KIND(pns_trail[1]) == PN_trailer_period
2219  && MP_PARSE_NODE_STRUCT_KIND(pns_trail[2]) == PN_trailer_paren) {
2220  // optimisation for method calls super().f(...), to eliminate heap allocation
2221  mp_parse_node_struct_t *pns_period = pns_trail[1];
2222  mp_parse_node_struct_t *pns_paren = pns_trail[2];
2223  EMIT_ARG(load_method, MP_PARSE_NODE_LEAF_ARG(pns_period->nodes[0]), true);
2224  compile_trailer_paren_helper(comp, pns_paren->nodes[0], true, 0);
2225  i = 3;
2226  } else {
2227  // a super() call
2228  EMIT_ARG(call_function, 2, 0, 0);
2229  i = 1;
2230  }
2231  }
2232 
2233  // compile the remaining trailers
2234  for (; i < num_trail; i++) {
2235  if (i + 1 < num_trail
2236  && MP_PARSE_NODE_STRUCT_KIND(pns_trail[i]) == PN_trailer_period
2237  && MP_PARSE_NODE_STRUCT_KIND(pns_trail[i + 1]) == PN_trailer_paren) {
2238  // optimisation for method calls a.f(...), following PyPy
2239  mp_parse_node_struct_t *pns_period = pns_trail[i];
2240  mp_parse_node_struct_t *pns_paren = pns_trail[i + 1];
2241  EMIT_ARG(load_method, MP_PARSE_NODE_LEAF_ARG(pns_period->nodes[0]), false);
2242  compile_trailer_paren_helper(comp, pns_paren->nodes[0], true, 0);
2243  i += 1;
2244  } else {
2245  // node is one of: trailer_paren, trailer_bracket, trailer_period
2246  compile_node(comp, (mp_parse_node_t)pns_trail[i]);
2247  }
2248  }
2249 }
2250 
2251 STATIC void compile_power(compiler_t *comp, mp_parse_node_struct_t *pns) {
2252  compile_generic_all_nodes(comp, pns); // 2 nodes, arguments of power
2253  EMIT_ARG(binary_op, MP_BINARY_OP_POWER);
2254 }
2255 
2256 STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_arglist, bool is_method_call, int n_positional_extra) {
2257  // function to call is on top of stack
2258 
2259  // get the list of arguments
2261  int n_args = mp_parse_node_extract_list(&pn_arglist, PN_arglist, &args);
2262 
2263  // compile the arguments
2264  // Rather than calling compile_node on the list, we go through the list of args
2265  // explicitly here so that we can count the number of arguments and give sensible
2266  // error messages.
2267  int n_positional = n_positional_extra;
2268  uint n_keyword = 0;
2269  uint star_flags = 0;
2270  mp_parse_node_struct_t *star_args_node = NULL, *dblstar_args_node = NULL;
2271  for (int i = 0; i < n_args; i++) {
2272  if (MP_PARSE_NODE_IS_STRUCT(args[i])) {
2274  if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_star) {
2275  if (star_flags & MP_EMIT_STAR_FLAG_SINGLE) {
2276  compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple *x");
2277  return;
2278  }
2279  star_flags |= MP_EMIT_STAR_FLAG_SINGLE;
2280  star_args_node = pns_arg;
2281  } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) {
2282  if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) {
2283  compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "can't have multiple **x");
2284  return;
2285  }
2286  star_flags |= MP_EMIT_STAR_FLAG_DOUBLE;
2287  dblstar_args_node = pns_arg;
2288  } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) {
2289  if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns_arg->nodes[1], PN_comp_for)) {
2290  if (!MP_PARSE_NODE_IS_ID(pns_arg->nodes[0])) {
2291  compile_syntax_error(comp, (mp_parse_node_t)pns_arg, "LHS of keyword arg must be an id");
2292  return;
2293  }
2294  EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0]));
2295  compile_node(comp, pns_arg->nodes[1]);
2296  n_keyword += 1;
2297  } else {
2298  compile_comprehension(comp, pns_arg, SCOPE_GEN_EXPR);
2299  n_positional++;
2300  }
2301  } else {
2302  goto normal_argument;
2303  }
2304  } else {
2305  normal_argument:
2306  if (star_flags) {
2307  compile_syntax_error(comp, args[i], "non-keyword arg after */**");
2308  return;
2309  }
2310  if (n_keyword > 0) {
2311  compile_syntax_error(comp, args[i], "non-keyword arg after keyword arg");
2312  return;
2313  }
2314  compile_node(comp, args[i]);
2315  n_positional++;
2316  }
2317  }
2318 
2319  // compile the star/double-star arguments if we had them
2320  // if we had one but not the other then we load "null" as a place holder
2321  if (star_flags != 0) {
2322  if (star_args_node == NULL) {
2323  EMIT(load_null);
2324  } else {
2325  compile_node(comp, star_args_node->nodes[0]);
2326  }
2327  if (dblstar_args_node == NULL) {
2328  EMIT(load_null);
2329  } else {
2330  compile_node(comp, dblstar_args_node->nodes[0]);
2331  }
2332  }
2333 
2334  // emit the function/method call
2335  if (is_method_call) {
2336  EMIT_ARG(call_method, n_positional, n_keyword, star_flags);
2337  } else {
2338  EMIT_ARG(call_function, n_positional, n_keyword, star_flags);
2339  }
2340 }
2341 
2342 // pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
2343 STATIC void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_kind_t kind) {
2345  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2346  mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1];
2347 
2348  if (comp->pass == MP_PASS_SCOPE) {
2349  // create a new scope for this comprehension
2350  scope_t *s = scope_new_and_link(comp, kind, (mp_parse_node_t)pns, comp->scope_cur->emit_options);
2351  // store the comprehension scope so the compiling function (this one) can use it at each pass
2352  pns_comp_for->nodes[3] = (mp_parse_node_t)s;
2353  }
2354 
2355  // get the scope for this comprehension
2356  scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
2357 
2358  // compile the comprehension
2359  close_over_variables_etc(comp, this_scope, 0, 0);
2360 
2361  compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
2362  if (kind == SCOPE_GEN_EXPR) {
2363  EMIT_ARG(get_iter, false);
2364  }
2365  EMIT_ARG(call_function, 1, 0, 0);
2366 }
2367 
2368 STATIC void compile_atom_paren(compiler_t *comp, mp_parse_node_struct_t *pns) {
2369  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2370  // an empty tuple
2371  c_tuple(comp, MP_PARSE_NODE_NULL, NULL);
2372  } else {
2373  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp));
2374  pns = (mp_parse_node_struct_t*)pns->nodes[0];
2375  assert(!MP_PARSE_NODE_IS_NULL(pns->nodes[1]));
2376  if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
2378  if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
2379  // tuple of one item, with trailing comma
2380  assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[0]));
2381  c_tuple(comp, pns->nodes[0], NULL);
2382  } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
2383  // tuple of many items
2384  c_tuple(comp, pns->nodes[0], pns2);
2385  } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2386  // generator expression
2387  compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2388  } else {
2389  // tuple with 2 items
2390  goto tuple_with_2_items;
2391  }
2392  } else {
2393  // tuple with 2 items
2394  tuple_with_2_items:
2395  c_tuple(comp, MP_PARSE_NODE_NULL, pns);
2396  }
2397  }
2398 }
2399 
2400 STATIC void compile_atom_bracket(compiler_t *comp, mp_parse_node_struct_t *pns) {
2401  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2402  // empty list
2403  EMIT_ARG(build_list, 0);
2404  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2406  if (MP_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
2408  if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
2409  // list of one item, with trailing comma
2410  assert(MP_PARSE_NODE_IS_NULL(pns3->nodes[0]));
2411  compile_node(comp, pns2->nodes[0]);
2412  EMIT_ARG(build_list, 1);
2413  } else if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
2414  // list of many items
2415  compile_node(comp, pns2->nodes[0]);
2416  compile_generic_all_nodes(comp, pns3);
2417  EMIT_ARG(build_list, 1 + MP_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2418  } else if (MP_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2419  // list comprehension
2420  compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2421  } else {
2422  // list with 2 items
2423  goto list_with_2_items;
2424  }
2425  } else {
2426  // list with 2 items
2427  list_with_2_items:
2428  compile_node(comp, pns2->nodes[0]);
2429  compile_node(comp, pns2->nodes[1]);
2430  EMIT_ARG(build_list, 2);
2431  }
2432  } else {
2433  // list with 1 item
2434  compile_node(comp, pns->nodes[0]);
2435  EMIT_ARG(build_list, 1);
2436  }
2437 }
2438 
2439 STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) {
2440  mp_parse_node_t pn = pns->nodes[0];
2441  if (MP_PARSE_NODE_IS_NULL(pn)) {
2442  // empty dict
2443  EMIT_ARG(build_map, 0);
2444  } else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
2445  pns = (mp_parse_node_struct_t*)pn;
2446  if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2447  // dict with one element
2448  EMIT_ARG(build_map, 1);
2449  compile_node(comp, pn);
2450  EMIT(store_map);
2451  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2452  assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2454  if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2455  // dict/set with multiple elements
2456 
2457  // get tail elements (2nd, 3rd, ...)
2458  mp_parse_node_t *nodes;
2459  int n = mp_parse_node_extract_list(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2460 
2461  // first element sets whether it's a dict or set
2462  bool is_dict;
2463  if (!MICROPY_PY_BUILTINS_SET || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2464  // a dictionary
2465  EMIT_ARG(build_map, 1 + n);
2466  compile_node(comp, pns->nodes[0]);
2467  EMIT(store_map);
2468  is_dict = true;
2469  } else {
2470  // a set
2471  compile_node(comp, pns->nodes[0]); // 1st value of set
2472  is_dict = false;
2473  }
2474 
2475  // process rest of elements
2476  for (int i = 0; i < n; i++) {
2477  mp_parse_node_t pn_i = nodes[i];
2478  bool is_key_value = MP_PARSE_NODE_IS_STRUCT_KIND(pn_i, PN_dictorsetmaker_item);
2479  compile_node(comp, pn_i);
2480  if (is_dict) {
2481  if (!is_key_value) {
2483  compile_syntax_error(comp, (mp_parse_node_t)pns, "invalid syntax");
2484  } else {
2485  compile_syntax_error(comp, (mp_parse_node_t)pns, "expecting key:value for dict");
2486  }
2487  return;
2488  }
2489  EMIT(store_map);
2490  } else {
2491  if (is_key_value) {
2493  compile_syntax_error(comp, (mp_parse_node_t)pns, "invalid syntax");
2494  } else {
2495  compile_syntax_error(comp, (mp_parse_node_t)pns, "expecting just a value for set");
2496  }
2497  return;
2498  }
2499  }
2500  }
2501 
2502  #if MICROPY_PY_BUILTINS_SET
2503  // if it's a set, build it
2504  if (!is_dict) {
2505  EMIT_ARG(build_set, 1 + n);
2506  }
2507  #endif
2508  } else {
2509  assert(MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for); // should be
2510  // dict/set comprehension
2511  if (!MICROPY_PY_BUILTINS_SET || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2512  // a dictionary comprehension
2513  compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2514  } else {
2515  // a set comprehension
2516  compile_comprehension(comp, pns, SCOPE_SET_COMP);
2517  }
2518  }
2519  } else {
2520  // set with one element
2521  goto set_with_one_element;
2522  }
2523  } else {
2524  // set with one element
2525  set_with_one_element:
2526  #if MICROPY_PY_BUILTINS_SET
2527  compile_node(comp, pn);
2528  EMIT_ARG(build_set, 1);
2529  #else
2530  assert(0);
2531  #endif
2532  }
2533 }
2534 
2535 STATIC void compile_trailer_paren(compiler_t *comp, mp_parse_node_struct_t *pns) {
2536  compile_trailer_paren_helper(comp, pns->nodes[0], false, 0);
2537 }
2538 
2539 STATIC void compile_trailer_bracket(compiler_t *comp, mp_parse_node_struct_t *pns) {
2540  // object who's index we want is on top of stack
2541  compile_node(comp, pns->nodes[0]); // the index
2542  EMIT(load_subscr);
2543 }
2544 
2545 STATIC void compile_trailer_period(compiler_t *comp, mp_parse_node_struct_t *pns) {
2546  // object who's attribute we want is on top of stack
2547  EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2548 }
2549 
2550 #if MICROPY_PY_BUILTINS_SLICE
2551 STATIC void compile_subscript_3_helper(compiler_t *comp, mp_parse_node_struct_t *pns) {
2552  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2553  mp_parse_node_t pn = pns->nodes[0];
2554  if (MP_PARSE_NODE_IS_NULL(pn)) {
2555  // [?:]
2556  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
2557  EMIT_ARG(build_slice, 2);
2558  } else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
2559  pns = (mp_parse_node_struct_t*)pn;
2560  if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2561  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
2562  pn = pns->nodes[0];
2563  if (MP_PARSE_NODE_IS_NULL(pn)) {
2564  // [?::]
2565  EMIT_ARG(build_slice, 2);
2566  } else {
2567  // [?::x]
2568  compile_node(comp, pn);
2569  EMIT_ARG(build_slice, 3);
2570  }
2571  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2572  compile_node(comp, pns->nodes[0]);
2573  assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2574  pns = (mp_parse_node_struct_t*)pns->nodes[1];
2575  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2576  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2577  // [?:x:]
2578  EMIT_ARG(build_slice, 2);
2579  } else {
2580  // [?:x:x]
2581  compile_node(comp, pns->nodes[0]);
2582  EMIT_ARG(build_slice, 3);
2583  }
2584  } else {
2585  // [?:x]
2586  compile_node(comp, pn);
2587  EMIT_ARG(build_slice, 2);
2588  }
2589  } else {
2590  // [?:x]
2591  compile_node(comp, pn);
2592  EMIT_ARG(build_slice, 2);
2593  }
2594 }
2595 
2596 STATIC void compile_subscript_2(compiler_t *comp, mp_parse_node_struct_t *pns) {
2597  compile_node(comp, pns->nodes[0]); // start of slice
2598  assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2599  compile_subscript_3_helper(comp, (mp_parse_node_struct_t*)pns->nodes[1]);
2600 }
2601 
2602 STATIC void compile_subscript_3(compiler_t *comp, mp_parse_node_struct_t *pns) {
2603  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
2604  compile_subscript_3_helper(comp, pns);
2605 }
2606 #endif // MICROPY_PY_BUILTINS_SLICE
2607 
2608 STATIC void compile_dictorsetmaker_item(compiler_t *comp, mp_parse_node_struct_t *pns) {
2609  // if this is called then we are compiling a dict key:value pair
2610  compile_node(comp, pns->nodes[1]); // value
2611  compile_node(comp, pns->nodes[0]); // key
2612 }
2613 
2614 STATIC void compile_classdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
2615  qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
2616  // store class object into class name
2617  compile_store_id(comp, cname);
2618 }
2619 
2620 STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
2621  if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) {
2622  compile_syntax_error(comp, (mp_parse_node_t)pns, "'yield' outside function");
2623  return;
2624  }
2625  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2626  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
2627  EMIT(yield_value);
2628  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2629  pns = (mp_parse_node_struct_t*)pns->nodes[0];
2630  compile_node(comp, pns->nodes[0]);
2631  compile_yield_from(comp);
2632  } else {
2633  compile_node(comp, pns->nodes[0]);
2634  EMIT(yield_value);
2635  }
2636 }
2637 
2638 #if MICROPY_PY_ASYNC_AWAIT
2639 STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pns) {
2640  if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) {
2641  compile_syntax_error(comp, (mp_parse_node_t)pns, "'await' outside function");
2642  return;
2643  }
2644  compile_atom_expr_normal(comp, pns);
2645  compile_yield_from(comp);
2646 }
2647 #endif
2648 
2649 STATIC mp_obj_t get_const_object(mp_parse_node_struct_t *pns) {
2650  #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D
2651  // nodes are 32-bit pointers, but need to extract 64-bit object
2652  return (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32);
2653  #else
2654  return (mp_obj_t)pns->nodes[0];
2655  #endif
2656 }
2657 
2658 STATIC void compile_const_object(compiler_t *comp, mp_parse_node_struct_t *pns) {
2659  EMIT_ARG(load_const_obj, get_const_object(pns));
2660 }
2661 
2662 typedef void (*compile_function_t)(compiler_t*, mp_parse_node_struct_t*);
2663 STATIC const compile_function_t compile_function[] = {
2664 // only define rules with a compile function
2665 #define c(f) compile_##f
2666 #define DEF_RULE(rule, comp, kind, ...) comp,
2667 #define DEF_RULE_NC(rule, kind, ...)
2668 #include "py/grammar.h"
2669 #undef c
2670 #undef DEF_RULE
2671 #undef DEF_RULE_NC
2672  compile_const_object,
2673 };
2674 
2675 STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) {
2676  if (MP_PARSE_NODE_IS_NULL(pn)) {
2677  // pass
2678  } else if (MP_PARSE_NODE_IS_SMALL_INT(pn)) {
2680  #if MICROPY_DYNAMIC_COMPILER
2681  mp_uint_t sign_mask = -(1 << (mp_dynamic_compiler.small_int_bits - 1));
2682  if ((arg & sign_mask) == 0 || (arg & sign_mask) == sign_mask) {
2683  // integer fits in target runtime's small-int
2684  EMIT_ARG(load_const_small_int, arg);
2685  } else {
2686  // integer doesn't fit, so create a multi-precision int object
2687  // (but only create the actual object on the last pass)
2688  if (comp->pass != MP_PASS_EMIT) {
2689  EMIT_ARG(load_const_obj, mp_const_none);
2690  } else {
2691  EMIT_ARG(load_const_obj, mp_obj_new_int_from_ll(arg));
2692  }
2693  }
2694  #else
2695  EMIT_ARG(load_const_small_int, arg);
2696  #endif
2697  } else if (MP_PARSE_NODE_IS_LEAF(pn)) {
2699  switch (MP_PARSE_NODE_LEAF_KIND(pn)) {
2700  case MP_PARSE_NODE_ID: compile_load_id(comp, arg); break;
2701  case MP_PARSE_NODE_STRING: EMIT_ARG(load_const_str, arg); break;
2702  case MP_PARSE_NODE_BYTES:
2703  // only create and load the actual bytes object on the last pass
2704  if (comp->pass != MP_PASS_EMIT) {
2705  EMIT_ARG(load_const_obj, mp_const_none);
2706  } else {
2707  size_t len;
2708  const byte *data = qstr_data(arg, &len);
2709  EMIT_ARG(load_const_obj, mp_obj_new_bytes(data, len));
2710  }
2711  break;
2712  case MP_PARSE_NODE_TOKEN: default:
2713  if (arg == MP_TOKEN_NEWLINE) {
2714  // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
2715  // or when single_input lets through a NEWLINE (user enters a blank line)
2716  // do nothing
2717  } else {
2718  EMIT_ARG(load_const_tok, arg);
2719  }
2720  break;
2721  }
2722  } else {
2724  EMIT_ARG(set_source_line, pns->source_line);
2725  assert(MP_PARSE_NODE_STRUCT_KIND(pns) <= PN_const_object);
2726  compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)];
2727  f(comp, pns);
2728  }
2729 }
2730 
2731 STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star) {
2732  // check that **kw is last
2733  if ((comp->scope_cur->scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) {
2734  compile_syntax_error(comp, pn, "invalid syntax");
2735  return;
2736  }
2737 
2738  qstr param_name = MP_QSTR_NULL;
2739  uint param_flag = ID_FLAG_IS_PARAM;
2740  if (MP_PARSE_NODE_IS_ID(pn)) {
2741  param_name = MP_PARSE_NODE_LEAF_ARG(pn);
2742  if (comp->have_star) {
2743  // comes after a star, so counts as a keyword-only parameter
2744  comp->scope_cur->num_kwonly_args += 1;
2745  } else {
2746  // comes before a star, so counts as a positional parameter
2747  comp->scope_cur->num_pos_args += 1;
2748  }
2749  } else {
2752  if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
2753  param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2754  if (comp->have_star) {
2755  // comes after a star, so counts as a keyword-only parameter
2756  comp->scope_cur->num_kwonly_args += 1;
2757  } else {
2758  // comes before a star, so counts as a positional parameter
2759  comp->scope_cur->num_pos_args += 1;
2760  }
2761  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2762  if (comp->have_star) {
2763  // more than one star
2764  compile_syntax_error(comp, pn, "invalid syntax");
2765  return;
2766  }
2767  comp->have_star = true;
2768  param_flag = ID_FLAG_IS_PARAM | ID_FLAG_IS_STAR_PARAM;
2769  if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2770  // bare star
2771  // TODO see http://www.python.org/dev/peps/pep-3102/
2772  //assert(comp->scope_cur->num_dict_params == 0);
2773  } else if (MP_PARSE_NODE_IS_ID(pns->nodes[0])) {
2774  // named star
2775  comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARARGS;
2776  param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2777  } else {
2778  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)); // should be
2779  // named star with possible annotation
2780  comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARARGS;
2781  pns = (mp_parse_node_struct_t*)pns->nodes[0];
2782  param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2783  }
2784  } else {
2785  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star); // should be
2786  param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2788  comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_VARKEYWORDS;
2789  }
2790  }
2791 
2792  if (param_name != MP_QSTR_NULL) {
2793  bool added;
2794  id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2795  if (!added) {
2796  compile_syntax_error(comp, pn, "name reused for argument");
2797  return;
2798  }
2799  id_info->kind = ID_INFO_KIND_LOCAL;
2800  id_info->flags = param_flag;
2801  }
2802 }
2803 
2804 STATIC void compile_scope_func_param(compiler_t *comp, mp_parse_node_t pn) {
2805  compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star);
2806 }
2807 
2808 STATIC void compile_scope_lambda_param(compiler_t *comp, mp_parse_node_t pn) {
2809  compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star);
2810 }
2811 
2812 #if MICROPY_EMIT_NATIVE
2813 STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn) {
2814  if (!MP_PARSE_NODE_IS_STRUCT(pn)) {
2815  // no annotation
2816  return;
2817  }
2818 
2820  if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_name) {
2821  // named parameter with possible annotation
2822  // fallthrough
2823  } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_star) {
2824  if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2825  // named star with possible annotation
2826  pns = (mp_parse_node_struct_t*)pns->nodes[0];
2827  // fallthrough
2828  } else {
2829  // no annotation
2830  return;
2831  }
2832  } else {
2833  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star);
2834  // double star with possible annotation
2835  // fallthrough
2836  }
2837 
2838  mp_parse_node_t pn_annotation = pns->nodes[1];
2839 
2840  if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) {
2841  qstr param_name = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2842  id_info_t *id_info = scope_find(comp->scope_cur, param_name);
2843  assert(id_info != NULL);
2844 
2845  if (MP_PARSE_NODE_IS_ID(pn_annotation)) {
2846  qstr arg_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
2847  EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ARG, id_info->local_num, arg_type);
2848  } else {
2849  compile_syntax_error(comp, pn_annotation, "parameter annotation must be an identifier");
2850  }
2851  }
2852 }
2853 #endif // MICROPY_EMIT_NATIVE
2854 
2855 STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pns_comp_for, mp_parse_node_t pn_inner_expr, int for_depth) {
2856  uint l_top = comp_next_label(comp);
2857  uint l_end = comp_next_label(comp);
2858  EMIT_ARG(label_assign, l_top);
2859  EMIT_ARG(for_iter, l_end);
2860  c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2861  mp_parse_node_t pn_iter = pns_comp_for->nodes[2];
2862 
2863  tail_recursion:
2864  if (MP_PARSE_NODE_IS_NULL(pn_iter)) {
2865  // no more nested if/for; compile inner expression
2866  compile_node(comp, pn_inner_expr);
2867  if (comp->scope_cur->kind == SCOPE_GEN_EXPR) {
2868  EMIT(yield_value);
2869  EMIT(pop_top);
2870  } else {
2871  EMIT_ARG(store_comp, comp->scope_cur->kind, 4 * for_depth + 5);
2872  }
2873  } else if (MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)pn_iter) == PN_comp_if) {
2874  // if condition
2875  mp_parse_node_struct_t *pns_comp_if = (mp_parse_node_struct_t*)pn_iter;
2876  c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2877  pn_iter = pns_comp_if->nodes[1];
2878  goto tail_recursion;
2879  } else {
2880  assert(MP_PARSE_NODE_STRUCT_KIND((mp_parse_node_struct_t*)pn_iter) == PN_comp_for); // should be
2881  // for loop
2882  mp_parse_node_struct_t *pns_comp_for2 = (mp_parse_node_struct_t*)pn_iter;
2883  compile_node(comp, pns_comp_for2->nodes[1]);
2884  EMIT_ARG(get_iter, true);
2885  compile_scope_comp_iter(comp, pns_comp_for2, pn_inner_expr, for_depth + 1);
2886  }
2887 
2888  EMIT_ARG(jump, l_top);
2889  EMIT_ARG(label_assign, l_end);
2890  EMIT(for_iter_end);
2891 }
2892 
2893 STATIC void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) {
2894 #if MICROPY_ENABLE_DOC_STRING
2895  // see http://www.python.org/dev/peps/pep-0257/
2896 
2897  // look for the first statement
2898  if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2899  // a statement; fall through
2900  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2901  // file input; find the first non-newline node
2903  int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
2904  for (int i = 0; i < num_nodes; i++) {
2905  pn = pns->nodes[i];
2907  // not a newline, so this is the first statement; finish search
2908  break;
2909  }
2910  }
2911  // if we didn't find a non-newline then it's okay to fall through; pn will be a newline and so doc-string test below will fail gracefully
2912  } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2913  // a list of statements; get the first one
2914  pn = ((mp_parse_node_struct_t*)pn)->nodes[0];
2915  } else {
2916  return;
2917  }
2918 
2919  // check the first statement for a doc string
2920  if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2922  if ((MP_PARSE_NODE_IS_LEAF(pns->nodes[0])
2924  || (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_const_object)
2925  && MP_OBJ_IS_STR(get_const_object((mp_parse_node_struct_t*)pns->nodes[0])))) {
2926  // compile the doc string
2927  compile_node(comp, pns->nodes[0]);
2928  // store the doc string
2929  compile_store_id(comp, MP_QSTR___doc__);
2930  }
2931  }
2932 #else
2933  (void)comp;
2934  (void)pn;
2935 #endif
2936 }
2937 
2938 STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2939  comp->pass = pass;
2940  comp->scope_cur = scope;
2941  comp->next_label = 0;
2942  EMIT_ARG(start_pass, pass, scope);
2943 
2944  if (comp->pass == MP_PASS_SCOPE) {
2945  // reset maximum stack sizes in scope
2946  // they will be computed in this first pass
2947  scope->stack_size = 0;
2948  scope->exc_stack_size = 0;
2949  }
2950 
2951  // compile
2952  if (MP_PARSE_NODE_IS_STRUCT_KIND(scope->pn, PN_eval_input)) {
2953  assert(scope->kind == SCOPE_MODULE);
2955  compile_node(comp, pns->nodes[0]); // compile the expression
2956  EMIT(return_value);
2957  } else if (scope->kind == SCOPE_MODULE) {
2958  if (!comp->is_repl) {
2959  check_for_doc_string(comp, scope->pn);
2960  }
2961  compile_node(comp, scope->pn);
2962  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
2963  EMIT(return_value);
2964  } else if (scope->kind == SCOPE_FUNCTION) {
2967  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2968 
2969  // work out number of parameters, keywords and default parameters, and add them to the id_info array
2970  // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
2971  if (comp->pass == MP_PASS_SCOPE) {
2972  comp->have_star = false;
2973  apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2974  }
2975  #if MICROPY_EMIT_NATIVE
2976  else if (scope->emit_options == MP_EMIT_OPT_VIPER) {
2977  // compile annotations; only needed on latter compiler passes
2978  // only needed for viper emitter
2979 
2980  // argument annotations
2981  apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_annotations);
2982 
2983  // pns->nodes[2] is return/whole function annotation
2984  mp_parse_node_t pn_annotation = pns->nodes[2];
2985  if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) {
2986  // nodes[2] can be null or a test-expr
2987  if (MP_PARSE_NODE_IS_ID(pn_annotation)) {
2988  qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
2989  EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type);
2990  } else {
2991  compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier");
2992  }
2993  }
2994  }
2995  #endif // MICROPY_EMIT_NATIVE
2996 
2997  compile_node(comp, pns->nodes[3]); // 3 is function body
2998  // emit return if it wasn't the last opcode
2999  if (!EMIT(last_emit_was_return_value)) {
3000  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
3001  EMIT(return_value);
3002  }
3003  } else if (scope->kind == SCOPE_LAMBDA) {
3007 
3008  // work out number of parameters, keywords and default parameters, and add them to the id_info array
3009  // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
3010  if (comp->pass == MP_PASS_SCOPE) {
3011  comp->have_star = false;
3012  apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
3013  }
3014 
3015  compile_node(comp, pns->nodes[1]); // 1 is lambda body
3016 
3017  // if the lambda is a generator, then we return None, not the result of the expression of the lambda
3018  if (scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) {
3019  EMIT(pop_top);
3020  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
3021  }
3022  EMIT(return_value);
3023  } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
3024  // a bit of a hack at the moment
3025 
3029  assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
3030  mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1];
3031 
3032  // We need a unique name for the comprehension argument (the iterator).
3033  // CPython uses .0, but we should be able to use anything that won't
3034  // clash with a user defined variable. Best to use an existing qstr,
3035  // so we use the blank qstr.
3036  qstr qstr_arg = MP_QSTR_;
3037  if (comp->pass == MP_PASS_SCOPE) {
3038  bool added;
3039  id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
3040  assert(added);
3041  id_info->kind = ID_INFO_KIND_LOCAL;
3042  scope->num_pos_args = 1;
3043  }
3044 
3045  if (scope->kind == SCOPE_LIST_COMP) {
3046  EMIT_ARG(build_list, 0);
3047  } else if (scope->kind == SCOPE_DICT_COMP) {
3048  EMIT_ARG(build_map, 0);
3049  #if MICROPY_PY_BUILTINS_SET
3050  } else if (scope->kind == SCOPE_SET_COMP) {
3051  EMIT_ARG(build_set, 0);
3052  #endif
3053  }
3054 
3055  // There are 4 slots on the stack for the iterator, and the first one is
3056  // NULL to indicate that the second one points to the iterator object.
3057  if (scope->kind == SCOPE_GEN_EXPR) {
3058  // TODO static assert that MP_OBJ_ITER_BUF_NSLOTS == 4
3059  EMIT(load_null);
3060  compile_load_id(comp, qstr_arg);
3061  EMIT(load_null);
3062  EMIT(load_null);
3063  } else {
3064  compile_load_id(comp, qstr_arg);
3065  EMIT_ARG(get_iter, true);
3066  }
3067 
3068  compile_scope_comp_iter(comp, pns_comp_for, pns->nodes[0], 0);
3069 
3070  if (scope->kind == SCOPE_GEN_EXPR) {
3071  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
3072  }
3073  EMIT(return_value);
3074  } else {
3075  assert(scope->kind == SCOPE_CLASS);
3078  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
3079 
3080  if (comp->pass == MP_PASS_SCOPE) {
3081  bool added;
3082  id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added);
3083  assert(added);
3084  id_info->kind = ID_INFO_KIND_LOCAL;
3085  }
3086 
3087  compile_load_id(comp, MP_QSTR___name__);
3088  compile_store_id(comp, MP_QSTR___module__);
3089  EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
3090  compile_store_id(comp, MP_QSTR___qualname__);
3091 
3092  check_for_doc_string(comp, pns->nodes[2]);
3093  compile_node(comp, pns->nodes[2]); // 2 is class body
3094 
3095  id_info_t *id = scope_find(scope, MP_QSTR___class__);
3096  assert(id != NULL);
3097  if (id->kind == ID_INFO_KIND_LOCAL) {
3098  EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
3099  } else {
3100  EMIT_LOAD_FAST(MP_QSTR___class__, id->local_num);
3101  }
3102  EMIT(return_value);
3103  }
3104 
3105  EMIT(end_pass);
3106 
3107  // make sure we match all the exception levels
3108  assert(comp->cur_except_level == 0);
3109 }
3110 
3111 #if MICROPY_EMIT_INLINE_ASM
3112 // requires 3 passes: SCOPE, CODE_SIZE, EMIT
3113 STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
3114  comp->pass = pass;
3115  comp->scope_cur = scope;
3116  comp->next_label = 0;
3117 
3118  if (scope->kind != SCOPE_FUNCTION) {
3119  compile_syntax_error(comp, MP_PARSE_NODE_NULL, "inline assembler must be a function");
3120  return;
3121  }
3122 
3123  if (comp->pass > MP_PASS_SCOPE) {
3124  EMIT_INLINE_ASM_ARG(start_pass, comp->pass, &comp->compile_error);
3125  }
3126 
3127  // get the function definition parse node
3130  assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
3131 
3132  //qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
3133 
3134  // parameters are in pns->nodes[1]
3135  if (comp->pass == MP_PASS_CODE_SIZE) {
3136  mp_parse_node_t *pn_params;
3137  int n_params = mp_parse_node_extract_list(&pns->nodes[1], PN_typedargslist, &pn_params);
3138  scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params);
3139  if (comp->compile_error != MP_OBJ_NULL) {
3140  goto inline_asm_error;
3141  }
3142  }
3143 
3144  // pns->nodes[2] is function return annotation
3145  mp_uint_t type_sig = MP_NATIVE_TYPE_INT;
3146  mp_parse_node_t pn_annotation = pns->nodes[2];
3147  if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) {
3148  // nodes[2] can be null or a test-expr
3149  if (MP_PARSE_NODE_IS_ID(pn_annotation)) {
3150  qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
3151  switch (ret_type) {
3152  case MP_QSTR_object: type_sig = MP_NATIVE_TYPE_OBJ; break;
3153  case MP_QSTR_bool: type_sig = MP_NATIVE_TYPE_BOOL; break;
3154  case MP_QSTR_int: type_sig = MP_NATIVE_TYPE_INT; break;
3155  case MP_QSTR_uint: type_sig = MP_NATIVE_TYPE_UINT; break;
3156  default: compile_syntax_error(comp, pn_annotation, "unknown type"); return;
3157  }
3158  } else {
3159  compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier");
3160  }
3161  }
3162 
3163  mp_parse_node_t pn_body = pns->nodes[3]; // body
3164  mp_parse_node_t *nodes;
3165  int num = mp_parse_node_extract_list(&pn_body, PN_suite_block_stmts, &nodes);
3166 
3167  for (int i = 0; i < num; i++) {
3168  assert(MP_PARSE_NODE_IS_STRUCT(nodes[i]));
3170  if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_pass_stmt) {
3171  // no instructions
3172  continue;
3173  } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_expr_stmt) {
3174  // not an instruction; error
3175  not_an_instruction:
3176  compile_syntax_error(comp, nodes[i], "expecting an assembler instruction");
3177  return;
3178  }
3179 
3180  // check structure of parse node
3182  if (!MP_PARSE_NODE_IS_NULL(pns2->nodes[1])) {
3183  goto not_an_instruction;
3184  }
3185  pns2 = (mp_parse_node_struct_t*)pns2->nodes[0];
3186  if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_atom_expr_normal) {
3187  goto not_an_instruction;
3188  }
3189  if (!MP_PARSE_NODE_IS_ID(pns2->nodes[0])) {
3190  goto not_an_instruction;
3191  }
3192  if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)) {
3193  goto not_an_instruction;
3194  }
3195 
3196  // parse node looks like an instruction
3197  // get instruction name and args
3198  qstr op = MP_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
3199  pns2 = (mp_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
3200  mp_parse_node_t *pn_arg;
3201  int n_args = mp_parse_node_extract_list(&pns2->nodes[0], PN_arglist, &pn_arg);
3202 
3203  // emit instructions
3204  if (op == MP_QSTR_label) {
3205  if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) {
3206  compile_syntax_error(comp, nodes[i], "'label' requires 1 argument");
3207  return;
3208  }
3209  uint lab = comp_next_label(comp);
3210  if (pass > MP_PASS_SCOPE) {
3211  if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) {
3212  compile_syntax_error(comp, nodes[i], "label redefined");
3213  return;
3214  }
3215  }
3216  } else if (op == MP_QSTR_align) {
3217  if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
3218  compile_syntax_error(comp, nodes[i], "'align' requires 1 argument");
3219  return;
3220  }
3221  if (pass > MP_PASS_SCOPE) {
3222  mp_asm_base_align((mp_asm_base_t*)comp->emit_inline_asm,
3223  MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]));
3224  }
3225  } else if (op == MP_QSTR_data) {
3226  if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
3227  compile_syntax_error(comp, nodes[i], "'data' requires at least 2 arguments");
3228  return;
3229  }
3230  if (pass > MP_PASS_SCOPE) {
3231  mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
3232  for (uint j = 1; j < n_args; j++) {
3233  if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) {
3234  compile_syntax_error(comp, nodes[i], "'data' requires integer arguments");
3235  return;
3236  }
3237  mp_asm_base_data((mp_asm_base_t*)comp->emit_inline_asm,
3238  bytesize, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[j]));
3239  }
3240  }
3241  } else {
3242  if (pass > MP_PASS_SCOPE) {
3243  EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg);
3244  }
3245  }
3246 
3247  if (comp->compile_error != MP_OBJ_NULL) {
3248  pns = pns2; // this is the parse node that had the error
3249  goto inline_asm_error;
3250  }
3251  }
3252 
3253  if (comp->pass > MP_PASS_SCOPE) {
3254  EMIT_INLINE_ASM_ARG(end_pass, type_sig);
3255 
3256  if (comp->pass == MP_PASS_EMIT) {
3257  void *f = mp_asm_base_get_code((mp_asm_base_t*)comp->emit_inline_asm);
3258  mp_emit_glue_assign_native(comp->scope_cur->raw_code, MP_CODE_NATIVE_ASM,
3259  f, mp_asm_base_get_code_size((mp_asm_base_t*)comp->emit_inline_asm),
3260  NULL, comp->scope_cur->num_pos_args, 0, type_sig);
3261  }
3262  }
3263 
3264  if (comp->compile_error != MP_OBJ_NULL) {
3265  // inline assembler had an error; set line for its exception
3266  inline_asm_error:
3267  comp->compile_error_line = pns->source_line;
3268  }
3269 }
3270 #endif
3271 
3272 STATIC void scope_compute_things(scope_t *scope) {
3273  // in MicroPython we put the *x parameter after all other parameters (except **y)
3274  if (scope->scope_flags & MP_SCOPE_FLAG_VARARGS) {
3275  id_info_t *id_param = NULL;
3276  for (int i = scope->id_info_len - 1; i >= 0; i--) {
3277  id_info_t *id = &scope->id_info[i];
3278  if (id->flags & ID_FLAG_IS_STAR_PARAM) {
3279  if (id_param != NULL) {
3280  // swap star param with last param
3281  id_info_t temp = *id_param; *id_param = *id; *id = temp;
3282  }
3283  break;
3284  } else if (id_param == NULL && id->flags == ID_FLAG_IS_PARAM) {
3285  id_param = id;
3286  }
3287  }
3288  }
3289 
3290  // in functions, turn implicit globals into explicit globals
3291  // compute the index of each local
3292  scope->num_locals = 0;
3293  for (int i = 0; i < scope->id_info_len; i++) {
3294  id_info_t *id = &scope->id_info[i];
3295  if (scope->kind == SCOPE_CLASS && id->qst == MP_QSTR___class__) {
3296  // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
3297  continue;
3298  }
3299  if (SCOPE_IS_FUNC_LIKE(scope->kind) && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
3301  }
3302  // params always count for 1 local, even if they are a cell
3303  if (id->kind == ID_INFO_KIND_LOCAL || (id->flags & ID_FLAG_IS_PARAM)) {
3304  id->local_num = scope->num_locals++;
3305  }
3306  }
3307 
3308  // compute the index of cell vars
3309  for (int i = 0; i < scope->id_info_len; i++) {
3310  id_info_t *id = &scope->id_info[i];
3311  // in MicroPython the cells come right after the fast locals
3312  // parameters are not counted here, since they remain at the start
3313  // of the locals, even if they are cell vars
3314  if (id->kind == ID_INFO_KIND_CELL && !(id->flags & ID_FLAG_IS_PARAM)) {
3315  id->local_num = scope->num_locals;
3316  scope->num_locals += 1;
3317  }
3318  }
3319 
3320  // compute the index of free vars
3321  // make sure they are in the order of the parent scope
3322  if (scope->parent != NULL) {
3323  int num_free = 0;
3324  for (int i = 0; i < scope->parent->id_info_len; i++) {
3325  id_info_t *id = &scope->parent->id_info[i];
3326  if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
3327  for (int j = 0; j < scope->id_info_len; j++) {
3328  id_info_t *id2 = &scope->id_info[j];
3329  if (id2->kind == ID_INFO_KIND_FREE && id->qst == id2->qst) {
3330  assert(!(id2->flags & ID_FLAG_IS_PARAM)); // free vars should not be params
3331  // in MicroPython the frees come first, before the params
3332  id2->local_num = num_free;
3333  num_free += 1;
3334  }
3335  }
3336  }
3337  }
3338  // in MicroPython shift all other locals after the free locals
3339  if (num_free > 0) {
3340  for (int i = 0; i < scope->id_info_len; i++) {
3341  id_info_t *id = &scope->id_info[i];
3342  if (id->kind != ID_INFO_KIND_FREE || (id->flags & ID_FLAG_IS_PARAM)) {
3343  id->local_num += num_free;
3344  }
3345  }
3346  scope->num_pos_args += num_free; // free vars are counted as params for passing them into the function
3347  scope->num_locals += num_free;
3348  }
3349  }
3350 }
3351 
3352 #if !MICROPY_PERSISTENT_CODE_SAVE
3353 STATIC
3354 #endif
3355 mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt, bool is_repl) {
3356  // put compiler state on the stack, it's relatively small
3357  compiler_t comp_state = {0};
3358  compiler_t *comp = &comp_state;
3359 
3360  comp->source_file = source_file;
3361  comp->is_repl = is_repl;
3362  comp->break_label = INVALID_LABEL;
3363  comp->continue_label = INVALID_LABEL;
3364 
3365  // create the module scope
3366  scope_t *module_scope = scope_new_and_link(comp, SCOPE_MODULE, parse_tree->root, emit_opt);
3367 
3368  // create standard emitter; it's used at least for MP_PASS_SCOPE
3369  emit_t *emit_bc = emit_bc_new();
3370 
3371  // compile pass 1
3372  comp->emit = emit_bc;
3373  #if MICROPY_EMIT_NATIVE
3374  comp->emit_method_table = &emit_bc_method_table;
3375  #endif
3376  uint max_num_labels = 0;
3377  for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
3378  if (false) {
3379  #if MICROPY_EMIT_INLINE_ASM
3380  } else if (s->emit_options == MP_EMIT_OPT_ASM) {
3381  compile_scope_inline_asm(comp, s, MP_PASS_SCOPE);
3382  #endif
3383  } else {
3384  compile_scope(comp, s, MP_PASS_SCOPE);
3385  }
3386 
3387  // update maximim number of labels needed
3388  if (comp->next_label > max_num_labels) {
3389  max_num_labels = comp->next_label;
3390  }
3391  }
3392 
3393  // compute some things related to scope and identifiers
3394  for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
3395  scope_compute_things(s);
3396  }
3397 
3398  // set max number of labels now that it's calculated
3399  emit_bc_set_max_num_labels(emit_bc, max_num_labels);
3400 
3401  // compile pass 2 and 3
3402 #if MICROPY_EMIT_NATIVE
3403  emit_t *emit_native = NULL;
3404 #endif
3405  for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
3406  if (false) {
3407  // dummy
3408 
3409  #if MICROPY_EMIT_INLINE_ASM
3410  } else if (s->emit_options == MP_EMIT_OPT_ASM) {
3411  // inline assembly
3412  if (comp->emit_inline_asm == NULL) {
3413  comp->emit_inline_asm = ASM_EMITTER(new)(max_num_labels);
3414  }
3415  comp->emit = NULL;
3416  comp->emit_inline_asm_method_table = &ASM_EMITTER(method_table);
3417  compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
3418  #if MICROPY_EMIT_INLINE_XTENSA
3419  // Xtensa requires an extra pass to compute size of l32r const table
3420  // TODO this can be improved by calculating it during SCOPE pass
3421  // but that requires some other structural changes to the asm emitters
3422  compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
3423  #endif
3424  if (comp->compile_error == MP_OBJ_NULL) {
3425  compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
3426  }
3427  #endif
3428 
3429  } else {
3430 
3431  // choose the emit type
3432 
3433  switch (s->emit_options) {
3434 
3435 #if MICROPY_EMIT_NATIVE
3437  case MP_EMIT_OPT_VIPER:
3438  if (emit_native == NULL) {
3439  emit_native = NATIVE_EMITTER(new)(&comp->compile_error, max_num_labels);
3440  }
3441  comp->emit_method_table = &NATIVE_EMITTER(method_table);
3442  comp->emit = emit_native;
3443  EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0);
3444  break;
3445 #endif // MICROPY_EMIT_NATIVE
3446 
3447  default:
3448  comp->emit = emit_bc;
3449  #if MICROPY_EMIT_NATIVE
3450  comp->emit_method_table = &emit_bc_method_table;
3451  #endif
3452  break;
3453  }
3454 
3455  // need a pass to compute stack size
3456  compile_scope(comp, s, MP_PASS_STACK_SIZE);
3457 
3458  // second last pass: compute code size
3459  if (comp->compile_error == MP_OBJ_NULL) {
3460  compile_scope(comp, s, MP_PASS_CODE_SIZE);
3461  }
3462 
3463  // final pass: emit code
3464  if (comp->compile_error == MP_OBJ_NULL) {
3465  compile_scope(comp, s, MP_PASS_EMIT);
3466  }
3467  }
3468  }
3469 
3470  if (comp->compile_error != MP_OBJ_NULL) {
3471  // if there is no line number for the error then use the line
3472  // number for the start of this scope
3473  compile_error_set_line(comp, comp->scope_cur->pn);
3474  // add a traceback to the exception using relevant source info
3475  mp_obj_exception_add_traceback(comp->compile_error, comp->source_file,
3476  comp->compile_error_line, comp->scope_cur->simple_name);
3477  }
3478 
3479  // free the emitters
3480 
3481  emit_bc_free(emit_bc);
3482 #if MICROPY_EMIT_NATIVE
3483  if (emit_native != NULL) {
3484  NATIVE_EMITTER(free)(emit_native);
3485  }
3486 #endif
3487  #if MICROPY_EMIT_INLINE_ASM
3488  if (comp->emit_inline_asm != NULL) {
3489  ASM_EMITTER(free)(comp->emit_inline_asm);
3490  }
3491  #endif
3492 
3493  // free the parse tree
3494  mp_parse_tree_clear(parse_tree);
3495 
3496  // free the scopes
3497  mp_raw_code_t *outer_raw_code = module_scope->raw_code;
3498  for (scope_t *s = module_scope; s;) {
3499  scope_t *next = s->next;
3500  scope_free(s);
3501  s = next;
3502  }
3503 
3504  if (comp->compile_error != MP_OBJ_NULL) {
3505  nlr_raise(comp->compile_error);
3506  } else {
3507  return outer_raw_code;
3508  }
3509 }
3510 
3511 mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt, bool is_repl) {
3512  mp_raw_code_t *rc = mp_compile_to_raw_code(parse_tree, source_file, emit_opt, is_repl);
3513  // return function that executes the outer module
3515 }
3516 
3517 #endif // MICROPY_ENABLE_COMPILER
uint16_t num_locals
Definition: scope.h:82
mp_parse_node_t pn
Definition: scope.h:73
bool mp_parse_node_is_const_true(mp_parse_node_t pn)
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN
Definition: mpconfigport.h:20
intptr_t mp_int_t
Definition: mpconfigport.h:73
uintptr_t mp_uint_t
Definition: mpconfigport.h:74
bool mp_parse_node_is_const_false(mp_parse_node_t pn)
mp_parse_node_t root
Definition: parse.h:98
void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emit_method_table, scope_t *scope, qstr qst)
id_info_t * scope_find_global(scope_t *scope, qstr qstr)
uint16_t id_info_len
Definition: scope.h:86
qstr qst
Definition: scope.h:52
#define assert(e)
Definition: assert.h:9
mp_parse_node_t nodes[]
Definition: parse.h:57
#define MICROPY_ERROR_REPORTING_TERSE
Definition: mpconfig.h:521
#define MP_SCOPE_FLAG_VARKEYWORDS
Definition: runtime0.h:31
#define mp_const_none
Definition: obj.h:614
uint16_t exc_stack_size
Definition: scope.h:84
uint16_t simple_name
Definition: scope.h:75
def data
Definition: i18n.py:176
scope_kind_t kind
Definition: scope.h:70
#define MP_PARSE_NODE_STRUCT_KIND(pns)
Definition: parse.h:76
STATIC const uint8_t attr[]
Definition: unicode.c:51
#define MP_PARSE_NODE_LEAF_KIND(pn)
Definition: parse.h:73
#define MP_PARSE_NODE_LEAF_SMALL_INT(pn)
Definition: parse.h:75
#define MP_PARSE_NODE_IS_SMALL_INT(pn)
Definition: parse.h:68
#define MICROPY_EMIT_NATIVE
Definition: mpconfig.h:301
unsigned int uintptr_t
Definition: stdint.h:14
#define MP_SCOPE_FLAG_VARARGS
Definition: runtime0.h:30
uint8_t emit_options
Definition: scope.h:78
void emit_bc_free(emit_t *emit)
unsigned short uint16_t
Definition: stdint.h:5
LIBA_BEGIN_DECLS void free(void *ptr)
Definition: malloc.c:33
#define MP_NATIVE_TYPE_OBJ
Definition: runtime0.h:36
#define MP_SCOPE_FLAG_GENERATOR
Definition: runtime0.h:32
#define MP_STATE_VM(x)
Definition: mpstate.h:241
unsigned char uint8_t
Definition: stdint.h:4
mp_unary_op_t
Definition: runtime0.h:45
#define MP_EMIT_STAR_FLAG_DOUBLE
Definition: emit.h:50
uint8_t scope_flags
Definition: scope.h:77
mp_obj_t mp_obj_new_int_from_ll(long long val)
Definition: objint.c:332
uintptr_t mp_parse_node_t
Definition: parse.h:52
uint32_t source_line
Definition: parse.h:55
#define MP_PARSE_NODE_STRUCT_NUM_NODES(pns)
Definition: parse.h:77
#define STATIC
Definition: mpconfig.h:1178
#define MP_EMIT_BREAK_FROM_FOR
Definition: emit.h:52
enum _mp_token_kind_t mp_token_kind_t
const mp_obj_type_t mp_type_SyntaxError
void mp_asm_base_align(mp_asm_base_t *as, unsigned int align)
emit_t * emit_bc_new(void)
#define MICROPY_PY_BUILTINS_SET
Definition: mpconfigport.h:41
#define MP_EMIT_NATIVE_TYPE_ARG
Definition: emit.h:56
mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg)
Definition: objexcept.c:343
id_info_t * scope_find(scope_t *scope, qstr qstr)
void mp_asm_base_data(mp_asm_base_t *as, unsigned int bytesize, uintptr_t val)
#define MP_EMIT_NATIVE_TYPE_RETURN
Definition: emit.h:55
id_info_t * id_info
Definition: scope.h:87
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig)
#define MP_PARSE_NODE_IS_ID(pn)
Definition: parse.h:69
#define MICROPY_ERROR_REPORTING
Definition: mpconfigport.h:32
#define MP_PARSE_NODE_BYTES
Definition: parse.h:49
#define MP_PARSE_NODE_IS_TOKEN_KIND(pn, k)
Definition: parse.h:71
#define MP_PARSE_NODE_IS_STRUCT_KIND(pn, k)
Definition: parse.h:66
#define MP_PARSE_NODE_IS_TOKEN(pn)
Definition: parse.h:70
mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt, bool is_repl)
int mp_parse_node_extract_list(mp_parse_node_t *pn, size_t pn_kind, mp_parse_node_t **nodes)
#define NULL
Definition: stddef.h:4
const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops
#define MP_OBJ_NULL
Definition: obj.h:73
#define MP_PARSE_NODE_STRING
Definition: parse.h:48
#define MP_PARSE_NODE_TOKEN
Definition: parse.h:50
unsigned long long uint64_t
Definition: stdint.h:7
void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst)
mp_raw_code_t * raw_code
Definition: scope.h:76
size_t qstr
Definition: qstr.h:48
#define MP_EMIT_NATIVE_TYPE_ENABLE
Definition: emit.h:54
mp_obj_t mp_obj_new_bytes(const byte *data, size_t len)
Definition: objstr.c:2046
mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args)
Definition: emitglue.c:116
mp_binary_op_t
Definition: runtime0.h:67
id_info_t * scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added)
#define MP_NATIVE_TYPE_UINT
Definition: runtime0.h:39
void scope_free(scope_t *scope)
uint16_t num_pos_args
Definition: scope.h:79
#define MP_PARSE_NODE_ID
Definition: parse.h:47
#define MICROPY_COMP_RETURN_IF_EXPR
Definition: mpconfig.h:358
args
Definition: i18n.py:175
scope_t * scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_uint_t emit_options)
void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst)
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block)
Definition: objexcept.c:485
#define MP_NATIVE_TYPE_BOOL
Definition: runtime0.h:37
tok(NEWLINE)
scope_kind_t
Definition: scope.h:58
unsigned char byte
Definition: misc.h:37
const byte * qstr_data(qstr q, size_t *len)
Definition: qstr.c:283
const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops
Definition: scope.h:69
struct _scope_t * parent
Definition: scope.h:71
uint8_t kind
Definition: scope.h:47
#define MP_PARSE_NODE_LEAF_ARG(pn)
Definition: parse.h:74
const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops
#define SCOPE_IS_FUNC_LIKE(s)
Definition: scope.h:55
byte * qstr_build_start(size_t len, byte **q_ptr)
Definition: qstr.c:246
void scope_find_local_and_close_over(scope_t *scope, id_info_t *id, qstr qst)
qstr qstr_build_end(byte *q_ptr)
Definition: qstr.c:253
#define MP_PARSE_NODE_IS_STRUCT(pn)
Definition: parse.h:65
uint8_t flags
Definition: scope.h:48
#define MP_EMIT_STAR_FLAG_SINGLE
Definition: emit.h:49
#define nlr_raise(val)
Definition: nlr.h:89
const emit_method_table_t emit_bc_method_table
uint64_t mp_obj_t
Definition: obj.h:39
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN
Definition: mpconfigport.h:21
uint16_t stack_size
Definition: scope.h:83
#define MP_PARSE_NODE_IS_LEAF(pn)
Definition: parse.h:64
#define MP_PARSE_NODE_IS_NULL(pn)
Definition: parse.h:63
void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels)
#define MP_OBJ_IS_STR(o)
Definition: obj.h:256
void mp_parse_tree_clear(mp_parse_tree_t *tree)
uint16_t local_num
Definition: scope.h:51
#define MP_SCOPE_FLAG_DEFKWARGS
Definition: runtime0.h:33
size_t qstr_len(qstr q)
Definition: qstr.c:273
uint16_t num_def_pos_args
Definition: scope.h:81
#define MP_NATIVE_TYPE_INT
Definition: runtime0.h:38
void * memcpy(void *dst, const void *src, size_t n)
Definition: memcpy.c:3
#define MP_PARSE_NODE_NULL
Definition: parse.h:45
struct _emit_t emit_t
Definition: emit.h:58
pass_kind_t
Definition: emit.h:42
struct _emit_inline_asm_t emit_inline_asm_t
Definition: emit.h:260
struct _scope_t * next
Definition: scope.h:72
unsigned int uint
Definition: misc.h:38