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