blob: 6a3a6694644b40836c8fae206e34d37072ed2bba [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"
9#include "lexer.h"
10#include "machine.h"
11#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)
Damien5bfb7592013-10-05 18:41:24 +010034#define EMIT_OPT_ASM_THUMB (3)
Damien6cdd3af2013-10-05 18:08:26 +010035
Damien429d7192013-10-04 19:53:11 +010036typedef struct _compiler_t {
37 qstr qstr___class__;
38 qstr qstr___locals__;
39 qstr qstr___name__;
40 qstr qstr___module__;
41 qstr qstr___qualname__;
42 qstr qstr___doc__;
43 qstr qstr_assertion_error;
Damien6cdd3af2013-10-05 18:08:26 +010044 qstr qstr_micropython;
45 qstr qstr_native;
Damien5bfb7592013-10-05 18:41:24 +010046 qstr qstr_asm_thumb;
Damien429d7192013-10-04 19:53:11 +010047
48 pass_kind_t pass;
49
Damienb05d7072013-10-05 13:37:10 +010050 int next_label;
Damienb05d7072013-10-05 13:37:10 +010051
Damien429d7192013-10-04 19:53:11 +010052 int break_label;
53 int continue_label;
54 int except_nest_level;
55
56 int n_arg_keyword;
57 bool have_star_arg;
58 bool have_dbl_star_arg;
59 bool have_bare_star;
60 int param_pass;
61 int param_pass_num_dict_params;
62 int param_pass_num_default_params;
63
64 scope_t *scope_head;
65 scope_t *scope_cur;
66
Damien6cdd3af2013-10-05 18:08:26 +010067 emit_t *emit; // current emitter
68 const emit_method_table_t *emit_method_table; // current emit method table
Damien826005c2013-10-05 23:17:28 +010069
70 emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
71 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 +010072} compiler_t;
73
74py_parse_node_t fold_constants(py_parse_node_t pn) {
75 if (PY_PARSE_NODE_IS_STRUCT(pn)) {
76 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
77 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
78
79 // fold arguments first
80 for (int i = 0; i < n; i++) {
81 pns->nodes[i] = fold_constants(pns->nodes[i]);
82 }
83
84 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
85 case PN_shift_expr:
86 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
87 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
88 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
89 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_LESS)) {
90 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1); // XXX can overflow; enabled only to compare with CPython
91 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) {
92 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1);
93 } else {
94 // shouldn't happen
95 assert(0);
96 }
97 }
98 break;
99
100 case PN_arith_expr:
101 // XXX can overflow; enabled only to compare with CPython
102 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
103 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
104 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
105 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) {
106 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 + arg1);
107 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) {
108 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 - arg1);
109 } else {
110 // shouldn't happen
111 assert(0);
112 }
113 }
114 break;
115
116 case PN_term:
117 // XXX can overflow; enabled only to compare with CPython
118 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
119 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
120 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
121 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
122 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1);
123 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) {
124 ; // pass
125 //} else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_)) {
126 //pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 - arg1);
127 } else {
128 // shouldn't happen
129 assert(0);
130 }
131 }
132 break;
133
134 case PN_factor_2:
135 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) {
136 machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
137 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
138 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg);
139 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
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_TILDE)) {
142 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg);
143 } else {
144 // shouldn't happen
145 assert(0);
146 }
147 }
148 break;
149
150 case PN_power:
151 // XXX can overflow; enabled only to compare with CPython
152 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])) {
153 py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2];
154 if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
155 int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
156 if (power >= 0) {
157 int ans = 1;
158 int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
159 for (; power > 0; power--) {
160 ans *= base;
161 }
162 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans);
163 }
164 }
165 }
166 break;
167 }
168 }
169
170 return pn;
171}
172
173void compile_node(compiler_t *comp, py_parse_node_t pn);
174
Damienb05d7072013-10-05 13:37:10 +0100175static int comp_next_label(compiler_t *comp) {
176 return comp->next_label++;
177}
178
Damien6cdd3af2013-10-05 18:08:26 +0100179static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse_node_t pn, uint emit_options) {
180 scope_t *scope = scope_new(kind, pn, rt_get_new_unique_code_id(), emit_options);
Damien429d7192013-10-04 19:53:11 +0100181 scope->parent = comp->scope_cur;
182 scope->next = NULL;
183 if (comp->scope_head == NULL) {
184 comp->scope_head = scope;
185 } else {
186 scope_t *s = comp->scope_head;
187 while (s->next != NULL) {
188 s = s->next;
189 }
190 s->next = scope;
191 }
192 return scope;
193}
194
Damienb05d7072013-10-05 13:37:10 +0100195static int list_len(py_parse_node_t pn, int pn_kind) {
Damien429d7192013-10-04 19:53:11 +0100196 if (PY_PARSE_NODE_IS_NULL(pn)) {
197 return 0;
198 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
199 return 1;
200 } else {
201 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
202 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
203 return 1;
204 } else {
205 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
206 }
207 }
208}
209
Damienb05d7072013-10-05 13:37:10 +0100210static 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 +0100211 if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) {
212 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
213 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
214 for (int i = 0; i < num_nodes; i++) {
215 f(comp, pns->nodes[i]);
216 }
217 } else if (!PY_PARSE_NODE_IS_NULL(pn)) {
218 f(comp, pn);
219 }
220}
221
Damienb05d7072013-10-05 13:37:10 +0100222static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) {
Damien429d7192013-10-04 19:53:11 +0100223 if (PY_PARSE_NODE_IS_NULL(*pn)) {
224 *nodes = NULL;
225 return 0;
226 } else if (PY_PARSE_NODE_IS_LEAF(*pn)) {
227 *nodes = pn;
228 return 1;
229 } else {
230 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn);
231 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
232 *nodes = pn;
233 return 1;
234 } else {
235 *nodes = pns->nodes;
236 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
237 }
238 }
239}
240
241void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) {
242}
243
244void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) {
245 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
246 for (int i = 0; i < num_nodes; i++) {
247 compile_node(comp, pns->nodes[i]);
248 }
249}
250
251bool c_tuple_is_const(py_parse_node_t pn) {
252 if (!PY_PARSE_NODE_IS_LEAF(pn)) {
253 return false;
254 }
255 if (PY_PARSE_NODE_IS_ID(pn)) {
256 return false;
257 }
258 return true;
259}
260
261void c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn) {
262 assert(PY_PARSE_NODE_IS_LEAF(pn));
263 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
264 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
265 case PY_PARSE_NODE_ID: assert(0);
266 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_verbatim_int, arg); break;
267 case PY_PARSE_NODE_INTEGER: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
268 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
269 case PY_PARSE_NODE_STRING: EMIT(load_const_verbatim_quoted_str, arg, false); break;
270 case PY_PARSE_NODE_BYTES: EMIT(load_const_verbatim_quoted_str, arg, true); break;
271 case PY_PARSE_NODE_TOKEN:
272 switch (arg) {
273 case PY_TOKEN_KW_FALSE: EMIT(load_const_verbatim_str, "False"); break;
274 case PY_TOKEN_KW_NONE: EMIT(load_const_verbatim_str, "None"); break;
275 case PY_TOKEN_KW_TRUE: EMIT(load_const_verbatim_str, "True"); break;
276 default: assert(0);
277 }
278 break;
279 default: assert(0);
280 }
281}
282
283// funnelling all tuple creations through this function and all this constant stuff is purely to agree with CPython
284void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
285 int n = 0;
286 if (pns_list != NULL) {
287 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
288 }
289 int total = n;
290 bool is_const = true;
291 if (!PY_PARSE_NODE_IS_NULL(pn)) {
292 total += 1;
293 if (!c_tuple_is_const(pn)) {
294 is_const = false;
295 }
296 }
297 for (int i = 0; i < n; i++) {
298 if (!c_tuple_is_const(pns_list->nodes[i])) {
299 is_const = false;
300 break;
301 }
302 }
303 if (total > 0 && is_const) {
304 bool need_comma = false;
305 EMIT(load_const_verbatim_start);
306 EMIT(load_const_verbatim_str, "(");
307 if (!PY_PARSE_NODE_IS_NULL(pn)) {
308 c_tuple_emit_const(comp, pn);
309 need_comma = true;
310 }
311 for (int i = 0; i < n; i++) {
312 if (need_comma) {
313 EMIT(load_const_verbatim_str, ", ");
314 }
315 c_tuple_emit_const(comp, pns_list->nodes[i]);
316 need_comma = true;
317 }
318 if (total == 1) {
319 EMIT(load_const_verbatim_str, ",)");
320 } else {
321 EMIT(load_const_verbatim_str, ")");
322 }
323 EMIT(load_const_verbatim_end);
324 } else {
325 if (!PY_PARSE_NODE_IS_NULL(pn)) {
326 compile_node(comp, pn);
327 }
328 for (int i = 0; i < n; i++) {
329 compile_node(comp, pns_list->nodes[i]);
330 }
331 EMIT(build_tuple, total);
332 }
333}
334
335void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
336 // a simple tuple expression
337 /*
338 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
339 for (int i = 0; i < n; i++) {
340 compile_node(comp, pns->nodes[i]);
341 }
342 EMIT(build_tuple, n);
343 */
344 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
345}
346
347bool node_is_const_false(py_parse_node_t pn) {
348 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
349 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
350}
351
352bool node_is_const_true(py_parse_node_t pn) {
353 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);
354}
355
356// having c_if_cond_2 and the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
357void c_if_cond_2(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label, bool is_nested) {
358 if (node_is_const_false(pn)) {
359 if (jump_if == false) {
360 EMIT(jump, label);
361 }
362 return;
363 } else if (node_is_const_true(pn)) {
364 if (jump_if == true) {
365 EMIT(jump, label);
366 }
367 return;
368 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
369 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
370 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
371 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
372 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100373 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100374 for (int i = 0; i < n - 1; i++) {
375 c_if_cond_2(comp, pns->nodes[i], true, label2, true);
376 }
377 c_if_cond_2(comp, pns->nodes[n - 1], false, label, true);
378 EMIT(label_assign, label2);
379 } else {
380 for (int i = 0; i < n; i++) {
381 c_if_cond_2(comp, pns->nodes[i], true, label, true);
382 }
383 }
384 return;
385 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
386 if (jump_if == false) {
387 for (int i = 0; i < n; i++) {
388 c_if_cond_2(comp, pns->nodes[i], false, label, true);
389 }
390 } else {
Damienb05d7072013-10-05 13:37:10 +0100391 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100392 for (int i = 0; i < n - 1; i++) {
393 c_if_cond_2(comp, pns->nodes[i], false, label2, true);
394 }
395 c_if_cond_2(comp, pns->nodes[n - 1], true, label, true);
396 EMIT(label_assign, label2);
397 }
398 return;
399 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
400 c_if_cond_2(comp, pns->nodes[0], !jump_if, label, true);
401 return;
402 }
403 }
404
405 // nothing special, fall back to default compiling for node and jump
406 compile_node(comp, pn);
407 if (jump_if == false) {
408 EMIT(pop_jump_if_false, label);
409 } else {
410 EMIT(pop_jump_if_true, label);
411 }
412}
413
414void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
415 c_if_cond_2(comp, pn, jump_if, label, false);
416}
417
418typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
419void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
420
421void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
422 if (assign_kind != ASSIGN_AUG_STORE) {
423 compile_node(comp, pns->nodes[0]);
424 }
425
426 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
427 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
428 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
429 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
430 if (assign_kind != ASSIGN_AUG_STORE) {
431 for (int i = 0; i < n - 1; i++) {
432 compile_node(comp, pns1->nodes[i]);
433 }
434 }
435 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
436 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
437 }
438 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
439 printf("SyntaxError: can't assign to function call\n");
440 return;
441 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
442 if (assign_kind == ASSIGN_AUG_STORE) {
443 EMIT(rot_three);
444 EMIT(store_subscr);
445 } else {
446 compile_node(comp, pns1->nodes[0]);
447 if (assign_kind == ASSIGN_AUG_LOAD) {
448 EMIT(dup_top_two);
449 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
450 } else {
451 EMIT(store_subscr);
452 }
453 }
454 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
455 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
456 if (assign_kind == ASSIGN_AUG_LOAD) {
457 EMIT(dup_top);
458 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
459 } else {
460 if (assign_kind == ASSIGN_AUG_STORE) {
461 EMIT(rot_two);
462 }
463 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
464 }
465 } else {
466 // shouldn't happen
467 assert(0);
468 }
469 } else {
470 // shouldn't happen
471 assert(0);
472 }
473
474 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
475 // SyntaxError, cannot assign
476 assert(0);
477 }
478}
479
480void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
481 assert(n >= 0);
482 int have_star_index = -1;
483 for (int i = 0; i < n; i++) {
484 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
485 if (have_star_index < 0) {
486 EMIT(unpack_ex, i, n - i - 1);
487 have_star_index = i;
488 } else {
489 printf("SyntaxError: two starred expressions in assignment\n");
490 return;
491 }
492 }
493 }
494 if (have_star_index < 0) {
495 EMIT(unpack_sequence, n);
496 }
497 for (int i = 0; i < n; i++) {
498 if (i == have_star_index) {
499 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
500 } else {
501 c_assign(comp, nodes[i], ASSIGN_STORE);
502 }
503 }
504}
505
506// assigns top of stack to pn
507void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
508 tail_recursion:
509 if (PY_PARSE_NODE_IS_NULL(pn)) {
510 assert(0);
511 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
512 if (PY_PARSE_NODE_IS_ID(pn)) {
513 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
514 switch (assign_kind) {
515 case ASSIGN_STORE:
516 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100517 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100518 break;
519 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100520 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100521 break;
522 }
523 } else {
524 printf("SyntaxError: can't assign to literal\n");
525 return;
526 }
527 } else {
528 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
529 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
530 case PN_power:
531 // lhs is an index or attribute
532 c_assign_power(comp, pns, assign_kind);
533 break;
534
535 case PN_testlist_star_expr:
536 case PN_exprlist:
537 // lhs is a tuple
538 if (assign_kind != ASSIGN_STORE) {
539 goto bad_aug;
540 }
541 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
542 break;
543
544 case PN_atom_paren:
545 // lhs is something in parenthesis
546 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
547 // empty tuple
548 printf("SyntaxError: can't assign to ()\n");
549 return;
550 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
551 pns = (py_parse_node_struct_t*)pns->nodes[0];
552 goto testlist_comp;
553 } else {
554 // parenthesis around 1 item, is just that item
555 pn = pns->nodes[0];
556 goto tail_recursion;
557 }
558 break;
559
560 case PN_atom_bracket:
561 // lhs is something in brackets
562 if (assign_kind != ASSIGN_STORE) {
563 goto bad_aug;
564 }
565 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
566 // empty list, assignment allowed
567 c_assign_tuple(comp, 0, NULL);
568 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
569 pns = (py_parse_node_struct_t*)pns->nodes[0];
570 goto testlist_comp;
571 } else {
572 // brackets around 1 item
573 c_assign_tuple(comp, 1, &pns->nodes[0]);
574 }
575 break;
576
577 default:
578 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
579 assert(0);
580 }
581 return;
582
583 testlist_comp:
584 // lhs is a sequence
585 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
586 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
587 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
588 // sequence of one item, with trailing comma
589 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
590 c_assign_tuple(comp, 1, &pns->nodes[0]);
591 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
592 // sequence of many items
593 // TODO call c_assign_tuple instead
594 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
595 EMIT(unpack_sequence, 1 + n);
596 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
597 for (int i = 0; i < n; i++) {
598 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
599 }
600 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
601 // TODO not implemented
602 assert(0);
603 } else {
604 // sequence with 2 items
605 goto sequence_with_2_items;
606 }
607 } else {
608 // sequence with 2 items
609 sequence_with_2_items:
610 c_assign_tuple(comp, 2, pns->nodes);
611 }
612 return;
613 }
614 return;
615
616 bad_aug:
617 printf("SyntaxError: illegal expression for augmented assignment\n");
618}
619
620// stuff for lambda and comprehensions and generators
621void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
622 // make closed over variables, if any
623 int nfree = 0;
624 if (comp->scope_cur->kind != SCOPE_MODULE) {
625 for (int i = 0; i < this_scope->id_info_len; i++) {
626 id_info_t *id_info = &this_scope->id_info[i];
627 if (id_info->kind == ID_INFO_KIND_FREE) {
628 EMIT(load_closure, id_info->qstr);
629 nfree += 1;
630 }
631 }
632 }
633 if (nfree > 0) {
634 EMIT(build_tuple, nfree);
635 }
636
637 // make the function/closure
638 if (nfree == 0) {
639 EMIT(make_function, this_scope, n_dict_params, n_default_params);
640 } else {
641 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
642 }
643}
644
645void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
646 assert(PY_PARSE_NODE_IS_STRUCT(pn));
647 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
648 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_name) {
649 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
650 // this parameter has a default value
651 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
652 if (comp->have_bare_star) {
653 comp->param_pass_num_dict_params += 1;
654 if (comp->param_pass == 1) {
655 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
656 compile_node(comp, pns->nodes[2]);
657 }
658 } else {
659 comp->param_pass_num_default_params += 1;
660 if (comp->param_pass == 2) {
661 compile_node(comp, pns->nodes[2]);
662 }
663 }
664 }
665 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_star) {
666 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
667 // bare star
668 comp->have_bare_star = true;
669 }
670 }
671}
672
673// leaves function object on stack
674// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100675qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100676 if (comp->pass == PASS_1) {
677 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100678 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100679 // store the function scope so the compiling function can use it at each pass
680 pns->nodes[4] = (py_parse_node_t)s;
681 }
682
683 // save variables (probably don't need to do this, since we can't have nested definitions..?)
684 bool old_have_bare_star = comp->have_bare_star;
685 int old_param_pass = comp->param_pass;
686 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
687 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
688
689 // compile default parameters
690 comp->have_bare_star = false;
691 comp->param_pass = 1; // pass 1 does any default parameters after bare star
692 comp->param_pass_num_dict_params = 0;
693 comp->param_pass_num_default_params = 0;
694 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
695 comp->have_bare_star = false;
696 comp->param_pass = 2; // pass 2 does any default parameters before bare star
697 comp->param_pass_num_dict_params = 0;
698 comp->param_pass_num_default_params = 0;
699 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
700
701 // get the scope for this function
702 scope_t *fscope = (scope_t*)pns->nodes[4];
703
704 // make the function
705 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
706
707 // restore variables
708 comp->have_bare_star = old_have_bare_star;
709 comp->param_pass = old_param_pass;
710 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
711 comp->param_pass_num_default_params = old_param_pass_num_default_params;
712
713 // return its name (the 'f' in "def f(...):")
714 return fscope->simple_name;
715}
716
717// leaves class object on stack
718// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100719qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100720 if (comp->pass == PASS_1) {
721 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100722 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100723 // store the class scope so the compiling function can use it at each pass
724 pns->nodes[3] = (py_parse_node_t)s;
725 }
726
727 EMIT(load_build_class);
728
729 // scope for this class
730 scope_t *cscope = (scope_t*)pns->nodes[3];
731
732 // compile the class
733 close_over_variables_etc(comp, cscope, 0, 0);
734
735 // get its name
736 EMIT(load_const_id, cscope->simple_name);
737
738 // nodes[1] has parent classes, if any
739 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
740 // no parent classes
741 EMIT(call_function, 2, 0, false, false);
742 } else {
743 // have a parent class or classes
744 // TODO what if we have, eg, *a or **a in the parent list?
745 compile_node(comp, pns->nodes[1]);
746 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
747 }
748
749 // return its name (the 'C' in class C(...):")
750 return cscope->simple_name;
751}
752
Damien6cdd3af2013-10-05 18:08:26 +0100753// returns true if it was a built-in decorator (even if the built-in had an error)
754static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
755 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
756 return false;
757 }
758
759 if (name_len != 2) {
760 printf("SyntaxError: invalid micropython decorator\n");
761 return true;
762 }
763
764 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
765 if (attr == comp->qstr_native) {
766 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien5bfb7592013-10-05 18:41:24 +0100767 } else if (attr == comp->qstr_asm_thumb) {
768 *emit_options = EMIT_OPT_ASM_THUMB;
Damien6cdd3af2013-10-05 18:08:26 +0100769 } else {
770 printf("SyntaxError: invalid micropython decorator\n");
771 }
772
773 return true;
774}
775
Damien429d7192013-10-04 19:53:11 +0100776void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
777 // get the list of decorators
778 py_parse_node_t *nodes;
779 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
780
Damien6cdd3af2013-10-05 18:08:26 +0100781 // inherit emit options for this function/class definition
782 uint emit_options = comp->scope_cur->emit_options;
783
784 // compile each decorator
785 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100786 for (int i = 0; i < n; i++) {
787 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
788 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100789
790 // nodes[0] contains the decorator function, which is a dotted name
791 py_parse_node_t *name_nodes;
792 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
793
794 // check for built-in decorators
795 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
796 // this was a built-in
797 num_built_in_decorators += 1;
798
799 } else {
800 // not a built-in, compile normally
801
802 // compile the decorator function
803 compile_node(comp, name_nodes[0]);
804 for (int i = 1; i < name_len; i++) {
805 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
806 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
807 }
808
809 // nodes[1] contains arguments to the decorator function, if any
810 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
811 // call the decorator function with the arguments in nodes[1]
812 compile_node(comp, pns_decorator->nodes[1]);
813 }
Damien429d7192013-10-04 19:53:11 +0100814 }
815 }
816
817 // compile the body (funcdef or classdef) and get its name
818 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
819 qstr body_name = 0;
820 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100821 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100822 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100823 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100824 } else {
825 // shouldn't happen
826 assert(0);
827 }
828
829 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100830 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100831 EMIT(call_function, 1, 0, false, false);
832 }
833
834 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100835 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100836}
837
838void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100839 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100840 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100841 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100842}
843
844void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
845 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100846 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100847 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
848 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
849
850 compile_node(comp, pns->nodes[0]); // base of the power node
851
852 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
853 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
854 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
855 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
856 for (int i = 0; i < n - 1; i++) {
857 compile_node(comp, pns1->nodes[i]);
858 }
859 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
860 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
861 }
862 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
863 // SyntaxError: can't delete a function call
864 assert(0);
865 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
866 compile_node(comp, pns1->nodes[0]);
867 EMIT(delete_subscr);
868 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
869 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
870 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
871 } else {
872 // shouldn't happen
873 assert(0);
874 }
875 } else {
876 // shouldn't happen
877 assert(0);
878 }
879
880 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
881 // SyntaxError, cannot delete
882 assert(0);
883 }
884 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
885 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
886 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
887 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
888 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
889
890 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
891 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
892 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
893 // sequence of one item, with trailing comma
894 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
895 c_del_stmt(comp, pns->nodes[0]);
896 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
897 // sequence of many items
898 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
899 c_del_stmt(comp, pns->nodes[0]);
900 for (int i = 0; i < n; i++) {
901 c_del_stmt(comp, pns1->nodes[i]);
902 }
903 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
904 // TODO not implemented; can't del comprehension?
905 assert(0);
906 } else {
907 // sequence with 2 items
908 goto sequence_with_2_items;
909 }
910 } else {
911 // sequence with 2 items
912 sequence_with_2_items:
913 c_del_stmt(comp, pns->nodes[0]);
914 c_del_stmt(comp, pns->nodes[1]);
915 }
916 } else {
917 // tuple with 1 element
918 c_del_stmt(comp, pn);
919 }
920 } else {
921 // not implemented
922 assert(0);
923 }
924}
925
926void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
927 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
928}
929
930void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
931 if (comp->break_label == 0) {
932 printf("ERROR: cannot break from here\n");
933 }
934 EMIT(break_loop, comp->break_label);
935}
936
937void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
938 if (comp->continue_label == 0) {
939 printf("ERROR: cannot continue from here\n");
940 }
941 if (comp->except_nest_level > 0) {
942 EMIT(continue_loop, comp->continue_label);
943 } else {
944 EMIT(jump, comp->continue_label);
945 }
946}
947
948void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
949 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
950 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
951 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
952 // special case when returning an if-expression; to match CPython optimisation
953 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
954 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
955
Damienb05d7072013-10-05 13:37:10 +0100956 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100957 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
958 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
959 EMIT(return_value);
960 EMIT(label_assign, l_fail);
961 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
962 } else {
963 compile_node(comp, pns->nodes[0]);
964 }
965 EMIT(return_value);
966}
967
968void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
969 compile_node(comp, pns->nodes[0]);
970 EMIT(pop_top);
971}
972
973void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
974 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
975 // raise
976 EMIT(raise_varargs, 0);
977 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
978 // raise x from y
979 pns = (py_parse_node_struct_t*)pns->nodes[0];
980 compile_node(comp, pns->nodes[0]);
981 compile_node(comp, pns->nodes[1]);
982 EMIT(raise_varargs, 2);
983 } else {
984 // raise x
985 compile_node(comp, pns->nodes[0]);
986 EMIT(raise_varargs, 1);
987 }
988}
989
990// q1 holds the base, q2 the full name
991// eg a -> q1=q2=a
992// a.b.c -> q1=a, q2=a.b.c
993void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
994 bool is_as = false;
995 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
996 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
997 // a name of the form x as y; unwrap it
998 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
999 pn = pns->nodes[0];
1000 is_as = true;
1001 }
1002 if (PY_PARSE_NODE_IS_ID(pn)) {
1003 // just a simple name
1004 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1005 if (!is_as) {
1006 *q1 = *q2;
1007 }
1008 EMIT(import_name, *q2);
1009 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1010 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1011 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1012 // a name of the form a.b.c
1013 if (!is_as) {
1014 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1015 }
1016 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1017 int len = n - 1;
1018 for (int i = 0; i < n; i++) {
1019 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1020 }
1021 char *str = m_new(char, len + 1);
1022 str[0] = 0;
1023 for (int i = 0; i < n; i++) {
1024 if (i > 0) {
1025 strcat(str, ".");
1026 }
1027 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1028 }
1029 *q2 = qstr_from_str_take(str);
1030 EMIT(import_name, *q2);
1031 if (is_as) {
1032 for (int i = 1; i < n; i++) {
1033 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1034 }
1035 }
1036 } else {
1037 // TODO not implemented
1038 assert(0);
1039 }
1040 } else {
1041 // TODO not implemented
1042 assert(0);
1043 }
1044}
1045
1046void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1047 EMIT(load_const_small_int, 0); // ??
1048 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1049 qstr q1, q2;
1050 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001051 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001052}
1053
1054void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1055 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1056}
1057
1058void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1059 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
1060 EMIT(load_const_small_int, 0); // what's this for??
1061 EMIT(load_const_verbatim_start);
1062 EMIT(load_const_verbatim_str, "('*',)");
1063 EMIT(load_const_verbatim_end);
1064 qstr dummy_q, id1;
1065 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1066 EMIT(import_star);
1067 } else {
1068 py_parse_node_t *pn_nodes;
1069 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1070
1071 EMIT(load_const_small_int, 0); // what's this for??
1072 EMIT(load_const_verbatim_start);
1073 EMIT(load_const_verbatim_str, "(");
1074 for (int i = 0; i < n; i++) {
1075 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1076 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1077 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1078 if (i > 0) {
1079 EMIT(load_const_verbatim_str, ", ");
1080 }
1081 EMIT(load_const_verbatim_str, "'");
1082 EMIT(load_const_verbatim_str, qstr_str(id2));
1083 EMIT(load_const_verbatim_str, "'");
1084 }
1085 if (n == 1) {
1086 EMIT(load_const_verbatim_str, ",");
1087 }
1088 EMIT(load_const_verbatim_str, ")");
1089 EMIT(load_const_verbatim_end);
1090 qstr dummy_q, id1;
1091 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1092 for (int i = 0; i < n; i++) {
1093 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1094 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1095 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1096 EMIT(import_from, id2);
1097 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001098 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001099 } else {
Damien4b03e772013-10-05 14:17:09 +01001100 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001101 }
1102 }
1103 EMIT(pop_top);
1104 }
1105}
1106
1107void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001108 if (comp->pass == PASS_1) {
1109 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1110 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1111 } else {
1112 pns = (py_parse_node_struct_t*)pns->nodes[0];
1113 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1114 for (int i = 0; i < num_nodes; i++) {
1115 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1116 }
Damien429d7192013-10-04 19:53:11 +01001117 }
1118 }
1119}
1120
1121void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001122 if (comp->pass == PASS_1) {
1123 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1124 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1125 } else {
1126 pns = (py_parse_node_struct_t*)pns->nodes[0];
1127 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1128 for (int i = 0; i < num_nodes; i++) {
1129 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1130 }
Damien429d7192013-10-04 19:53:11 +01001131 }
1132 }
1133}
1134
1135void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001136 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001137 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001138 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001139 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1140 // assertion message
1141 compile_node(comp, pns->nodes[1]);
1142 EMIT(call_function, 1, 0, false, false);
1143 }
1144 EMIT(raise_varargs, 1);
1145 EMIT(label_assign, l_end);
1146}
1147
1148void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1149 // TODO proper and/or short circuiting
1150
Damienb05d7072013-10-05 13:37:10 +01001151 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001152
Damienb05d7072013-10-05 13:37:10 +01001153 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001154 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1155
1156 compile_node(comp, pns->nodes[1]); // if block
1157 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1158 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001159 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001160 EMIT(jump, l_end);
1161 }
1162 //}
1163 EMIT(label_assign, l_fail);
1164
1165 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1166 // compile elif blocks
1167
1168 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1169
1170 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1171 // multiple elif blocks
1172
1173 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1174 for (int i = 0; i < n; i++) {
1175 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001176 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001177 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1178
1179 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001180 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001181 EMIT(jump, l_end);
1182 }
1183 EMIT(label_assign, l_fail);
1184 }
1185
1186 } else {
1187 // a single elif block
1188
Damienb05d7072013-10-05 13:37:10 +01001189 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001190 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1191
1192 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001193 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001194 EMIT(jump, l_end);
1195 }
1196 EMIT(label_assign, l_fail);
1197 }
1198 }
1199
1200 // compile else block
1201 compile_node(comp, pns->nodes[3]); // can be null
1202
1203 EMIT(label_assign, l_end);
1204}
1205
1206void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1207 int old_break_label = comp->break_label;
1208 int old_continue_label = comp->continue_label;
1209
Damienb05d7072013-10-05 13:37:10 +01001210 int done_label = comp_next_label(comp);
1211 int end_label = comp_next_label(comp);
1212 int break_label = comp_next_label(comp);
1213 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001214
1215 comp->break_label = break_label;
1216 comp->continue_label = continue_label;
1217
1218 EMIT(setup_loop, end_label);
1219 EMIT(label_assign, continue_label);
1220 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1221 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001222 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001223 EMIT(jump, continue_label);
1224 }
1225 EMIT(label_assign, done_label);
1226
1227 // break/continue apply to outer loop (if any) in the else block
1228 comp->break_label = old_break_label;
1229 comp->continue_label = old_continue_label;
1230
1231 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1232 // this is a small hack to agree with CPython
1233 if (!node_is_const_true(pns->nodes[0])) {
1234 EMIT(pop_block);
1235 }
1236
1237 compile_node(comp, pns->nodes[2]); // else
1238
1239 EMIT(label_assign, break_label);
1240 EMIT(label_assign, end_label);
1241}
1242
1243void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1244 int old_break_label = comp->break_label;
1245 int old_continue_label = comp->continue_label;
1246
Damienb05d7072013-10-05 13:37:10 +01001247 int for_label = comp_next_label(comp);
1248 int pop_label = comp_next_label(comp);
1249 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001250
Damienb05d7072013-10-05 13:37:10 +01001251 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001252
1253 comp->continue_label = for_label;
1254 comp->break_label = break_label;
1255
1256 EMIT(setup_loop, end_label);
1257 compile_node(comp, pns->nodes[1]); // iterator
1258 EMIT(get_iter);
1259 EMIT(label_assign, for_label);
1260 EMIT(for_iter, pop_label);
1261 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1262 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001263 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001264 EMIT(jump, for_label);
1265 }
1266 EMIT(label_assign, pop_label);
1267 EMIT(for_iter_end);
1268
1269 // break/continue apply to outer loop (if any) in the else block
1270 comp->break_label = old_break_label;
1271 comp->continue_label = old_continue_label;
1272
1273 EMIT(pop_block);
1274
1275 compile_node(comp, pns->nodes[3]); // else (not tested)
1276
1277 EMIT(label_assign, break_label);
1278 EMIT(label_assign, end_label);
1279}
1280
1281void 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) {
1282 // this function is a bit of a hack at the moment
1283 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1284
1285 // setup code
1286 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001287 int l1 = comp_next_label(comp);
1288 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001289 comp->except_nest_level += 1; // for correct handling of continue
1290 EMIT(setup_except, l1);
1291 compile_node(comp, pn_body); // body
1292 EMIT(pop_block);
1293 EMIT(jump, success_label);
1294 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001295 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001296
1297 for (int i = 0; i < n_except; i++) {
1298 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1299 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1300
1301 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001302 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001303
1304 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1305 // this is a catch all exception handler
1306 if (i + 1 != n_except) {
1307 printf("SyntaxError: default 'except:' must be last\n");
1308 return;
1309 }
1310 } else {
1311 // this exception handler requires a match to a certain type of exception
1312 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1313 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1314 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1315 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1316 // handler binds the exception to a local
1317 pns_exception_expr = pns3->nodes[0];
1318 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1319 }
1320 }
1321 EMIT(dup_top);
1322 compile_node(comp, pns_exception_expr);
1323 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1324 EMIT(pop_jump_if_false, end_finally_label);
1325 }
1326
1327 EMIT(pop_top);
1328
1329 if (qstr_exception_local == 0) {
1330 EMIT(pop_top);
1331 } else {
Damien4b03e772013-10-05 14:17:09 +01001332 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001333 }
1334
1335 EMIT(pop_top);
1336
1337 int l3;
1338 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001339 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001340 EMIT(setup_finally, l3);
1341 }
1342 compile_node(comp, pns_except->nodes[1]);
1343 if (qstr_exception_local != 0) {
1344 EMIT(pop_block);
1345 }
1346 EMIT(pop_except);
1347 if (qstr_exception_local != 0) {
1348 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1349 EMIT(label_assign, l3);
1350 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001351 EMIT(store_id, qstr_exception_local);
1352 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001353 EMIT(end_finally);
1354 }
1355 EMIT(jump, l2);
1356 EMIT(label_assign, end_finally_label);
1357 }
1358
1359 EMIT(end_finally);
1360 EMIT(label_assign, success_label);
1361 comp->except_nest_level -= 1;
1362 compile_node(comp, pn_else); // else block, can be null
1363 EMIT(label_assign, l2);
1364 EMIT(set_stack_size, stack_size);
1365}
1366
1367void 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) {
1368 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1369 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001370 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001371 EMIT(setup_finally, l_finally_block);
1372 if (n_except == 0) {
1373 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1374 compile_node(comp, pn_body);
1375 } else {
1376 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1377 }
1378 EMIT(pop_block);
1379 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1380 EMIT(label_assign, l_finally_block);
1381 compile_node(comp, pn_finally);
1382 EMIT(end_finally);
1383 EMIT(set_stack_size, stack_size);
1384}
1385
1386void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1387 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1388 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1389 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1390 // just try-finally
1391 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1392 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1393 // try-except and possibly else and/or finally
1394 py_parse_node_t *pn_excepts;
1395 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1396 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1397 // no finally
1398 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1399 } else {
1400 // have finally
1401 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1402 }
1403 } else {
1404 // just try-except
1405 py_parse_node_t *pn_excepts;
1406 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1407 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1408 }
1409 } else {
1410 // shouldn't happen
1411 assert(0);
1412 }
1413}
1414
1415void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1416 if (n == 0) {
1417 // no more pre-bits, compile the body of the with
1418 compile_node(comp, body);
1419 } else {
Damienb05d7072013-10-05 13:37:10 +01001420 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001421 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1422 // this pre-bit is of the form "a as b"
1423 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1424 compile_node(comp, pns->nodes[0]);
1425 EMIT(setup_with, l_end);
1426 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1427 } else {
1428 // this pre-bit is just an expression
1429 compile_node(comp, nodes[0]);
1430 EMIT(setup_with, l_end);
1431 EMIT(pop_top);
1432 }
1433 // compile additional pre-bits and the body
1434 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1435 // finish this with block
1436 EMIT(pop_block);
1437 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1438 EMIT(label_assign, l_end);
1439 EMIT(with_cleanup);
1440 EMIT(end_finally);
1441 }
1442}
1443
1444void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1445 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1446 py_parse_node_t *nodes;
1447 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1448 assert(n > 0);
1449
1450 // compile in a nested fashion
1451 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1452}
1453
1454void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1455 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1456 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1457 // do nothing with a lonely constant
1458 } else {
1459 compile_node(comp, pns->nodes[0]); // just an expression
1460 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1461 }
1462 } else {
1463 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1464 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1465 if (kind == PN_expr_stmt_augassign) {
1466 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1467 compile_node(comp, pns1->nodes[1]); // rhs
1468 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1469 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1470 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1471 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1472 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1473 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1474 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1475 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1476 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1477 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1478 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1479 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1480 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1481 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1482 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1483 default: assert(0); // shouldn't happen
1484 }
1485 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1486 } else if (kind == PN_expr_stmt_assign_list) {
1487 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1488 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1489 // following CPython, we store left-most first
1490 if (rhs > 0) {
1491 EMIT(dup_top);
1492 }
1493 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1494 for (int i = 0; i < rhs; i++) {
1495 if (i + 1 < rhs) {
1496 EMIT(dup_top);
1497 }
1498 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1499 }
1500 } else if (kind == PN_expr_stmt_assign) {
1501 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1502 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1503 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1504 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1505 // optimisation for a, b = c, d; to match CPython's optimisation
1506 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1507 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1508 compile_node(comp, pns10->nodes[0]); // rhs
1509 compile_node(comp, pns10->nodes[1]); // rhs
1510 EMIT(rot_two);
1511 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1512 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1513 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1514 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1515 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1516 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1517 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1518 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1519 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1520 compile_node(comp, pns10->nodes[0]); // rhs
1521 compile_node(comp, pns10->nodes[1]); // rhs
1522 compile_node(comp, pns10->nodes[2]); // rhs
1523 EMIT(rot_three);
1524 EMIT(rot_two);
1525 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1526 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1527 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1528 } else {
1529 compile_node(comp, pns1->nodes[0]); // rhs
1530 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1531 }
1532 } else {
1533 // shouldn't happen
1534 assert(0);
1535 }
1536 }
1537}
1538
1539void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1540 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1541 compile_node(comp, pns->nodes[0]);
1542 for (int i = 1; i < num_nodes; i += 1) {
1543 compile_node(comp, pns->nodes[i]);
1544 EMIT(binary_op, binary_op);
1545 }
1546}
1547
1548void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1549 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1550 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1551
1552 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001553 int l_fail = comp_next_label(comp);
1554 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001555 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1556 compile_node(comp, pns->nodes[0]); // success value
1557 EMIT(jump, l_end);
1558 EMIT(label_assign, l_fail);
1559 EMIT(set_stack_size, stack_size); // force stack size reset
1560 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1561 EMIT(label_assign, l_end);
1562}
1563
1564void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1565 // TODO default params etc for lambda; possibly just use funcdef code
1566 //py_parse_node_t pn_params = pns->nodes[0];
1567 //py_parse_node_t pn_body = pns->nodes[1];
1568
1569 if (comp->pass == PASS_1) {
1570 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001571 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 +01001572 // store the lambda scope so the compiling function (this one) can use it at each pass
1573 pns->nodes[2] = (py_parse_node_t)s;
1574 }
1575
1576 // get the scope for this lambda
1577 scope_t *this_scope = (scope_t*)pns->nodes[2];
1578
1579 // make the lambda
1580 close_over_variables_etc(comp, this_scope, 0, 0);
1581}
1582
1583void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001584 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001585 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1586 for (int i = 0; i < n; i += 1) {
1587 compile_node(comp, pns->nodes[i]);
1588 if (i + 1 < n) {
1589 EMIT(jump_if_true_or_pop, l_end);
1590 }
1591 }
1592 EMIT(label_assign, l_end);
1593}
1594
1595void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001596 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001597 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1598 for (int i = 0; i < n; i += 1) {
1599 compile_node(comp, pns->nodes[i]);
1600 if (i + 1 < n) {
1601 EMIT(jump_if_false_or_pop, l_end);
1602 }
1603 }
1604 EMIT(label_assign, l_end);
1605}
1606
1607void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1608 compile_node(comp, pns->nodes[0]);
1609 EMIT(unary_op, RT_UNARY_OP_NOT);
1610}
1611
1612void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1613 int stack_size = EMIT(get_stack_size);
1614 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1615 compile_node(comp, pns->nodes[0]);
1616 bool multi = (num_nodes > 3);
1617 int l_fail = 0;
1618 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001619 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001620 }
1621 for (int i = 1; i + 1 < num_nodes; i += 2) {
1622 compile_node(comp, pns->nodes[i + 1]);
1623 if (i + 2 < num_nodes) {
1624 EMIT(dup_top);
1625 EMIT(rot_three);
1626 }
1627 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1628 EMIT(compare_op, RT_COMPARE_OP_LESS);
1629 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1630 EMIT(compare_op, RT_COMPARE_OP_MORE);
1631 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1632 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1633 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1634 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1635 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1636 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1637 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1638 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1639 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1640 EMIT(compare_op, RT_COMPARE_OP_IN);
1641 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1642 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1643 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1644 if (kind == PN_comp_op_not_in) {
1645 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1646 } else if (kind == PN_comp_op_is) {
1647 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1648 EMIT(compare_op, RT_COMPARE_OP_IS);
1649 } else {
1650 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1651 }
1652 } else {
1653 // shouldn't happen
1654 assert(0);
1655 }
1656 } else {
1657 // shouldn't happen
1658 assert(0);
1659 }
1660 if (i + 2 < num_nodes) {
1661 EMIT(jump_if_false_or_pop, l_fail);
1662 }
1663 }
1664 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001665 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001666 EMIT(jump, l_end);
1667 EMIT(label_assign, l_fail);
1668 EMIT(rot_two);
1669 EMIT(pop_top);
1670 EMIT(label_assign, l_end);
1671 EMIT(set_stack_size, stack_size + 1); // force stack size
1672 }
1673}
1674
1675void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1676 // TODO
1677 assert(0);
1678 compile_node(comp, pns->nodes[0]);
1679 //EMIT(unary_op, "UNARY_STAR");
1680}
1681
1682void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1683 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1684}
1685
1686void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1687 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1688}
1689
1690void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1691 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1692}
1693
1694void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1695 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1696 compile_node(comp, pns->nodes[0]);
1697 for (int i = 1; i + 1 < num_nodes; i += 2) {
1698 compile_node(comp, pns->nodes[i + 1]);
1699 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1700 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1701 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1702 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1703 } else {
1704 // shouldn't happen
1705 assert(0);
1706 }
1707 }
1708}
1709
1710void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1711 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1712 compile_node(comp, pns->nodes[0]);
1713 for (int i = 1; i + 1 < num_nodes; i += 2) {
1714 compile_node(comp, pns->nodes[i + 1]);
1715 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
1716 EMIT(binary_op, RT_BINARY_OP_ADD);
1717 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1718 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1719 } else {
1720 // shouldn't happen
1721 assert(0);
1722 }
1723 }
1724}
1725
1726void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1727 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1728 compile_node(comp, pns->nodes[0]);
1729 for (int i = 1; i + 1 < num_nodes; i += 2) {
1730 compile_node(comp, pns->nodes[i + 1]);
1731 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1732 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1733 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1734 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1735 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1736 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1737 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1738 EMIT(binary_op, RT_BINARY_OP_MODULO);
1739 } else {
1740 // shouldn't happen
1741 assert(0);
1742 }
1743 }
1744}
1745
1746void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1747 compile_node(comp, pns->nodes[1]);
1748 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1749 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1750 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1751 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1752 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1753 EMIT(unary_op, RT_UNARY_OP_INVERT);
1754 } else {
1755 // shouldn't happen
1756 assert(0);
1757 }
1758}
1759
1760void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
1761 // function to call is on top of stack
1762
1763 int old_n_arg_keyword = comp->n_arg_keyword;
1764 bool old_have_star_arg = comp->have_star_arg;
1765 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
1766 comp->n_arg_keyword = 0;
1767 comp->have_star_arg = false;
1768 comp->have_dbl_star_arg = false;
1769
1770 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
1771
1772 // compute number of positional arguments
1773 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
1774 if (comp->have_star_arg) {
1775 n_positional -= 1;
1776 }
1777 if (comp->have_dbl_star_arg) {
1778 n_positional -= 1;
1779 }
1780
1781 if (is_method_call) {
1782 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1783 } else {
1784 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1785 }
1786
1787 comp->n_arg_keyword = old_n_arg_keyword;
1788 comp->have_star_arg = old_have_star_arg;
1789 comp->have_dbl_star_arg = old_have_dbl_star_arg;
1790}
1791
1792void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
1793 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1794 for (int i = 0; i < num_nodes; i++) {
1795 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)) {
1796 // optimisation for method calls a.f(...), following PyPy
1797 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
1798 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
1799 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
1800 compile_trailer_paren_helper(comp, pns_paren, true);
1801 i += 1;
1802 } else {
1803 compile_node(comp, pns->nodes[i]);
1804 }
1805 }
1806}
1807
1808void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
1809 compile_node(comp, pns->nodes[0]);
1810 EMIT(binary_op, RT_BINARY_OP_POWER);
1811}
1812
1813void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
1814 // a list of strings
1815 EMIT(load_const_verbatim_start);
1816 EMIT(load_const_verbatim_str, "'");
1817 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1818 for (int i = 0; i < n; i++) {
1819 // TODO allow concatenation of either strings or bytes, but not mixed
1820 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
1821 assert(PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]) == PY_PARSE_NODE_STRING);
1822 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1823 EMIT(load_const_verbatim_strn, str, strlen(str));
1824 }
1825 EMIT(load_const_verbatim_str, "'");
1826 EMIT(load_const_verbatim_end);
1827}
1828
1829// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
1830void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
1831 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
1832 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
1833 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
1834
1835 if (comp->pass == PASS_1) {
1836 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01001837 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 +01001838 // store the comprehension scope so the compiling function (this one) can use it at each pass
1839 pns_comp_for->nodes[3] = (py_parse_node_t)s;
1840 }
1841
1842 // get the scope for this comprehension
1843 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
1844
1845 // compile the comprehension
1846 close_over_variables_etc(comp, this_scope, 0, 0);
1847
1848 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
1849 EMIT(get_iter);
1850 EMIT(call_function, 1, 0, false, false);
1851}
1852
1853void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
1854 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1855 // an empty tuple
1856 /*
1857 EMIT(build_tuple, 0);
1858 */
1859 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
1860 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1861 pns = (py_parse_node_struct_t*)pns->nodes[0];
1862 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
1863 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1864 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1865 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
1866 // tuple of one item, with trailing comma
1867 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
1868 /*
1869 compile_node(comp, pns->nodes[0]);
1870 EMIT(build_tuple, 1);
1871 */
1872 c_tuple(comp, pns->nodes[0], NULL);
1873 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
1874 // tuple of many items
1875 /*
1876 compile_node(comp, pns->nodes[0]);
1877 compile_generic_all_nodes(comp, pns2);
1878 EMIT(build_tuple, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns2));
1879 */
1880 c_tuple(comp, pns->nodes[0], pns2);
1881 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
1882 // generator expression
1883 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
1884 } else {
1885 // tuple with 2 items
1886 goto tuple_with_2_items;
1887 }
1888 } else {
1889 // tuple with 2 items
1890 tuple_with_2_items:
1891 /*
1892 compile_node(comp, pns->nodes[0]);
1893 compile_node(comp, pns->nodes[1]);
1894 EMIT(build_tuple, 2);
1895 */
1896 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
1897 }
1898 } else {
1899 // parenthesis around a single item, is just that item
1900 compile_node(comp, pns->nodes[0]);
1901 }
1902}
1903
1904void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
1905 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1906 // empty list
1907 EMIT(build_list, 0);
1908 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1909 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
1910 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
1911 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
1912 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
1913 // list of one item, with trailing comma
1914 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
1915 compile_node(comp, pns2->nodes[0]);
1916 EMIT(build_list, 1);
1917 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
1918 // list of many items
1919 compile_node(comp, pns2->nodes[0]);
1920 compile_generic_all_nodes(comp, pns3);
1921 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
1922 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
1923 // list comprehension
1924 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
1925 } else {
1926 // list with 2 items
1927 goto list_with_2_items;
1928 }
1929 } else {
1930 // list with 2 items
1931 list_with_2_items:
1932 compile_node(comp, pns2->nodes[0]);
1933 compile_node(comp, pns2->nodes[1]);
1934 EMIT(build_list, 2);
1935 }
1936 } else {
1937 // list with 1 item
1938 compile_node(comp, pns->nodes[0]);
1939 EMIT(build_list, 1);
1940 }
1941}
1942
1943void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
1944 py_parse_node_t pn = pns->nodes[0];
1945 if (PY_PARSE_NODE_IS_NULL(pn)) {
1946 // empty dict
1947 EMIT(build_map, 0);
1948 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1949 pns = (py_parse_node_struct_t*)pn;
1950 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
1951 // dict with one element
1952 EMIT(build_map, 1);
1953 compile_node(comp, pn);
1954 EMIT(store_map);
1955 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
1956 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
1957 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1958 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
1959 // dict/set with multiple elements
1960
1961 // get tail elements (2nd, 3rd, ...)
1962 py_parse_node_t *nodes;
1963 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
1964
1965 // first element sets whether it's a dict or set
1966 bool is_dict;
1967 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
1968 // a dictionary
1969 EMIT(build_map, 1 + n);
1970 compile_node(comp, pns->nodes[0]);
1971 EMIT(store_map);
1972 is_dict = true;
1973 } else {
1974 // a set
1975 compile_node(comp, pns->nodes[0]); // 1st value of set
1976 is_dict = false;
1977 }
1978
1979 // process rest of elements
1980 for (int i = 0; i < n; i++) {
1981 py_parse_node_t pn = nodes[i];
1982 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
1983 compile_node(comp, pn);
1984 if (is_dict) {
1985 if (!is_key_value) {
1986 printf("SyntaxError?: expecting key:value for dictionary");
1987 return;
1988 }
1989 EMIT(store_map);
1990 } else {
1991 if (is_key_value) {
1992 printf("SyntaxError?: expecting just a value for set");
1993 return;
1994 }
1995 }
1996 }
1997
1998 // if it's a set, build it
1999 if (!is_dict) {
2000 EMIT(build_set, 1 + n);
2001 }
2002 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2003 // dict/set comprehension
2004 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2005 // a dictionary comprehension
2006 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2007 } else {
2008 // a set comprehension
2009 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2010 }
2011 } else {
2012 // shouldn't happen
2013 assert(0);
2014 }
2015 } else {
2016 // set with one element
2017 goto set_with_one_element;
2018 }
2019 } else {
2020 // set with one element
2021 set_with_one_element:
2022 compile_node(comp, pn);
2023 EMIT(build_set, 1);
2024 }
2025}
2026
2027void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2028 compile_trailer_paren_helper(comp, pns, false);
2029}
2030
2031void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2032 // object who's index we want is on top of stack
2033 compile_node(comp, pns->nodes[0]); // the index
2034 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2035}
2036
2037void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2038 // object who's attribute we want is on top of stack
2039 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2040}
2041
2042void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2043 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2044 py_parse_node_t pn = pns->nodes[0];
2045 if (PY_PARSE_NODE_IS_NULL(pn)) {
2046 // [?:]
2047 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2048 EMIT(build_slice, 2);
2049 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2050 pns = (py_parse_node_struct_t*)pn;
2051 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2052 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2053 pn = pns->nodes[0];
2054 if (PY_PARSE_NODE_IS_NULL(pn)) {
2055 // [?::]
2056 EMIT(build_slice, 2);
2057 } else {
2058 // [?::x]
2059 compile_node(comp, pn);
2060 EMIT(build_slice, 3);
2061 }
2062 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2063 compile_node(comp, pns->nodes[0]);
2064 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2065 pns = (py_parse_node_struct_t*)pns->nodes[1];
2066 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2067 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2068 // [?:x:]
2069 EMIT(build_slice, 2);
2070 } else {
2071 // [?:x:x]
2072 compile_node(comp, pns->nodes[0]);
2073 EMIT(build_slice, 3);
2074 }
2075 } else {
2076 // [?:x]
2077 compile_node(comp, pn);
2078 EMIT(build_slice, 2);
2079 }
2080 } else {
2081 // [?:x]
2082 compile_node(comp, pn);
2083 EMIT(build_slice, 2);
2084 }
2085}
2086
2087void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2088 compile_node(comp, pns->nodes[0]); // start of slice
2089 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2090 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2091}
2092
2093void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2094 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2095 compile_subscript_3_helper(comp, pns);
2096}
2097
2098void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2099 // if this is called then we are compiling a dict key:value pair
2100 compile_node(comp, pns->nodes[1]); // value
2101 compile_node(comp, pns->nodes[0]); // key
2102}
2103
2104void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002105 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002106 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002107 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002108}
2109
2110void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2111 if (comp->have_star_arg) {
2112 printf("SyntaxError?: can't have multiple *x\n");
2113 return;
2114 }
2115 comp->have_star_arg = true;
2116 compile_node(comp, pns->nodes[0]);
2117}
2118
2119void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2120 if (comp->have_dbl_star_arg) {
2121 printf("SyntaxError?: can't have multiple **x\n");
2122 return;
2123 }
2124 comp->have_dbl_star_arg = true;
2125 compile_node(comp, pns->nodes[0]);
2126}
2127
2128void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2129 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2130 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2131 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2132 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2133 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2134 return;
2135 }
2136 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2137 compile_node(comp, pns2->nodes[0]);
2138 comp->n_arg_keyword += 1;
2139 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2140 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2141 } else {
2142 // shouldn't happen
2143 assert(0);
2144 }
2145}
2146
2147void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2148 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2149 printf("SyntaxError: 'yield' outside function\n");
2150 return;
2151 }
2152 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2153 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2154 EMIT(yield_value);
2155 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2156 pns = (py_parse_node_struct_t*)pns->nodes[0];
2157 compile_node(comp, pns->nodes[0]);
2158 EMIT(get_iter);
2159 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2160 EMIT(yield_from);
2161 } else {
2162 compile_node(comp, pns->nodes[0]);
2163 EMIT(yield_value);
2164 }
2165}
2166
2167typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2168static compile_function_t compile_function[] = {
2169 NULL,
2170#define nc NULL
2171#define c(f) compile_##f
2172#define DEF_RULE(rule, comp, kind, arg...) comp,
2173#include "grammar.h"
2174#undef nc
2175#undef c
2176#undef DEF_RULE
2177};
2178
2179void compile_node(compiler_t *comp, py_parse_node_t pn) {
2180 if (PY_PARSE_NODE_IS_NULL(pn)) {
2181 // pass
2182 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2183 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2184 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002185 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002186 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2187 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2188 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2189 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2190 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
2191 case PY_PARSE_NODE_TOKEN: EMIT(load_const_tok, arg); break;
2192 default: assert(0);
2193 }
2194 } else {
2195 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2196 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2197 if (f == NULL) {
2198 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
2199 parse_node_show(pn, 0);
2200 assert(0);
2201 } else {
2202 f(comp, pns);
2203 }
2204 }
2205}
2206
2207void 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) {
2208 // TODO verify that *k and **k are last etc
2209 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2210 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2211 qstr param_name = 0;
2212 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
2213 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
2214 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2215 //int node_index = 1; unused
2216 if (allow_annotations) {
2217 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2218 // this parameter has an annotation
2219 pn_annotation = pns->nodes[1];
2220 }
2221 //node_index = 2; unused
2222 }
2223 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2224 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2225 // this parameter has a default value
2226 if (comp->have_bare_star) {
2227 comp->scope_cur->num_dict_params += 1;
2228 } else {
2229 comp->scope_cur->num_default_params += 1;
2230 }
2231 }
2232 */
2233 if (comp->have_bare_star) {
2234 // comes after a bare star, so doesn't count as a parameter
2235 } else {
2236 comp->scope_cur->num_params += 1;
2237 }
2238 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2239 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2240 // bare star
2241 // TODO see http://www.python.org/dev/peps/pep-3102/
2242 comp->have_bare_star = true;
2243 //assert(comp->scope_cur->num_dict_params == 0);
2244 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2245 // named star
2246 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2247 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2248 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2249 // named star with annotation
2250 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2251 pns = (py_parse_node_struct_t*)pns->nodes[0];
2252 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2253 pn_annotation = pns->nodes[1];
2254 } else {
2255 // shouldn't happen
2256 assert(0);
2257 }
2258 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
2259 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2260 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2261 // this parameter has an annotation
2262 pn_annotation = pns->nodes[1];
2263 }
2264 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
2265 } else {
2266 // TODO anything to implement?
2267 assert(0);
2268 }
2269
2270 if (param_name != 0) {
2271 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2272 // TODO this parameter has an annotation
2273 }
2274 bool added;
2275 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2276 if (!added) {
2277 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2278 return;
2279 }
2280 id_info->param = true;
2281 id_info->kind = ID_INFO_KIND_LOCAL;
2282 }
2283}
2284
2285void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2286 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2287}
2288
2289void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2290 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2291}
2292
2293void 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) {
2294 tail_recursion:
2295 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2296 // no more nested if/for; compile inner expression
2297 compile_node(comp, pn_inner_expr);
2298 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2299 EMIT(list_append, for_depth + 2);
2300 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2301 EMIT(map_add, for_depth + 2);
2302 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2303 EMIT(set_add, for_depth + 2);
2304 } else {
2305 EMIT(yield_value);
2306 EMIT(pop_top);
2307 }
2308 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2309 // if condition
2310 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2311 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2312 pn_iter = pns_comp_if->nodes[1];
2313 goto tail_recursion;
2314 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2315 // for loop
2316 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2317 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002318 int l_end2 = comp_next_label(comp);
2319 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002320 EMIT(get_iter);
2321 EMIT(label_assign, l_top2);
2322 EMIT(for_iter, l_end2);
2323 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2324 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2325 EMIT(jump, l_top2);
2326 EMIT(label_assign, l_end2);
2327 EMIT(for_iter_end);
2328 } else {
2329 // shouldn't happen
2330 assert(0);
2331 }
2332}
2333
2334void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2335 // see http://www.python.org/dev/peps/pep-0257/
2336
2337 // look for the first statement
2338 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2339 // fall through
2340 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2341 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2342 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2343 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2344 } else {
2345 return;
2346 }
2347
2348 // check the first statement for a doc string
2349 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2350 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2351 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2352 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2353 if (kind == PY_PARSE_NODE_STRING) {
2354 compile_node(comp, pns->nodes[0]); // a doc string
2355 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002356 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002357 }
2358 }
2359 }
2360}
2361
2362void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2363 comp->pass = pass;
2364 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002365 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002366 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002367
2368 if (comp->pass == PASS_1) {
2369 scope->stack_size = 0;
2370 }
2371
2372 if (comp->pass == PASS_3) {
2373 //printf("----\n");
2374 scope_print_info(scope);
2375 }
2376
2377 // compile
2378 if (scope->kind == SCOPE_MODULE) {
2379 check_for_doc_string(comp, scope->pn);
2380 compile_node(comp, scope->pn);
2381 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2382 EMIT(return_value);
2383 } else if (scope->kind == SCOPE_FUNCTION) {
2384 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2385 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2386 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2387
2388 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002389 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002390 if (comp->pass == PASS_1) {
2391 comp->have_bare_star = false;
2392 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2393 }
2394
Damien826005c2013-10-05 23:17:28 +01002395 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002396
2397 compile_node(comp, pns->nodes[3]); // 3 is function body
2398 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002399 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002400 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2401 EMIT(return_value);
2402 }
2403 } else if (scope->kind == SCOPE_LAMBDA) {
2404 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2405 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2406 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2407
2408 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002409 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002410 if (comp->pass == PASS_1) {
2411 comp->have_bare_star = false;
2412 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2413 }
2414
2415 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2416 EMIT(return_value);
2417 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2418 // a bit of a hack at the moment
2419
2420 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2421 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2422 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2423 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2424 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2425
Damien6cdd3af2013-10-05 18:08:26 +01002426 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002427 if (comp->pass == PASS_1) {
2428 bool added;
2429 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2430 assert(added);
2431 id_info->kind = ID_INFO_KIND_LOCAL;
2432 scope->num_params = 1;
2433 }
2434
2435 if (scope->kind == SCOPE_LIST_COMP) {
2436 EMIT(build_list, 0);
2437 } else if (scope->kind == SCOPE_DICT_COMP) {
2438 EMIT(build_map, 0);
2439 } else if (scope->kind == SCOPE_SET_COMP) {
2440 EMIT(build_set, 0);
2441 }
2442
Damienb05d7072013-10-05 13:37:10 +01002443 int l_end = comp_next_label(comp);
2444 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002445 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002446 EMIT(label_assign, l_top);
2447 EMIT(for_iter, l_end);
2448 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2449 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2450 EMIT(jump, l_top);
2451 EMIT(label_assign, l_end);
2452 EMIT(for_iter_end);
2453
2454 if (scope->kind == SCOPE_GEN_EXPR) {
2455 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2456 }
2457 EMIT(return_value);
2458 } else {
2459 assert(scope->kind == SCOPE_CLASS);
2460 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2461 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2462 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2463
2464 if (comp->pass == PASS_1) {
2465 bool added;
2466 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2467 assert(added);
2468 id_info->kind = ID_INFO_KIND_LOCAL;
2469 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2470 assert(added);
2471 id_info->kind = ID_INFO_KIND_LOCAL;
2472 id_info->param = true;
2473 scope->num_params = 1; // __locals__ is the parameter
2474 }
2475
Damien4b03e772013-10-05 14:17:09 +01002476 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002477 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002478 EMIT(load_id, comp->qstr___name__);
2479 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002480 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002481 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002482
2483 check_for_doc_string(comp, pns->nodes[2]);
2484 compile_node(comp, pns->nodes[2]); // 2 is class body
2485
2486 id_info_t *id = scope_find(scope, comp->qstr___class__);
2487 assert(id != NULL);
2488 if (id->kind == ID_INFO_KIND_LOCAL) {
2489 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2490 } else {
2491 EMIT(load_closure, comp->qstr___class__);
2492 }
2493 EMIT(return_value);
2494 }
2495
Damien415eb6f2013-10-05 12:19:06 +01002496 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002497
Damien826005c2013-10-05 23:17:28 +01002498}
2499
2500void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2501 comp->pass = pass;
2502 comp->scope_cur = scope;
2503 comp->next_label = 1;
2504
2505 if (scope->kind != SCOPE_FUNCTION) {
2506 printf("Error: inline assembler must be a function\n");
2507 return;
2508 }
2509
2510 // get the function definition parse node
2511 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2512 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2513 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2514
2515 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // name
2516
2517 scope->num_params = 0;
2518 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[1])); // arguments
2519 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2520
2521 py_parse_node_t pn_body = pns->nodes[3]; // body
2522 py_parse_node_t *nodes;
2523 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2524
2525 if (comp->pass > PASS_1) {
2526 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2527 }
2528
2529 if (comp->pass == PASS_3) {
2530 //printf("----\n");
2531 scope_print_info(scope);
2532 }
2533
2534 for (int i = 0; i < num; i++) {
2535 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2536 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2537 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2538 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2539 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2540 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2541 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2542 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2543 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2544 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2545 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2546 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2547 py_parse_node_t *pn_arg;
2548 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2549
2550 // emit instructions
2551 if (strcmp(qstr_str(op), "label") == 0) {
2552 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2553 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2554 return;
2555 }
2556 int lab = comp_next_label(comp);
2557 if (pass > PASS_1) {
2558 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2559 }
2560 } else {
2561 if (pass > PASS_1) {
2562 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2563 }
2564 }
2565 }
2566
2567 if (comp->pass > PASS_1) {
2568 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002569 }
Damien429d7192013-10-04 19:53:11 +01002570}
2571
2572void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2573 // in functions, turn implicit globals into explicit globals
2574 // compute num_locals, and the index of each local
2575 scope->num_locals = 0;
2576 for (int i = 0; i < scope->id_info_len; i++) {
2577 id_info_t *id = &scope->id_info[i];
2578 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2579 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2580 continue;
2581 }
2582 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2583 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2584 }
2585 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2586 id->local_num = scope->num_locals;
2587 scope->num_locals += 1;
2588 }
2589 }
2590
2591 // compute flags
2592 //scope->flags = 0; since we set some things in parameters
2593 if (scope->kind != SCOPE_MODULE) {
2594 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2595 }
2596 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) {
2597 assert(scope->parent != NULL);
2598 scope->flags |= SCOPE_FLAG_OPTIMISED;
2599
2600 // TODO possibly other ways it can be nested
2601 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2602 scope->flags |= SCOPE_FLAG_NESTED;
2603 }
2604 }
2605 int num_free = 0;
2606 for (int i = 0; i < scope->id_info_len; i++) {
2607 id_info_t *id = &scope->id_info[i];
2608 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2609 num_free += 1;
2610 }
2611 }
2612 if (num_free == 0) {
2613 scope->flags |= SCOPE_FLAG_NOFREE;
2614 }
2615}
2616
2617void py_compile(py_parse_node_t pn) {
2618 compiler_t *comp = m_new(compiler_t, 1);
2619
Damien6cdd3af2013-10-05 18:08:26 +01002620 comp->qstr___class__ = qstr_from_str_static("__class__");
2621 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2622 comp->qstr___name__ = qstr_from_str_static("__name__");
2623 comp->qstr___module__ = qstr_from_str_static("__module__");
2624 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2625 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2626 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2627 comp->qstr_micropython = qstr_from_str_static("micropython");
2628 comp->qstr_native = qstr_from_str_static("native");
Damien5bfb7592013-10-05 18:41:24 +01002629 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damien429d7192013-10-04 19:53:11 +01002630
2631 comp->break_label = 0;
2632 comp->continue_label = 0;
2633 comp->except_nest_level = 0;
2634 comp->scope_head = NULL;
2635 comp->scope_cur = NULL;
2636
Damien826005c2013-10-05 23:17:28 +01002637 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002638 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002639
2640 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002641 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002642
Damien826005c2013-10-05 23:17:28 +01002643 // compile pass 1
2644 comp->emit = emit_pass1_new(comp->qstr___class__);
2645 comp->emit_method_table = &emit_pass1_method_table;
2646 comp->emit_inline_asm = NULL;
2647 comp->emit_inline_asm_method_table = NULL;
2648 uint max_num_labels = 0;
Damien429d7192013-10-04 19:53:11 +01002649 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damien826005c2013-10-05 23:17:28 +01002650 if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2651 compile_scope_inline_asm(comp, s, PASS_1);
2652 } else {
2653 compile_scope(comp, s, PASS_1);
2654 }
2655
2656 // update maximim number of labels needed
2657 if (comp->next_label > max_num_labels) {
2658 max_num_labels = comp->next_label;
2659 }
Damien429d7192013-10-04 19:53:11 +01002660 }
2661
Damien826005c2013-10-05 23:17:28 +01002662 // compute some things related to scope and identifiers
Damien429d7192013-10-04 19:53:11 +01002663 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
2664 compile_scope_compute_things(comp, s);
2665 }
2666
Damien826005c2013-10-05 23:17:28 +01002667 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002668 emit_pass1_free(comp->emit);
2669
Damien826005c2013-10-05 23:17:28 +01002670 // compile pass 2 and 3
Damien6cdd3af2013-10-05 18:08:26 +01002671 emit_t *emit_bc = NULL;
2672 emit_t *emit_x64 = NULL;
Damien826005c2013-10-05 23:17:28 +01002673 emit_inline_asm_t *emit_inline_thumb = NULL;
Damien429d7192013-10-04 19:53:11 +01002674 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damien826005c2013-10-05 23:17:28 +01002675 if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2676 if (emit_inline_thumb == NULL) {
2677 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2678 }
2679 comp->emit = NULL;
2680 comp->emit_method_table = NULL;
2681 comp->emit_inline_asm = emit_inline_thumb;
2682 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2683 compile_scope_inline_asm(comp, s, PASS_2);
2684 compile_scope_inline_asm(comp, s, PASS_3);
2685 } else {
2686 switch (s->emit_options) {
2687 case EMIT_OPT_NATIVE_PYTHON:
2688 if (emit_x64 == NULL) {
2689 emit_x64 = emit_x64_new(max_num_labels);
2690 }
2691 comp->emit = emit_x64;
2692 comp->emit_method_table = &emit_x64_method_table;
2693 break;
Damien6cdd3af2013-10-05 18:08:26 +01002694
Damien826005c2013-10-05 23:17:28 +01002695 default:
2696 if (emit_bc == NULL) {
2697 emit_bc = emit_bc_new(max_num_labels);
2698 }
2699 comp->emit = emit_bc;
2700 comp->emit_method_table = &emit_bc_method_table;
2701 break;
2702 }
2703 compile_scope(comp, s, PASS_2);
2704 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01002705 }
Damien429d7192013-10-04 19:53:11 +01002706 }
2707
2708 m_free(comp);
2709}