blob: 810446189d58f09cd222b0bf28e4414612bc4146 [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <unistd.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <stdio.h>
5#include <string.h>
6#include <assert.h>
7
8#include "misc.h"
Damienc025ebb2013-10-12 14:30:21 +01009#include "mpyconfig.h"
Damien429d7192013-10-04 19:53:11 +010010#include "lexer.h"
Damien429d7192013-10-04 19:53:11 +010011#include "parse.h"
12#include "scope.h"
13#include "compile.h"
14#include "runtime.h"
15#include "emit.h"
16
17// TODO need to mangle __attr names
Damien415eb6f2013-10-05 12:19:06 +010018// TODO add #define to enable/disable CPython compatibility
Damien429d7192013-10-04 19:53:11 +010019
20typedef enum {
21 PN_none = 0,
22#define DEF_RULE(rule, comp, kind, arg...) PN_##rule,
23#include "grammar.h"
24#undef DEF_RULE
25 PN_maximum_number_of,
26} pn_kind_t;
27
Damien415eb6f2013-10-05 12:19:06 +010028#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
Damien826005c2013-10-05 23:17:28 +010029#define EMIT_INLINE_ASM(fun, arg...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, ##arg))
Damien429d7192013-10-04 19:53:11 +010030
Damien6cdd3af2013-10-05 18:08:26 +010031#define EMIT_OPT_NONE (0)
32#define EMIT_OPT_BYTE_CODE (1)
33#define EMIT_OPT_NATIVE_PYTHON (2)
Damien7af3d192013-10-07 00:02:49 +010034#define EMIT_OPT_VIPER (3)
35#define EMIT_OPT_ASM_THUMB (4)
Damien6cdd3af2013-10-05 18:08:26 +010036
Damien429d7192013-10-04 19:53:11 +010037typedef struct _compiler_t {
38 qstr qstr___class__;
39 qstr qstr___locals__;
40 qstr qstr___name__;
41 qstr qstr___module__;
42 qstr qstr___qualname__;
43 qstr qstr___doc__;
44 qstr qstr_assertion_error;
Damien6cdd3af2013-10-05 18:08:26 +010045 qstr qstr_micropython;
46 qstr qstr_native;
Damien7af3d192013-10-07 00:02:49 +010047 qstr qstr_viper;
Damien5bfb7592013-10-05 18:41:24 +010048 qstr qstr_asm_thumb;
Damien429d7192013-10-04 19:53:11 +010049
50 pass_kind_t pass;
51
Damienb05d7072013-10-05 13:37:10 +010052 int next_label;
Damienb05d7072013-10-05 13:37:10 +010053
Damien429d7192013-10-04 19:53:11 +010054 int break_label;
55 int continue_label;
56 int except_nest_level;
57
58 int n_arg_keyword;
59 bool have_star_arg;
60 bool have_dbl_star_arg;
61 bool have_bare_star;
62 int param_pass;
63 int param_pass_num_dict_params;
64 int param_pass_num_default_params;
65
66 scope_t *scope_head;
67 scope_t *scope_cur;
68
Damien6cdd3af2013-10-05 18:08:26 +010069 emit_t *emit; // current emitter
70 const emit_method_table_t *emit_method_table; // current emit method table
Damien826005c2013-10-05 23:17:28 +010071
72 emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
73 const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm
Damien429d7192013-10-04 19:53:11 +010074} compiler_t;
75
76py_parse_node_t fold_constants(py_parse_node_t pn) {
77 if (PY_PARSE_NODE_IS_STRUCT(pn)) {
78 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
79 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
80
81 // fold arguments first
82 for (int i = 0; i < n; i++) {
83 pns->nodes[i] = fold_constants(pns->nodes[i]);
84 }
85
86 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
87 case PN_shift_expr:
88 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
89 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
90 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
91 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_LESS)) {
92 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1); // XXX can overflow; enabled only to compare with CPython
93 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) {
94 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1);
95 } else {
96 // shouldn't happen
97 assert(0);
98 }
99 }
100 break;
101
102 case PN_arith_expr:
103 // XXX can overflow; enabled only to compare with CPython
104 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
105 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
106 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
107 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) {
108 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 + arg1);
109 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) {
110 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 - arg1);
111 } else {
112 // shouldn't happen
113 assert(0);
114 }
115 }
116 break;
117
118 case PN_term:
119 // XXX can overflow; enabled only to compare with CPython
120 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
121 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
122 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
123 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
124 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1);
125 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) {
126 ; // pass
127 //} else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_)) {
128 //pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 - arg1);
129 } else {
130 // shouldn't happen
131 assert(0);
132 }
133 }
134 break;
135
136 case PN_factor_2:
137 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) {
138 machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
139 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
140 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg);
141 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
142 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, -arg);
143 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
144 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg);
145 } else {
146 // shouldn't happen
147 assert(0);
148 }
149 }
150 break;
151
152 case PN_power:
153 // XXX can overflow; enabled only to compare with CPython
154 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_NULL(pns->nodes[1]) && !PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
155 py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2];
156 if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
157 int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
158 if (power >= 0) {
159 int ans = 1;
160 int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
161 for (; power > 0; power--) {
162 ans *= base;
163 }
164 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans);
165 }
166 }
167 }
168 break;
169 }
170 }
171
172 return pn;
173}
174
175void compile_node(compiler_t *comp, py_parse_node_t pn);
176
Damienb05d7072013-10-05 13:37:10 +0100177static int comp_next_label(compiler_t *comp) {
178 return comp->next_label++;
179}
180
Damien6cdd3af2013-10-05 18:08:26 +0100181static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse_node_t pn, uint emit_options) {
182 scope_t *scope = scope_new(kind, pn, rt_get_new_unique_code_id(), emit_options);
Damien429d7192013-10-04 19:53:11 +0100183 scope->parent = comp->scope_cur;
184 scope->next = NULL;
185 if (comp->scope_head == NULL) {
186 comp->scope_head = scope;
187 } else {
188 scope_t *s = comp->scope_head;
189 while (s->next != NULL) {
190 s = s->next;
191 }
192 s->next = scope;
193 }
194 return scope;
195}
196
Damienb05d7072013-10-05 13:37:10 +0100197static int list_len(py_parse_node_t pn, int pn_kind) {
Damien429d7192013-10-04 19:53:11 +0100198 if (PY_PARSE_NODE_IS_NULL(pn)) {
199 return 0;
200 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
201 return 1;
202 } else {
203 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
204 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
205 return 1;
206 } else {
207 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
208 }
209 }
210}
211
Damienb05d7072013-10-05 13:37:10 +0100212static void apply_to_single_or_list(compiler_t *comp, py_parse_node_t pn, int pn_list_kind, void (*f)(compiler_t*, py_parse_node_t)) {
Damien429d7192013-10-04 19:53:11 +0100213 if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) {
214 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
215 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
216 for (int i = 0; i < num_nodes; i++) {
217 f(comp, pns->nodes[i]);
218 }
219 } else if (!PY_PARSE_NODE_IS_NULL(pn)) {
220 f(comp, pn);
221 }
222}
223
Damienb05d7072013-10-05 13:37:10 +0100224static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) {
Damien429d7192013-10-04 19:53:11 +0100225 if (PY_PARSE_NODE_IS_NULL(*pn)) {
226 *nodes = NULL;
227 return 0;
228 } else if (PY_PARSE_NODE_IS_LEAF(*pn)) {
229 *nodes = pn;
230 return 1;
231 } else {
232 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn);
233 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
234 *nodes = pn;
235 return 1;
236 } else {
237 *nodes = pns->nodes;
238 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
239 }
240 }
241}
242
243void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) {
244}
245
246void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) {
247 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
248 for (int i = 0; i < num_nodes; i++) {
249 compile_node(comp, pns->nodes[i]);
250 }
251}
252
253bool c_tuple_is_const(py_parse_node_t pn) {
254 if (!PY_PARSE_NODE_IS_LEAF(pn)) {
255 return false;
256 }
257 if (PY_PARSE_NODE_IS_ID(pn)) {
258 return false;
259 }
260 return true;
261}
262
263void c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn) {
264 assert(PY_PARSE_NODE_IS_LEAF(pn));
265 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
266 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
267 case PY_PARSE_NODE_ID: assert(0);
268 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_verbatim_int, arg); break;
269 case PY_PARSE_NODE_INTEGER: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
270 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
271 case PY_PARSE_NODE_STRING: EMIT(load_const_verbatim_quoted_str, arg, false); break;
272 case PY_PARSE_NODE_BYTES: EMIT(load_const_verbatim_quoted_str, arg, true); break;
273 case PY_PARSE_NODE_TOKEN:
274 switch (arg) {
275 case PY_TOKEN_KW_FALSE: EMIT(load_const_verbatim_str, "False"); break;
276 case PY_TOKEN_KW_NONE: EMIT(load_const_verbatim_str, "None"); break;
277 case PY_TOKEN_KW_TRUE: EMIT(load_const_verbatim_str, "True"); break;
278 default: assert(0);
279 }
280 break;
281 default: assert(0);
282 }
283}
284
285// funnelling all tuple creations through this function and all this constant stuff is purely to agree with CPython
286void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
287 int n = 0;
288 if (pns_list != NULL) {
289 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
290 }
291 int total = n;
292 bool is_const = true;
293 if (!PY_PARSE_NODE_IS_NULL(pn)) {
294 total += 1;
295 if (!c_tuple_is_const(pn)) {
296 is_const = false;
297 }
298 }
299 for (int i = 0; i < n; i++) {
300 if (!c_tuple_is_const(pns_list->nodes[i])) {
301 is_const = false;
302 break;
303 }
304 }
305 if (total > 0 && is_const) {
306 bool need_comma = false;
307 EMIT(load_const_verbatim_start);
308 EMIT(load_const_verbatim_str, "(");
309 if (!PY_PARSE_NODE_IS_NULL(pn)) {
310 c_tuple_emit_const(comp, pn);
311 need_comma = true;
312 }
313 for (int i = 0; i < n; i++) {
314 if (need_comma) {
315 EMIT(load_const_verbatim_str, ", ");
316 }
317 c_tuple_emit_const(comp, pns_list->nodes[i]);
318 need_comma = true;
319 }
320 if (total == 1) {
321 EMIT(load_const_verbatim_str, ",)");
322 } else {
323 EMIT(load_const_verbatim_str, ")");
324 }
325 EMIT(load_const_verbatim_end);
326 } else {
327 if (!PY_PARSE_NODE_IS_NULL(pn)) {
328 compile_node(comp, pn);
329 }
330 for (int i = 0; i < n; i++) {
331 compile_node(comp, pns_list->nodes[i]);
332 }
333 EMIT(build_tuple, total);
334 }
335}
336
337void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
338 // a simple tuple expression
339 /*
340 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
341 for (int i = 0; i < n; i++) {
342 compile_node(comp, pns->nodes[i]);
343 }
344 EMIT(build_tuple, n);
345 */
346 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
347}
348
349bool node_is_const_false(py_parse_node_t pn) {
350 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
351 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
352}
353
354bool node_is_const_true(py_parse_node_t pn) {
355 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_TRUE) || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
356}
357
358// having c_if_cond_2 and the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
359void c_if_cond_2(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label, bool is_nested) {
360 if (node_is_const_false(pn)) {
361 if (jump_if == false) {
362 EMIT(jump, label);
363 }
364 return;
365 } else if (node_is_const_true(pn)) {
366 if (jump_if == true) {
367 EMIT(jump, label);
368 }
369 return;
370 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
371 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
372 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
373 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
374 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100375 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100376 for (int i = 0; i < n - 1; i++) {
377 c_if_cond_2(comp, pns->nodes[i], true, label2, true);
378 }
379 c_if_cond_2(comp, pns->nodes[n - 1], false, label, true);
380 EMIT(label_assign, label2);
381 } else {
382 for (int i = 0; i < n; i++) {
383 c_if_cond_2(comp, pns->nodes[i], true, label, true);
384 }
385 }
386 return;
387 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
388 if (jump_if == false) {
389 for (int i = 0; i < n; i++) {
390 c_if_cond_2(comp, pns->nodes[i], false, label, true);
391 }
392 } else {
Damienb05d7072013-10-05 13:37:10 +0100393 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100394 for (int i = 0; i < n - 1; i++) {
395 c_if_cond_2(comp, pns->nodes[i], false, label2, true);
396 }
397 c_if_cond_2(comp, pns->nodes[n - 1], true, label, true);
398 EMIT(label_assign, label2);
399 }
400 return;
401 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
402 c_if_cond_2(comp, pns->nodes[0], !jump_if, label, true);
403 return;
404 }
405 }
406
407 // nothing special, fall back to default compiling for node and jump
408 compile_node(comp, pn);
409 if (jump_if == false) {
410 EMIT(pop_jump_if_false, label);
411 } else {
412 EMIT(pop_jump_if_true, label);
413 }
414}
415
416void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
417 c_if_cond_2(comp, pn, jump_if, label, false);
418}
419
420typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
421void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
422
423void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
424 if (assign_kind != ASSIGN_AUG_STORE) {
425 compile_node(comp, pns->nodes[0]);
426 }
427
428 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
429 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
430 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
431 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
432 if (assign_kind != ASSIGN_AUG_STORE) {
433 for (int i = 0; i < n - 1; i++) {
434 compile_node(comp, pns1->nodes[i]);
435 }
436 }
437 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
438 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
439 }
440 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
441 printf("SyntaxError: can't assign to function call\n");
442 return;
443 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
444 if (assign_kind == ASSIGN_AUG_STORE) {
445 EMIT(rot_three);
446 EMIT(store_subscr);
447 } else {
448 compile_node(comp, pns1->nodes[0]);
449 if (assign_kind == ASSIGN_AUG_LOAD) {
450 EMIT(dup_top_two);
451 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
452 } else {
453 EMIT(store_subscr);
454 }
455 }
456 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
457 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
458 if (assign_kind == ASSIGN_AUG_LOAD) {
459 EMIT(dup_top);
460 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
461 } else {
462 if (assign_kind == ASSIGN_AUG_STORE) {
463 EMIT(rot_two);
464 }
465 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
466 }
467 } else {
468 // shouldn't happen
469 assert(0);
470 }
471 } else {
472 // shouldn't happen
473 assert(0);
474 }
475
476 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
477 // SyntaxError, cannot assign
478 assert(0);
479 }
480}
481
482void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
483 assert(n >= 0);
484 int have_star_index = -1;
485 for (int i = 0; i < n; i++) {
486 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
487 if (have_star_index < 0) {
488 EMIT(unpack_ex, i, n - i - 1);
489 have_star_index = i;
490 } else {
491 printf("SyntaxError: two starred expressions in assignment\n");
492 return;
493 }
494 }
495 }
496 if (have_star_index < 0) {
497 EMIT(unpack_sequence, n);
498 }
499 for (int i = 0; i < n; i++) {
500 if (i == have_star_index) {
501 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
502 } else {
503 c_assign(comp, nodes[i], ASSIGN_STORE);
504 }
505 }
506}
507
508// assigns top of stack to pn
509void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
510 tail_recursion:
511 if (PY_PARSE_NODE_IS_NULL(pn)) {
512 assert(0);
513 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
514 if (PY_PARSE_NODE_IS_ID(pn)) {
515 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
516 switch (assign_kind) {
517 case ASSIGN_STORE:
518 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100519 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100520 break;
521 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100522 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100523 break;
524 }
525 } else {
526 printf("SyntaxError: can't assign to literal\n");
527 return;
528 }
529 } else {
530 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
531 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
532 case PN_power:
533 // lhs is an index or attribute
534 c_assign_power(comp, pns, assign_kind);
535 break;
536
537 case PN_testlist_star_expr:
538 case PN_exprlist:
539 // lhs is a tuple
540 if (assign_kind != ASSIGN_STORE) {
541 goto bad_aug;
542 }
543 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
544 break;
545
546 case PN_atom_paren:
547 // lhs is something in parenthesis
548 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
549 // empty tuple
550 printf("SyntaxError: can't assign to ()\n");
551 return;
552 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
553 pns = (py_parse_node_struct_t*)pns->nodes[0];
554 goto testlist_comp;
555 } else {
556 // parenthesis around 1 item, is just that item
557 pn = pns->nodes[0];
558 goto tail_recursion;
559 }
560 break;
561
562 case PN_atom_bracket:
563 // lhs is something in brackets
564 if (assign_kind != ASSIGN_STORE) {
565 goto bad_aug;
566 }
567 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
568 // empty list, assignment allowed
569 c_assign_tuple(comp, 0, NULL);
570 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
571 pns = (py_parse_node_struct_t*)pns->nodes[0];
572 goto testlist_comp;
573 } else {
574 // brackets around 1 item
575 c_assign_tuple(comp, 1, &pns->nodes[0]);
576 }
577 break;
578
579 default:
580 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
581 assert(0);
582 }
583 return;
584
585 testlist_comp:
586 // lhs is a sequence
587 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
588 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
589 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
590 // sequence of one item, with trailing comma
591 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
592 c_assign_tuple(comp, 1, &pns->nodes[0]);
593 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
594 // sequence of many items
595 // TODO call c_assign_tuple instead
596 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
597 EMIT(unpack_sequence, 1 + n);
598 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
599 for (int i = 0; i < n; i++) {
600 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
601 }
602 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
603 // TODO not implemented
604 assert(0);
605 } else {
606 // sequence with 2 items
607 goto sequence_with_2_items;
608 }
609 } else {
610 // sequence with 2 items
611 sequence_with_2_items:
612 c_assign_tuple(comp, 2, pns->nodes);
613 }
614 return;
615 }
616 return;
617
618 bad_aug:
619 printf("SyntaxError: illegal expression for augmented assignment\n");
620}
621
622// stuff for lambda and comprehensions and generators
623void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
624 // make closed over variables, if any
625 int nfree = 0;
626 if (comp->scope_cur->kind != SCOPE_MODULE) {
627 for (int i = 0; i < this_scope->id_info_len; i++) {
628 id_info_t *id_info = &this_scope->id_info[i];
629 if (id_info->kind == ID_INFO_KIND_FREE) {
630 EMIT(load_closure, id_info->qstr);
631 nfree += 1;
632 }
633 }
634 }
635 if (nfree > 0) {
636 EMIT(build_tuple, nfree);
637 }
638
639 // make the function/closure
640 if (nfree == 0) {
641 EMIT(make_function, this_scope, n_dict_params, n_default_params);
642 } else {
643 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
644 }
645}
646
647void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100648 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
649 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100650 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
651 // this parameter has a default value
652 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
653 if (comp->have_bare_star) {
654 comp->param_pass_num_dict_params += 1;
655 if (comp->param_pass == 1) {
656 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
657 compile_node(comp, pns->nodes[2]);
658 }
659 } else {
660 comp->param_pass_num_default_params += 1;
661 if (comp->param_pass == 2) {
662 compile_node(comp, pns->nodes[2]);
663 }
664 }
665 }
Damienb14de212013-10-06 00:28:28 +0100666 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
667 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100668 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
669 // bare star
670 comp->have_bare_star = true;
671 }
672 }
673}
674
675// leaves function object on stack
676// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100677qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100678 if (comp->pass == PASS_1) {
679 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100680 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100681 // store the function scope so the compiling function can use it at each pass
682 pns->nodes[4] = (py_parse_node_t)s;
683 }
684
685 // save variables (probably don't need to do this, since we can't have nested definitions..?)
686 bool old_have_bare_star = comp->have_bare_star;
687 int old_param_pass = comp->param_pass;
688 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
689 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
690
691 // compile default parameters
692 comp->have_bare_star = false;
693 comp->param_pass = 1; // pass 1 does any default parameters after bare star
694 comp->param_pass_num_dict_params = 0;
695 comp->param_pass_num_default_params = 0;
696 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
697 comp->have_bare_star = false;
698 comp->param_pass = 2; // pass 2 does any default parameters before bare star
699 comp->param_pass_num_dict_params = 0;
700 comp->param_pass_num_default_params = 0;
701 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
702
703 // get the scope for this function
704 scope_t *fscope = (scope_t*)pns->nodes[4];
705
706 // make the function
707 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
708
709 // restore variables
710 comp->have_bare_star = old_have_bare_star;
711 comp->param_pass = old_param_pass;
712 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
713 comp->param_pass_num_default_params = old_param_pass_num_default_params;
714
715 // return its name (the 'f' in "def f(...):")
716 return fscope->simple_name;
717}
718
719// leaves class object on stack
720// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100721qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100722 if (comp->pass == PASS_1) {
723 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100724 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100725 // store the class scope so the compiling function can use it at each pass
726 pns->nodes[3] = (py_parse_node_t)s;
727 }
728
729 EMIT(load_build_class);
730
731 // scope for this class
732 scope_t *cscope = (scope_t*)pns->nodes[3];
733
734 // compile the class
735 close_over_variables_etc(comp, cscope, 0, 0);
736
737 // get its name
738 EMIT(load_const_id, cscope->simple_name);
739
740 // nodes[1] has parent classes, if any
741 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
742 // no parent classes
743 EMIT(call_function, 2, 0, false, false);
744 } else {
745 // have a parent class or classes
746 // TODO what if we have, eg, *a or **a in the parent list?
747 compile_node(comp, pns->nodes[1]);
748 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
749 }
750
751 // return its name (the 'C' in class C(...):")
752 return cscope->simple_name;
753}
754
Damien6cdd3af2013-10-05 18:08:26 +0100755// returns true if it was a built-in decorator (even if the built-in had an error)
756static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
757 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
758 return false;
759 }
760
761 if (name_len != 2) {
762 printf("SyntaxError: invalid micropython decorator\n");
763 return true;
764 }
765
766 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
767 if (attr == comp->qstr_native) {
768 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100769 } else if (attr == comp->qstr_viper) {
770 *emit_options = EMIT_OPT_VIPER;
Damienc025ebb2013-10-12 14:30:21 +0100771#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
Damien5bfb7592013-10-05 18:41:24 +0100772 } else if (attr == comp->qstr_asm_thumb) {
773 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100774#endif
Damien6cdd3af2013-10-05 18:08:26 +0100775 } else {
776 printf("SyntaxError: invalid micropython decorator\n");
777 }
778
779 return true;
780}
781
Damien429d7192013-10-04 19:53:11 +0100782void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
783 // get the list of decorators
784 py_parse_node_t *nodes;
785 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
786
Damien6cdd3af2013-10-05 18:08:26 +0100787 // inherit emit options for this function/class definition
788 uint emit_options = comp->scope_cur->emit_options;
789
790 // compile each decorator
791 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100792 for (int i = 0; i < n; i++) {
793 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
794 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100795
796 // nodes[0] contains the decorator function, which is a dotted name
797 py_parse_node_t *name_nodes;
798 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
799
800 // check for built-in decorators
801 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
802 // this was a built-in
803 num_built_in_decorators += 1;
804
805 } else {
806 // not a built-in, compile normally
807
808 // compile the decorator function
809 compile_node(comp, name_nodes[0]);
810 for (int i = 1; i < name_len; i++) {
811 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
812 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
813 }
814
815 // nodes[1] contains arguments to the decorator function, if any
816 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
817 // call the decorator function with the arguments in nodes[1]
818 compile_node(comp, pns_decorator->nodes[1]);
819 }
Damien429d7192013-10-04 19:53:11 +0100820 }
821 }
822
823 // compile the body (funcdef or classdef) and get its name
824 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
825 qstr body_name = 0;
826 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100827 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100828 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100829 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100830 } else {
831 // shouldn't happen
832 assert(0);
833 }
834
835 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100836 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100837 EMIT(call_function, 1, 0, false, false);
838 }
839
840 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100841 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100842}
843
844void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100845 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100846 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100847 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100848}
849
850void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
851 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100852 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100853 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
854 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
855
856 compile_node(comp, pns->nodes[0]); // base of the power node
857
858 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
859 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
860 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
861 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
862 for (int i = 0; i < n - 1; i++) {
863 compile_node(comp, pns1->nodes[i]);
864 }
865 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
866 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
867 }
868 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
869 // SyntaxError: can't delete a function call
870 assert(0);
871 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
872 compile_node(comp, pns1->nodes[0]);
873 EMIT(delete_subscr);
874 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
875 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
876 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
877 } else {
878 // shouldn't happen
879 assert(0);
880 }
881 } else {
882 // shouldn't happen
883 assert(0);
884 }
885
886 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
887 // SyntaxError, cannot delete
888 assert(0);
889 }
890 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
891 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
892 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
893 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
894 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
895
896 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
897 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
898 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
899 // sequence of one item, with trailing comma
900 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
901 c_del_stmt(comp, pns->nodes[0]);
902 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
903 // sequence of many items
904 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
905 c_del_stmt(comp, pns->nodes[0]);
906 for (int i = 0; i < n; i++) {
907 c_del_stmt(comp, pns1->nodes[i]);
908 }
909 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
910 // TODO not implemented; can't del comprehension?
911 assert(0);
912 } else {
913 // sequence with 2 items
914 goto sequence_with_2_items;
915 }
916 } else {
917 // sequence with 2 items
918 sequence_with_2_items:
919 c_del_stmt(comp, pns->nodes[0]);
920 c_del_stmt(comp, pns->nodes[1]);
921 }
922 } else {
923 // tuple with 1 element
924 c_del_stmt(comp, pn);
925 }
926 } else {
927 // not implemented
928 assert(0);
929 }
930}
931
932void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
933 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
934}
935
936void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
937 if (comp->break_label == 0) {
938 printf("ERROR: cannot break from here\n");
939 }
940 EMIT(break_loop, comp->break_label);
941}
942
943void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
944 if (comp->continue_label == 0) {
945 printf("ERROR: cannot continue from here\n");
946 }
947 if (comp->except_nest_level > 0) {
948 EMIT(continue_loop, comp->continue_label);
949 } else {
950 EMIT(jump, comp->continue_label);
951 }
952}
953
954void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
955 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
956 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
957 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
958 // special case when returning an if-expression; to match CPython optimisation
959 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
960 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
961
Damienb05d7072013-10-05 13:37:10 +0100962 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100963 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
964 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
965 EMIT(return_value);
966 EMIT(label_assign, l_fail);
967 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
968 } else {
969 compile_node(comp, pns->nodes[0]);
970 }
971 EMIT(return_value);
972}
973
974void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
975 compile_node(comp, pns->nodes[0]);
976 EMIT(pop_top);
977}
978
979void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
980 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
981 // raise
982 EMIT(raise_varargs, 0);
983 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
984 // raise x from y
985 pns = (py_parse_node_struct_t*)pns->nodes[0];
986 compile_node(comp, pns->nodes[0]);
987 compile_node(comp, pns->nodes[1]);
988 EMIT(raise_varargs, 2);
989 } else {
990 // raise x
991 compile_node(comp, pns->nodes[0]);
992 EMIT(raise_varargs, 1);
993 }
994}
995
996// q1 holds the base, q2 the full name
997// eg a -> q1=q2=a
998// a.b.c -> q1=a, q2=a.b.c
999void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1000 bool is_as = false;
1001 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1002 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1003 // a name of the form x as y; unwrap it
1004 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1005 pn = pns->nodes[0];
1006 is_as = true;
1007 }
1008 if (PY_PARSE_NODE_IS_ID(pn)) {
1009 // just a simple name
1010 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1011 if (!is_as) {
1012 *q1 = *q2;
1013 }
1014 EMIT(import_name, *q2);
1015 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1016 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1017 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1018 // a name of the form a.b.c
1019 if (!is_as) {
1020 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1021 }
1022 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1023 int len = n - 1;
1024 for (int i = 0; i < n; i++) {
1025 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1026 }
1027 char *str = m_new(char, len + 1);
1028 str[0] = 0;
1029 for (int i = 0; i < n; i++) {
1030 if (i > 0) {
1031 strcat(str, ".");
1032 }
1033 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1034 }
1035 *q2 = qstr_from_str_take(str);
1036 EMIT(import_name, *q2);
1037 if (is_as) {
1038 for (int i = 1; i < n; i++) {
1039 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1040 }
1041 }
1042 } else {
1043 // TODO not implemented
1044 assert(0);
1045 }
1046 } else {
1047 // TODO not implemented
1048 assert(0);
1049 }
1050}
1051
1052void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1053 EMIT(load_const_small_int, 0); // ??
1054 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1055 qstr q1, q2;
1056 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001057 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001058}
1059
1060void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1061 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1062}
1063
1064void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1065 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
1066 EMIT(load_const_small_int, 0); // what's this for??
1067 EMIT(load_const_verbatim_start);
1068 EMIT(load_const_verbatim_str, "('*',)");
1069 EMIT(load_const_verbatim_end);
1070 qstr dummy_q, id1;
1071 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1072 EMIT(import_star);
1073 } else {
1074 py_parse_node_t *pn_nodes;
1075 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1076
1077 EMIT(load_const_small_int, 0); // what's this for??
1078 EMIT(load_const_verbatim_start);
1079 EMIT(load_const_verbatim_str, "(");
1080 for (int i = 0; i < n; i++) {
1081 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1082 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1083 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1084 if (i > 0) {
1085 EMIT(load_const_verbatim_str, ", ");
1086 }
1087 EMIT(load_const_verbatim_str, "'");
1088 EMIT(load_const_verbatim_str, qstr_str(id2));
1089 EMIT(load_const_verbatim_str, "'");
1090 }
1091 if (n == 1) {
1092 EMIT(load_const_verbatim_str, ",");
1093 }
1094 EMIT(load_const_verbatim_str, ")");
1095 EMIT(load_const_verbatim_end);
1096 qstr dummy_q, id1;
1097 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1098 for (int i = 0; i < n; i++) {
1099 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1100 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1101 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1102 EMIT(import_from, id2);
1103 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001104 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001105 } else {
Damien4b03e772013-10-05 14:17:09 +01001106 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001107 }
1108 }
1109 EMIT(pop_top);
1110 }
1111}
1112
1113void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001114 if (comp->pass == PASS_1) {
1115 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1116 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1117 } else {
1118 pns = (py_parse_node_struct_t*)pns->nodes[0];
1119 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1120 for (int i = 0; i < num_nodes; i++) {
1121 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1122 }
Damien429d7192013-10-04 19:53:11 +01001123 }
1124 }
1125}
1126
1127void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001128 if (comp->pass == PASS_1) {
1129 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1130 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1131 } else {
1132 pns = (py_parse_node_struct_t*)pns->nodes[0];
1133 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1134 for (int i = 0; i < num_nodes; i++) {
1135 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1136 }
Damien429d7192013-10-04 19:53:11 +01001137 }
1138 }
1139}
1140
1141void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001142 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001143 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001144 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001145 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1146 // assertion message
1147 compile_node(comp, pns->nodes[1]);
1148 EMIT(call_function, 1, 0, false, false);
1149 }
1150 EMIT(raise_varargs, 1);
1151 EMIT(label_assign, l_end);
1152}
1153
1154void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1155 // TODO proper and/or short circuiting
1156
Damienb05d7072013-10-05 13:37:10 +01001157 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001158
Damienb05d7072013-10-05 13:37:10 +01001159 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001160 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1161
1162 compile_node(comp, pns->nodes[1]); // if block
1163 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1164 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001165 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001166 EMIT(jump, l_end);
1167 }
1168 //}
1169 EMIT(label_assign, l_fail);
1170
1171 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1172 // compile elif blocks
1173
1174 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1175
1176 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1177 // multiple elif blocks
1178
1179 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1180 for (int i = 0; i < n; i++) {
1181 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001182 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001183 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1184
1185 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001186 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001187 EMIT(jump, l_end);
1188 }
1189 EMIT(label_assign, l_fail);
1190 }
1191
1192 } else {
1193 // a single elif block
1194
Damienb05d7072013-10-05 13:37:10 +01001195 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001196 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1197
1198 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001199 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001200 EMIT(jump, l_end);
1201 }
1202 EMIT(label_assign, l_fail);
1203 }
1204 }
1205
1206 // compile else block
1207 compile_node(comp, pns->nodes[3]); // can be null
1208
1209 EMIT(label_assign, l_end);
1210}
1211
1212void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1213 int old_break_label = comp->break_label;
1214 int old_continue_label = comp->continue_label;
1215
Damienb05d7072013-10-05 13:37:10 +01001216 int done_label = comp_next_label(comp);
1217 int end_label = comp_next_label(comp);
1218 int break_label = comp_next_label(comp);
1219 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001220
1221 comp->break_label = break_label;
1222 comp->continue_label = continue_label;
1223
1224 EMIT(setup_loop, end_label);
1225 EMIT(label_assign, continue_label);
1226 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1227 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001228 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001229 EMIT(jump, continue_label);
1230 }
1231 EMIT(label_assign, done_label);
1232
1233 // break/continue apply to outer loop (if any) in the else block
1234 comp->break_label = old_break_label;
1235 comp->continue_label = old_continue_label;
1236
1237 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1238 // this is a small hack to agree with CPython
1239 if (!node_is_const_true(pns->nodes[0])) {
1240 EMIT(pop_block);
1241 }
1242
1243 compile_node(comp, pns->nodes[2]); // else
1244
1245 EMIT(label_assign, break_label);
1246 EMIT(label_assign, end_label);
1247}
1248
1249void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1250 int old_break_label = comp->break_label;
1251 int old_continue_label = comp->continue_label;
1252
Damienb05d7072013-10-05 13:37:10 +01001253 int for_label = comp_next_label(comp);
1254 int pop_label = comp_next_label(comp);
1255 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001256
Damienb05d7072013-10-05 13:37:10 +01001257 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001258
1259 comp->continue_label = for_label;
1260 comp->break_label = break_label;
1261
1262 EMIT(setup_loop, end_label);
1263 compile_node(comp, pns->nodes[1]); // iterator
1264 EMIT(get_iter);
1265 EMIT(label_assign, for_label);
1266 EMIT(for_iter, pop_label);
1267 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1268 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001269 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001270 EMIT(jump, for_label);
1271 }
1272 EMIT(label_assign, pop_label);
1273 EMIT(for_iter_end);
1274
1275 // break/continue apply to outer loop (if any) in the else block
1276 comp->break_label = old_break_label;
1277 comp->continue_label = old_continue_label;
1278
1279 EMIT(pop_block);
1280
1281 compile_node(comp, pns->nodes[3]); // else (not tested)
1282
1283 EMIT(label_assign, break_label);
1284 EMIT(label_assign, end_label);
1285}
1286
1287void compile_try_except(compiler_t *comp, py_parse_node_t pn_body, int n_except, py_parse_node_t *pn_excepts, py_parse_node_t pn_else) {
1288 // this function is a bit of a hack at the moment
1289 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1290
1291 // setup code
1292 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001293 int l1 = comp_next_label(comp);
1294 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001295 comp->except_nest_level += 1; // for correct handling of continue
1296 EMIT(setup_except, l1);
1297 compile_node(comp, pn_body); // body
1298 EMIT(pop_block);
1299 EMIT(jump, success_label);
1300 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001301 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001302
1303 for (int i = 0; i < n_except; i++) {
1304 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1305 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1306
1307 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001308 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001309
1310 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1311 // this is a catch all exception handler
1312 if (i + 1 != n_except) {
1313 printf("SyntaxError: default 'except:' must be last\n");
1314 return;
1315 }
1316 } else {
1317 // this exception handler requires a match to a certain type of exception
1318 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1319 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1320 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1321 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1322 // handler binds the exception to a local
1323 pns_exception_expr = pns3->nodes[0];
1324 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1325 }
1326 }
1327 EMIT(dup_top);
1328 compile_node(comp, pns_exception_expr);
1329 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1330 EMIT(pop_jump_if_false, end_finally_label);
1331 }
1332
1333 EMIT(pop_top);
1334
1335 if (qstr_exception_local == 0) {
1336 EMIT(pop_top);
1337 } else {
Damien4b03e772013-10-05 14:17:09 +01001338 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001339 }
1340
1341 EMIT(pop_top);
1342
1343 int l3;
1344 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001345 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001346 EMIT(setup_finally, l3);
1347 }
1348 compile_node(comp, pns_except->nodes[1]);
1349 if (qstr_exception_local != 0) {
1350 EMIT(pop_block);
1351 }
1352 EMIT(pop_except);
1353 if (qstr_exception_local != 0) {
1354 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1355 EMIT(label_assign, l3);
1356 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001357 EMIT(store_id, qstr_exception_local);
1358 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001359 EMIT(end_finally);
1360 }
1361 EMIT(jump, l2);
1362 EMIT(label_assign, end_finally_label);
1363 }
1364
1365 EMIT(end_finally);
1366 EMIT(label_assign, success_label);
1367 comp->except_nest_level -= 1;
1368 compile_node(comp, pn_else); // else block, can be null
1369 EMIT(label_assign, l2);
1370 EMIT(set_stack_size, stack_size);
1371}
1372
1373void compile_try_finally(compiler_t *comp, py_parse_node_t pn_body, int n_except, py_parse_node_t *pn_except, py_parse_node_t pn_else, py_parse_node_t pn_finally) {
1374 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1375 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001376 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001377 EMIT(setup_finally, l_finally_block);
1378 if (n_except == 0) {
1379 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1380 compile_node(comp, pn_body);
1381 } else {
1382 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1383 }
1384 EMIT(pop_block);
1385 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1386 EMIT(label_assign, l_finally_block);
1387 compile_node(comp, pn_finally);
1388 EMIT(end_finally);
1389 EMIT(set_stack_size, stack_size);
1390}
1391
1392void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1393 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1394 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1395 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1396 // just try-finally
1397 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1398 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1399 // try-except and possibly else and/or finally
1400 py_parse_node_t *pn_excepts;
1401 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1402 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1403 // no finally
1404 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1405 } else {
1406 // have finally
1407 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1408 }
1409 } else {
1410 // just try-except
1411 py_parse_node_t *pn_excepts;
1412 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1413 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1414 }
1415 } else {
1416 // shouldn't happen
1417 assert(0);
1418 }
1419}
1420
1421void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1422 if (n == 0) {
1423 // no more pre-bits, compile the body of the with
1424 compile_node(comp, body);
1425 } else {
Damienb05d7072013-10-05 13:37:10 +01001426 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001427 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1428 // this pre-bit is of the form "a as b"
1429 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1430 compile_node(comp, pns->nodes[0]);
1431 EMIT(setup_with, l_end);
1432 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1433 } else {
1434 // this pre-bit is just an expression
1435 compile_node(comp, nodes[0]);
1436 EMIT(setup_with, l_end);
1437 EMIT(pop_top);
1438 }
1439 // compile additional pre-bits and the body
1440 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1441 // finish this with block
1442 EMIT(pop_block);
1443 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1444 EMIT(label_assign, l_end);
1445 EMIT(with_cleanup);
1446 EMIT(end_finally);
1447 }
1448}
1449
1450void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1451 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1452 py_parse_node_t *nodes;
1453 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1454 assert(n > 0);
1455
1456 // compile in a nested fashion
1457 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1458}
1459
1460void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1461 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1462 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1463 // do nothing with a lonely constant
1464 } else {
1465 compile_node(comp, pns->nodes[0]); // just an expression
1466 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1467 }
1468 } else {
1469 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1470 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1471 if (kind == PN_expr_stmt_augassign) {
1472 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1473 compile_node(comp, pns1->nodes[1]); // rhs
1474 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1475 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1476 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1477 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1478 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1479 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1480 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1481 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1482 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1483 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1484 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1485 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1486 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1487 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1488 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1489 default: assert(0); // shouldn't happen
1490 }
1491 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1492 } else if (kind == PN_expr_stmt_assign_list) {
1493 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1494 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1495 // following CPython, we store left-most first
1496 if (rhs > 0) {
1497 EMIT(dup_top);
1498 }
1499 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1500 for (int i = 0; i < rhs; i++) {
1501 if (i + 1 < rhs) {
1502 EMIT(dup_top);
1503 }
1504 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1505 }
1506 } else if (kind == PN_expr_stmt_assign) {
1507 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1508 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1509 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1510 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1511 // optimisation for a, b = c, d; to match CPython's optimisation
1512 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1513 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1514 compile_node(comp, pns10->nodes[0]); // rhs
1515 compile_node(comp, pns10->nodes[1]); // rhs
1516 EMIT(rot_two);
1517 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1518 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1519 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1520 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1521 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1522 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1523 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1524 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1525 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1526 compile_node(comp, pns10->nodes[0]); // rhs
1527 compile_node(comp, pns10->nodes[1]); // rhs
1528 compile_node(comp, pns10->nodes[2]); // rhs
1529 EMIT(rot_three);
1530 EMIT(rot_two);
1531 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1532 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1533 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1534 } else {
1535 compile_node(comp, pns1->nodes[0]); // rhs
1536 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1537 }
1538 } else {
1539 // shouldn't happen
1540 assert(0);
1541 }
1542 }
1543}
1544
1545void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1546 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1547 compile_node(comp, pns->nodes[0]);
1548 for (int i = 1; i < num_nodes; i += 1) {
1549 compile_node(comp, pns->nodes[i]);
1550 EMIT(binary_op, binary_op);
1551 }
1552}
1553
1554void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1555 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1556 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1557
1558 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001559 int l_fail = comp_next_label(comp);
1560 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001561 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1562 compile_node(comp, pns->nodes[0]); // success value
1563 EMIT(jump, l_end);
1564 EMIT(label_assign, l_fail);
1565 EMIT(set_stack_size, stack_size); // force stack size reset
1566 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1567 EMIT(label_assign, l_end);
1568}
1569
1570void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1571 // TODO default params etc for lambda; possibly just use funcdef code
1572 //py_parse_node_t pn_params = pns->nodes[0];
1573 //py_parse_node_t pn_body = pns->nodes[1];
1574
1575 if (comp->pass == PASS_1) {
1576 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001577 scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (py_parse_node_t)pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01001578 // store the lambda scope so the compiling function (this one) can use it at each pass
1579 pns->nodes[2] = (py_parse_node_t)s;
1580 }
1581
1582 // get the scope for this lambda
1583 scope_t *this_scope = (scope_t*)pns->nodes[2];
1584
1585 // make the lambda
1586 close_over_variables_etc(comp, this_scope, 0, 0);
1587}
1588
1589void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001590 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001591 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1592 for (int i = 0; i < n; i += 1) {
1593 compile_node(comp, pns->nodes[i]);
1594 if (i + 1 < n) {
1595 EMIT(jump_if_true_or_pop, l_end);
1596 }
1597 }
1598 EMIT(label_assign, l_end);
1599}
1600
1601void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001602 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001603 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1604 for (int i = 0; i < n; i += 1) {
1605 compile_node(comp, pns->nodes[i]);
1606 if (i + 1 < n) {
1607 EMIT(jump_if_false_or_pop, l_end);
1608 }
1609 }
1610 EMIT(label_assign, l_end);
1611}
1612
1613void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1614 compile_node(comp, pns->nodes[0]);
1615 EMIT(unary_op, RT_UNARY_OP_NOT);
1616}
1617
1618void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1619 int stack_size = EMIT(get_stack_size);
1620 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1621 compile_node(comp, pns->nodes[0]);
1622 bool multi = (num_nodes > 3);
1623 int l_fail = 0;
1624 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001625 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001626 }
1627 for (int i = 1; i + 1 < num_nodes; i += 2) {
1628 compile_node(comp, pns->nodes[i + 1]);
1629 if (i + 2 < num_nodes) {
1630 EMIT(dup_top);
1631 EMIT(rot_three);
1632 }
1633 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1634 EMIT(compare_op, RT_COMPARE_OP_LESS);
1635 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1636 EMIT(compare_op, RT_COMPARE_OP_MORE);
1637 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1638 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1639 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1640 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1641 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1642 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1643 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1644 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1645 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1646 EMIT(compare_op, RT_COMPARE_OP_IN);
1647 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1648 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1649 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1650 if (kind == PN_comp_op_not_in) {
1651 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1652 } else if (kind == PN_comp_op_is) {
1653 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1654 EMIT(compare_op, RT_COMPARE_OP_IS);
1655 } else {
1656 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1657 }
1658 } else {
1659 // shouldn't happen
1660 assert(0);
1661 }
1662 } else {
1663 // shouldn't happen
1664 assert(0);
1665 }
1666 if (i + 2 < num_nodes) {
1667 EMIT(jump_if_false_or_pop, l_fail);
1668 }
1669 }
1670 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001671 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001672 EMIT(jump, l_end);
1673 EMIT(label_assign, l_fail);
1674 EMIT(rot_two);
1675 EMIT(pop_top);
1676 EMIT(label_assign, l_end);
1677 EMIT(set_stack_size, stack_size + 1); // force stack size
1678 }
1679}
1680
1681void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1682 // TODO
1683 assert(0);
1684 compile_node(comp, pns->nodes[0]);
1685 //EMIT(unary_op, "UNARY_STAR");
1686}
1687
1688void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1689 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1690}
1691
1692void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1693 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1694}
1695
1696void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1697 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1698}
1699
1700void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1701 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1702 compile_node(comp, pns->nodes[0]);
1703 for (int i = 1; i + 1 < num_nodes; i += 2) {
1704 compile_node(comp, pns->nodes[i + 1]);
1705 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1706 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1707 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1708 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1709 } else {
1710 // shouldn't happen
1711 assert(0);
1712 }
1713 }
1714}
1715
1716void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1717 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1718 compile_node(comp, pns->nodes[0]);
1719 for (int i = 1; i + 1 < num_nodes; i += 2) {
1720 compile_node(comp, pns->nodes[i + 1]);
1721 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
1722 EMIT(binary_op, RT_BINARY_OP_ADD);
1723 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1724 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1725 } else {
1726 // shouldn't happen
1727 assert(0);
1728 }
1729 }
1730}
1731
1732void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1733 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1734 compile_node(comp, pns->nodes[0]);
1735 for (int i = 1; i + 1 < num_nodes; i += 2) {
1736 compile_node(comp, pns->nodes[i + 1]);
1737 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1738 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1739 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1740 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1741 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1742 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1743 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1744 EMIT(binary_op, RT_BINARY_OP_MODULO);
1745 } else {
1746 // shouldn't happen
1747 assert(0);
1748 }
1749 }
1750}
1751
1752void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1753 compile_node(comp, pns->nodes[1]);
1754 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1755 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1756 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1757 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1758 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1759 EMIT(unary_op, RT_UNARY_OP_INVERT);
1760 } else {
1761 // shouldn't happen
1762 assert(0);
1763 }
1764}
1765
1766void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
1767 // function to call is on top of stack
1768
1769 int old_n_arg_keyword = comp->n_arg_keyword;
1770 bool old_have_star_arg = comp->have_star_arg;
1771 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
1772 comp->n_arg_keyword = 0;
1773 comp->have_star_arg = false;
1774 comp->have_dbl_star_arg = false;
1775
1776 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
1777
1778 // compute number of positional arguments
1779 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
1780 if (comp->have_star_arg) {
1781 n_positional -= 1;
1782 }
1783 if (comp->have_dbl_star_arg) {
1784 n_positional -= 1;
1785 }
1786
1787 if (is_method_call) {
1788 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1789 } else {
1790 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1791 }
1792
1793 comp->n_arg_keyword = old_n_arg_keyword;
1794 comp->have_star_arg = old_have_star_arg;
1795 comp->have_dbl_star_arg = old_have_dbl_star_arg;
1796}
1797
1798void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
1799 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1800 for (int i = 0; i < num_nodes; i++) {
1801 if (i + 1 < num_nodes && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i], PN_trailer_period) && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[i + 1], PN_trailer_paren)) {
1802 // optimisation for method calls a.f(...), following PyPy
1803 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
1804 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
1805 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
1806 compile_trailer_paren_helper(comp, pns_paren, true);
1807 i += 1;
1808 } else {
1809 compile_node(comp, pns->nodes[i]);
1810 }
1811 }
1812}
1813
1814void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
1815 compile_node(comp, pns->nodes[0]);
1816 EMIT(binary_op, RT_BINARY_OP_POWER);
1817}
1818
1819void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
1820 // a list of strings
1821 EMIT(load_const_verbatim_start);
1822 EMIT(load_const_verbatim_str, "'");
1823 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1824 for (int i = 0; i < n; i++) {
1825 // TODO allow concatenation of either strings or bytes, but not mixed
1826 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
1827 assert(PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]) == PY_PARSE_NODE_STRING);
1828 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1829 EMIT(load_const_verbatim_strn, str, strlen(str));
1830 }
1831 EMIT(load_const_verbatim_str, "'");
1832 EMIT(load_const_verbatim_end);
1833}
1834
1835// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
1836void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
1837 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
1838 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
1839 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
1840
1841 if (comp->pass == PASS_1) {
1842 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01001843 scope_t *s = scope_new_and_link(comp, kind, (py_parse_node_t)pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01001844 // store the comprehension scope so the compiling function (this one) can use it at each pass
1845 pns_comp_for->nodes[3] = (py_parse_node_t)s;
1846 }
1847
1848 // get the scope for this comprehension
1849 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
1850
1851 // compile the comprehension
1852 close_over_variables_etc(comp, this_scope, 0, 0);
1853
1854 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
1855 EMIT(get_iter);
1856 EMIT(call_function, 1, 0, false, false);
1857}
1858
1859void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
1860 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1861 // an empty tuple
1862 /*
1863 EMIT(build_tuple, 0);
1864 */
1865 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
1866 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1867 pns = (py_parse_node_struct_t*)pns->nodes[0];
1868 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
1869 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1870 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1871 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
1872 // tuple of one item, with trailing comma
1873 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
1874 /*
1875 compile_node(comp, pns->nodes[0]);
1876 EMIT(build_tuple, 1);
1877 */
1878 c_tuple(comp, pns->nodes[0], NULL);
1879 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
1880 // tuple of many items
1881 /*
1882 compile_node(comp, pns->nodes[0]);
1883 compile_generic_all_nodes(comp, pns2);
1884 EMIT(build_tuple, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns2));
1885 */
1886 c_tuple(comp, pns->nodes[0], pns2);
1887 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
1888 // generator expression
1889 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
1890 } else {
1891 // tuple with 2 items
1892 goto tuple_with_2_items;
1893 }
1894 } else {
1895 // tuple with 2 items
1896 tuple_with_2_items:
1897 /*
1898 compile_node(comp, pns->nodes[0]);
1899 compile_node(comp, pns->nodes[1]);
1900 EMIT(build_tuple, 2);
1901 */
1902 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
1903 }
1904 } else {
1905 // parenthesis around a single item, is just that item
1906 compile_node(comp, pns->nodes[0]);
1907 }
1908}
1909
1910void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
1911 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1912 // empty list
1913 EMIT(build_list, 0);
1914 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1915 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
1916 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
1917 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
1918 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
1919 // list of one item, with trailing comma
1920 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
1921 compile_node(comp, pns2->nodes[0]);
1922 EMIT(build_list, 1);
1923 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
1924 // list of many items
1925 compile_node(comp, pns2->nodes[0]);
1926 compile_generic_all_nodes(comp, pns3);
1927 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
1928 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
1929 // list comprehension
1930 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
1931 } else {
1932 // list with 2 items
1933 goto list_with_2_items;
1934 }
1935 } else {
1936 // list with 2 items
1937 list_with_2_items:
1938 compile_node(comp, pns2->nodes[0]);
1939 compile_node(comp, pns2->nodes[1]);
1940 EMIT(build_list, 2);
1941 }
1942 } else {
1943 // list with 1 item
1944 compile_node(comp, pns->nodes[0]);
1945 EMIT(build_list, 1);
1946 }
1947}
1948
1949void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
1950 py_parse_node_t pn = pns->nodes[0];
1951 if (PY_PARSE_NODE_IS_NULL(pn)) {
1952 // empty dict
1953 EMIT(build_map, 0);
1954 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1955 pns = (py_parse_node_struct_t*)pn;
1956 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
1957 // dict with one element
1958 EMIT(build_map, 1);
1959 compile_node(comp, pn);
1960 EMIT(store_map);
1961 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
1962 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
1963 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1964 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
1965 // dict/set with multiple elements
1966
1967 // get tail elements (2nd, 3rd, ...)
1968 py_parse_node_t *nodes;
1969 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
1970
1971 // first element sets whether it's a dict or set
1972 bool is_dict;
1973 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
1974 // a dictionary
1975 EMIT(build_map, 1 + n);
1976 compile_node(comp, pns->nodes[0]);
1977 EMIT(store_map);
1978 is_dict = true;
1979 } else {
1980 // a set
1981 compile_node(comp, pns->nodes[0]); // 1st value of set
1982 is_dict = false;
1983 }
1984
1985 // process rest of elements
1986 for (int i = 0; i < n; i++) {
1987 py_parse_node_t pn = nodes[i];
1988 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
1989 compile_node(comp, pn);
1990 if (is_dict) {
1991 if (!is_key_value) {
1992 printf("SyntaxError?: expecting key:value for dictionary");
1993 return;
1994 }
1995 EMIT(store_map);
1996 } else {
1997 if (is_key_value) {
1998 printf("SyntaxError?: expecting just a value for set");
1999 return;
2000 }
2001 }
2002 }
2003
2004 // if it's a set, build it
2005 if (!is_dict) {
2006 EMIT(build_set, 1 + n);
2007 }
2008 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2009 // dict/set comprehension
2010 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2011 // a dictionary comprehension
2012 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2013 } else {
2014 // a set comprehension
2015 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2016 }
2017 } else {
2018 // shouldn't happen
2019 assert(0);
2020 }
2021 } else {
2022 // set with one element
2023 goto set_with_one_element;
2024 }
2025 } else {
2026 // set with one element
2027 set_with_one_element:
2028 compile_node(comp, pn);
2029 EMIT(build_set, 1);
2030 }
2031}
2032
2033void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2034 compile_trailer_paren_helper(comp, pns, false);
2035}
2036
2037void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2038 // object who's index we want is on top of stack
2039 compile_node(comp, pns->nodes[0]); // the index
2040 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2041}
2042
2043void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2044 // object who's attribute we want is on top of stack
2045 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2046}
2047
2048void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2049 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2050 py_parse_node_t pn = pns->nodes[0];
2051 if (PY_PARSE_NODE_IS_NULL(pn)) {
2052 // [?:]
2053 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2054 EMIT(build_slice, 2);
2055 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2056 pns = (py_parse_node_struct_t*)pn;
2057 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2058 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2059 pn = pns->nodes[0];
2060 if (PY_PARSE_NODE_IS_NULL(pn)) {
2061 // [?::]
2062 EMIT(build_slice, 2);
2063 } else {
2064 // [?::x]
2065 compile_node(comp, pn);
2066 EMIT(build_slice, 3);
2067 }
2068 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2069 compile_node(comp, pns->nodes[0]);
2070 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2071 pns = (py_parse_node_struct_t*)pns->nodes[1];
2072 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2073 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2074 // [?:x:]
2075 EMIT(build_slice, 2);
2076 } else {
2077 // [?:x:x]
2078 compile_node(comp, pns->nodes[0]);
2079 EMIT(build_slice, 3);
2080 }
2081 } else {
2082 // [?:x]
2083 compile_node(comp, pn);
2084 EMIT(build_slice, 2);
2085 }
2086 } else {
2087 // [?:x]
2088 compile_node(comp, pn);
2089 EMIT(build_slice, 2);
2090 }
2091}
2092
2093void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2094 compile_node(comp, pns->nodes[0]); // start of slice
2095 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2096 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2097}
2098
2099void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2100 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2101 compile_subscript_3_helper(comp, pns);
2102}
2103
2104void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2105 // if this is called then we are compiling a dict key:value pair
2106 compile_node(comp, pns->nodes[1]); // value
2107 compile_node(comp, pns->nodes[0]); // key
2108}
2109
2110void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002111 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002112 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002113 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002114}
2115
2116void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2117 if (comp->have_star_arg) {
2118 printf("SyntaxError?: can't have multiple *x\n");
2119 return;
2120 }
2121 comp->have_star_arg = true;
2122 compile_node(comp, pns->nodes[0]);
2123}
2124
2125void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2126 if (comp->have_dbl_star_arg) {
2127 printf("SyntaxError?: can't have multiple **x\n");
2128 return;
2129 }
2130 comp->have_dbl_star_arg = true;
2131 compile_node(comp, pns->nodes[0]);
2132}
2133
2134void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2135 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2136 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2137 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2138 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2139 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2140 return;
2141 }
2142 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2143 compile_node(comp, pns2->nodes[0]);
2144 comp->n_arg_keyword += 1;
2145 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2146 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2147 } else {
2148 // shouldn't happen
2149 assert(0);
2150 }
2151}
2152
2153void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2154 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2155 printf("SyntaxError: 'yield' outside function\n");
2156 return;
2157 }
2158 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2159 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2160 EMIT(yield_value);
2161 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2162 pns = (py_parse_node_struct_t*)pns->nodes[0];
2163 compile_node(comp, pns->nodes[0]);
2164 EMIT(get_iter);
2165 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2166 EMIT(yield_from);
2167 } else {
2168 compile_node(comp, pns->nodes[0]);
2169 EMIT(yield_value);
2170 }
2171}
2172
2173typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2174static compile_function_t compile_function[] = {
2175 NULL,
2176#define nc NULL
2177#define c(f) compile_##f
2178#define DEF_RULE(rule, comp, kind, arg...) comp,
2179#include "grammar.h"
2180#undef nc
2181#undef c
2182#undef DEF_RULE
2183};
2184
2185void compile_node(compiler_t *comp, py_parse_node_t pn) {
2186 if (PY_PARSE_NODE_IS_NULL(pn)) {
2187 // pass
2188 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2189 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2190 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002191 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002192 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2193 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2194 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2195 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2196 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002197 case PY_PARSE_NODE_TOKEN:
2198 if (arg == PY_TOKEN_NEWLINE) {
2199 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
2200 // do nothing
2201 } else {
2202 EMIT(load_const_tok, arg);
2203 }
2204 break;
Damien429d7192013-10-04 19:53:11 +01002205 default: assert(0);
2206 }
2207 } else {
2208 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2209 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2210 if (f == NULL) {
2211 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
2212 parse_node_show(pn, 0);
2213 assert(0);
2214 } else {
2215 f(comp, pns);
2216 }
2217 }
2218}
2219
2220void compile_scope_func_lambda_param(compiler_t *comp, py_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star, bool allow_annotations) {
2221 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002222 qstr param_name = 0;
2223 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002224 if (PY_PARSE_NODE_IS_ID(pn)) {
2225 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002226 if (comp->have_bare_star) {
2227 // comes after a bare star, so doesn't count as a parameter
2228 } else {
2229 comp->scope_cur->num_params += 1;
2230 }
Damienb14de212013-10-06 00:28:28 +01002231 } else {
2232 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2233 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2234 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002235 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002236 //int node_index = 1; unused
2237 if (allow_annotations) {
2238 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2239 // this parameter has an annotation
2240 pn_annotation = pns->nodes[1];
2241 }
2242 //node_index = 2; unused
2243 }
2244 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2245 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2246 // this parameter has a default value
2247 if (comp->have_bare_star) {
2248 comp->scope_cur->num_dict_params += 1;
2249 } else {
2250 comp->scope_cur->num_default_params += 1;
2251 }
2252 }
2253 */
2254 if (comp->have_bare_star) {
2255 // comes after a bare star, so doesn't count as a parameter
2256 } else {
2257 comp->scope_cur->num_params += 1;
2258 }
2259 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2260 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2261 // bare star
2262 // TODO see http://www.python.org/dev/peps/pep-3102/
2263 comp->have_bare_star = true;
2264 //assert(comp->scope_cur->num_dict_params == 0);
2265 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2266 // named star
2267 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2268 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2269 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2270 // named star with annotation
2271 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2272 pns = (py_parse_node_struct_t*)pns->nodes[0];
2273 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2274 pn_annotation = pns->nodes[1];
2275 } else {
2276 // shouldn't happen
2277 assert(0);
2278 }
2279 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002280 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002281 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2282 // this parameter has an annotation
2283 pn_annotation = pns->nodes[1];
2284 }
2285 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002286 } else {
Damienb14de212013-10-06 00:28:28 +01002287 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002288 assert(0);
2289 }
Damien429d7192013-10-04 19:53:11 +01002290 }
2291
2292 if (param_name != 0) {
2293 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2294 // TODO this parameter has an annotation
2295 }
2296 bool added;
2297 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2298 if (!added) {
2299 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2300 return;
2301 }
2302 id_info->param = true;
2303 id_info->kind = ID_INFO_KIND_LOCAL;
2304 }
2305}
2306
2307void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2308 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2309}
2310
2311void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2312 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2313}
2314
2315void compile_scope_comp_iter(compiler_t *comp, py_parse_node_t pn_iter, py_parse_node_t pn_inner_expr, int l_top, int for_depth) {
2316 tail_recursion:
2317 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2318 // no more nested if/for; compile inner expression
2319 compile_node(comp, pn_inner_expr);
2320 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2321 EMIT(list_append, for_depth + 2);
2322 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2323 EMIT(map_add, for_depth + 2);
2324 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2325 EMIT(set_add, for_depth + 2);
2326 } else {
2327 EMIT(yield_value);
2328 EMIT(pop_top);
2329 }
2330 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2331 // if condition
2332 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2333 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2334 pn_iter = pns_comp_if->nodes[1];
2335 goto tail_recursion;
2336 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2337 // for loop
2338 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2339 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002340 int l_end2 = comp_next_label(comp);
2341 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002342 EMIT(get_iter);
2343 EMIT(label_assign, l_top2);
2344 EMIT(for_iter, l_end2);
2345 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2346 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2347 EMIT(jump, l_top2);
2348 EMIT(label_assign, l_end2);
2349 EMIT(for_iter_end);
2350 } else {
2351 // shouldn't happen
2352 assert(0);
2353 }
2354}
2355
2356void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2357 // see http://www.python.org/dev/peps/pep-0257/
2358
2359 // look for the first statement
2360 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2361 // fall through
2362 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2363 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2364 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2365 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2366 } else {
2367 return;
2368 }
2369
2370 // check the first statement for a doc string
2371 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2372 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2373 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2374 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2375 if (kind == PY_PARSE_NODE_STRING) {
2376 compile_node(comp, pns->nodes[0]); // a doc string
2377 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002378 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002379 }
2380 }
2381 }
2382}
2383
2384void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2385 comp->pass = pass;
2386 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002387 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002388 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002389
2390 if (comp->pass == PASS_1) {
2391 scope->stack_size = 0;
2392 }
2393
2394 if (comp->pass == PASS_3) {
2395 //printf("----\n");
2396 scope_print_info(scope);
2397 }
2398
2399 // compile
2400 if (scope->kind == SCOPE_MODULE) {
2401 check_for_doc_string(comp, scope->pn);
2402 compile_node(comp, scope->pn);
2403 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2404 EMIT(return_value);
2405 } else if (scope->kind == SCOPE_FUNCTION) {
2406 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2407 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2408 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2409
2410 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002411 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002412 if (comp->pass == PASS_1) {
2413 comp->have_bare_star = false;
2414 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2415 }
2416
Damien826005c2013-10-05 23:17:28 +01002417 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002418
2419 compile_node(comp, pns->nodes[3]); // 3 is function body
2420 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002421 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002422 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2423 EMIT(return_value);
2424 }
2425 } else if (scope->kind == SCOPE_LAMBDA) {
2426 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2427 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2428 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2429
2430 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002431 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002432 if (comp->pass == PASS_1) {
2433 comp->have_bare_star = false;
2434 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2435 }
2436
2437 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2438 EMIT(return_value);
2439 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2440 // a bit of a hack at the moment
2441
2442 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2443 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2444 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2445 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2446 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2447
Damien6cdd3af2013-10-05 18:08:26 +01002448 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002449 if (comp->pass == PASS_1) {
2450 bool added;
2451 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2452 assert(added);
2453 id_info->kind = ID_INFO_KIND_LOCAL;
2454 scope->num_params = 1;
2455 }
2456
2457 if (scope->kind == SCOPE_LIST_COMP) {
2458 EMIT(build_list, 0);
2459 } else if (scope->kind == SCOPE_DICT_COMP) {
2460 EMIT(build_map, 0);
2461 } else if (scope->kind == SCOPE_SET_COMP) {
2462 EMIT(build_set, 0);
2463 }
2464
Damienb05d7072013-10-05 13:37:10 +01002465 int l_end = comp_next_label(comp);
2466 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002467 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002468 EMIT(label_assign, l_top);
2469 EMIT(for_iter, l_end);
2470 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2471 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2472 EMIT(jump, l_top);
2473 EMIT(label_assign, l_end);
2474 EMIT(for_iter_end);
2475
2476 if (scope->kind == SCOPE_GEN_EXPR) {
2477 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2478 }
2479 EMIT(return_value);
2480 } else {
2481 assert(scope->kind == SCOPE_CLASS);
2482 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2483 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2484 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2485
2486 if (comp->pass == PASS_1) {
2487 bool added;
2488 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2489 assert(added);
2490 id_info->kind = ID_INFO_KIND_LOCAL;
2491 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2492 assert(added);
2493 id_info->kind = ID_INFO_KIND_LOCAL;
2494 id_info->param = true;
2495 scope->num_params = 1; // __locals__ is the parameter
2496 }
2497
Damien4b03e772013-10-05 14:17:09 +01002498 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002499 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002500 EMIT(load_id, comp->qstr___name__);
2501 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002502 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002503 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002504
2505 check_for_doc_string(comp, pns->nodes[2]);
2506 compile_node(comp, pns->nodes[2]); // 2 is class body
2507
2508 id_info_t *id = scope_find(scope, comp->qstr___class__);
2509 assert(id != NULL);
2510 if (id->kind == ID_INFO_KIND_LOCAL) {
2511 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2512 } else {
2513 EMIT(load_closure, comp->qstr___class__);
2514 }
2515 EMIT(return_value);
2516 }
2517
Damien415eb6f2013-10-05 12:19:06 +01002518 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002519
Damien826005c2013-10-05 23:17:28 +01002520}
2521
2522void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2523 comp->pass = pass;
2524 comp->scope_cur = scope;
2525 comp->next_label = 1;
2526
2527 if (scope->kind != SCOPE_FUNCTION) {
2528 printf("Error: inline assembler must be a function\n");
2529 return;
2530 }
2531
Damiena2f2f7d2013-10-06 00:14:13 +01002532 if (comp->pass > PASS_1) {
2533 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2534 }
2535
Damien826005c2013-10-05 23:17:28 +01002536 // get the function definition parse node
2537 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2538 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2539 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2540
Damiena2f2f7d2013-10-06 00:14:13 +01002541 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002542
Damiena2f2f7d2013-10-06 00:14:13 +01002543 // parameters are in pns->nodes[1]
2544 if (comp->pass == PASS_2) {
2545 py_parse_node_t *pn_params;
2546 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2547 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2548 }
2549
Damien826005c2013-10-05 23:17:28 +01002550 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2551
2552 py_parse_node_t pn_body = pns->nodes[3]; // body
2553 py_parse_node_t *nodes;
2554 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2555
Damien826005c2013-10-05 23:17:28 +01002556 if (comp->pass == PASS_3) {
2557 //printf("----\n");
2558 scope_print_info(scope);
2559 }
2560
2561 for (int i = 0; i < num; i++) {
2562 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2563 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2564 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2565 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2566 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2567 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2568 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2569 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2570 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2571 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2572 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2573 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2574 py_parse_node_t *pn_arg;
2575 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2576
2577 // emit instructions
2578 if (strcmp(qstr_str(op), "label") == 0) {
2579 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2580 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2581 return;
2582 }
2583 int lab = comp_next_label(comp);
2584 if (pass > PASS_1) {
2585 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2586 }
2587 } else {
2588 if (pass > PASS_1) {
2589 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2590 }
2591 }
2592 }
2593
2594 if (comp->pass > PASS_1) {
2595 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002596 }
Damien429d7192013-10-04 19:53:11 +01002597}
2598
2599void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2600 // in functions, turn implicit globals into explicit globals
2601 // compute num_locals, and the index of each local
2602 scope->num_locals = 0;
2603 for (int i = 0; i < scope->id_info_len; i++) {
2604 id_info_t *id = &scope->id_info[i];
2605 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2606 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2607 continue;
2608 }
2609 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2610 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2611 }
2612 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2613 id->local_num = scope->num_locals;
2614 scope->num_locals += 1;
2615 }
2616 }
2617
2618 // compute flags
2619 //scope->flags = 0; since we set some things in parameters
2620 if (scope->kind != SCOPE_MODULE) {
2621 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2622 }
2623 if (scope->kind == SCOPE_FUNCTION || scope->kind == SCOPE_LAMBDA || scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2624 assert(scope->parent != NULL);
2625 scope->flags |= SCOPE_FLAG_OPTIMISED;
2626
2627 // TODO possibly other ways it can be nested
2628 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2629 scope->flags |= SCOPE_FLAG_NESTED;
2630 }
2631 }
2632 int num_free = 0;
2633 for (int i = 0; i < scope->id_info_len; i++) {
2634 id_info_t *id = &scope->id_info[i];
2635 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2636 num_free += 1;
2637 }
2638 }
2639 if (num_free == 0) {
2640 scope->flags |= SCOPE_FLAG_NOFREE;
2641 }
2642}
2643
2644void py_compile(py_parse_node_t pn) {
2645 compiler_t *comp = m_new(compiler_t, 1);
2646
Damien6cdd3af2013-10-05 18:08:26 +01002647 comp->qstr___class__ = qstr_from_str_static("__class__");
2648 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2649 comp->qstr___name__ = qstr_from_str_static("__name__");
2650 comp->qstr___module__ = qstr_from_str_static("__module__");
2651 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2652 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2653 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2654 comp->qstr_micropython = qstr_from_str_static("micropython");
2655 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002656 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002657 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damien429d7192013-10-04 19:53:11 +01002658
2659 comp->break_label = 0;
2660 comp->continue_label = 0;
2661 comp->except_nest_level = 0;
2662 comp->scope_head = NULL;
2663 comp->scope_cur = NULL;
2664
Damien826005c2013-10-05 23:17:28 +01002665 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002666 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002667
2668 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002669 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002670
Damien826005c2013-10-05 23:17:28 +01002671 // compile pass 1
2672 comp->emit = emit_pass1_new(comp->qstr___class__);
2673 comp->emit_method_table = &emit_pass1_method_table;
2674 comp->emit_inline_asm = NULL;
2675 comp->emit_inline_asm_method_table = NULL;
2676 uint max_num_labels = 0;
Damien429d7192013-10-04 19:53:11 +01002677 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002678 if (false) {
2679#ifdef MICROPY_EMIT_ENABLE_INLINE_THUMB
2680 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01002681 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01002682#endif
Damien826005c2013-10-05 23:17:28 +01002683 } else {
2684 compile_scope(comp, s, PASS_1);
2685 }
2686
2687 // update maximim number of labels needed
2688 if (comp->next_label > max_num_labels) {
2689 max_num_labels = comp->next_label;
2690 }
Damien429d7192013-10-04 19:53:11 +01002691 }
2692
Damien826005c2013-10-05 23:17:28 +01002693 // compute some things related to scope and identifiers
Damien429d7192013-10-04 19:53:11 +01002694 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
2695 compile_scope_compute_things(comp, s);
2696 }
2697
Damien826005c2013-10-05 23:17:28 +01002698 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002699 emit_pass1_free(comp->emit);
2700
Damien826005c2013-10-05 23:17:28 +01002701 // compile pass 2 and 3
Damienc025ebb2013-10-12 14:30:21 +01002702#if !defined(MICROPY_EMIT_ENABLE_CPYTHON)
Damien6cdd3af2013-10-05 18:08:26 +01002703 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01002704 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002705#endif
2706#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
Damien826005c2013-10-05 23:17:28 +01002707 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002708#endif
Damien429d7192013-10-04 19:53:11 +01002709 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002710 if (false) {
2711 // dummy
2712
2713#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
2714 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2715 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01002716 if (emit_inline_thumb == NULL) {
2717 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2718 }
2719 comp->emit = NULL;
2720 comp->emit_method_table = NULL;
2721 comp->emit_inline_asm = emit_inline_thumb;
2722 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2723 compile_scope_inline_asm(comp, s, PASS_2);
2724 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01002725#endif
2726
Damien826005c2013-10-05 23:17:28 +01002727 } else {
Damienc025ebb2013-10-12 14:30:21 +01002728
2729 // choose the emit type
2730
2731#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
2732 comp->emit = emit_cpython_new(max_num_labels);
2733 comp->emit_method_table = &emit_cpython_method_table;
2734#else
Damien826005c2013-10-05 23:17:28 +01002735 switch (s->emit_options) {
2736 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01002737 case EMIT_OPT_VIPER:
Damienc025ebb2013-10-12 14:30:21 +01002738#if defined(MICROPY_EMIT_ENABLE_X64)
Damiendc833822013-10-06 01:01:01 +01002739 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01002740 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01002741 }
Damien13ed3a62013-10-08 09:05:10 +01002742 comp->emit_method_table = &emit_native_x64_method_table;
Damienc025ebb2013-10-12 14:30:21 +01002743#elif defined(MICROPY_EMIT_ENABLE_THUMB)
2744 if (emit_native == NULL) {
2745 emit_native = emit_native_thumb_new(max_num_labels);
2746 }
2747 comp->emit_method_table = &emit_native_thumb_method_table;
2748#endif
2749 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01002750 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01002751 break;
2752
Damien826005c2013-10-05 23:17:28 +01002753 default:
2754 if (emit_bc == NULL) {
2755 emit_bc = emit_bc_new(max_num_labels);
2756 }
2757 comp->emit = emit_bc;
2758 comp->emit_method_table = &emit_bc_method_table;
2759 break;
2760 }
Damienc025ebb2013-10-12 14:30:21 +01002761#endif
2762
2763 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01002764 compile_scope(comp, s, PASS_2);
2765 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01002766 }
Damien429d7192013-10-04 19:53:11 +01002767 }
2768
2769 m_free(comp);
2770}