blob: bd1107ed7db6c422233481e3d8dc06a82e026161 [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <unistd.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <stdio.h>
5#include <string.h>
6#include <assert.h>
7
8#include "misc.h"
Damienc025ebb2013-10-12 14:30:21 +01009#include "mpyconfig.h"
Damien429d7192013-10-04 19:53:11 +010010#include "lexer.h"
Damien429d7192013-10-04 19:53:11 +010011#include "parse.h"
12#include "scope.h"
13#include "compile.h"
14#include "runtime.h"
15#include "emit.h"
16
17// TODO need to mangle __attr names
18
19typedef enum {
20 PN_none = 0,
21#define DEF_RULE(rule, comp, kind, arg...) PN_##rule,
22#include "grammar.h"
23#undef DEF_RULE
24 PN_maximum_number_of,
25} pn_kind_t;
26
Damien415eb6f2013-10-05 12:19:06 +010027#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
Damien826005c2013-10-05 23:17:28 +010028#define EMIT_INLINE_ASM(fun, arg...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, ##arg))
Damien429d7192013-10-04 19:53:11 +010029
Damien6cdd3af2013-10-05 18:08:26 +010030#define EMIT_OPT_NONE (0)
31#define EMIT_OPT_BYTE_CODE (1)
32#define EMIT_OPT_NATIVE_PYTHON (2)
Damien7af3d192013-10-07 00:02:49 +010033#define EMIT_OPT_VIPER (3)
34#define EMIT_OPT_ASM_THUMB (4)
Damien6cdd3af2013-10-05 18:08:26 +010035
Damien429d7192013-10-04 19:53:11 +010036typedef struct _compiler_t {
37 qstr qstr___class__;
38 qstr qstr___locals__;
39 qstr qstr___name__;
40 qstr qstr___module__;
41 qstr qstr___qualname__;
42 qstr qstr___doc__;
43 qstr qstr_assertion_error;
Damien6cdd3af2013-10-05 18:08:26 +010044 qstr qstr_micropython;
45 qstr qstr_native;
Damien7af3d192013-10-07 00:02:49 +010046 qstr qstr_viper;
Damien5bfb7592013-10-05 18:41:24 +010047 qstr qstr_asm_thumb;
Damien429d7192013-10-04 19:53:11 +010048
49 pass_kind_t pass;
50
Damienb05d7072013-10-05 13:37:10 +010051 int next_label;
Damienb05d7072013-10-05 13:37:10 +010052
Damien429d7192013-10-04 19:53:11 +010053 int break_label;
54 int continue_label;
55 int except_nest_level;
56
57 int n_arg_keyword;
58 bool have_star_arg;
59 bool have_dbl_star_arg;
60 bool have_bare_star;
61 int param_pass;
62 int param_pass_num_dict_params;
63 int param_pass_num_default_params;
64
65 scope_t *scope_head;
66 scope_t *scope_cur;
67
Damien6cdd3af2013-10-05 18:08:26 +010068 emit_t *emit; // current emitter
69 const emit_method_table_t *emit_method_table; // current emit method table
Damien826005c2013-10-05 23:17:28 +010070
71 emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
72 const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm
Damien429d7192013-10-04 19:53:11 +010073} compiler_t;
74
75py_parse_node_t fold_constants(py_parse_node_t pn) {
76 if (PY_PARSE_NODE_IS_STRUCT(pn)) {
77 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
78 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
79
80 // fold arguments first
81 for (int i = 0; i < n; i++) {
82 pns->nodes[i] = fold_constants(pns->nodes[i]);
83 }
84
85 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
86 case PN_shift_expr:
87 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
88 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
89 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
90 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_LESS)) {
91 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1); // XXX can overflow; enabled only to compare with CPython
92 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) {
93 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1);
94 } else {
95 // shouldn't happen
96 assert(0);
97 }
98 }
99 break;
100
101 case PN_arith_expr:
102 // XXX can overflow; enabled only to compare with CPython
103 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
104 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
105 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
106 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) {
107 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 + arg1);
108 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) {
109 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 - arg1);
110 } else {
111 // shouldn't happen
112 assert(0);
113 }
114 }
115 break;
116
117 case PN_term:
118 // XXX can overflow; enabled only to compare with CPython
119 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
120 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
121 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
122 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
123 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1);
124 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) {
125 ; // pass
126 //} else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_)) {
127 //pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 - arg1);
128 } else {
129 // shouldn't happen
130 assert(0);
131 }
132 }
133 break;
134
135 case PN_factor_2:
136 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) {
137 machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
138 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
139 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg);
140 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
141 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, -arg);
142 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
143 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg);
144 } else {
145 // shouldn't happen
146 assert(0);
147 }
148 }
149 break;
150
151 case PN_power:
152 // XXX can overflow; enabled only to compare with CPython
153 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])) {
154 py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2];
155 if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
156 int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
157 if (power >= 0) {
158 int ans = 1;
159 int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
160 for (; power > 0; power--) {
161 ans *= base;
162 }
163 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans);
164 }
165 }
166 }
167 break;
168 }
169 }
170
171 return pn;
172}
173
174void compile_node(compiler_t *comp, py_parse_node_t pn);
175
Damienb05d7072013-10-05 13:37:10 +0100176static int comp_next_label(compiler_t *comp) {
177 return comp->next_label++;
178}
179
Damien6cdd3af2013-10-05 18:08:26 +0100180static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse_node_t pn, uint emit_options) {
181 scope_t *scope = scope_new(kind, pn, rt_get_new_unique_code_id(), emit_options);
Damien429d7192013-10-04 19:53:11 +0100182 scope->parent = comp->scope_cur;
183 scope->next = NULL;
184 if (comp->scope_head == NULL) {
185 comp->scope_head = scope;
186 } else {
187 scope_t *s = comp->scope_head;
188 while (s->next != NULL) {
189 s = s->next;
190 }
191 s->next = scope;
192 }
193 return scope;
194}
195
Damienb05d7072013-10-05 13:37:10 +0100196static int list_len(py_parse_node_t pn, int pn_kind) {
Damien429d7192013-10-04 19:53:11 +0100197 if (PY_PARSE_NODE_IS_NULL(pn)) {
198 return 0;
199 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
200 return 1;
201 } else {
202 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
203 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
204 return 1;
205 } else {
206 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
207 }
208 }
209}
210
Damienb05d7072013-10-05 13:37:10 +0100211static 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 +0100212 if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) {
213 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
214 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
215 for (int i = 0; i < num_nodes; i++) {
216 f(comp, pns->nodes[i]);
217 }
218 } else if (!PY_PARSE_NODE_IS_NULL(pn)) {
219 f(comp, pn);
220 }
221}
222
Damienb05d7072013-10-05 13:37:10 +0100223static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) {
Damien429d7192013-10-04 19:53:11 +0100224 if (PY_PARSE_NODE_IS_NULL(*pn)) {
225 *nodes = NULL;
226 return 0;
227 } else if (PY_PARSE_NODE_IS_LEAF(*pn)) {
228 *nodes = pn;
229 return 1;
230 } else {
231 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn);
232 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
233 *nodes = pn;
234 return 1;
235 } else {
236 *nodes = pns->nodes;
237 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
238 }
239 }
240}
241
242void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) {
243}
244
245void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) {
246 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
247 for (int i = 0; i < num_nodes; i++) {
248 compile_node(comp, pns->nodes[i]);
249 }
250}
251
Damien3a205172013-10-12 15:01:56 +0100252#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
253static bool cpython_c_tuple_is_const(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100254 if (!PY_PARSE_NODE_IS_LEAF(pn)) {
255 return false;
256 }
257 if (PY_PARSE_NODE_IS_ID(pn)) {
258 return false;
259 }
260 return true;
261}
262
Damien3a205172013-10-12 15:01:56 +0100263static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100264 assert(PY_PARSE_NODE_IS_LEAF(pn));
265 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
266 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
267 case PY_PARSE_NODE_ID: assert(0);
268 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_verbatim_int, arg); break;
269 case PY_PARSE_NODE_INTEGER: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
270 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
271 case PY_PARSE_NODE_STRING: EMIT(load_const_verbatim_quoted_str, arg, false); break;
272 case PY_PARSE_NODE_BYTES: EMIT(load_const_verbatim_quoted_str, arg, true); break;
273 case PY_PARSE_NODE_TOKEN:
274 switch (arg) {
275 case PY_TOKEN_KW_FALSE: EMIT(load_const_verbatim_str, "False"); break;
276 case PY_TOKEN_KW_NONE: EMIT(load_const_verbatim_str, "None"); break;
277 case PY_TOKEN_KW_TRUE: EMIT(load_const_verbatim_str, "True"); break;
278 default: assert(0);
279 }
280 break;
281 default: assert(0);
282 }
283}
284
Damien3a205172013-10-12 15:01:56 +0100285static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
Damien429d7192013-10-04 19:53:11 +0100286 int n = 0;
287 if (pns_list != NULL) {
288 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
289 }
290 int total = n;
291 bool is_const = true;
292 if (!PY_PARSE_NODE_IS_NULL(pn)) {
293 total += 1;
Damien3a205172013-10-12 15:01:56 +0100294 if (!cpython_c_tuple_is_const(pn)) {
Damien429d7192013-10-04 19:53:11 +0100295 is_const = false;
296 }
297 }
298 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100299 if (!cpython_c_tuple_is_const(pns_list->nodes[i])) {
Damien429d7192013-10-04 19:53:11 +0100300 is_const = false;
301 break;
302 }
303 }
304 if (total > 0 && is_const) {
305 bool need_comma = false;
306 EMIT(load_const_verbatim_start);
307 EMIT(load_const_verbatim_str, "(");
308 if (!PY_PARSE_NODE_IS_NULL(pn)) {
Damien3a205172013-10-12 15:01:56 +0100309 cpython_c_tuple_emit_const(comp, pn);
Damien429d7192013-10-04 19:53:11 +0100310 need_comma = true;
311 }
312 for (int i = 0; i < n; i++) {
313 if (need_comma) {
314 EMIT(load_const_verbatim_str, ", ");
315 }
Damien3a205172013-10-12 15:01:56 +0100316 cpython_c_tuple_emit_const(comp, pns_list->nodes[i]);
Damien429d7192013-10-04 19:53:11 +0100317 need_comma = true;
318 }
319 if (total == 1) {
320 EMIT(load_const_verbatim_str, ",)");
321 } else {
322 EMIT(load_const_verbatim_str, ")");
323 }
324 EMIT(load_const_verbatim_end);
325 } else {
326 if (!PY_PARSE_NODE_IS_NULL(pn)) {
327 compile_node(comp, pn);
328 }
329 for (int i = 0; i < n; i++) {
330 compile_node(comp, pns_list->nodes[i]);
331 }
332 EMIT(build_tuple, total);
333 }
334}
Damien3a205172013-10-12 15:01:56 +0100335#endif
336
337// funnelling all tuple creations through this function is purely so we can optionally agree with CPython
338void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
339#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
340 cpython_c_tuple(comp, pn, pns_list);
341#else
342 int total = 0;
343 if (!PY_PARSE_NODE_IS_NULL(pn)) {
344 compile_node(comp, pn);
345 total += 1;
346 }
347 if (pns_list != NULL) {
348 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
349 for (int i = 0; i < n; i++) {
350 compile_node(comp, pns_list->nodes[i]);
351 }
352 total += n;
353 }
354 EMIT(build_tuple, total);
355#endif
356}
Damien429d7192013-10-04 19:53:11 +0100357
358void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
359 // a simple tuple expression
Damien429d7192013-10-04 19:53:11 +0100360 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
361}
362
Damien3a205172013-10-12 15:01:56 +0100363static bool node_is_const_false(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100364 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
365 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
366}
367
Damien3a205172013-10-12 15:01:56 +0100368static bool node_is_const_true(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100369 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);
370}
371
Damien3a205172013-10-12 15:01:56 +0100372#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
373// the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
374static void cpython_c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label, bool is_nested) {
Damien429d7192013-10-04 19:53:11 +0100375 if (node_is_const_false(pn)) {
376 if (jump_if == false) {
377 EMIT(jump, label);
378 }
379 return;
380 } else if (node_is_const_true(pn)) {
381 if (jump_if == true) {
382 EMIT(jump, label);
383 }
384 return;
385 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
386 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
387 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
388 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
389 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100390 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100391 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100392 cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
Damien429d7192013-10-04 19:53:11 +0100393 }
Damien3a205172013-10-12 15:01:56 +0100394 cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100395 EMIT(label_assign, label2);
396 } else {
397 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100398 cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100399 }
400 }
401 return;
402 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
403 if (jump_if == false) {
404 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100405 cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100406 }
407 } else {
Damienb05d7072013-10-05 13:37:10 +0100408 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100409 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100410 cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
Damien429d7192013-10-04 19:53:11 +0100411 }
Damien3a205172013-10-12 15:01:56 +0100412 cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100413 EMIT(label_assign, label2);
414 }
415 return;
416 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
Damien3a205172013-10-12 15:01:56 +0100417 cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true);
Damien429d7192013-10-04 19:53:11 +0100418 return;
419 }
420 }
421
422 // nothing special, fall back to default compiling for node and jump
423 compile_node(comp, pn);
424 if (jump_if == false) {
425 EMIT(pop_jump_if_false, label);
426 } else {
427 EMIT(pop_jump_if_true, label);
428 }
429}
Damien3a205172013-10-12 15:01:56 +0100430#endif
Damien429d7192013-10-04 19:53:11 +0100431
Damien3a205172013-10-12 15:01:56 +0100432static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
433#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
434 cpython_c_if_cond(comp, pn, jump_if, label, false);
435#else
436 if (node_is_const_false(pn)) {
437 if (jump_if == false) {
438 EMIT(jump, label);
439 }
440 return;
441 } else if (node_is_const_true(pn)) {
442 if (jump_if == true) {
443 EMIT(jump, label);
444 }
445 return;
446 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
447 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
448 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
449 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
450 if (jump_if == false) {
451 int label2 = comp_next_label(comp);
452 for (int i = 0; i < n - 1; i++) {
453 c_if_cond(comp, pns->nodes[i], true, label2);
454 }
455 c_if_cond(comp, pns->nodes[n - 1], false, label);
456 EMIT(label_assign, label2);
457 } else {
458 for (int i = 0; i < n; i++) {
459 c_if_cond(comp, pns->nodes[i], true, label);
460 }
461 }
462 return;
463 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
464 if (jump_if == false) {
465 for (int i = 0; i < n; i++) {
466 c_if_cond(comp, pns->nodes[i], false, label);
467 }
468 } else {
469 int label2 = comp_next_label(comp);
470 for (int i = 0; i < n - 1; i++) {
471 c_if_cond(comp, pns->nodes[i], false, label2);
472 }
473 c_if_cond(comp, pns->nodes[n - 1], true, label);
474 EMIT(label_assign, label2);
475 }
476 return;
477 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
478 c_if_cond(comp, pns->nodes[0], !jump_if, label);
479 return;
480 }
481 }
482
483 // nothing special, fall back to default compiling for node and jump
484 compile_node(comp, pn);
485 if (jump_if == false) {
486 EMIT(pop_jump_if_false, label);
487 } else {
488 EMIT(pop_jump_if_true, label);
489 }
490#endif
Damien429d7192013-10-04 19:53:11 +0100491}
492
493typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
494void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
495
496void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
497 if (assign_kind != ASSIGN_AUG_STORE) {
498 compile_node(comp, pns->nodes[0]);
499 }
500
501 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
502 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
503 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
504 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
505 if (assign_kind != ASSIGN_AUG_STORE) {
506 for (int i = 0; i < n - 1; i++) {
507 compile_node(comp, pns1->nodes[i]);
508 }
509 }
510 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
511 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
512 }
513 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
514 printf("SyntaxError: can't assign to function call\n");
515 return;
516 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
517 if (assign_kind == ASSIGN_AUG_STORE) {
518 EMIT(rot_three);
519 EMIT(store_subscr);
520 } else {
521 compile_node(comp, pns1->nodes[0]);
522 if (assign_kind == ASSIGN_AUG_LOAD) {
523 EMIT(dup_top_two);
524 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
525 } else {
526 EMIT(store_subscr);
527 }
528 }
529 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
530 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
531 if (assign_kind == ASSIGN_AUG_LOAD) {
532 EMIT(dup_top);
533 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
534 } else {
535 if (assign_kind == ASSIGN_AUG_STORE) {
536 EMIT(rot_two);
537 }
538 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
539 }
540 } else {
541 // shouldn't happen
542 assert(0);
543 }
544 } else {
545 // shouldn't happen
546 assert(0);
547 }
548
549 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
550 // SyntaxError, cannot assign
551 assert(0);
552 }
553}
554
555void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
556 assert(n >= 0);
557 int have_star_index = -1;
558 for (int i = 0; i < n; i++) {
559 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
560 if (have_star_index < 0) {
561 EMIT(unpack_ex, i, n - i - 1);
562 have_star_index = i;
563 } else {
564 printf("SyntaxError: two starred expressions in assignment\n");
565 return;
566 }
567 }
568 }
569 if (have_star_index < 0) {
570 EMIT(unpack_sequence, n);
571 }
572 for (int i = 0; i < n; i++) {
573 if (i == have_star_index) {
574 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
575 } else {
576 c_assign(comp, nodes[i], ASSIGN_STORE);
577 }
578 }
579}
580
581// assigns top of stack to pn
582void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
583 tail_recursion:
584 if (PY_PARSE_NODE_IS_NULL(pn)) {
585 assert(0);
586 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
587 if (PY_PARSE_NODE_IS_ID(pn)) {
588 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
589 switch (assign_kind) {
590 case ASSIGN_STORE:
591 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100592 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100593 break;
594 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100595 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100596 break;
597 }
598 } else {
599 printf("SyntaxError: can't assign to literal\n");
600 return;
601 }
602 } else {
603 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
604 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
605 case PN_power:
606 // lhs is an index or attribute
607 c_assign_power(comp, pns, assign_kind);
608 break;
609
610 case PN_testlist_star_expr:
611 case PN_exprlist:
612 // lhs is a tuple
613 if (assign_kind != ASSIGN_STORE) {
614 goto bad_aug;
615 }
616 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
617 break;
618
619 case PN_atom_paren:
620 // lhs is something in parenthesis
621 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
622 // empty tuple
623 printf("SyntaxError: can't assign to ()\n");
624 return;
625 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
626 pns = (py_parse_node_struct_t*)pns->nodes[0];
627 goto testlist_comp;
628 } else {
629 // parenthesis around 1 item, is just that item
630 pn = pns->nodes[0];
631 goto tail_recursion;
632 }
633 break;
634
635 case PN_atom_bracket:
636 // lhs is something in brackets
637 if (assign_kind != ASSIGN_STORE) {
638 goto bad_aug;
639 }
640 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
641 // empty list, assignment allowed
642 c_assign_tuple(comp, 0, NULL);
643 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
644 pns = (py_parse_node_struct_t*)pns->nodes[0];
645 goto testlist_comp;
646 } else {
647 // brackets around 1 item
648 c_assign_tuple(comp, 1, &pns->nodes[0]);
649 }
650 break;
651
652 default:
653 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
654 assert(0);
655 }
656 return;
657
658 testlist_comp:
659 // lhs is a sequence
660 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
661 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
662 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
663 // sequence of one item, with trailing comma
664 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
665 c_assign_tuple(comp, 1, &pns->nodes[0]);
666 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
667 // sequence of many items
668 // TODO call c_assign_tuple instead
669 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
670 EMIT(unpack_sequence, 1 + n);
671 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
672 for (int i = 0; i < n; i++) {
673 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
674 }
675 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
676 // TODO not implemented
677 assert(0);
678 } else {
679 // sequence with 2 items
680 goto sequence_with_2_items;
681 }
682 } else {
683 // sequence with 2 items
684 sequence_with_2_items:
685 c_assign_tuple(comp, 2, pns->nodes);
686 }
687 return;
688 }
689 return;
690
691 bad_aug:
692 printf("SyntaxError: illegal expression for augmented assignment\n");
693}
694
695// stuff for lambda and comprehensions and generators
696void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
697 // make closed over variables, if any
698 int nfree = 0;
699 if (comp->scope_cur->kind != SCOPE_MODULE) {
700 for (int i = 0; i < this_scope->id_info_len; i++) {
701 id_info_t *id_info = &this_scope->id_info[i];
702 if (id_info->kind == ID_INFO_KIND_FREE) {
703 EMIT(load_closure, id_info->qstr);
704 nfree += 1;
705 }
706 }
707 }
708 if (nfree > 0) {
709 EMIT(build_tuple, nfree);
710 }
711
712 // make the function/closure
713 if (nfree == 0) {
714 EMIT(make_function, this_scope, n_dict_params, n_default_params);
715 } else {
716 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
717 }
718}
719
720void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100721 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
722 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100723 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
724 // this parameter has a default value
725 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
726 if (comp->have_bare_star) {
727 comp->param_pass_num_dict_params += 1;
728 if (comp->param_pass == 1) {
729 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
730 compile_node(comp, pns->nodes[2]);
731 }
732 } else {
733 comp->param_pass_num_default_params += 1;
734 if (comp->param_pass == 2) {
735 compile_node(comp, pns->nodes[2]);
736 }
737 }
738 }
Damienb14de212013-10-06 00:28:28 +0100739 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
740 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100741 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
742 // bare star
743 comp->have_bare_star = true;
744 }
745 }
746}
747
748// leaves function object on stack
749// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100750qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100751 if (comp->pass == PASS_1) {
752 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100753 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100754 // store the function scope so the compiling function can use it at each pass
755 pns->nodes[4] = (py_parse_node_t)s;
756 }
757
758 // save variables (probably don't need to do this, since we can't have nested definitions..?)
759 bool old_have_bare_star = comp->have_bare_star;
760 int old_param_pass = comp->param_pass;
761 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
762 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
763
764 // compile default parameters
765 comp->have_bare_star = false;
766 comp->param_pass = 1; // pass 1 does any default parameters after bare star
767 comp->param_pass_num_dict_params = 0;
768 comp->param_pass_num_default_params = 0;
769 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
770 comp->have_bare_star = false;
771 comp->param_pass = 2; // pass 2 does any default parameters before bare star
772 comp->param_pass_num_dict_params = 0;
773 comp->param_pass_num_default_params = 0;
774 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
775
776 // get the scope for this function
777 scope_t *fscope = (scope_t*)pns->nodes[4];
778
779 // make the function
780 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
781
782 // restore variables
783 comp->have_bare_star = old_have_bare_star;
784 comp->param_pass = old_param_pass;
785 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
786 comp->param_pass_num_default_params = old_param_pass_num_default_params;
787
788 // return its name (the 'f' in "def f(...):")
789 return fscope->simple_name;
790}
791
792// leaves class object on stack
793// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100794qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100795 if (comp->pass == PASS_1) {
796 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100797 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100798 // store the class scope so the compiling function can use it at each pass
799 pns->nodes[3] = (py_parse_node_t)s;
800 }
801
802 EMIT(load_build_class);
803
804 // scope for this class
805 scope_t *cscope = (scope_t*)pns->nodes[3];
806
807 // compile the class
808 close_over_variables_etc(comp, cscope, 0, 0);
809
810 // get its name
811 EMIT(load_const_id, cscope->simple_name);
812
813 // nodes[1] has parent classes, if any
814 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
815 // no parent classes
816 EMIT(call_function, 2, 0, false, false);
817 } else {
818 // have a parent class or classes
819 // TODO what if we have, eg, *a or **a in the parent list?
820 compile_node(comp, pns->nodes[1]);
821 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
822 }
823
824 // return its name (the 'C' in class C(...):")
825 return cscope->simple_name;
826}
827
Damien6cdd3af2013-10-05 18:08:26 +0100828// returns true if it was a built-in decorator (even if the built-in had an error)
829static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
830 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
831 return false;
832 }
833
834 if (name_len != 2) {
835 printf("SyntaxError: invalid micropython decorator\n");
836 return true;
837 }
838
839 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
840 if (attr == comp->qstr_native) {
841 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100842 } else if (attr == comp->qstr_viper) {
843 *emit_options = EMIT_OPT_VIPER;
Damienc025ebb2013-10-12 14:30:21 +0100844#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
Damien5bfb7592013-10-05 18:41:24 +0100845 } else if (attr == comp->qstr_asm_thumb) {
846 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100847#endif
Damien6cdd3af2013-10-05 18:08:26 +0100848 } else {
849 printf("SyntaxError: invalid micropython decorator\n");
850 }
851
852 return true;
853}
854
Damien429d7192013-10-04 19:53:11 +0100855void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
856 // get the list of decorators
857 py_parse_node_t *nodes;
858 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
859
Damien6cdd3af2013-10-05 18:08:26 +0100860 // inherit emit options for this function/class definition
861 uint emit_options = comp->scope_cur->emit_options;
862
863 // compile each decorator
864 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100865 for (int i = 0; i < n; i++) {
866 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
867 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100868
869 // nodes[0] contains the decorator function, which is a dotted name
870 py_parse_node_t *name_nodes;
871 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
872
873 // check for built-in decorators
874 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
875 // this was a built-in
876 num_built_in_decorators += 1;
877
878 } else {
879 // not a built-in, compile normally
880
881 // compile the decorator function
882 compile_node(comp, name_nodes[0]);
883 for (int i = 1; i < name_len; i++) {
884 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
885 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
886 }
887
888 // nodes[1] contains arguments to the decorator function, if any
889 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
890 // call the decorator function with the arguments in nodes[1]
891 compile_node(comp, pns_decorator->nodes[1]);
892 }
Damien429d7192013-10-04 19:53:11 +0100893 }
894 }
895
896 // compile the body (funcdef or classdef) and get its name
897 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
898 qstr body_name = 0;
899 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100900 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100901 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100902 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100903 } else {
904 // shouldn't happen
905 assert(0);
906 }
907
908 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100909 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100910 EMIT(call_function, 1, 0, false, false);
911 }
912
913 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100914 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100915}
916
917void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100918 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100919 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100920 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100921}
922
923void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
924 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100925 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100926 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
927 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
928
929 compile_node(comp, pns->nodes[0]); // base of the power node
930
931 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
932 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
933 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
934 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
935 for (int i = 0; i < n - 1; i++) {
936 compile_node(comp, pns1->nodes[i]);
937 }
938 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
939 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
940 }
941 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
942 // SyntaxError: can't delete a function call
943 assert(0);
944 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
945 compile_node(comp, pns1->nodes[0]);
946 EMIT(delete_subscr);
947 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
948 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
949 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
950 } else {
951 // shouldn't happen
952 assert(0);
953 }
954 } else {
955 // shouldn't happen
956 assert(0);
957 }
958
959 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
960 // SyntaxError, cannot delete
961 assert(0);
962 }
963 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
964 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
965 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
966 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
967 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
968
969 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
970 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
971 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
972 // sequence of one item, with trailing comma
973 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
974 c_del_stmt(comp, pns->nodes[0]);
975 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
976 // sequence of many items
977 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
978 c_del_stmt(comp, pns->nodes[0]);
979 for (int i = 0; i < n; i++) {
980 c_del_stmt(comp, pns1->nodes[i]);
981 }
982 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
983 // TODO not implemented; can't del comprehension?
984 assert(0);
985 } else {
986 // sequence with 2 items
987 goto sequence_with_2_items;
988 }
989 } else {
990 // sequence with 2 items
991 sequence_with_2_items:
992 c_del_stmt(comp, pns->nodes[0]);
993 c_del_stmt(comp, pns->nodes[1]);
994 }
995 } else {
996 // tuple with 1 element
997 c_del_stmt(comp, pn);
998 }
999 } else {
1000 // not implemented
1001 assert(0);
1002 }
1003}
1004
1005void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1006 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
1007}
1008
1009void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1010 if (comp->break_label == 0) {
1011 printf("ERROR: cannot break from here\n");
1012 }
1013 EMIT(break_loop, comp->break_label);
1014}
1015
1016void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1017 if (comp->continue_label == 0) {
1018 printf("ERROR: cannot continue from here\n");
1019 }
1020 if (comp->except_nest_level > 0) {
1021 EMIT(continue_loop, comp->continue_label);
1022 } else {
1023 EMIT(jump, comp->continue_label);
1024 }
1025}
1026
1027void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1028 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1029 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1030 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
1031 // special case when returning an if-expression; to match CPython optimisation
1032 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
1033 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
1034
Damienb05d7072013-10-05 13:37:10 +01001035 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001036 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1037 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
1038 EMIT(return_value);
1039 EMIT(label_assign, l_fail);
1040 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1041 } else {
1042 compile_node(comp, pns->nodes[0]);
1043 }
1044 EMIT(return_value);
1045}
1046
1047void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1048 compile_node(comp, pns->nodes[0]);
1049 EMIT(pop_top);
1050}
1051
1052void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1053 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1054 // raise
1055 EMIT(raise_varargs, 0);
1056 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1057 // raise x from y
1058 pns = (py_parse_node_struct_t*)pns->nodes[0];
1059 compile_node(comp, pns->nodes[0]);
1060 compile_node(comp, pns->nodes[1]);
1061 EMIT(raise_varargs, 2);
1062 } else {
1063 // raise x
1064 compile_node(comp, pns->nodes[0]);
1065 EMIT(raise_varargs, 1);
1066 }
1067}
1068
1069// q1 holds the base, q2 the full name
1070// eg a -> q1=q2=a
1071// a.b.c -> q1=a, q2=a.b.c
1072void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1073 bool is_as = false;
1074 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1075 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1076 // a name of the form x as y; unwrap it
1077 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1078 pn = pns->nodes[0];
1079 is_as = true;
1080 }
1081 if (PY_PARSE_NODE_IS_ID(pn)) {
1082 // just a simple name
1083 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1084 if (!is_as) {
1085 *q1 = *q2;
1086 }
1087 EMIT(import_name, *q2);
1088 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1089 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1090 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1091 // a name of the form a.b.c
1092 if (!is_as) {
1093 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1094 }
1095 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1096 int len = n - 1;
1097 for (int i = 0; i < n; i++) {
1098 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1099 }
1100 char *str = m_new(char, len + 1);
1101 str[0] = 0;
1102 for (int i = 0; i < n; i++) {
1103 if (i > 0) {
1104 strcat(str, ".");
1105 }
1106 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1107 }
1108 *q2 = qstr_from_str_take(str);
1109 EMIT(import_name, *q2);
1110 if (is_as) {
1111 for (int i = 1; i < n; i++) {
1112 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1113 }
1114 }
1115 } else {
1116 // TODO not implemented
1117 assert(0);
1118 }
1119 } else {
1120 // TODO not implemented
1121 assert(0);
1122 }
1123}
1124
1125void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1126 EMIT(load_const_small_int, 0); // ??
1127 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1128 qstr q1, q2;
1129 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001130 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001131}
1132
1133void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1134 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1135}
1136
1137void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1138 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
1139 EMIT(load_const_small_int, 0); // what's this for??
1140 EMIT(load_const_verbatim_start);
1141 EMIT(load_const_verbatim_str, "('*',)");
1142 EMIT(load_const_verbatim_end);
1143 qstr dummy_q, id1;
1144 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1145 EMIT(import_star);
1146 } else {
1147 py_parse_node_t *pn_nodes;
1148 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1149
1150 EMIT(load_const_small_int, 0); // what's this for??
1151 EMIT(load_const_verbatim_start);
1152 EMIT(load_const_verbatim_str, "(");
1153 for (int i = 0; i < n; i++) {
1154 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1155 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1156 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1157 if (i > 0) {
1158 EMIT(load_const_verbatim_str, ", ");
1159 }
1160 EMIT(load_const_verbatim_str, "'");
1161 EMIT(load_const_verbatim_str, qstr_str(id2));
1162 EMIT(load_const_verbatim_str, "'");
1163 }
1164 if (n == 1) {
1165 EMIT(load_const_verbatim_str, ",");
1166 }
1167 EMIT(load_const_verbatim_str, ")");
1168 EMIT(load_const_verbatim_end);
1169 qstr dummy_q, id1;
1170 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1171 for (int i = 0; i < n; i++) {
1172 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1173 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1174 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1175 EMIT(import_from, id2);
1176 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001177 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001178 } else {
Damien4b03e772013-10-05 14:17:09 +01001179 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001180 }
1181 }
1182 EMIT(pop_top);
1183 }
1184}
1185
1186void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001187 if (comp->pass == PASS_1) {
1188 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1189 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1190 } else {
1191 pns = (py_parse_node_struct_t*)pns->nodes[0];
1192 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1193 for (int i = 0; i < num_nodes; i++) {
1194 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1195 }
Damien429d7192013-10-04 19:53:11 +01001196 }
1197 }
1198}
1199
1200void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001201 if (comp->pass == PASS_1) {
1202 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1203 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1204 } else {
1205 pns = (py_parse_node_struct_t*)pns->nodes[0];
1206 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1207 for (int i = 0; i < num_nodes; i++) {
1208 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1209 }
Damien429d7192013-10-04 19:53:11 +01001210 }
1211 }
1212}
1213
1214void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001215 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001216 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001217 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001218 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1219 // assertion message
1220 compile_node(comp, pns->nodes[1]);
1221 EMIT(call_function, 1, 0, false, false);
1222 }
1223 EMIT(raise_varargs, 1);
1224 EMIT(label_assign, l_end);
1225}
1226
1227void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1228 // TODO proper and/or short circuiting
1229
Damienb05d7072013-10-05 13:37:10 +01001230 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001231
Damienb05d7072013-10-05 13:37:10 +01001232 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001233 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1234
1235 compile_node(comp, pns->nodes[1]); // if block
1236 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1237 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001238 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001239 EMIT(jump, l_end);
1240 }
1241 //}
1242 EMIT(label_assign, l_fail);
1243
1244 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1245 // compile elif blocks
1246
1247 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1248
1249 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1250 // multiple elif blocks
1251
1252 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1253 for (int i = 0; i < n; i++) {
1254 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001255 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001256 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1257
1258 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001259 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001260 EMIT(jump, l_end);
1261 }
1262 EMIT(label_assign, l_fail);
1263 }
1264
1265 } else {
1266 // a single elif block
1267
Damienb05d7072013-10-05 13:37:10 +01001268 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001269 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1270
1271 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001272 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001273 EMIT(jump, l_end);
1274 }
1275 EMIT(label_assign, l_fail);
1276 }
1277 }
1278
1279 // compile else block
1280 compile_node(comp, pns->nodes[3]); // can be null
1281
1282 EMIT(label_assign, l_end);
1283}
1284
1285void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1286 int old_break_label = comp->break_label;
1287 int old_continue_label = comp->continue_label;
1288
Damienb05d7072013-10-05 13:37:10 +01001289 int done_label = comp_next_label(comp);
1290 int end_label = comp_next_label(comp);
1291 int break_label = comp_next_label(comp);
1292 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001293
1294 comp->break_label = break_label;
1295 comp->continue_label = continue_label;
1296
1297 EMIT(setup_loop, end_label);
1298 EMIT(label_assign, continue_label);
1299 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1300 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001301 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001302 EMIT(jump, continue_label);
1303 }
1304 EMIT(label_assign, done_label);
1305
1306 // break/continue apply to outer loop (if any) in the else block
1307 comp->break_label = old_break_label;
1308 comp->continue_label = old_continue_label;
1309
1310 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1311 // this is a small hack to agree with CPython
1312 if (!node_is_const_true(pns->nodes[0])) {
1313 EMIT(pop_block);
1314 }
1315
1316 compile_node(comp, pns->nodes[2]); // else
1317
1318 EMIT(label_assign, break_label);
1319 EMIT(label_assign, end_label);
1320}
1321
1322void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1323 int old_break_label = comp->break_label;
1324 int old_continue_label = comp->continue_label;
1325
Damienb05d7072013-10-05 13:37:10 +01001326 int for_label = comp_next_label(comp);
1327 int pop_label = comp_next_label(comp);
1328 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001329
Damienb05d7072013-10-05 13:37:10 +01001330 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001331
1332 comp->continue_label = for_label;
1333 comp->break_label = break_label;
1334
1335 EMIT(setup_loop, end_label);
1336 compile_node(comp, pns->nodes[1]); // iterator
1337 EMIT(get_iter);
1338 EMIT(label_assign, for_label);
1339 EMIT(for_iter, pop_label);
1340 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1341 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001342 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001343 EMIT(jump, for_label);
1344 }
1345 EMIT(label_assign, pop_label);
1346 EMIT(for_iter_end);
1347
1348 // break/continue apply to outer loop (if any) in the else block
1349 comp->break_label = old_break_label;
1350 comp->continue_label = old_continue_label;
1351
1352 EMIT(pop_block);
1353
1354 compile_node(comp, pns->nodes[3]); // else (not tested)
1355
1356 EMIT(label_assign, break_label);
1357 EMIT(label_assign, end_label);
1358}
1359
1360void 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) {
1361 // this function is a bit of a hack at the moment
1362 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1363
1364 // setup code
1365 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001366 int l1 = comp_next_label(comp);
1367 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001368 comp->except_nest_level += 1; // for correct handling of continue
1369 EMIT(setup_except, l1);
1370 compile_node(comp, pn_body); // body
1371 EMIT(pop_block);
1372 EMIT(jump, success_label);
1373 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001374 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001375
1376 for (int i = 0; i < n_except; i++) {
1377 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1378 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1379
1380 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001381 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001382
1383 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1384 // this is a catch all exception handler
1385 if (i + 1 != n_except) {
1386 printf("SyntaxError: default 'except:' must be last\n");
1387 return;
1388 }
1389 } else {
1390 // this exception handler requires a match to a certain type of exception
1391 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1392 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1393 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1394 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1395 // handler binds the exception to a local
1396 pns_exception_expr = pns3->nodes[0];
1397 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1398 }
1399 }
1400 EMIT(dup_top);
1401 compile_node(comp, pns_exception_expr);
1402 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1403 EMIT(pop_jump_if_false, end_finally_label);
1404 }
1405
1406 EMIT(pop_top);
1407
1408 if (qstr_exception_local == 0) {
1409 EMIT(pop_top);
1410 } else {
Damien4b03e772013-10-05 14:17:09 +01001411 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001412 }
1413
1414 EMIT(pop_top);
1415
1416 int l3;
1417 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001418 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001419 EMIT(setup_finally, l3);
1420 }
1421 compile_node(comp, pns_except->nodes[1]);
1422 if (qstr_exception_local != 0) {
1423 EMIT(pop_block);
1424 }
1425 EMIT(pop_except);
1426 if (qstr_exception_local != 0) {
1427 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1428 EMIT(label_assign, l3);
1429 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001430 EMIT(store_id, qstr_exception_local);
1431 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001432 EMIT(end_finally);
1433 }
1434 EMIT(jump, l2);
1435 EMIT(label_assign, end_finally_label);
1436 }
1437
1438 EMIT(end_finally);
1439 EMIT(label_assign, success_label);
1440 comp->except_nest_level -= 1;
1441 compile_node(comp, pn_else); // else block, can be null
1442 EMIT(label_assign, l2);
1443 EMIT(set_stack_size, stack_size);
1444}
1445
1446void 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) {
1447 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1448 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001449 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001450 EMIT(setup_finally, l_finally_block);
1451 if (n_except == 0) {
1452 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1453 compile_node(comp, pn_body);
1454 } else {
1455 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1456 }
1457 EMIT(pop_block);
1458 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1459 EMIT(label_assign, l_finally_block);
1460 compile_node(comp, pn_finally);
1461 EMIT(end_finally);
1462 EMIT(set_stack_size, stack_size);
1463}
1464
1465void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1466 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1467 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1468 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1469 // just try-finally
1470 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1471 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1472 // try-except and possibly else and/or finally
1473 py_parse_node_t *pn_excepts;
1474 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1475 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1476 // no finally
1477 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1478 } else {
1479 // have finally
1480 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1481 }
1482 } else {
1483 // just try-except
1484 py_parse_node_t *pn_excepts;
1485 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1486 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1487 }
1488 } else {
1489 // shouldn't happen
1490 assert(0);
1491 }
1492}
1493
1494void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1495 if (n == 0) {
1496 // no more pre-bits, compile the body of the with
1497 compile_node(comp, body);
1498 } else {
Damienb05d7072013-10-05 13:37:10 +01001499 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001500 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1501 // this pre-bit is of the form "a as b"
1502 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1503 compile_node(comp, pns->nodes[0]);
1504 EMIT(setup_with, l_end);
1505 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1506 } else {
1507 // this pre-bit is just an expression
1508 compile_node(comp, nodes[0]);
1509 EMIT(setup_with, l_end);
1510 EMIT(pop_top);
1511 }
1512 // compile additional pre-bits and the body
1513 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1514 // finish this with block
1515 EMIT(pop_block);
1516 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1517 EMIT(label_assign, l_end);
1518 EMIT(with_cleanup);
1519 EMIT(end_finally);
1520 }
1521}
1522
1523void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1524 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1525 py_parse_node_t *nodes;
1526 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1527 assert(n > 0);
1528
1529 // compile in a nested fashion
1530 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1531}
1532
1533void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1534 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1535 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1536 // do nothing with a lonely constant
1537 } else {
1538 compile_node(comp, pns->nodes[0]); // just an expression
1539 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1540 }
1541 } else {
1542 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1543 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1544 if (kind == PN_expr_stmt_augassign) {
1545 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1546 compile_node(comp, pns1->nodes[1]); // rhs
1547 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1548 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1549 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1550 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1551 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1552 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1553 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1554 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1555 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1556 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1557 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1558 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1559 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1560 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1561 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1562 default: assert(0); // shouldn't happen
1563 }
1564 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1565 } else if (kind == PN_expr_stmt_assign_list) {
1566 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1567 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1568 // following CPython, we store left-most first
1569 if (rhs > 0) {
1570 EMIT(dup_top);
1571 }
1572 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1573 for (int i = 0; i < rhs; i++) {
1574 if (i + 1 < rhs) {
1575 EMIT(dup_top);
1576 }
1577 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1578 }
1579 } else if (kind == PN_expr_stmt_assign) {
1580 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1581 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1582 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1583 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1584 // optimisation for a, b = c, d; to match CPython's optimisation
1585 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1586 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1587 compile_node(comp, pns10->nodes[0]); // rhs
1588 compile_node(comp, pns10->nodes[1]); // rhs
1589 EMIT(rot_two);
1590 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1591 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1592 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1593 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1594 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1595 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1596 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1597 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1598 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1599 compile_node(comp, pns10->nodes[0]); // rhs
1600 compile_node(comp, pns10->nodes[1]); // rhs
1601 compile_node(comp, pns10->nodes[2]); // rhs
1602 EMIT(rot_three);
1603 EMIT(rot_two);
1604 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1605 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1606 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1607 } else {
1608 compile_node(comp, pns1->nodes[0]); // rhs
1609 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1610 }
1611 } else {
1612 // shouldn't happen
1613 assert(0);
1614 }
1615 }
1616}
1617
1618void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1619 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1620 compile_node(comp, pns->nodes[0]);
1621 for (int i = 1; i < num_nodes; i += 1) {
1622 compile_node(comp, pns->nodes[i]);
1623 EMIT(binary_op, binary_op);
1624 }
1625}
1626
1627void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1628 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1629 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1630
1631 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001632 int l_fail = comp_next_label(comp);
1633 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001634 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1635 compile_node(comp, pns->nodes[0]); // success value
1636 EMIT(jump, l_end);
1637 EMIT(label_assign, l_fail);
1638 EMIT(set_stack_size, stack_size); // force stack size reset
1639 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1640 EMIT(label_assign, l_end);
1641}
1642
1643void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1644 // TODO default params etc for lambda; possibly just use funcdef code
1645 //py_parse_node_t pn_params = pns->nodes[0];
1646 //py_parse_node_t pn_body = pns->nodes[1];
1647
1648 if (comp->pass == PASS_1) {
1649 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001650 scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (py_parse_node_t)pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01001651 // store the lambda scope so the compiling function (this one) can use it at each pass
1652 pns->nodes[2] = (py_parse_node_t)s;
1653 }
1654
1655 // get the scope for this lambda
1656 scope_t *this_scope = (scope_t*)pns->nodes[2];
1657
1658 // make the lambda
1659 close_over_variables_etc(comp, this_scope, 0, 0);
1660}
1661
1662void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001663 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001664 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1665 for (int i = 0; i < n; i += 1) {
1666 compile_node(comp, pns->nodes[i]);
1667 if (i + 1 < n) {
1668 EMIT(jump_if_true_or_pop, l_end);
1669 }
1670 }
1671 EMIT(label_assign, l_end);
1672}
1673
1674void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001675 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001676 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1677 for (int i = 0; i < n; i += 1) {
1678 compile_node(comp, pns->nodes[i]);
1679 if (i + 1 < n) {
1680 EMIT(jump_if_false_or_pop, l_end);
1681 }
1682 }
1683 EMIT(label_assign, l_end);
1684}
1685
1686void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1687 compile_node(comp, pns->nodes[0]);
1688 EMIT(unary_op, RT_UNARY_OP_NOT);
1689}
1690
1691void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1692 int stack_size = EMIT(get_stack_size);
1693 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1694 compile_node(comp, pns->nodes[0]);
1695 bool multi = (num_nodes > 3);
1696 int l_fail = 0;
1697 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001698 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001699 }
1700 for (int i = 1; i + 1 < num_nodes; i += 2) {
1701 compile_node(comp, pns->nodes[i + 1]);
1702 if (i + 2 < num_nodes) {
1703 EMIT(dup_top);
1704 EMIT(rot_three);
1705 }
1706 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1707 EMIT(compare_op, RT_COMPARE_OP_LESS);
1708 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1709 EMIT(compare_op, RT_COMPARE_OP_MORE);
1710 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1711 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1712 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1713 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1714 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1715 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1716 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1717 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1718 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1719 EMIT(compare_op, RT_COMPARE_OP_IN);
1720 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1721 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1722 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1723 if (kind == PN_comp_op_not_in) {
1724 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1725 } else if (kind == PN_comp_op_is) {
1726 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1727 EMIT(compare_op, RT_COMPARE_OP_IS);
1728 } else {
1729 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1730 }
1731 } else {
1732 // shouldn't happen
1733 assert(0);
1734 }
1735 } else {
1736 // shouldn't happen
1737 assert(0);
1738 }
1739 if (i + 2 < num_nodes) {
1740 EMIT(jump_if_false_or_pop, l_fail);
1741 }
1742 }
1743 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001744 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001745 EMIT(jump, l_end);
1746 EMIT(label_assign, l_fail);
1747 EMIT(rot_two);
1748 EMIT(pop_top);
1749 EMIT(label_assign, l_end);
1750 EMIT(set_stack_size, stack_size + 1); // force stack size
1751 }
1752}
1753
1754void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1755 // TODO
1756 assert(0);
1757 compile_node(comp, pns->nodes[0]);
1758 //EMIT(unary_op, "UNARY_STAR");
1759}
1760
1761void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1762 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1763}
1764
1765void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1766 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1767}
1768
1769void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1770 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1771}
1772
1773void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1774 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1775 compile_node(comp, pns->nodes[0]);
1776 for (int i = 1; i + 1 < num_nodes; i += 2) {
1777 compile_node(comp, pns->nodes[i + 1]);
1778 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1779 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1780 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1781 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1782 } else {
1783 // shouldn't happen
1784 assert(0);
1785 }
1786 }
1787}
1788
1789void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1790 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1791 compile_node(comp, pns->nodes[0]);
1792 for (int i = 1; i + 1 < num_nodes; i += 2) {
1793 compile_node(comp, pns->nodes[i + 1]);
1794 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
1795 EMIT(binary_op, RT_BINARY_OP_ADD);
1796 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1797 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1798 } else {
1799 // shouldn't happen
1800 assert(0);
1801 }
1802 }
1803}
1804
1805void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1806 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1807 compile_node(comp, pns->nodes[0]);
1808 for (int i = 1; i + 1 < num_nodes; i += 2) {
1809 compile_node(comp, pns->nodes[i + 1]);
1810 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1811 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1812 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1813 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1814 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1815 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1816 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1817 EMIT(binary_op, RT_BINARY_OP_MODULO);
1818 } else {
1819 // shouldn't happen
1820 assert(0);
1821 }
1822 }
1823}
1824
1825void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1826 compile_node(comp, pns->nodes[1]);
1827 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1828 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1829 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1830 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1831 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1832 EMIT(unary_op, RT_UNARY_OP_INVERT);
1833 } else {
1834 // shouldn't happen
1835 assert(0);
1836 }
1837}
1838
1839void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
1840 // function to call is on top of stack
1841
1842 int old_n_arg_keyword = comp->n_arg_keyword;
1843 bool old_have_star_arg = comp->have_star_arg;
1844 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
1845 comp->n_arg_keyword = 0;
1846 comp->have_star_arg = false;
1847 comp->have_dbl_star_arg = false;
1848
1849 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
1850
1851 // compute number of positional arguments
1852 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
1853 if (comp->have_star_arg) {
1854 n_positional -= 1;
1855 }
1856 if (comp->have_dbl_star_arg) {
1857 n_positional -= 1;
1858 }
1859
1860 if (is_method_call) {
1861 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1862 } else {
1863 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1864 }
1865
1866 comp->n_arg_keyword = old_n_arg_keyword;
1867 comp->have_star_arg = old_have_star_arg;
1868 comp->have_dbl_star_arg = old_have_dbl_star_arg;
1869}
1870
1871void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
1872 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1873 for (int i = 0; i < num_nodes; i++) {
1874 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)) {
1875 // optimisation for method calls a.f(...), following PyPy
1876 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
1877 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
1878 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
1879 compile_trailer_paren_helper(comp, pns_paren, true);
1880 i += 1;
1881 } else {
1882 compile_node(comp, pns->nodes[i]);
1883 }
1884 }
1885}
1886
1887void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
1888 compile_node(comp, pns->nodes[0]);
1889 EMIT(binary_op, RT_BINARY_OP_POWER);
1890}
1891
1892void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
1893 // a list of strings
1894 EMIT(load_const_verbatim_start);
1895 EMIT(load_const_verbatim_str, "'");
1896 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1897 for (int i = 0; i < n; i++) {
1898 // TODO allow concatenation of either strings or bytes, but not mixed
1899 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
1900 assert(PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]) == PY_PARSE_NODE_STRING);
1901 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1902 EMIT(load_const_verbatim_strn, str, strlen(str));
1903 }
1904 EMIT(load_const_verbatim_str, "'");
1905 EMIT(load_const_verbatim_end);
1906}
1907
1908// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
1909void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
1910 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
1911 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
1912 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
1913
1914 if (comp->pass == PASS_1) {
1915 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01001916 scope_t *s = scope_new_and_link(comp, kind, (py_parse_node_t)pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01001917 // store the comprehension scope so the compiling function (this one) can use it at each pass
1918 pns_comp_for->nodes[3] = (py_parse_node_t)s;
1919 }
1920
1921 // get the scope for this comprehension
1922 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
1923
1924 // compile the comprehension
1925 close_over_variables_etc(comp, this_scope, 0, 0);
1926
1927 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
1928 EMIT(get_iter);
1929 EMIT(call_function, 1, 0, false, false);
1930}
1931
1932void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
1933 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1934 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01001935 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
1936 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1937 pns = (py_parse_node_struct_t*)pns->nodes[0];
1938 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
1939 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1940 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1941 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
1942 // tuple of one item, with trailing comma
1943 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01001944 c_tuple(comp, pns->nodes[0], NULL);
1945 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
1946 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01001947 c_tuple(comp, pns->nodes[0], pns2);
1948 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
1949 // generator expression
1950 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
1951 } else {
1952 // tuple with 2 items
1953 goto tuple_with_2_items;
1954 }
1955 } else {
1956 // tuple with 2 items
1957 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01001958 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
1959 }
1960 } else {
1961 // parenthesis around a single item, is just that item
1962 compile_node(comp, pns->nodes[0]);
1963 }
1964}
1965
1966void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
1967 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1968 // empty list
1969 EMIT(build_list, 0);
1970 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1971 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
1972 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
1973 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
1974 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
1975 // list of one item, with trailing comma
1976 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
1977 compile_node(comp, pns2->nodes[0]);
1978 EMIT(build_list, 1);
1979 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
1980 // list of many items
1981 compile_node(comp, pns2->nodes[0]);
1982 compile_generic_all_nodes(comp, pns3);
1983 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
1984 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
1985 // list comprehension
1986 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
1987 } else {
1988 // list with 2 items
1989 goto list_with_2_items;
1990 }
1991 } else {
1992 // list with 2 items
1993 list_with_2_items:
1994 compile_node(comp, pns2->nodes[0]);
1995 compile_node(comp, pns2->nodes[1]);
1996 EMIT(build_list, 2);
1997 }
1998 } else {
1999 // list with 1 item
2000 compile_node(comp, pns->nodes[0]);
2001 EMIT(build_list, 1);
2002 }
2003}
2004
2005void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2006 py_parse_node_t pn = pns->nodes[0];
2007 if (PY_PARSE_NODE_IS_NULL(pn)) {
2008 // empty dict
2009 EMIT(build_map, 0);
2010 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2011 pns = (py_parse_node_struct_t*)pn;
2012 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2013 // dict with one element
2014 EMIT(build_map, 1);
2015 compile_node(comp, pn);
2016 EMIT(store_map);
2017 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2018 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2019 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2020 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2021 // dict/set with multiple elements
2022
2023 // get tail elements (2nd, 3rd, ...)
2024 py_parse_node_t *nodes;
2025 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2026
2027 // first element sets whether it's a dict or set
2028 bool is_dict;
2029 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2030 // a dictionary
2031 EMIT(build_map, 1 + n);
2032 compile_node(comp, pns->nodes[0]);
2033 EMIT(store_map);
2034 is_dict = true;
2035 } else {
2036 // a set
2037 compile_node(comp, pns->nodes[0]); // 1st value of set
2038 is_dict = false;
2039 }
2040
2041 // process rest of elements
2042 for (int i = 0; i < n; i++) {
2043 py_parse_node_t pn = nodes[i];
2044 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2045 compile_node(comp, pn);
2046 if (is_dict) {
2047 if (!is_key_value) {
2048 printf("SyntaxError?: expecting key:value for dictionary");
2049 return;
2050 }
2051 EMIT(store_map);
2052 } else {
2053 if (is_key_value) {
2054 printf("SyntaxError?: expecting just a value for set");
2055 return;
2056 }
2057 }
2058 }
2059
2060 // if it's a set, build it
2061 if (!is_dict) {
2062 EMIT(build_set, 1 + n);
2063 }
2064 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2065 // dict/set comprehension
2066 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2067 // a dictionary comprehension
2068 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2069 } else {
2070 // a set comprehension
2071 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2072 }
2073 } else {
2074 // shouldn't happen
2075 assert(0);
2076 }
2077 } else {
2078 // set with one element
2079 goto set_with_one_element;
2080 }
2081 } else {
2082 // set with one element
2083 set_with_one_element:
2084 compile_node(comp, pn);
2085 EMIT(build_set, 1);
2086 }
2087}
2088
2089void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2090 compile_trailer_paren_helper(comp, pns, false);
2091}
2092
2093void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2094 // object who's index we want is on top of stack
2095 compile_node(comp, pns->nodes[0]); // the index
2096 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2097}
2098
2099void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2100 // object who's attribute we want is on top of stack
2101 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2102}
2103
2104void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2105 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2106 py_parse_node_t pn = pns->nodes[0];
2107 if (PY_PARSE_NODE_IS_NULL(pn)) {
2108 // [?:]
2109 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2110 EMIT(build_slice, 2);
2111 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2112 pns = (py_parse_node_struct_t*)pn;
2113 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2114 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2115 pn = pns->nodes[0];
2116 if (PY_PARSE_NODE_IS_NULL(pn)) {
2117 // [?::]
2118 EMIT(build_slice, 2);
2119 } else {
2120 // [?::x]
2121 compile_node(comp, pn);
2122 EMIT(build_slice, 3);
2123 }
2124 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2125 compile_node(comp, pns->nodes[0]);
2126 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2127 pns = (py_parse_node_struct_t*)pns->nodes[1];
2128 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2129 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2130 // [?:x:]
2131 EMIT(build_slice, 2);
2132 } else {
2133 // [?:x:x]
2134 compile_node(comp, pns->nodes[0]);
2135 EMIT(build_slice, 3);
2136 }
2137 } else {
2138 // [?:x]
2139 compile_node(comp, pn);
2140 EMIT(build_slice, 2);
2141 }
2142 } else {
2143 // [?:x]
2144 compile_node(comp, pn);
2145 EMIT(build_slice, 2);
2146 }
2147}
2148
2149void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2150 compile_node(comp, pns->nodes[0]); // start of slice
2151 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2152 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2153}
2154
2155void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2156 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2157 compile_subscript_3_helper(comp, pns);
2158}
2159
2160void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2161 // if this is called then we are compiling a dict key:value pair
2162 compile_node(comp, pns->nodes[1]); // value
2163 compile_node(comp, pns->nodes[0]); // key
2164}
2165
2166void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002167 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002168 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002169 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002170}
2171
2172void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2173 if (comp->have_star_arg) {
2174 printf("SyntaxError?: can't have multiple *x\n");
2175 return;
2176 }
2177 comp->have_star_arg = true;
2178 compile_node(comp, pns->nodes[0]);
2179}
2180
2181void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2182 if (comp->have_dbl_star_arg) {
2183 printf("SyntaxError?: can't have multiple **x\n");
2184 return;
2185 }
2186 comp->have_dbl_star_arg = true;
2187 compile_node(comp, pns->nodes[0]);
2188}
2189
2190void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2191 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2192 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2193 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2194 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2195 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2196 return;
2197 }
2198 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2199 compile_node(comp, pns2->nodes[0]);
2200 comp->n_arg_keyword += 1;
2201 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2202 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2203 } else {
2204 // shouldn't happen
2205 assert(0);
2206 }
2207}
2208
2209void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2210 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2211 printf("SyntaxError: 'yield' outside function\n");
2212 return;
2213 }
2214 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2215 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2216 EMIT(yield_value);
2217 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2218 pns = (py_parse_node_struct_t*)pns->nodes[0];
2219 compile_node(comp, pns->nodes[0]);
2220 EMIT(get_iter);
2221 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2222 EMIT(yield_from);
2223 } else {
2224 compile_node(comp, pns->nodes[0]);
2225 EMIT(yield_value);
2226 }
2227}
2228
2229typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2230static compile_function_t compile_function[] = {
2231 NULL,
2232#define nc NULL
2233#define c(f) compile_##f
2234#define DEF_RULE(rule, comp, kind, arg...) comp,
2235#include "grammar.h"
2236#undef nc
2237#undef c
2238#undef DEF_RULE
2239};
2240
2241void compile_node(compiler_t *comp, py_parse_node_t pn) {
2242 if (PY_PARSE_NODE_IS_NULL(pn)) {
2243 // pass
2244 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2245 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2246 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002247 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002248 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2249 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2250 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2251 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2252 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002253 case PY_PARSE_NODE_TOKEN:
2254 if (arg == PY_TOKEN_NEWLINE) {
2255 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
2256 // do nothing
2257 } else {
2258 EMIT(load_const_tok, arg);
2259 }
2260 break;
Damien429d7192013-10-04 19:53:11 +01002261 default: assert(0);
2262 }
2263 } else {
2264 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2265 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2266 if (f == NULL) {
2267 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
2268 parse_node_show(pn, 0);
2269 assert(0);
2270 } else {
2271 f(comp, pns);
2272 }
2273 }
2274}
2275
2276void 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) {
2277 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002278 qstr param_name = 0;
2279 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002280 if (PY_PARSE_NODE_IS_ID(pn)) {
2281 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002282 if (comp->have_bare_star) {
2283 // comes after a bare star, so doesn't count as a parameter
2284 } else {
2285 comp->scope_cur->num_params += 1;
2286 }
Damienb14de212013-10-06 00:28:28 +01002287 } else {
2288 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2289 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2290 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002291 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002292 //int node_index = 1; unused
2293 if (allow_annotations) {
2294 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2295 // this parameter has an annotation
2296 pn_annotation = pns->nodes[1];
2297 }
2298 //node_index = 2; unused
2299 }
2300 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2301 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2302 // this parameter has a default value
2303 if (comp->have_bare_star) {
2304 comp->scope_cur->num_dict_params += 1;
2305 } else {
2306 comp->scope_cur->num_default_params += 1;
2307 }
2308 }
2309 */
2310 if (comp->have_bare_star) {
2311 // comes after a bare star, so doesn't count as a parameter
2312 } else {
2313 comp->scope_cur->num_params += 1;
2314 }
2315 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2316 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2317 // bare star
2318 // TODO see http://www.python.org/dev/peps/pep-3102/
2319 comp->have_bare_star = true;
2320 //assert(comp->scope_cur->num_dict_params == 0);
2321 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2322 // named star
2323 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2324 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2325 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2326 // named star with annotation
2327 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2328 pns = (py_parse_node_struct_t*)pns->nodes[0];
2329 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2330 pn_annotation = pns->nodes[1];
2331 } else {
2332 // shouldn't happen
2333 assert(0);
2334 }
2335 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002336 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002337 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2338 // this parameter has an annotation
2339 pn_annotation = pns->nodes[1];
2340 }
2341 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002342 } else {
Damienb14de212013-10-06 00:28:28 +01002343 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002344 assert(0);
2345 }
Damien429d7192013-10-04 19:53:11 +01002346 }
2347
2348 if (param_name != 0) {
2349 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2350 // TODO this parameter has an annotation
2351 }
2352 bool added;
2353 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2354 if (!added) {
2355 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2356 return;
2357 }
2358 id_info->param = true;
2359 id_info->kind = ID_INFO_KIND_LOCAL;
2360 }
2361}
2362
2363void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2364 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2365}
2366
2367void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2368 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2369}
2370
2371void 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) {
2372 tail_recursion:
2373 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2374 // no more nested if/for; compile inner expression
2375 compile_node(comp, pn_inner_expr);
2376 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2377 EMIT(list_append, for_depth + 2);
2378 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2379 EMIT(map_add, for_depth + 2);
2380 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2381 EMIT(set_add, for_depth + 2);
2382 } else {
2383 EMIT(yield_value);
2384 EMIT(pop_top);
2385 }
2386 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2387 // if condition
2388 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2389 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2390 pn_iter = pns_comp_if->nodes[1];
2391 goto tail_recursion;
2392 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2393 // for loop
2394 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2395 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002396 int l_end2 = comp_next_label(comp);
2397 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002398 EMIT(get_iter);
2399 EMIT(label_assign, l_top2);
2400 EMIT(for_iter, l_end2);
2401 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2402 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2403 EMIT(jump, l_top2);
2404 EMIT(label_assign, l_end2);
2405 EMIT(for_iter_end);
2406 } else {
2407 // shouldn't happen
2408 assert(0);
2409 }
2410}
2411
2412void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2413 // see http://www.python.org/dev/peps/pep-0257/
2414
2415 // look for the first statement
2416 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2417 // fall through
2418 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2419 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2420 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2421 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2422 } else {
2423 return;
2424 }
2425
2426 // check the first statement for a doc string
2427 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2428 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2429 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2430 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2431 if (kind == PY_PARSE_NODE_STRING) {
2432 compile_node(comp, pns->nodes[0]); // a doc string
2433 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002434 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002435 }
2436 }
2437 }
2438}
2439
2440void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2441 comp->pass = pass;
2442 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002443 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002444 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002445
2446 if (comp->pass == PASS_1) {
2447 scope->stack_size = 0;
2448 }
2449
2450 if (comp->pass == PASS_3) {
2451 //printf("----\n");
2452 scope_print_info(scope);
2453 }
2454
2455 // compile
2456 if (scope->kind == SCOPE_MODULE) {
2457 check_for_doc_string(comp, scope->pn);
2458 compile_node(comp, scope->pn);
2459 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2460 EMIT(return_value);
2461 } else if (scope->kind == SCOPE_FUNCTION) {
2462 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2463 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2464 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2465
2466 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002467 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002468 if (comp->pass == PASS_1) {
2469 comp->have_bare_star = false;
2470 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2471 }
2472
Damien826005c2013-10-05 23:17:28 +01002473 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002474
2475 compile_node(comp, pns->nodes[3]); // 3 is function body
2476 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002477 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002478 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2479 EMIT(return_value);
2480 }
2481 } else if (scope->kind == SCOPE_LAMBDA) {
2482 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2483 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2484 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2485
2486 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002487 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002488 if (comp->pass == PASS_1) {
2489 comp->have_bare_star = false;
2490 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2491 }
2492
2493 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2494 EMIT(return_value);
2495 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2496 // a bit of a hack at the moment
2497
2498 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2499 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2500 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2501 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2502 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2503
Damien6cdd3af2013-10-05 18:08:26 +01002504 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002505 if (comp->pass == PASS_1) {
2506 bool added;
2507 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2508 assert(added);
2509 id_info->kind = ID_INFO_KIND_LOCAL;
2510 scope->num_params = 1;
2511 }
2512
2513 if (scope->kind == SCOPE_LIST_COMP) {
2514 EMIT(build_list, 0);
2515 } else if (scope->kind == SCOPE_DICT_COMP) {
2516 EMIT(build_map, 0);
2517 } else if (scope->kind == SCOPE_SET_COMP) {
2518 EMIT(build_set, 0);
2519 }
2520
Damienb05d7072013-10-05 13:37:10 +01002521 int l_end = comp_next_label(comp);
2522 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002523 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002524 EMIT(label_assign, l_top);
2525 EMIT(for_iter, l_end);
2526 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2527 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2528 EMIT(jump, l_top);
2529 EMIT(label_assign, l_end);
2530 EMIT(for_iter_end);
2531
2532 if (scope->kind == SCOPE_GEN_EXPR) {
2533 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2534 }
2535 EMIT(return_value);
2536 } else {
2537 assert(scope->kind == SCOPE_CLASS);
2538 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2539 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2540 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2541
2542 if (comp->pass == PASS_1) {
2543 bool added;
2544 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2545 assert(added);
2546 id_info->kind = ID_INFO_KIND_LOCAL;
2547 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2548 assert(added);
2549 id_info->kind = ID_INFO_KIND_LOCAL;
2550 id_info->param = true;
2551 scope->num_params = 1; // __locals__ is the parameter
2552 }
2553
Damien4b03e772013-10-05 14:17:09 +01002554 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002555 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002556 EMIT(load_id, comp->qstr___name__);
2557 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002558 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002559 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002560
2561 check_for_doc_string(comp, pns->nodes[2]);
2562 compile_node(comp, pns->nodes[2]); // 2 is class body
2563
2564 id_info_t *id = scope_find(scope, comp->qstr___class__);
2565 assert(id != NULL);
2566 if (id->kind == ID_INFO_KIND_LOCAL) {
2567 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2568 } else {
2569 EMIT(load_closure, comp->qstr___class__);
2570 }
2571 EMIT(return_value);
2572 }
2573
Damien415eb6f2013-10-05 12:19:06 +01002574 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002575
Damien826005c2013-10-05 23:17:28 +01002576}
2577
2578void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2579 comp->pass = pass;
2580 comp->scope_cur = scope;
2581 comp->next_label = 1;
2582
2583 if (scope->kind != SCOPE_FUNCTION) {
2584 printf("Error: inline assembler must be a function\n");
2585 return;
2586 }
2587
Damiena2f2f7d2013-10-06 00:14:13 +01002588 if (comp->pass > PASS_1) {
2589 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2590 }
2591
Damien826005c2013-10-05 23:17:28 +01002592 // get the function definition parse node
2593 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2594 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2595 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2596
Damiena2f2f7d2013-10-06 00:14:13 +01002597 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002598
Damiena2f2f7d2013-10-06 00:14:13 +01002599 // parameters are in pns->nodes[1]
2600 if (comp->pass == PASS_2) {
2601 py_parse_node_t *pn_params;
2602 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2603 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2604 }
2605
Damien826005c2013-10-05 23:17:28 +01002606 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2607
2608 py_parse_node_t pn_body = pns->nodes[3]; // body
2609 py_parse_node_t *nodes;
2610 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2611
Damien826005c2013-10-05 23:17:28 +01002612 if (comp->pass == PASS_3) {
2613 //printf("----\n");
2614 scope_print_info(scope);
2615 }
2616
2617 for (int i = 0; i < num; i++) {
2618 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2619 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2620 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2621 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2622 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2623 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2624 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2625 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2626 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2627 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2628 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2629 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2630 py_parse_node_t *pn_arg;
2631 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2632
2633 // emit instructions
2634 if (strcmp(qstr_str(op), "label") == 0) {
2635 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2636 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2637 return;
2638 }
2639 int lab = comp_next_label(comp);
2640 if (pass > PASS_1) {
2641 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2642 }
2643 } else {
2644 if (pass > PASS_1) {
2645 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2646 }
2647 }
2648 }
2649
2650 if (comp->pass > PASS_1) {
2651 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002652 }
Damien429d7192013-10-04 19:53:11 +01002653}
2654
2655void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2656 // in functions, turn implicit globals into explicit globals
2657 // compute num_locals, and the index of each local
2658 scope->num_locals = 0;
2659 for (int i = 0; i < scope->id_info_len; i++) {
2660 id_info_t *id = &scope->id_info[i];
2661 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2662 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2663 continue;
2664 }
2665 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2666 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2667 }
2668 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2669 id->local_num = scope->num_locals;
2670 scope->num_locals += 1;
2671 }
2672 }
2673
2674 // compute flags
2675 //scope->flags = 0; since we set some things in parameters
2676 if (scope->kind != SCOPE_MODULE) {
2677 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2678 }
2679 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) {
2680 assert(scope->parent != NULL);
2681 scope->flags |= SCOPE_FLAG_OPTIMISED;
2682
2683 // TODO possibly other ways it can be nested
2684 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2685 scope->flags |= SCOPE_FLAG_NESTED;
2686 }
2687 }
2688 int num_free = 0;
2689 for (int i = 0; i < scope->id_info_len; i++) {
2690 id_info_t *id = &scope->id_info[i];
2691 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2692 num_free += 1;
2693 }
2694 }
2695 if (num_free == 0) {
2696 scope->flags |= SCOPE_FLAG_NOFREE;
2697 }
2698}
2699
2700void py_compile(py_parse_node_t pn) {
2701 compiler_t *comp = m_new(compiler_t, 1);
2702
Damien6cdd3af2013-10-05 18:08:26 +01002703 comp->qstr___class__ = qstr_from_str_static("__class__");
2704 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2705 comp->qstr___name__ = qstr_from_str_static("__name__");
2706 comp->qstr___module__ = qstr_from_str_static("__module__");
2707 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2708 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2709 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2710 comp->qstr_micropython = qstr_from_str_static("micropython");
2711 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002712 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002713 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damien429d7192013-10-04 19:53:11 +01002714
2715 comp->break_label = 0;
2716 comp->continue_label = 0;
2717 comp->except_nest_level = 0;
2718 comp->scope_head = NULL;
2719 comp->scope_cur = NULL;
2720
Damien826005c2013-10-05 23:17:28 +01002721 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002722 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002723
2724 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002725 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002726
Damien826005c2013-10-05 23:17:28 +01002727 // compile pass 1
2728 comp->emit = emit_pass1_new(comp->qstr___class__);
2729 comp->emit_method_table = &emit_pass1_method_table;
2730 comp->emit_inline_asm = NULL;
2731 comp->emit_inline_asm_method_table = NULL;
2732 uint max_num_labels = 0;
Damien429d7192013-10-04 19:53:11 +01002733 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002734 if (false) {
2735#ifdef MICROPY_EMIT_ENABLE_INLINE_THUMB
2736 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01002737 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01002738#endif
Damien826005c2013-10-05 23:17:28 +01002739 } else {
2740 compile_scope(comp, s, PASS_1);
2741 }
2742
2743 // update maximim number of labels needed
2744 if (comp->next_label > max_num_labels) {
2745 max_num_labels = comp->next_label;
2746 }
Damien429d7192013-10-04 19:53:11 +01002747 }
2748
Damien826005c2013-10-05 23:17:28 +01002749 // compute some things related to scope and identifiers
Damien429d7192013-10-04 19:53:11 +01002750 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
2751 compile_scope_compute_things(comp, s);
2752 }
2753
Damien826005c2013-10-05 23:17:28 +01002754 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002755 emit_pass1_free(comp->emit);
2756
Damien826005c2013-10-05 23:17:28 +01002757 // compile pass 2 and 3
Damienc025ebb2013-10-12 14:30:21 +01002758#if !defined(MICROPY_EMIT_ENABLE_CPYTHON)
Damien6cdd3af2013-10-05 18:08:26 +01002759 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01002760 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002761#endif
2762#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
Damien826005c2013-10-05 23:17:28 +01002763 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002764#endif
Damien429d7192013-10-04 19:53:11 +01002765 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002766 if (false) {
2767 // dummy
2768
2769#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
2770 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2771 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01002772 if (emit_inline_thumb == NULL) {
2773 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2774 }
2775 comp->emit = NULL;
2776 comp->emit_method_table = NULL;
2777 comp->emit_inline_asm = emit_inline_thumb;
2778 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2779 compile_scope_inline_asm(comp, s, PASS_2);
2780 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01002781#endif
2782
Damien826005c2013-10-05 23:17:28 +01002783 } else {
Damienc025ebb2013-10-12 14:30:21 +01002784
2785 // choose the emit type
2786
2787#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
2788 comp->emit = emit_cpython_new(max_num_labels);
2789 comp->emit_method_table = &emit_cpython_method_table;
2790#else
Damien826005c2013-10-05 23:17:28 +01002791 switch (s->emit_options) {
2792 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01002793 case EMIT_OPT_VIPER:
Damienc025ebb2013-10-12 14:30:21 +01002794#if defined(MICROPY_EMIT_ENABLE_X64)
Damiendc833822013-10-06 01:01:01 +01002795 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01002796 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01002797 }
Damien13ed3a62013-10-08 09:05:10 +01002798 comp->emit_method_table = &emit_native_x64_method_table;
Damienc025ebb2013-10-12 14:30:21 +01002799#elif defined(MICROPY_EMIT_ENABLE_THUMB)
2800 if (emit_native == NULL) {
2801 emit_native = emit_native_thumb_new(max_num_labels);
2802 }
2803 comp->emit_method_table = &emit_native_thumb_method_table;
2804#endif
2805 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01002806 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01002807 break;
2808
Damien826005c2013-10-05 23:17:28 +01002809 default:
2810 if (emit_bc == NULL) {
2811 emit_bc = emit_bc_new(max_num_labels);
2812 }
2813 comp->emit = emit_bc;
2814 comp->emit_method_table = &emit_bc_method_table;
2815 break;
2816 }
Damienc025ebb2013-10-12 14:30:21 +01002817#endif
2818
2819 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01002820 compile_scope(comp, s, PASS_2);
2821 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01002822 }
Damien429d7192013-10-04 19:53:11 +01002823 }
2824
2825 m_free(comp);
2826}