blob: 83c2cfd6718fbbafd26e4ed3a578c88fe5497e46 [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)) {
Damien0efb3a12013-10-12 16:16:56 +010091#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
92 // can overflow; enabled only to compare with CPython
93 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1);
94#endif
Damien429d7192013-10-04 19:53:11 +010095 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) {
96 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1);
97 } else {
98 // shouldn't happen
99 assert(0);
100 }
101 }
102 break;
103
104 case PN_arith_expr:
Damien0efb3a12013-10-12 16:16:56 +0100105 // overflow checking here relies on SMALL_INT being strictly smaller than machine_int_t
Damien429d7192013-10-04 19:53:11 +0100106 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
Damien0efb3a12013-10-12 16:16:56 +0100107 machine_int_t arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
108 machine_int_t arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
109 machine_int_t res;
Damien429d7192013-10-04 19:53:11 +0100110 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) {
Damien0efb3a12013-10-12 16:16:56 +0100111 res = arg0 + arg1;
Damien429d7192013-10-04 19:53:11 +0100112 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) {
Damien0efb3a12013-10-12 16:16:56 +0100113 res = arg0 - arg1;
Damien429d7192013-10-04 19:53:11 +0100114 } else {
115 // shouldn't happen
116 assert(0);
Damien0efb3a12013-10-12 16:16:56 +0100117 res = 0;
118 }
119 if (PY_FIT_SMALL_INT(res)) {
120 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, res);
Damien429d7192013-10-04 19:53:11 +0100121 }
122 }
123 break;
124
125 case PN_term:
Damien429d7192013-10-04 19:53:11 +0100126 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
127 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
128 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
129 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
Damien0efb3a12013-10-12 16:16:56 +0100130#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
131 // can overflow; enabled only to compare with CPython
Damien429d7192013-10-04 19:53:11 +0100132 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1);
Damien0efb3a12013-10-12 16:16:56 +0100133#endif
Damien429d7192013-10-04 19:53:11 +0100134 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) {
135 ; // pass
Damien0efb3a12013-10-12 16:16:56 +0100136 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PERCENT)) {
137 // XXX implement this properly as Python's % operator acts differently to C's
138 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 % arg1);
139 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_SLASH)) {
140 // XXX implement this properly as Python's // operator acts differently to C's
141 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 / arg1);
Damien429d7192013-10-04 19:53:11 +0100142 } else {
143 // shouldn't happen
144 assert(0);
145 }
146 }
147 break;
148
149 case PN_factor_2:
150 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) {
151 machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
152 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
153 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg);
154 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
155 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, -arg);
156 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
157 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg);
158 } else {
159 // shouldn't happen
160 assert(0);
161 }
162 }
163 break;
164
Damien0efb3a12013-10-12 16:16:56 +0100165#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
Damien429d7192013-10-04 19:53:11 +0100166 case PN_power:
Damien0efb3a12013-10-12 16:16:56 +0100167 // can overflow; enabled only to compare with CPython
Damien429d7192013-10-04 19:53:11 +0100168 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])) {
169 py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2];
170 if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
171 int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
172 if (power >= 0) {
173 int ans = 1;
174 int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
175 for (; power > 0; power--) {
176 ans *= base;
177 }
178 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans);
179 }
180 }
181 }
182 break;
Damien0efb3a12013-10-12 16:16:56 +0100183#endif
Damien429d7192013-10-04 19:53:11 +0100184 }
185 }
186
187 return pn;
188}
189
190void compile_node(compiler_t *comp, py_parse_node_t pn);
191
Damienb05d7072013-10-05 13:37:10 +0100192static int comp_next_label(compiler_t *comp) {
193 return comp->next_label++;
194}
195
Damien6cdd3af2013-10-05 18:08:26 +0100196static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse_node_t pn, uint emit_options) {
197 scope_t *scope = scope_new(kind, pn, rt_get_new_unique_code_id(), emit_options);
Damien429d7192013-10-04 19:53:11 +0100198 scope->parent = comp->scope_cur;
199 scope->next = NULL;
200 if (comp->scope_head == NULL) {
201 comp->scope_head = scope;
202 } else {
203 scope_t *s = comp->scope_head;
204 while (s->next != NULL) {
205 s = s->next;
206 }
207 s->next = scope;
208 }
209 return scope;
210}
211
Damienb05d7072013-10-05 13:37:10 +0100212static int list_len(py_parse_node_t pn, int pn_kind) {
Damien429d7192013-10-04 19:53:11 +0100213 if (PY_PARSE_NODE_IS_NULL(pn)) {
214 return 0;
215 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
216 return 1;
217 } else {
218 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
219 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
220 return 1;
221 } else {
222 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
223 }
224 }
225}
226
Damienb05d7072013-10-05 13:37:10 +0100227static 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 +0100228 if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) {
229 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
230 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
231 for (int i = 0; i < num_nodes; i++) {
232 f(comp, pns->nodes[i]);
233 }
234 } else if (!PY_PARSE_NODE_IS_NULL(pn)) {
235 f(comp, pn);
236 }
237}
238
Damienb05d7072013-10-05 13:37:10 +0100239static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) {
Damien429d7192013-10-04 19:53:11 +0100240 if (PY_PARSE_NODE_IS_NULL(*pn)) {
241 *nodes = NULL;
242 return 0;
243 } else if (PY_PARSE_NODE_IS_LEAF(*pn)) {
244 *nodes = pn;
245 return 1;
246 } else {
247 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn);
248 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
249 *nodes = pn;
250 return 1;
251 } else {
252 *nodes = pns->nodes;
253 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
254 }
255 }
256}
257
258void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) {
259}
260
261void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) {
262 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
263 for (int i = 0; i < num_nodes; i++) {
264 compile_node(comp, pns->nodes[i]);
265 }
266}
267
Damien3a205172013-10-12 15:01:56 +0100268#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
269static bool cpython_c_tuple_is_const(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100270 if (!PY_PARSE_NODE_IS_LEAF(pn)) {
271 return false;
272 }
273 if (PY_PARSE_NODE_IS_ID(pn)) {
274 return false;
275 }
276 return true;
277}
278
Damien3a205172013-10-12 15:01:56 +0100279static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100280 assert(PY_PARSE_NODE_IS_LEAF(pn));
281 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
282 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
283 case PY_PARSE_NODE_ID: assert(0);
284 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_verbatim_int, arg); break;
285 case PY_PARSE_NODE_INTEGER: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
286 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
287 case PY_PARSE_NODE_STRING: EMIT(load_const_verbatim_quoted_str, arg, false); break;
288 case PY_PARSE_NODE_BYTES: EMIT(load_const_verbatim_quoted_str, arg, true); break;
289 case PY_PARSE_NODE_TOKEN:
290 switch (arg) {
291 case PY_TOKEN_KW_FALSE: EMIT(load_const_verbatim_str, "False"); break;
292 case PY_TOKEN_KW_NONE: EMIT(load_const_verbatim_str, "None"); break;
293 case PY_TOKEN_KW_TRUE: EMIT(load_const_verbatim_str, "True"); break;
294 default: assert(0);
295 }
296 break;
297 default: assert(0);
298 }
299}
300
Damien3a205172013-10-12 15:01:56 +0100301static 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 +0100302 int n = 0;
303 if (pns_list != NULL) {
304 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
305 }
306 int total = n;
307 bool is_const = true;
308 if (!PY_PARSE_NODE_IS_NULL(pn)) {
309 total += 1;
Damien3a205172013-10-12 15:01:56 +0100310 if (!cpython_c_tuple_is_const(pn)) {
Damien429d7192013-10-04 19:53:11 +0100311 is_const = false;
312 }
313 }
314 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100315 if (!cpython_c_tuple_is_const(pns_list->nodes[i])) {
Damien429d7192013-10-04 19:53:11 +0100316 is_const = false;
317 break;
318 }
319 }
320 if (total > 0 && is_const) {
321 bool need_comma = false;
322 EMIT(load_const_verbatim_start);
323 EMIT(load_const_verbatim_str, "(");
324 if (!PY_PARSE_NODE_IS_NULL(pn)) {
Damien3a205172013-10-12 15:01:56 +0100325 cpython_c_tuple_emit_const(comp, pn);
Damien429d7192013-10-04 19:53:11 +0100326 need_comma = true;
327 }
328 for (int i = 0; i < n; i++) {
329 if (need_comma) {
330 EMIT(load_const_verbatim_str, ", ");
331 }
Damien3a205172013-10-12 15:01:56 +0100332 cpython_c_tuple_emit_const(comp, pns_list->nodes[i]);
Damien429d7192013-10-04 19:53:11 +0100333 need_comma = true;
334 }
335 if (total == 1) {
336 EMIT(load_const_verbatim_str, ",)");
337 } else {
338 EMIT(load_const_verbatim_str, ")");
339 }
340 EMIT(load_const_verbatim_end);
341 } else {
342 if (!PY_PARSE_NODE_IS_NULL(pn)) {
343 compile_node(comp, pn);
344 }
345 for (int i = 0; i < n; i++) {
346 compile_node(comp, pns_list->nodes[i]);
347 }
348 EMIT(build_tuple, total);
349 }
350}
Damien3a205172013-10-12 15:01:56 +0100351#endif
352
353// funnelling all tuple creations through this function is purely so we can optionally agree with CPython
354void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
355#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
356 cpython_c_tuple(comp, pn, pns_list);
357#else
358 int total = 0;
359 if (!PY_PARSE_NODE_IS_NULL(pn)) {
360 compile_node(comp, pn);
361 total += 1;
362 }
363 if (pns_list != NULL) {
364 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
365 for (int i = 0; i < n; i++) {
366 compile_node(comp, pns_list->nodes[i]);
367 }
368 total += n;
369 }
370 EMIT(build_tuple, total);
371#endif
372}
Damien429d7192013-10-04 19:53:11 +0100373
374void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
375 // a simple tuple expression
Damien429d7192013-10-04 19:53:11 +0100376 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
377}
378
Damien3a205172013-10-12 15:01:56 +0100379static bool node_is_const_false(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100380 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
381 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
382}
383
Damien3a205172013-10-12 15:01:56 +0100384static bool node_is_const_true(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100385 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);
386}
387
Damien3a205172013-10-12 15:01:56 +0100388#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
389// the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
390static 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 +0100391 if (node_is_const_false(pn)) {
392 if (jump_if == false) {
393 EMIT(jump, label);
394 }
395 return;
396 } else if (node_is_const_true(pn)) {
397 if (jump_if == true) {
398 EMIT(jump, label);
399 }
400 return;
401 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
402 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
403 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
404 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
405 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100406 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100407 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100408 cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
Damien429d7192013-10-04 19:53:11 +0100409 }
Damien3a205172013-10-12 15:01:56 +0100410 cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100411 EMIT(label_assign, label2);
412 } else {
413 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100414 cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100415 }
416 }
417 return;
418 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
419 if (jump_if == false) {
420 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100421 cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100422 }
423 } else {
Damienb05d7072013-10-05 13:37:10 +0100424 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100425 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100426 cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
Damien429d7192013-10-04 19:53:11 +0100427 }
Damien3a205172013-10-12 15:01:56 +0100428 cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100429 EMIT(label_assign, label2);
430 }
431 return;
432 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
Damien3a205172013-10-12 15:01:56 +0100433 cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true);
Damien429d7192013-10-04 19:53:11 +0100434 return;
435 }
436 }
437
438 // nothing special, fall back to default compiling for node and jump
439 compile_node(comp, pn);
440 if (jump_if == false) {
441 EMIT(pop_jump_if_false, label);
442 } else {
443 EMIT(pop_jump_if_true, label);
444 }
445}
Damien3a205172013-10-12 15:01:56 +0100446#endif
Damien429d7192013-10-04 19:53:11 +0100447
Damien3a205172013-10-12 15:01:56 +0100448static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
449#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
450 cpython_c_if_cond(comp, pn, jump_if, label, false);
451#else
452 if (node_is_const_false(pn)) {
453 if (jump_if == false) {
454 EMIT(jump, label);
455 }
456 return;
457 } else if (node_is_const_true(pn)) {
458 if (jump_if == true) {
459 EMIT(jump, label);
460 }
461 return;
462 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
463 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
464 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
465 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
466 if (jump_if == false) {
467 int label2 = comp_next_label(comp);
468 for (int i = 0; i < n - 1; i++) {
469 c_if_cond(comp, pns->nodes[i], true, label2);
470 }
471 c_if_cond(comp, pns->nodes[n - 1], false, label);
472 EMIT(label_assign, label2);
473 } else {
474 for (int i = 0; i < n; i++) {
475 c_if_cond(comp, pns->nodes[i], true, label);
476 }
477 }
478 return;
479 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
480 if (jump_if == false) {
481 for (int i = 0; i < n; i++) {
482 c_if_cond(comp, pns->nodes[i], false, label);
483 }
484 } else {
485 int label2 = comp_next_label(comp);
486 for (int i = 0; i < n - 1; i++) {
487 c_if_cond(comp, pns->nodes[i], false, label2);
488 }
489 c_if_cond(comp, pns->nodes[n - 1], true, label);
490 EMIT(label_assign, label2);
491 }
492 return;
493 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
494 c_if_cond(comp, pns->nodes[0], !jump_if, label);
495 return;
496 }
497 }
498
499 // nothing special, fall back to default compiling for node and jump
500 compile_node(comp, pn);
501 if (jump_if == false) {
502 EMIT(pop_jump_if_false, label);
503 } else {
504 EMIT(pop_jump_if_true, label);
505 }
506#endif
Damien429d7192013-10-04 19:53:11 +0100507}
508
509typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
510void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
511
512void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
513 if (assign_kind != ASSIGN_AUG_STORE) {
514 compile_node(comp, pns->nodes[0]);
515 }
516
517 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
518 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
519 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
520 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
521 if (assign_kind != ASSIGN_AUG_STORE) {
522 for (int i = 0; i < n - 1; i++) {
523 compile_node(comp, pns1->nodes[i]);
524 }
525 }
526 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
527 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
528 }
529 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
530 printf("SyntaxError: can't assign to function call\n");
531 return;
532 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
533 if (assign_kind == ASSIGN_AUG_STORE) {
534 EMIT(rot_three);
535 EMIT(store_subscr);
536 } else {
537 compile_node(comp, pns1->nodes[0]);
538 if (assign_kind == ASSIGN_AUG_LOAD) {
539 EMIT(dup_top_two);
540 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
541 } else {
542 EMIT(store_subscr);
543 }
544 }
545 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
546 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
547 if (assign_kind == ASSIGN_AUG_LOAD) {
548 EMIT(dup_top);
549 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
550 } else {
551 if (assign_kind == ASSIGN_AUG_STORE) {
552 EMIT(rot_two);
553 }
554 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
555 }
556 } else {
557 // shouldn't happen
558 assert(0);
559 }
560 } else {
561 // shouldn't happen
562 assert(0);
563 }
564
565 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
566 // SyntaxError, cannot assign
567 assert(0);
568 }
569}
570
571void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
572 assert(n >= 0);
573 int have_star_index = -1;
574 for (int i = 0; i < n; i++) {
575 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
576 if (have_star_index < 0) {
577 EMIT(unpack_ex, i, n - i - 1);
578 have_star_index = i;
579 } else {
580 printf("SyntaxError: two starred expressions in assignment\n");
581 return;
582 }
583 }
584 }
585 if (have_star_index < 0) {
586 EMIT(unpack_sequence, n);
587 }
588 for (int i = 0; i < n; i++) {
589 if (i == have_star_index) {
590 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
591 } else {
592 c_assign(comp, nodes[i], ASSIGN_STORE);
593 }
594 }
595}
596
597// assigns top of stack to pn
598void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
599 tail_recursion:
600 if (PY_PARSE_NODE_IS_NULL(pn)) {
601 assert(0);
602 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
603 if (PY_PARSE_NODE_IS_ID(pn)) {
604 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
605 switch (assign_kind) {
606 case ASSIGN_STORE:
607 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100608 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100609 break;
610 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100611 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100612 break;
613 }
614 } else {
615 printf("SyntaxError: can't assign to literal\n");
616 return;
617 }
618 } else {
619 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
620 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
621 case PN_power:
622 // lhs is an index or attribute
623 c_assign_power(comp, pns, assign_kind);
624 break;
625
626 case PN_testlist_star_expr:
627 case PN_exprlist:
628 // lhs is a tuple
629 if (assign_kind != ASSIGN_STORE) {
630 goto bad_aug;
631 }
632 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
633 break;
634
635 case PN_atom_paren:
636 // lhs is something in parenthesis
637 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
638 // empty tuple
639 printf("SyntaxError: can't assign to ()\n");
640 return;
641 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
642 pns = (py_parse_node_struct_t*)pns->nodes[0];
643 goto testlist_comp;
644 } else {
645 // parenthesis around 1 item, is just that item
646 pn = pns->nodes[0];
647 goto tail_recursion;
648 }
649 break;
650
651 case PN_atom_bracket:
652 // lhs is something in brackets
653 if (assign_kind != ASSIGN_STORE) {
654 goto bad_aug;
655 }
656 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
657 // empty list, assignment allowed
658 c_assign_tuple(comp, 0, NULL);
659 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
660 pns = (py_parse_node_struct_t*)pns->nodes[0];
661 goto testlist_comp;
662 } else {
663 // brackets around 1 item
664 c_assign_tuple(comp, 1, &pns->nodes[0]);
665 }
666 break;
667
668 default:
669 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
670 assert(0);
671 }
672 return;
673
674 testlist_comp:
675 // lhs is a sequence
676 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
677 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
678 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
679 // sequence of one item, with trailing comma
680 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
681 c_assign_tuple(comp, 1, &pns->nodes[0]);
682 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
683 // sequence of many items
684 // TODO call c_assign_tuple instead
685 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
686 EMIT(unpack_sequence, 1 + n);
687 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
688 for (int i = 0; i < n; i++) {
689 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
690 }
691 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
692 // TODO not implemented
693 assert(0);
694 } else {
695 // sequence with 2 items
696 goto sequence_with_2_items;
697 }
698 } else {
699 // sequence with 2 items
700 sequence_with_2_items:
701 c_assign_tuple(comp, 2, pns->nodes);
702 }
703 return;
704 }
705 return;
706
707 bad_aug:
708 printf("SyntaxError: illegal expression for augmented assignment\n");
709}
710
711// stuff for lambda and comprehensions and generators
712void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
713 // make closed over variables, if any
714 int nfree = 0;
715 if (comp->scope_cur->kind != SCOPE_MODULE) {
716 for (int i = 0; i < this_scope->id_info_len; i++) {
717 id_info_t *id_info = &this_scope->id_info[i];
718 if (id_info->kind == ID_INFO_KIND_FREE) {
719 EMIT(load_closure, id_info->qstr);
720 nfree += 1;
721 }
722 }
723 }
724 if (nfree > 0) {
725 EMIT(build_tuple, nfree);
726 }
727
728 // make the function/closure
729 if (nfree == 0) {
730 EMIT(make_function, this_scope, n_dict_params, n_default_params);
731 } else {
732 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
733 }
734}
735
736void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100737 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
738 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100739 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
740 // this parameter has a default value
741 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
742 if (comp->have_bare_star) {
743 comp->param_pass_num_dict_params += 1;
744 if (comp->param_pass == 1) {
745 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
746 compile_node(comp, pns->nodes[2]);
747 }
748 } else {
749 comp->param_pass_num_default_params += 1;
750 if (comp->param_pass == 2) {
751 compile_node(comp, pns->nodes[2]);
752 }
753 }
754 }
Damienb14de212013-10-06 00:28:28 +0100755 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
756 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100757 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
758 // bare star
759 comp->have_bare_star = true;
760 }
761 }
762}
763
764// leaves function object on stack
765// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100766qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100767 if (comp->pass == PASS_1) {
768 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100769 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100770 // store the function scope so the compiling function can use it at each pass
771 pns->nodes[4] = (py_parse_node_t)s;
772 }
773
774 // save variables (probably don't need to do this, since we can't have nested definitions..?)
775 bool old_have_bare_star = comp->have_bare_star;
776 int old_param_pass = comp->param_pass;
777 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
778 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
779
780 // compile default parameters
781 comp->have_bare_star = false;
782 comp->param_pass = 1; // pass 1 does any default parameters after bare star
783 comp->param_pass_num_dict_params = 0;
784 comp->param_pass_num_default_params = 0;
785 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
786 comp->have_bare_star = false;
787 comp->param_pass = 2; // pass 2 does any default parameters before bare star
788 comp->param_pass_num_dict_params = 0;
789 comp->param_pass_num_default_params = 0;
790 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
791
792 // get the scope for this function
793 scope_t *fscope = (scope_t*)pns->nodes[4];
794
795 // make the function
796 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
797
798 // restore variables
799 comp->have_bare_star = old_have_bare_star;
800 comp->param_pass = old_param_pass;
801 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
802 comp->param_pass_num_default_params = old_param_pass_num_default_params;
803
804 // return its name (the 'f' in "def f(...):")
805 return fscope->simple_name;
806}
807
808// leaves class object on stack
809// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100810qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100811 if (comp->pass == PASS_1) {
812 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100813 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100814 // store the class scope so the compiling function can use it at each pass
815 pns->nodes[3] = (py_parse_node_t)s;
816 }
817
818 EMIT(load_build_class);
819
820 // scope for this class
821 scope_t *cscope = (scope_t*)pns->nodes[3];
822
823 // compile the class
824 close_over_variables_etc(comp, cscope, 0, 0);
825
826 // get its name
827 EMIT(load_const_id, cscope->simple_name);
828
829 // nodes[1] has parent classes, if any
830 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
831 // no parent classes
832 EMIT(call_function, 2, 0, false, false);
833 } else {
834 // have a parent class or classes
835 // TODO what if we have, eg, *a or **a in the parent list?
836 compile_node(comp, pns->nodes[1]);
837 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
838 }
839
840 // return its name (the 'C' in class C(...):")
841 return cscope->simple_name;
842}
843
Damien6cdd3af2013-10-05 18:08:26 +0100844// returns true if it was a built-in decorator (even if the built-in had an error)
845static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
846 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
847 return false;
848 }
849
850 if (name_len != 2) {
851 printf("SyntaxError: invalid micropython decorator\n");
852 return true;
853 }
854
855 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
856 if (attr == comp->qstr_native) {
857 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100858 } else if (attr == comp->qstr_viper) {
859 *emit_options = EMIT_OPT_VIPER;
Damienc025ebb2013-10-12 14:30:21 +0100860#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
Damien5bfb7592013-10-05 18:41:24 +0100861 } else if (attr == comp->qstr_asm_thumb) {
862 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100863#endif
Damien6cdd3af2013-10-05 18:08:26 +0100864 } else {
865 printf("SyntaxError: invalid micropython decorator\n");
866 }
867
868 return true;
869}
870
Damien429d7192013-10-04 19:53:11 +0100871void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
872 // get the list of decorators
873 py_parse_node_t *nodes;
874 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
875
Damien6cdd3af2013-10-05 18:08:26 +0100876 // inherit emit options for this function/class definition
877 uint emit_options = comp->scope_cur->emit_options;
878
879 // compile each decorator
880 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100881 for (int i = 0; i < n; i++) {
882 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
883 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100884
885 // nodes[0] contains the decorator function, which is a dotted name
886 py_parse_node_t *name_nodes;
887 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
888
889 // check for built-in decorators
890 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
891 // this was a built-in
892 num_built_in_decorators += 1;
893
894 } else {
895 // not a built-in, compile normally
896
897 // compile the decorator function
898 compile_node(comp, name_nodes[0]);
899 for (int i = 1; i < name_len; i++) {
900 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
901 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
902 }
903
904 // nodes[1] contains arguments to the decorator function, if any
905 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
906 // call the decorator function with the arguments in nodes[1]
907 compile_node(comp, pns_decorator->nodes[1]);
908 }
Damien429d7192013-10-04 19:53:11 +0100909 }
910 }
911
912 // compile the body (funcdef or classdef) and get its name
913 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
914 qstr body_name = 0;
915 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100916 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100917 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100918 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100919 } else {
920 // shouldn't happen
921 assert(0);
922 }
923
924 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100925 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100926 EMIT(call_function, 1, 0, false, false);
927 }
928
929 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100930 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100931}
932
933void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100934 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100935 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100936 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100937}
938
939void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
940 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100941 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100942 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
943 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
944
945 compile_node(comp, pns->nodes[0]); // base of the power node
946
947 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
948 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
949 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
950 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
951 for (int i = 0; i < n - 1; i++) {
952 compile_node(comp, pns1->nodes[i]);
953 }
954 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
955 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
956 }
957 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
958 // SyntaxError: can't delete a function call
959 assert(0);
960 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
961 compile_node(comp, pns1->nodes[0]);
962 EMIT(delete_subscr);
963 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
964 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
965 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
966 } else {
967 // shouldn't happen
968 assert(0);
969 }
970 } else {
971 // shouldn't happen
972 assert(0);
973 }
974
975 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
976 // SyntaxError, cannot delete
977 assert(0);
978 }
979 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
980 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
981 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
982 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
983 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
984
985 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
986 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
987 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
988 // sequence of one item, with trailing comma
989 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
990 c_del_stmt(comp, pns->nodes[0]);
991 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
992 // sequence of many items
993 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
994 c_del_stmt(comp, pns->nodes[0]);
995 for (int i = 0; i < n; i++) {
996 c_del_stmt(comp, pns1->nodes[i]);
997 }
998 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
999 // TODO not implemented; can't del comprehension?
1000 assert(0);
1001 } else {
1002 // sequence with 2 items
1003 goto sequence_with_2_items;
1004 }
1005 } else {
1006 // sequence with 2 items
1007 sequence_with_2_items:
1008 c_del_stmt(comp, pns->nodes[0]);
1009 c_del_stmt(comp, pns->nodes[1]);
1010 }
1011 } else {
1012 // tuple with 1 element
1013 c_del_stmt(comp, pn);
1014 }
1015 } else {
1016 // not implemented
1017 assert(0);
1018 }
1019}
1020
1021void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1022 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
1023}
1024
1025void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1026 if (comp->break_label == 0) {
1027 printf("ERROR: cannot break from here\n");
1028 }
1029 EMIT(break_loop, comp->break_label);
1030}
1031
1032void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1033 if (comp->continue_label == 0) {
1034 printf("ERROR: cannot continue from here\n");
1035 }
1036 if (comp->except_nest_level > 0) {
1037 EMIT(continue_loop, comp->continue_label);
1038 } else {
1039 EMIT(jump, comp->continue_label);
1040 }
1041}
1042
1043void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1044 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1045 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1046 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
1047 // special case when returning an if-expression; to match CPython optimisation
1048 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
1049 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
1050
Damienb05d7072013-10-05 13:37:10 +01001051 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001052 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1053 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
1054 EMIT(return_value);
1055 EMIT(label_assign, l_fail);
1056 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1057 } else {
1058 compile_node(comp, pns->nodes[0]);
1059 }
1060 EMIT(return_value);
1061}
1062
1063void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1064 compile_node(comp, pns->nodes[0]);
1065 EMIT(pop_top);
1066}
1067
1068void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1069 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1070 // raise
1071 EMIT(raise_varargs, 0);
1072 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1073 // raise x from y
1074 pns = (py_parse_node_struct_t*)pns->nodes[0];
1075 compile_node(comp, pns->nodes[0]);
1076 compile_node(comp, pns->nodes[1]);
1077 EMIT(raise_varargs, 2);
1078 } else {
1079 // raise x
1080 compile_node(comp, pns->nodes[0]);
1081 EMIT(raise_varargs, 1);
1082 }
1083}
1084
1085// q1 holds the base, q2 the full name
1086// eg a -> q1=q2=a
1087// a.b.c -> q1=a, q2=a.b.c
1088void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1089 bool is_as = false;
1090 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1091 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1092 // a name of the form x as y; unwrap it
1093 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1094 pn = pns->nodes[0];
1095 is_as = true;
1096 }
1097 if (PY_PARSE_NODE_IS_ID(pn)) {
1098 // just a simple name
1099 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1100 if (!is_as) {
1101 *q1 = *q2;
1102 }
1103 EMIT(import_name, *q2);
1104 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1105 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1106 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1107 // a name of the form a.b.c
1108 if (!is_as) {
1109 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1110 }
1111 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1112 int len = n - 1;
1113 for (int i = 0; i < n; i++) {
1114 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1115 }
1116 char *str = m_new(char, len + 1);
1117 str[0] = 0;
1118 for (int i = 0; i < n; i++) {
1119 if (i > 0) {
1120 strcat(str, ".");
1121 }
1122 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1123 }
1124 *q2 = qstr_from_str_take(str);
1125 EMIT(import_name, *q2);
1126 if (is_as) {
1127 for (int i = 1; i < n; i++) {
1128 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1129 }
1130 }
1131 } else {
1132 // TODO not implemented
1133 assert(0);
1134 }
1135 } else {
1136 // TODO not implemented
1137 assert(0);
1138 }
1139}
1140
1141void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1142 EMIT(load_const_small_int, 0); // ??
1143 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1144 qstr q1, q2;
1145 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001146 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001147}
1148
1149void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1150 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1151}
1152
1153void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1154 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
1155 EMIT(load_const_small_int, 0); // what's this for??
1156 EMIT(load_const_verbatim_start);
1157 EMIT(load_const_verbatim_str, "('*',)");
1158 EMIT(load_const_verbatim_end);
1159 qstr dummy_q, id1;
1160 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1161 EMIT(import_star);
1162 } else {
1163 py_parse_node_t *pn_nodes;
1164 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1165
1166 EMIT(load_const_small_int, 0); // what's this for??
1167 EMIT(load_const_verbatim_start);
1168 EMIT(load_const_verbatim_str, "(");
1169 for (int i = 0; i < n; i++) {
1170 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1171 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1172 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1173 if (i > 0) {
1174 EMIT(load_const_verbatim_str, ", ");
1175 }
1176 EMIT(load_const_verbatim_str, "'");
1177 EMIT(load_const_verbatim_str, qstr_str(id2));
1178 EMIT(load_const_verbatim_str, "'");
1179 }
1180 if (n == 1) {
1181 EMIT(load_const_verbatim_str, ",");
1182 }
1183 EMIT(load_const_verbatim_str, ")");
1184 EMIT(load_const_verbatim_end);
1185 qstr dummy_q, id1;
1186 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1187 for (int i = 0; i < n; i++) {
1188 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1189 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1190 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1191 EMIT(import_from, id2);
1192 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001193 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001194 } else {
Damien4b03e772013-10-05 14:17:09 +01001195 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001196 }
1197 }
1198 EMIT(pop_top);
1199 }
1200}
1201
1202void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001203 if (comp->pass == PASS_1) {
1204 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1205 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1206 } else {
1207 pns = (py_parse_node_struct_t*)pns->nodes[0];
1208 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1209 for (int i = 0; i < num_nodes; i++) {
1210 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1211 }
Damien429d7192013-10-04 19:53:11 +01001212 }
1213 }
1214}
1215
1216void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001217 if (comp->pass == PASS_1) {
1218 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1219 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1220 } else {
1221 pns = (py_parse_node_struct_t*)pns->nodes[0];
1222 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1223 for (int i = 0; i < num_nodes; i++) {
1224 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1225 }
Damien429d7192013-10-04 19:53:11 +01001226 }
1227 }
1228}
1229
1230void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001231 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001232 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001233 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001234 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1235 // assertion message
1236 compile_node(comp, pns->nodes[1]);
1237 EMIT(call_function, 1, 0, false, false);
1238 }
1239 EMIT(raise_varargs, 1);
1240 EMIT(label_assign, l_end);
1241}
1242
1243void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1244 // TODO proper and/or short circuiting
1245
Damienb05d7072013-10-05 13:37:10 +01001246 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001247
Damienb05d7072013-10-05 13:37:10 +01001248 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001249 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1250
1251 compile_node(comp, pns->nodes[1]); // if block
1252 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1253 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001254 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001255 EMIT(jump, l_end);
1256 }
1257 //}
1258 EMIT(label_assign, l_fail);
1259
1260 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1261 // compile elif blocks
1262
1263 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1264
1265 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1266 // multiple elif blocks
1267
1268 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1269 for (int i = 0; i < n; i++) {
1270 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001271 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001272 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1273
1274 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001275 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001276 EMIT(jump, l_end);
1277 }
1278 EMIT(label_assign, l_fail);
1279 }
1280
1281 } else {
1282 // a single elif block
1283
Damienb05d7072013-10-05 13:37:10 +01001284 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001285 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1286
1287 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001288 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001289 EMIT(jump, l_end);
1290 }
1291 EMIT(label_assign, l_fail);
1292 }
1293 }
1294
1295 // compile else block
1296 compile_node(comp, pns->nodes[3]); // can be null
1297
1298 EMIT(label_assign, l_end);
1299}
1300
1301void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1302 int old_break_label = comp->break_label;
1303 int old_continue_label = comp->continue_label;
1304
Damienb05d7072013-10-05 13:37:10 +01001305 int done_label = comp_next_label(comp);
1306 int end_label = comp_next_label(comp);
1307 int break_label = comp_next_label(comp);
1308 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001309
1310 comp->break_label = break_label;
1311 comp->continue_label = continue_label;
1312
1313 EMIT(setup_loop, end_label);
1314 EMIT(label_assign, continue_label);
1315 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1316 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001317 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001318 EMIT(jump, continue_label);
1319 }
1320 EMIT(label_assign, done_label);
1321
1322 // break/continue apply to outer loop (if any) in the else block
1323 comp->break_label = old_break_label;
1324 comp->continue_label = old_continue_label;
1325
1326 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1327 // this is a small hack to agree with CPython
1328 if (!node_is_const_true(pns->nodes[0])) {
1329 EMIT(pop_block);
1330 }
1331
1332 compile_node(comp, pns->nodes[2]); // else
1333
1334 EMIT(label_assign, break_label);
1335 EMIT(label_assign, end_label);
1336}
1337
1338void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1339 int old_break_label = comp->break_label;
1340 int old_continue_label = comp->continue_label;
1341
Damienb05d7072013-10-05 13:37:10 +01001342 int for_label = comp_next_label(comp);
1343 int pop_label = comp_next_label(comp);
1344 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001345
Damienb05d7072013-10-05 13:37:10 +01001346 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001347
1348 comp->continue_label = for_label;
1349 comp->break_label = break_label;
1350
1351 EMIT(setup_loop, end_label);
1352 compile_node(comp, pns->nodes[1]); // iterator
1353 EMIT(get_iter);
1354 EMIT(label_assign, for_label);
1355 EMIT(for_iter, pop_label);
1356 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1357 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001358 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001359 EMIT(jump, for_label);
1360 }
1361 EMIT(label_assign, pop_label);
1362 EMIT(for_iter_end);
1363
1364 // break/continue apply to outer loop (if any) in the else block
1365 comp->break_label = old_break_label;
1366 comp->continue_label = old_continue_label;
1367
1368 EMIT(pop_block);
1369
1370 compile_node(comp, pns->nodes[3]); // else (not tested)
1371
1372 EMIT(label_assign, break_label);
1373 EMIT(label_assign, end_label);
1374}
1375
1376void 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) {
1377 // this function is a bit of a hack at the moment
1378 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1379
1380 // setup code
1381 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001382 int l1 = comp_next_label(comp);
1383 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001384 comp->except_nest_level += 1; // for correct handling of continue
1385 EMIT(setup_except, l1);
1386 compile_node(comp, pn_body); // body
1387 EMIT(pop_block);
1388 EMIT(jump, success_label);
1389 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001390 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001391
1392 for (int i = 0; i < n_except; i++) {
1393 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1394 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1395
1396 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001397 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001398
1399 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1400 // this is a catch all exception handler
1401 if (i + 1 != n_except) {
1402 printf("SyntaxError: default 'except:' must be last\n");
1403 return;
1404 }
1405 } else {
1406 // this exception handler requires a match to a certain type of exception
1407 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1408 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1409 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1410 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1411 // handler binds the exception to a local
1412 pns_exception_expr = pns3->nodes[0];
1413 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1414 }
1415 }
1416 EMIT(dup_top);
1417 compile_node(comp, pns_exception_expr);
1418 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1419 EMIT(pop_jump_if_false, end_finally_label);
1420 }
1421
1422 EMIT(pop_top);
1423
1424 if (qstr_exception_local == 0) {
1425 EMIT(pop_top);
1426 } else {
Damien4b03e772013-10-05 14:17:09 +01001427 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001428 }
1429
1430 EMIT(pop_top);
1431
1432 int l3;
1433 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001434 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001435 EMIT(setup_finally, l3);
1436 }
1437 compile_node(comp, pns_except->nodes[1]);
1438 if (qstr_exception_local != 0) {
1439 EMIT(pop_block);
1440 }
1441 EMIT(pop_except);
1442 if (qstr_exception_local != 0) {
1443 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1444 EMIT(label_assign, l3);
1445 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001446 EMIT(store_id, qstr_exception_local);
1447 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001448 EMIT(end_finally);
1449 }
1450 EMIT(jump, l2);
1451 EMIT(label_assign, end_finally_label);
1452 }
1453
1454 EMIT(end_finally);
1455 EMIT(label_assign, success_label);
1456 comp->except_nest_level -= 1;
1457 compile_node(comp, pn_else); // else block, can be null
1458 EMIT(label_assign, l2);
1459 EMIT(set_stack_size, stack_size);
1460}
1461
1462void 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) {
1463 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1464 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001465 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001466 EMIT(setup_finally, l_finally_block);
1467 if (n_except == 0) {
1468 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1469 compile_node(comp, pn_body);
1470 } else {
1471 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1472 }
1473 EMIT(pop_block);
1474 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1475 EMIT(label_assign, l_finally_block);
1476 compile_node(comp, pn_finally);
1477 EMIT(end_finally);
1478 EMIT(set_stack_size, stack_size);
1479}
1480
1481void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1482 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1483 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1484 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1485 // just try-finally
1486 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1487 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1488 // try-except and possibly else and/or finally
1489 py_parse_node_t *pn_excepts;
1490 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1491 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1492 // no finally
1493 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1494 } else {
1495 // have finally
1496 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1497 }
1498 } else {
1499 // just try-except
1500 py_parse_node_t *pn_excepts;
1501 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1502 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1503 }
1504 } else {
1505 // shouldn't happen
1506 assert(0);
1507 }
1508}
1509
1510void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1511 if (n == 0) {
1512 // no more pre-bits, compile the body of the with
1513 compile_node(comp, body);
1514 } else {
Damienb05d7072013-10-05 13:37:10 +01001515 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001516 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1517 // this pre-bit is of the form "a as b"
1518 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1519 compile_node(comp, pns->nodes[0]);
1520 EMIT(setup_with, l_end);
1521 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1522 } else {
1523 // this pre-bit is just an expression
1524 compile_node(comp, nodes[0]);
1525 EMIT(setup_with, l_end);
1526 EMIT(pop_top);
1527 }
1528 // compile additional pre-bits and the body
1529 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1530 // finish this with block
1531 EMIT(pop_block);
1532 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1533 EMIT(label_assign, l_end);
1534 EMIT(with_cleanup);
1535 EMIT(end_finally);
1536 }
1537}
1538
1539void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1540 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1541 py_parse_node_t *nodes;
1542 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1543 assert(n > 0);
1544
1545 // compile in a nested fashion
1546 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1547}
1548
1549void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1550 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1551 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1552 // do nothing with a lonely constant
1553 } else {
1554 compile_node(comp, pns->nodes[0]); // just an expression
1555 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1556 }
1557 } else {
1558 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1559 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1560 if (kind == PN_expr_stmt_augassign) {
1561 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1562 compile_node(comp, pns1->nodes[1]); // rhs
1563 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1564 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1565 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1566 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1567 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1568 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1569 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1570 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1571 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1572 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1573 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1574 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1575 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1576 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1577 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1578 default: assert(0); // shouldn't happen
1579 }
1580 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1581 } else if (kind == PN_expr_stmt_assign_list) {
1582 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1583 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1584 // following CPython, we store left-most first
1585 if (rhs > 0) {
1586 EMIT(dup_top);
1587 }
1588 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1589 for (int i = 0; i < rhs; i++) {
1590 if (i + 1 < rhs) {
1591 EMIT(dup_top);
1592 }
1593 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1594 }
1595 } else if (kind == PN_expr_stmt_assign) {
1596 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1597 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1598 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1599 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1600 // optimisation for a, b = c, d; to match CPython's optimisation
1601 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1602 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1603 compile_node(comp, pns10->nodes[0]); // rhs
1604 compile_node(comp, pns10->nodes[1]); // rhs
1605 EMIT(rot_two);
1606 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1607 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1608 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1609 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1610 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1611 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1612 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1613 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1614 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1615 compile_node(comp, pns10->nodes[0]); // rhs
1616 compile_node(comp, pns10->nodes[1]); // rhs
1617 compile_node(comp, pns10->nodes[2]); // rhs
1618 EMIT(rot_three);
1619 EMIT(rot_two);
1620 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1621 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1622 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1623 } else {
1624 compile_node(comp, pns1->nodes[0]); // rhs
1625 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1626 }
1627 } else {
1628 // shouldn't happen
1629 assert(0);
1630 }
1631 }
1632}
1633
1634void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1635 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1636 compile_node(comp, pns->nodes[0]);
1637 for (int i = 1; i < num_nodes; i += 1) {
1638 compile_node(comp, pns->nodes[i]);
1639 EMIT(binary_op, binary_op);
1640 }
1641}
1642
1643void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1644 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1645 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1646
1647 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001648 int l_fail = comp_next_label(comp);
1649 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001650 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1651 compile_node(comp, pns->nodes[0]); // success value
1652 EMIT(jump, l_end);
1653 EMIT(label_assign, l_fail);
1654 EMIT(set_stack_size, stack_size); // force stack size reset
1655 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1656 EMIT(label_assign, l_end);
1657}
1658
1659void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1660 // TODO default params etc for lambda; possibly just use funcdef code
1661 //py_parse_node_t pn_params = pns->nodes[0];
1662 //py_parse_node_t pn_body = pns->nodes[1];
1663
1664 if (comp->pass == PASS_1) {
1665 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001666 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 +01001667 // store the lambda scope so the compiling function (this one) can use it at each pass
1668 pns->nodes[2] = (py_parse_node_t)s;
1669 }
1670
1671 // get the scope for this lambda
1672 scope_t *this_scope = (scope_t*)pns->nodes[2];
1673
1674 // make the lambda
1675 close_over_variables_etc(comp, this_scope, 0, 0);
1676}
1677
1678void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001679 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001680 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1681 for (int i = 0; i < n; i += 1) {
1682 compile_node(comp, pns->nodes[i]);
1683 if (i + 1 < n) {
1684 EMIT(jump_if_true_or_pop, l_end);
1685 }
1686 }
1687 EMIT(label_assign, l_end);
1688}
1689
1690void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001691 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001692 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1693 for (int i = 0; i < n; i += 1) {
1694 compile_node(comp, pns->nodes[i]);
1695 if (i + 1 < n) {
1696 EMIT(jump_if_false_or_pop, l_end);
1697 }
1698 }
1699 EMIT(label_assign, l_end);
1700}
1701
1702void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1703 compile_node(comp, pns->nodes[0]);
1704 EMIT(unary_op, RT_UNARY_OP_NOT);
1705}
1706
1707void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1708 int stack_size = EMIT(get_stack_size);
1709 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1710 compile_node(comp, pns->nodes[0]);
1711 bool multi = (num_nodes > 3);
1712 int l_fail = 0;
1713 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001714 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001715 }
1716 for (int i = 1; i + 1 < num_nodes; i += 2) {
1717 compile_node(comp, pns->nodes[i + 1]);
1718 if (i + 2 < num_nodes) {
1719 EMIT(dup_top);
1720 EMIT(rot_three);
1721 }
1722 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1723 EMIT(compare_op, RT_COMPARE_OP_LESS);
1724 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1725 EMIT(compare_op, RT_COMPARE_OP_MORE);
1726 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1727 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1728 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1729 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1730 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1731 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1732 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1733 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1734 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1735 EMIT(compare_op, RT_COMPARE_OP_IN);
1736 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1737 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1738 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1739 if (kind == PN_comp_op_not_in) {
1740 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1741 } else if (kind == PN_comp_op_is) {
1742 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1743 EMIT(compare_op, RT_COMPARE_OP_IS);
1744 } else {
1745 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1746 }
1747 } else {
1748 // shouldn't happen
1749 assert(0);
1750 }
1751 } else {
1752 // shouldn't happen
1753 assert(0);
1754 }
1755 if (i + 2 < num_nodes) {
1756 EMIT(jump_if_false_or_pop, l_fail);
1757 }
1758 }
1759 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001760 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001761 EMIT(jump, l_end);
1762 EMIT(label_assign, l_fail);
1763 EMIT(rot_two);
1764 EMIT(pop_top);
1765 EMIT(label_assign, l_end);
1766 EMIT(set_stack_size, stack_size + 1); // force stack size
1767 }
1768}
1769
1770void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1771 // TODO
1772 assert(0);
1773 compile_node(comp, pns->nodes[0]);
1774 //EMIT(unary_op, "UNARY_STAR");
1775}
1776
1777void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1778 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1779}
1780
1781void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1782 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1783}
1784
1785void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1786 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1787}
1788
1789void compile_shift_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_DBL_LESS)) {
1795 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1796 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1797 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1798 } else {
1799 // shouldn't happen
1800 assert(0);
1801 }
1802 }
1803}
1804
1805void compile_arith_expr(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_PLUS)) {
1811 EMIT(binary_op, RT_BINARY_OP_ADD);
1812 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1813 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1814 } else {
1815 // shouldn't happen
1816 assert(0);
1817 }
1818 }
1819}
1820
1821void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1822 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1823 compile_node(comp, pns->nodes[0]);
1824 for (int i = 1; i + 1 < num_nodes; i += 2) {
1825 compile_node(comp, pns->nodes[i + 1]);
1826 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1827 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1828 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1829 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1830 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1831 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1832 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1833 EMIT(binary_op, RT_BINARY_OP_MODULO);
1834 } else {
1835 // shouldn't happen
1836 assert(0);
1837 }
1838 }
1839}
1840
1841void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1842 compile_node(comp, pns->nodes[1]);
1843 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1844 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1845 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1846 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1847 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1848 EMIT(unary_op, RT_UNARY_OP_INVERT);
1849 } else {
1850 // shouldn't happen
1851 assert(0);
1852 }
1853}
1854
1855void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
1856 // function to call is on top of stack
1857
1858 int old_n_arg_keyword = comp->n_arg_keyword;
1859 bool old_have_star_arg = comp->have_star_arg;
1860 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
1861 comp->n_arg_keyword = 0;
1862 comp->have_star_arg = false;
1863 comp->have_dbl_star_arg = false;
1864
1865 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
1866
1867 // compute number of positional arguments
1868 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
1869 if (comp->have_star_arg) {
1870 n_positional -= 1;
1871 }
1872 if (comp->have_dbl_star_arg) {
1873 n_positional -= 1;
1874 }
1875
1876 if (is_method_call) {
1877 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1878 } else {
1879 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1880 }
1881
1882 comp->n_arg_keyword = old_n_arg_keyword;
1883 comp->have_star_arg = old_have_star_arg;
1884 comp->have_dbl_star_arg = old_have_dbl_star_arg;
1885}
1886
1887void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
1888 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1889 for (int i = 0; i < num_nodes; i++) {
1890 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)) {
1891 // optimisation for method calls a.f(...), following PyPy
1892 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
1893 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
1894 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
1895 compile_trailer_paren_helper(comp, pns_paren, true);
1896 i += 1;
1897 } else {
1898 compile_node(comp, pns->nodes[i]);
1899 }
1900 }
1901}
1902
1903void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
1904 compile_node(comp, pns->nodes[0]);
1905 EMIT(binary_op, RT_BINARY_OP_POWER);
1906}
1907
1908void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
1909 // a list of strings
1910 EMIT(load_const_verbatim_start);
1911 EMIT(load_const_verbatim_str, "'");
1912 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1913 for (int i = 0; i < n; i++) {
1914 // TODO allow concatenation of either strings or bytes, but not mixed
1915 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
1916 assert(PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]) == PY_PARSE_NODE_STRING);
1917 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1918 EMIT(load_const_verbatim_strn, str, strlen(str));
1919 }
1920 EMIT(load_const_verbatim_str, "'");
1921 EMIT(load_const_verbatim_end);
1922}
1923
1924// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
1925void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
1926 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
1927 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
1928 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
1929
1930 if (comp->pass == PASS_1) {
1931 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01001932 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 +01001933 // store the comprehension scope so the compiling function (this one) can use it at each pass
1934 pns_comp_for->nodes[3] = (py_parse_node_t)s;
1935 }
1936
1937 // get the scope for this comprehension
1938 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
1939
1940 // compile the comprehension
1941 close_over_variables_etc(comp, this_scope, 0, 0);
1942
1943 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
1944 EMIT(get_iter);
1945 EMIT(call_function, 1, 0, false, false);
1946}
1947
1948void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
1949 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1950 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01001951 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
1952 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1953 pns = (py_parse_node_struct_t*)pns->nodes[0];
1954 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
1955 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1956 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1957 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
1958 // tuple of one item, with trailing comma
1959 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01001960 c_tuple(comp, pns->nodes[0], NULL);
1961 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
1962 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01001963 c_tuple(comp, pns->nodes[0], pns2);
1964 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
1965 // generator expression
1966 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
1967 } else {
1968 // tuple with 2 items
1969 goto tuple_with_2_items;
1970 }
1971 } else {
1972 // tuple with 2 items
1973 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01001974 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
1975 }
1976 } else {
1977 // parenthesis around a single item, is just that item
1978 compile_node(comp, pns->nodes[0]);
1979 }
1980}
1981
1982void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
1983 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1984 // empty list
1985 EMIT(build_list, 0);
1986 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1987 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
1988 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
1989 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
1990 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
1991 // list of one item, with trailing comma
1992 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
1993 compile_node(comp, pns2->nodes[0]);
1994 EMIT(build_list, 1);
1995 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
1996 // list of many items
1997 compile_node(comp, pns2->nodes[0]);
1998 compile_generic_all_nodes(comp, pns3);
1999 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2000 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2001 // list comprehension
2002 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2003 } else {
2004 // list with 2 items
2005 goto list_with_2_items;
2006 }
2007 } else {
2008 // list with 2 items
2009 list_with_2_items:
2010 compile_node(comp, pns2->nodes[0]);
2011 compile_node(comp, pns2->nodes[1]);
2012 EMIT(build_list, 2);
2013 }
2014 } else {
2015 // list with 1 item
2016 compile_node(comp, pns->nodes[0]);
2017 EMIT(build_list, 1);
2018 }
2019}
2020
2021void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2022 py_parse_node_t pn = pns->nodes[0];
2023 if (PY_PARSE_NODE_IS_NULL(pn)) {
2024 // empty dict
2025 EMIT(build_map, 0);
2026 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2027 pns = (py_parse_node_struct_t*)pn;
2028 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2029 // dict with one element
2030 EMIT(build_map, 1);
2031 compile_node(comp, pn);
2032 EMIT(store_map);
2033 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2034 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2035 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2036 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2037 // dict/set with multiple elements
2038
2039 // get tail elements (2nd, 3rd, ...)
2040 py_parse_node_t *nodes;
2041 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2042
2043 // first element sets whether it's a dict or set
2044 bool is_dict;
2045 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2046 // a dictionary
2047 EMIT(build_map, 1 + n);
2048 compile_node(comp, pns->nodes[0]);
2049 EMIT(store_map);
2050 is_dict = true;
2051 } else {
2052 // a set
2053 compile_node(comp, pns->nodes[0]); // 1st value of set
2054 is_dict = false;
2055 }
2056
2057 // process rest of elements
2058 for (int i = 0; i < n; i++) {
2059 py_parse_node_t pn = nodes[i];
2060 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2061 compile_node(comp, pn);
2062 if (is_dict) {
2063 if (!is_key_value) {
2064 printf("SyntaxError?: expecting key:value for dictionary");
2065 return;
2066 }
2067 EMIT(store_map);
2068 } else {
2069 if (is_key_value) {
2070 printf("SyntaxError?: expecting just a value for set");
2071 return;
2072 }
2073 }
2074 }
2075
2076 // if it's a set, build it
2077 if (!is_dict) {
2078 EMIT(build_set, 1 + n);
2079 }
2080 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2081 // dict/set comprehension
2082 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2083 // a dictionary comprehension
2084 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2085 } else {
2086 // a set comprehension
2087 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2088 }
2089 } else {
2090 // shouldn't happen
2091 assert(0);
2092 }
2093 } else {
2094 // set with one element
2095 goto set_with_one_element;
2096 }
2097 } else {
2098 // set with one element
2099 set_with_one_element:
2100 compile_node(comp, pn);
2101 EMIT(build_set, 1);
2102 }
2103}
2104
2105void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2106 compile_trailer_paren_helper(comp, pns, false);
2107}
2108
2109void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2110 // object who's index we want is on top of stack
2111 compile_node(comp, pns->nodes[0]); // the index
2112 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2113}
2114
2115void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2116 // object who's attribute we want is on top of stack
2117 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2118}
2119
2120void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2121 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2122 py_parse_node_t pn = pns->nodes[0];
2123 if (PY_PARSE_NODE_IS_NULL(pn)) {
2124 // [?:]
2125 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2126 EMIT(build_slice, 2);
2127 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2128 pns = (py_parse_node_struct_t*)pn;
2129 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2130 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2131 pn = pns->nodes[0];
2132 if (PY_PARSE_NODE_IS_NULL(pn)) {
2133 // [?::]
2134 EMIT(build_slice, 2);
2135 } else {
2136 // [?::x]
2137 compile_node(comp, pn);
2138 EMIT(build_slice, 3);
2139 }
2140 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2141 compile_node(comp, pns->nodes[0]);
2142 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2143 pns = (py_parse_node_struct_t*)pns->nodes[1];
2144 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2145 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2146 // [?:x:]
2147 EMIT(build_slice, 2);
2148 } else {
2149 // [?:x:x]
2150 compile_node(comp, pns->nodes[0]);
2151 EMIT(build_slice, 3);
2152 }
2153 } else {
2154 // [?:x]
2155 compile_node(comp, pn);
2156 EMIT(build_slice, 2);
2157 }
2158 } else {
2159 // [?:x]
2160 compile_node(comp, pn);
2161 EMIT(build_slice, 2);
2162 }
2163}
2164
2165void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2166 compile_node(comp, pns->nodes[0]); // start of slice
2167 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2168 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2169}
2170
2171void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2172 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2173 compile_subscript_3_helper(comp, pns);
2174}
2175
2176void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2177 // if this is called then we are compiling a dict key:value pair
2178 compile_node(comp, pns->nodes[1]); // value
2179 compile_node(comp, pns->nodes[0]); // key
2180}
2181
2182void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002183 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002184 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002185 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002186}
2187
2188void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2189 if (comp->have_star_arg) {
2190 printf("SyntaxError?: can't have multiple *x\n");
2191 return;
2192 }
2193 comp->have_star_arg = true;
2194 compile_node(comp, pns->nodes[0]);
2195}
2196
2197void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2198 if (comp->have_dbl_star_arg) {
2199 printf("SyntaxError?: can't have multiple **x\n");
2200 return;
2201 }
2202 comp->have_dbl_star_arg = true;
2203 compile_node(comp, pns->nodes[0]);
2204}
2205
2206void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2207 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2208 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2209 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2210 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2211 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2212 return;
2213 }
2214 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2215 compile_node(comp, pns2->nodes[0]);
2216 comp->n_arg_keyword += 1;
2217 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2218 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2219 } else {
2220 // shouldn't happen
2221 assert(0);
2222 }
2223}
2224
2225void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2226 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2227 printf("SyntaxError: 'yield' outside function\n");
2228 return;
2229 }
2230 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2231 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2232 EMIT(yield_value);
2233 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2234 pns = (py_parse_node_struct_t*)pns->nodes[0];
2235 compile_node(comp, pns->nodes[0]);
2236 EMIT(get_iter);
2237 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2238 EMIT(yield_from);
2239 } else {
2240 compile_node(comp, pns->nodes[0]);
2241 EMIT(yield_value);
2242 }
2243}
2244
2245typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2246static compile_function_t compile_function[] = {
2247 NULL,
2248#define nc NULL
2249#define c(f) compile_##f
2250#define DEF_RULE(rule, comp, kind, arg...) comp,
2251#include "grammar.h"
2252#undef nc
2253#undef c
2254#undef DEF_RULE
2255};
2256
2257void compile_node(compiler_t *comp, py_parse_node_t pn) {
2258 if (PY_PARSE_NODE_IS_NULL(pn)) {
2259 // pass
2260 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2261 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2262 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002263 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002264 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2265 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2266 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2267 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2268 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002269 case PY_PARSE_NODE_TOKEN:
2270 if (arg == PY_TOKEN_NEWLINE) {
2271 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
2272 // do nothing
2273 } else {
2274 EMIT(load_const_tok, arg);
2275 }
2276 break;
Damien429d7192013-10-04 19:53:11 +01002277 default: assert(0);
2278 }
2279 } else {
2280 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2281 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2282 if (f == NULL) {
2283 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
2284 parse_node_show(pn, 0);
2285 assert(0);
2286 } else {
2287 f(comp, pns);
2288 }
2289 }
2290}
2291
2292void 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) {
2293 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002294 qstr param_name = 0;
2295 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002296 if (PY_PARSE_NODE_IS_ID(pn)) {
2297 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002298 if (comp->have_bare_star) {
2299 // comes after a bare star, so doesn't count as a parameter
2300 } else {
2301 comp->scope_cur->num_params += 1;
2302 }
Damienb14de212013-10-06 00:28:28 +01002303 } else {
2304 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2305 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2306 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002307 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002308 //int node_index = 1; unused
2309 if (allow_annotations) {
2310 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2311 // this parameter has an annotation
2312 pn_annotation = pns->nodes[1];
2313 }
2314 //node_index = 2; unused
2315 }
2316 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2317 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2318 // this parameter has a default value
2319 if (comp->have_bare_star) {
2320 comp->scope_cur->num_dict_params += 1;
2321 } else {
2322 comp->scope_cur->num_default_params += 1;
2323 }
2324 }
2325 */
2326 if (comp->have_bare_star) {
2327 // comes after a bare star, so doesn't count as a parameter
2328 } else {
2329 comp->scope_cur->num_params += 1;
2330 }
2331 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2332 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2333 // bare star
2334 // TODO see http://www.python.org/dev/peps/pep-3102/
2335 comp->have_bare_star = true;
2336 //assert(comp->scope_cur->num_dict_params == 0);
2337 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2338 // named star
2339 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2340 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2341 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2342 // named star with annotation
2343 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2344 pns = (py_parse_node_struct_t*)pns->nodes[0];
2345 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2346 pn_annotation = pns->nodes[1];
2347 } else {
2348 // shouldn't happen
2349 assert(0);
2350 }
2351 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002352 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002353 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2354 // this parameter has an annotation
2355 pn_annotation = pns->nodes[1];
2356 }
2357 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002358 } else {
Damienb14de212013-10-06 00:28:28 +01002359 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002360 assert(0);
2361 }
Damien429d7192013-10-04 19:53:11 +01002362 }
2363
2364 if (param_name != 0) {
2365 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2366 // TODO this parameter has an annotation
2367 }
2368 bool added;
2369 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2370 if (!added) {
2371 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2372 return;
2373 }
2374 id_info->param = true;
2375 id_info->kind = ID_INFO_KIND_LOCAL;
2376 }
2377}
2378
2379void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2380 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2381}
2382
2383void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2384 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2385}
2386
2387void 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) {
2388 tail_recursion:
2389 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2390 // no more nested if/for; compile inner expression
2391 compile_node(comp, pn_inner_expr);
2392 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2393 EMIT(list_append, for_depth + 2);
2394 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2395 EMIT(map_add, for_depth + 2);
2396 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2397 EMIT(set_add, for_depth + 2);
2398 } else {
2399 EMIT(yield_value);
2400 EMIT(pop_top);
2401 }
2402 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2403 // if condition
2404 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2405 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2406 pn_iter = pns_comp_if->nodes[1];
2407 goto tail_recursion;
2408 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2409 // for loop
2410 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2411 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002412 int l_end2 = comp_next_label(comp);
2413 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002414 EMIT(get_iter);
2415 EMIT(label_assign, l_top2);
2416 EMIT(for_iter, l_end2);
2417 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2418 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2419 EMIT(jump, l_top2);
2420 EMIT(label_assign, l_end2);
2421 EMIT(for_iter_end);
2422 } else {
2423 // shouldn't happen
2424 assert(0);
2425 }
2426}
2427
2428void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2429 // see http://www.python.org/dev/peps/pep-0257/
2430
2431 // look for the first statement
2432 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2433 // fall through
2434 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2435 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2436 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2437 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2438 } else {
2439 return;
2440 }
2441
2442 // check the first statement for a doc string
2443 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2444 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2445 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2446 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2447 if (kind == PY_PARSE_NODE_STRING) {
2448 compile_node(comp, pns->nodes[0]); // a doc string
2449 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002450 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002451 }
2452 }
2453 }
2454}
2455
2456void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2457 comp->pass = pass;
2458 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002459 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002460 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002461
2462 if (comp->pass == PASS_1) {
2463 scope->stack_size = 0;
2464 }
2465
2466 if (comp->pass == PASS_3) {
2467 //printf("----\n");
2468 scope_print_info(scope);
2469 }
2470
2471 // compile
2472 if (scope->kind == SCOPE_MODULE) {
2473 check_for_doc_string(comp, scope->pn);
2474 compile_node(comp, scope->pn);
2475 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2476 EMIT(return_value);
2477 } else if (scope->kind == SCOPE_FUNCTION) {
2478 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2479 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2480 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2481
2482 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002483 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002484 if (comp->pass == PASS_1) {
2485 comp->have_bare_star = false;
2486 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2487 }
2488
Damien826005c2013-10-05 23:17:28 +01002489 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002490
2491 compile_node(comp, pns->nodes[3]); // 3 is function body
2492 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002493 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002494 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2495 EMIT(return_value);
2496 }
2497 } else if (scope->kind == SCOPE_LAMBDA) {
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) == 3);
2501
2502 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002503 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002504 if (comp->pass == PASS_1) {
2505 comp->have_bare_star = false;
2506 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2507 }
2508
2509 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2510 EMIT(return_value);
2511 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2512 // a bit of a hack at the moment
2513
2514 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2515 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2516 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2517 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2518 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2519
Damien6cdd3af2013-10-05 18:08:26 +01002520 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002521 if (comp->pass == PASS_1) {
2522 bool added;
2523 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2524 assert(added);
2525 id_info->kind = ID_INFO_KIND_LOCAL;
2526 scope->num_params = 1;
2527 }
2528
2529 if (scope->kind == SCOPE_LIST_COMP) {
2530 EMIT(build_list, 0);
2531 } else if (scope->kind == SCOPE_DICT_COMP) {
2532 EMIT(build_map, 0);
2533 } else if (scope->kind == SCOPE_SET_COMP) {
2534 EMIT(build_set, 0);
2535 }
2536
Damienb05d7072013-10-05 13:37:10 +01002537 int l_end = comp_next_label(comp);
2538 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002539 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002540 EMIT(label_assign, l_top);
2541 EMIT(for_iter, l_end);
2542 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2543 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2544 EMIT(jump, l_top);
2545 EMIT(label_assign, l_end);
2546 EMIT(for_iter_end);
2547
2548 if (scope->kind == SCOPE_GEN_EXPR) {
2549 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2550 }
2551 EMIT(return_value);
2552 } else {
2553 assert(scope->kind == SCOPE_CLASS);
2554 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2555 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2556 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2557
2558 if (comp->pass == PASS_1) {
2559 bool added;
2560 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2561 assert(added);
2562 id_info->kind = ID_INFO_KIND_LOCAL;
2563 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2564 assert(added);
2565 id_info->kind = ID_INFO_KIND_LOCAL;
2566 id_info->param = true;
2567 scope->num_params = 1; // __locals__ is the parameter
2568 }
2569
Damien4b03e772013-10-05 14:17:09 +01002570 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002571 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002572 EMIT(load_id, comp->qstr___name__);
2573 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002574 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002575 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002576
2577 check_for_doc_string(comp, pns->nodes[2]);
2578 compile_node(comp, pns->nodes[2]); // 2 is class body
2579
2580 id_info_t *id = scope_find(scope, comp->qstr___class__);
2581 assert(id != NULL);
2582 if (id->kind == ID_INFO_KIND_LOCAL) {
2583 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2584 } else {
2585 EMIT(load_closure, comp->qstr___class__);
2586 }
2587 EMIT(return_value);
2588 }
2589
Damien415eb6f2013-10-05 12:19:06 +01002590 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002591
Damien826005c2013-10-05 23:17:28 +01002592}
2593
2594void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2595 comp->pass = pass;
2596 comp->scope_cur = scope;
2597 comp->next_label = 1;
2598
2599 if (scope->kind != SCOPE_FUNCTION) {
2600 printf("Error: inline assembler must be a function\n");
2601 return;
2602 }
2603
Damiena2f2f7d2013-10-06 00:14:13 +01002604 if (comp->pass > PASS_1) {
2605 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2606 }
2607
Damien826005c2013-10-05 23:17:28 +01002608 // get the function definition parse node
2609 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2610 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2611 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2612
Damiena2f2f7d2013-10-06 00:14:13 +01002613 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002614
Damiena2f2f7d2013-10-06 00:14:13 +01002615 // parameters are in pns->nodes[1]
2616 if (comp->pass == PASS_2) {
2617 py_parse_node_t *pn_params;
2618 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2619 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2620 }
2621
Damien826005c2013-10-05 23:17:28 +01002622 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2623
2624 py_parse_node_t pn_body = pns->nodes[3]; // body
2625 py_parse_node_t *nodes;
2626 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2627
Damien826005c2013-10-05 23:17:28 +01002628 if (comp->pass == PASS_3) {
2629 //printf("----\n");
2630 scope_print_info(scope);
2631 }
2632
2633 for (int i = 0; i < num; i++) {
2634 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2635 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2636 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2637 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2638 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2639 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2640 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2641 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2642 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2643 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2644 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2645 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2646 py_parse_node_t *pn_arg;
2647 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2648
2649 // emit instructions
2650 if (strcmp(qstr_str(op), "label") == 0) {
2651 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2652 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2653 return;
2654 }
2655 int lab = comp_next_label(comp);
2656 if (pass > PASS_1) {
2657 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2658 }
2659 } else {
2660 if (pass > PASS_1) {
2661 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2662 }
2663 }
2664 }
2665
2666 if (comp->pass > PASS_1) {
2667 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002668 }
Damien429d7192013-10-04 19:53:11 +01002669}
2670
2671void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2672 // in functions, turn implicit globals into explicit globals
2673 // compute num_locals, and the index of each local
2674 scope->num_locals = 0;
2675 for (int i = 0; i < scope->id_info_len; i++) {
2676 id_info_t *id = &scope->id_info[i];
2677 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2678 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2679 continue;
2680 }
2681 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2682 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2683 }
2684 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2685 id->local_num = scope->num_locals;
2686 scope->num_locals += 1;
2687 }
2688 }
2689
2690 // compute flags
2691 //scope->flags = 0; since we set some things in parameters
2692 if (scope->kind != SCOPE_MODULE) {
2693 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2694 }
2695 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) {
2696 assert(scope->parent != NULL);
2697 scope->flags |= SCOPE_FLAG_OPTIMISED;
2698
2699 // TODO possibly other ways it can be nested
2700 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2701 scope->flags |= SCOPE_FLAG_NESTED;
2702 }
2703 }
2704 int num_free = 0;
2705 for (int i = 0; i < scope->id_info_len; i++) {
2706 id_info_t *id = &scope->id_info[i];
2707 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2708 num_free += 1;
2709 }
2710 }
2711 if (num_free == 0) {
2712 scope->flags |= SCOPE_FLAG_NOFREE;
2713 }
2714}
2715
2716void py_compile(py_parse_node_t pn) {
2717 compiler_t *comp = m_new(compiler_t, 1);
2718
Damien6cdd3af2013-10-05 18:08:26 +01002719 comp->qstr___class__ = qstr_from_str_static("__class__");
2720 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2721 comp->qstr___name__ = qstr_from_str_static("__name__");
2722 comp->qstr___module__ = qstr_from_str_static("__module__");
2723 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2724 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2725 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2726 comp->qstr_micropython = qstr_from_str_static("micropython");
2727 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002728 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002729 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damien429d7192013-10-04 19:53:11 +01002730
2731 comp->break_label = 0;
2732 comp->continue_label = 0;
2733 comp->except_nest_level = 0;
2734 comp->scope_head = NULL;
2735 comp->scope_cur = NULL;
2736
Damien826005c2013-10-05 23:17:28 +01002737 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002738 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002739
2740 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002741 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002742
Damien826005c2013-10-05 23:17:28 +01002743 // compile pass 1
2744 comp->emit = emit_pass1_new(comp->qstr___class__);
2745 comp->emit_method_table = &emit_pass1_method_table;
2746 comp->emit_inline_asm = NULL;
2747 comp->emit_inline_asm_method_table = NULL;
2748 uint max_num_labels = 0;
Damien429d7192013-10-04 19:53:11 +01002749 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002750 if (false) {
2751#ifdef MICROPY_EMIT_ENABLE_INLINE_THUMB
2752 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01002753 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01002754#endif
Damien826005c2013-10-05 23:17:28 +01002755 } else {
2756 compile_scope(comp, s, PASS_1);
2757 }
2758
2759 // update maximim number of labels needed
2760 if (comp->next_label > max_num_labels) {
2761 max_num_labels = comp->next_label;
2762 }
Damien429d7192013-10-04 19:53:11 +01002763 }
2764
Damien826005c2013-10-05 23:17:28 +01002765 // compute some things related to scope and identifiers
Damien429d7192013-10-04 19:53:11 +01002766 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
2767 compile_scope_compute_things(comp, s);
2768 }
2769
Damien826005c2013-10-05 23:17:28 +01002770 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002771 emit_pass1_free(comp->emit);
2772
Damien826005c2013-10-05 23:17:28 +01002773 // compile pass 2 and 3
Damienc025ebb2013-10-12 14:30:21 +01002774#if !defined(MICROPY_EMIT_ENABLE_CPYTHON)
Damien6cdd3af2013-10-05 18:08:26 +01002775 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01002776 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002777#endif
2778#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
Damien826005c2013-10-05 23:17:28 +01002779 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002780#endif
Damien429d7192013-10-04 19:53:11 +01002781 for (scope_t *s = comp->scope_head; s != NULL; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002782 if (false) {
2783 // dummy
2784
2785#if defined(MICROPY_EMIT_ENABLE_INLINE_THUMB)
2786 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2787 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01002788 if (emit_inline_thumb == NULL) {
2789 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2790 }
2791 comp->emit = NULL;
2792 comp->emit_method_table = NULL;
2793 comp->emit_inline_asm = emit_inline_thumb;
2794 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2795 compile_scope_inline_asm(comp, s, PASS_2);
2796 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01002797#endif
2798
Damien826005c2013-10-05 23:17:28 +01002799 } else {
Damienc025ebb2013-10-12 14:30:21 +01002800
2801 // choose the emit type
2802
2803#if defined(MICROPY_EMIT_ENABLE_CPYTHON)
2804 comp->emit = emit_cpython_new(max_num_labels);
2805 comp->emit_method_table = &emit_cpython_method_table;
2806#else
Damien826005c2013-10-05 23:17:28 +01002807 switch (s->emit_options) {
2808 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01002809 case EMIT_OPT_VIPER:
Damienc025ebb2013-10-12 14:30:21 +01002810#if defined(MICROPY_EMIT_ENABLE_X64)
Damiendc833822013-10-06 01:01:01 +01002811 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01002812 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01002813 }
Damien13ed3a62013-10-08 09:05:10 +01002814 comp->emit_method_table = &emit_native_x64_method_table;
Damienc025ebb2013-10-12 14:30:21 +01002815#elif defined(MICROPY_EMIT_ENABLE_THUMB)
2816 if (emit_native == NULL) {
2817 emit_native = emit_native_thumb_new(max_num_labels);
2818 }
2819 comp->emit_method_table = &emit_native_thumb_method_table;
2820#endif
2821 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01002822 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01002823 break;
2824
Damien826005c2013-10-05 23:17:28 +01002825 default:
2826 if (emit_bc == NULL) {
2827 emit_bc = emit_bc_new(max_num_labels);
2828 }
2829 comp->emit = emit_bc;
2830 comp->emit_method_table = &emit_bc_method_table;
2831 break;
2832 }
Damienc025ebb2013-10-12 14:30:21 +01002833#endif
2834
2835 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01002836 compile_scope(comp, s, PASS_2);
2837 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01002838 }
Damien429d7192013-10-04 19:53:11 +01002839 }
2840
2841 m_free(comp);
2842}