blob: 5fbf623b29e2c4aede8e23bdbd9f9623e3b9d20e [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
Damience89a212013-10-15 22:25:17 +010019#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_THUMB)
20
Damien429d7192013-10-04 19:53:11 +010021typedef enum {
22 PN_none = 0,
23#define DEF_RULE(rule, comp, kind, arg...) PN_##rule,
24#include "grammar.h"
25#undef DEF_RULE
26 PN_maximum_number_of,
27} pn_kind_t;
28
Damien415eb6f2013-10-05 12:19:06 +010029#define EMIT(fun, arg...) (comp->emit_method_table->fun(comp->emit, ##arg))
Damien826005c2013-10-05 23:17:28 +010030#define EMIT_INLINE_ASM(fun, arg...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, ##arg))
Damien429d7192013-10-04 19:53:11 +010031
Damien6cdd3af2013-10-05 18:08:26 +010032#define EMIT_OPT_NONE (0)
33#define EMIT_OPT_BYTE_CODE (1)
34#define EMIT_OPT_NATIVE_PYTHON (2)
Damien7af3d192013-10-07 00:02:49 +010035#define EMIT_OPT_VIPER (3)
36#define EMIT_OPT_ASM_THUMB (4)
Damien6cdd3af2013-10-05 18:08:26 +010037
Damien429d7192013-10-04 19:53:11 +010038typedef struct _compiler_t {
39 qstr qstr___class__;
40 qstr qstr___locals__;
41 qstr qstr___name__;
42 qstr qstr___module__;
43 qstr qstr___qualname__;
44 qstr qstr___doc__;
45 qstr qstr_assertion_error;
Damien6cdd3af2013-10-05 18:08:26 +010046 qstr qstr_micropython;
Damien5ac1b2e2013-10-18 19:58:12 +010047 qstr qstr_byte_code;
Damien6cdd3af2013-10-05 18:08:26 +010048 qstr qstr_native;
Damien7af3d192013-10-07 00:02:49 +010049 qstr qstr_viper;
Damien5bfb7592013-10-05 18:41:24 +010050 qstr qstr_asm_thumb;
Damiend7933892013-11-28 19:12:18 +000051 qstr qstr_range;
Damien429d7192013-10-04 19:53:11 +010052
Damien5ac1b2e2013-10-18 19:58:12 +010053 bool is_repl;
Damien429d7192013-10-04 19:53:11 +010054 pass_kind_t pass;
Damien5ac1b2e2013-10-18 19:58:12 +010055 bool had_error; // try to keep compiler clean from nlr
Damien429d7192013-10-04 19:53:11 +010056
Damienb05d7072013-10-05 13:37:10 +010057 int next_label;
Damienb05d7072013-10-05 13:37:10 +010058
Damien429d7192013-10-04 19:53:11 +010059 int break_label;
60 int continue_label;
61 int except_nest_level;
62
63 int n_arg_keyword;
64 bool have_star_arg;
65 bool have_dbl_star_arg;
66 bool have_bare_star;
67 int param_pass;
68 int param_pass_num_dict_params;
69 int param_pass_num_default_params;
70
71 scope_t *scope_head;
72 scope_t *scope_cur;
73
Damien6cdd3af2013-10-05 18:08:26 +010074 emit_t *emit; // current emitter
75 const emit_method_table_t *emit_method_table; // current emit method table
Damien826005c2013-10-05 23:17:28 +010076
77 emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
78 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 +010079} compiler_t;
80
81py_parse_node_t fold_constants(py_parse_node_t pn) {
82 if (PY_PARSE_NODE_IS_STRUCT(pn)) {
83 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
84 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
85
86 // fold arguments first
87 for (int i = 0; i < n; i++) {
88 pns->nodes[i] = fold_constants(pns->nodes[i]);
89 }
90
91 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
92 case PN_shift_expr:
93 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
94 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
95 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
96 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_LESS)) {
Damien3ef4abb2013-10-12 16:53:13 +010097#if MICROPY_EMIT_CPYTHON
Damien0efb3a12013-10-12 16:16:56 +010098 // can overflow; enabled only to compare with CPython
99 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1);
100#endif
Damien429d7192013-10-04 19:53:11 +0100101 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) {
102 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1);
103 } else {
104 // shouldn't happen
105 assert(0);
106 }
107 }
108 break;
109
110 case PN_arith_expr:
Damien0efb3a12013-10-12 16:16:56 +0100111 // overflow checking here relies on SMALL_INT being strictly smaller than machine_int_t
Damien429d7192013-10-04 19:53:11 +0100112 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 +0100113 machine_int_t arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
114 machine_int_t arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
115 machine_int_t res;
Damien429d7192013-10-04 19:53:11 +0100116 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) {
Damien0efb3a12013-10-12 16:16:56 +0100117 res = arg0 + arg1;
Damien429d7192013-10-04 19:53:11 +0100118 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) {
Damien0efb3a12013-10-12 16:16:56 +0100119 res = arg0 - arg1;
Damien429d7192013-10-04 19:53:11 +0100120 } else {
121 // shouldn't happen
122 assert(0);
Damien0efb3a12013-10-12 16:16:56 +0100123 res = 0;
124 }
125 if (PY_FIT_SMALL_INT(res)) {
126 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, res);
Damien429d7192013-10-04 19:53:11 +0100127 }
128 }
129 break;
130
131 case PN_term:
Damien429d7192013-10-04 19:53:11 +0100132 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
133 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
134 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
135 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
Damien3ef4abb2013-10-12 16:53:13 +0100136#if MICROPY_EMIT_CPYTHON
Damien0efb3a12013-10-12 16:16:56 +0100137 // can overflow; enabled only to compare with CPython
Damien429d7192013-10-04 19:53:11 +0100138 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1);
Damien0efb3a12013-10-12 16:16:56 +0100139#endif
Damien429d7192013-10-04 19:53:11 +0100140 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) {
141 ; // pass
Damien0efb3a12013-10-12 16:16:56 +0100142 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PERCENT)) {
143 // XXX implement this properly as Python's % operator acts differently to C's
144 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 % arg1);
145 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_SLASH)) {
146 // XXX implement this properly as Python's // operator acts differently to C's
147 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 / arg1);
Damien429d7192013-10-04 19:53:11 +0100148 } else {
149 // shouldn't happen
150 assert(0);
151 }
152 }
153 break;
154
155 case PN_factor_2:
156 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) {
157 machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
158 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
159 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg);
160 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
161 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, -arg);
162 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
163 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg);
164 } else {
165 // shouldn't happen
166 assert(0);
167 }
168 }
169 break;
170
Damien3ef4abb2013-10-12 16:53:13 +0100171#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +0100172 case PN_power:
Damien0efb3a12013-10-12 16:16:56 +0100173 // can overflow; enabled only to compare with CPython
Damien429d7192013-10-04 19:53:11 +0100174 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])) {
175 py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2];
176 if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
177 int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
178 if (power >= 0) {
179 int ans = 1;
180 int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
181 for (; power > 0; power--) {
182 ans *= base;
183 }
184 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans);
185 }
186 }
187 }
188 break;
Damien0efb3a12013-10-12 16:16:56 +0100189#endif
Damien429d7192013-10-04 19:53:11 +0100190 }
191 }
192
193 return pn;
194}
195
196void compile_node(compiler_t *comp, py_parse_node_t pn);
197
Damienb05d7072013-10-05 13:37:10 +0100198static int comp_next_label(compiler_t *comp) {
199 return comp->next_label++;
200}
201
Damien6cdd3af2013-10-05 18:08:26 +0100202static scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, py_parse_node_t pn, uint emit_options) {
Damien5ac1b2e2013-10-18 19:58:12 +0100203 scope_t *scope = scope_new(kind, pn, rt_get_unique_code_id(kind == SCOPE_MODULE), emit_options);
Damien429d7192013-10-04 19:53:11 +0100204 scope->parent = comp->scope_cur;
205 scope->next = NULL;
206 if (comp->scope_head == NULL) {
207 comp->scope_head = scope;
208 } else {
209 scope_t *s = comp->scope_head;
210 while (s->next != NULL) {
211 s = s->next;
212 }
213 s->next = scope;
214 }
215 return scope;
216}
217
Damienb05d7072013-10-05 13:37:10 +0100218static int list_len(py_parse_node_t pn, int pn_kind) {
Damien429d7192013-10-04 19:53:11 +0100219 if (PY_PARSE_NODE_IS_NULL(pn)) {
220 return 0;
221 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
222 return 1;
223 } else {
224 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
225 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
226 return 1;
227 } else {
228 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
229 }
230 }
231}
232
Damienb05d7072013-10-05 13:37:10 +0100233static 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 +0100234 if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) {
235 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
236 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
237 for (int i = 0; i < num_nodes; i++) {
238 f(comp, pns->nodes[i]);
239 }
240 } else if (!PY_PARSE_NODE_IS_NULL(pn)) {
241 f(comp, pn);
242 }
243}
244
Damienb05d7072013-10-05 13:37:10 +0100245static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) {
Damien429d7192013-10-04 19:53:11 +0100246 if (PY_PARSE_NODE_IS_NULL(*pn)) {
247 *nodes = NULL;
248 return 0;
249 } else if (PY_PARSE_NODE_IS_LEAF(*pn)) {
250 *nodes = pn;
251 return 1;
252 } else {
253 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn);
254 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
255 *nodes = pn;
256 return 1;
257 } else {
258 *nodes = pns->nodes;
259 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
260 }
261 }
262}
263
264void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) {
265}
266
267void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) {
268 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
269 for (int i = 0; i < num_nodes; i++) {
270 compile_node(comp, pns->nodes[i]);
271 }
272}
273
Damien3ef4abb2013-10-12 16:53:13 +0100274#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100275static bool cpython_c_tuple_is_const(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100276 if (!PY_PARSE_NODE_IS_LEAF(pn)) {
277 return false;
278 }
279 if (PY_PARSE_NODE_IS_ID(pn)) {
280 return false;
281 }
282 return true;
283}
284
Damien02f89412013-12-12 15:13:36 +0000285static void cpython_c_print_quoted_str(vstr_t *vstr, qstr qstr, bool bytes) {
286 const char *str = qstr_str(qstr);
287 int len = strlen(str);
288 bool has_single_quote = false;
289 bool has_double_quote = false;
290 for (int i = 0; i < len; i++) {
291 if (str[i] == '\'') {
292 has_single_quote = true;
293 } else if (str[i] == '"') {
294 has_double_quote = true;
295 }
296 }
297 if (bytes) {
298 vstr_printf(vstr, "b");
299 }
300 bool quote_single = false;
301 if (has_single_quote && !has_double_quote) {
302 vstr_printf(vstr, "\"");
303 } else {
304 quote_single = true;
305 vstr_printf(vstr, "'");
306 }
307 for (int i = 0; i < len; i++) {
308 if (str[i] == '\n') {
309 vstr_printf(vstr, "\\n");
310 } else if (str[i] == '\\') {
311 vstr_printf(vstr, "\\\\");
312 } else if (str[i] == '\'' && quote_single) {
313 vstr_printf(vstr, "\\'");
314 } else {
315 vstr_printf(vstr, "%c", str[i]);
316 }
317 }
318 if (has_single_quote && !has_double_quote) {
319 vstr_printf(vstr, "\"");
320 } else {
321 vstr_printf(vstr, "'");
322 }
323}
324
325static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn, vstr_t *vstr) {
Damien429d7192013-10-04 19:53:11 +0100326 assert(PY_PARSE_NODE_IS_LEAF(pn));
327 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
328 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
329 case PY_PARSE_NODE_ID: assert(0);
Damien02f89412013-12-12 15:13:36 +0000330 case PY_PARSE_NODE_SMALL_INT: vstr_printf(vstr, "%d", arg); break;
331 case PY_PARSE_NODE_INTEGER: vstr_printf(vstr, "%s", qstr_str(arg)); break;
332 case PY_PARSE_NODE_DECIMAL: vstr_printf(vstr, "%s", qstr_str(arg)); break;
333 case PY_PARSE_NODE_STRING: cpython_c_print_quoted_str(vstr, arg, false); break;
334 case PY_PARSE_NODE_BYTES: cpython_c_print_quoted_str(vstr, arg, true); break;
Damien429d7192013-10-04 19:53:11 +0100335 case PY_PARSE_NODE_TOKEN:
336 switch (arg) {
Damien02f89412013-12-12 15:13:36 +0000337 case PY_TOKEN_KW_FALSE: vstr_printf(vstr, "False"); break;
338 case PY_TOKEN_KW_NONE: vstr_printf(vstr, "None"); break;
339 case PY_TOKEN_KW_TRUE: vstr_printf(vstr, "True"); break;
Damien429d7192013-10-04 19:53:11 +0100340 default: assert(0);
341 }
342 break;
343 default: assert(0);
344 }
345}
346
Damien3a205172013-10-12 15:01:56 +0100347static 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 +0100348 int n = 0;
349 if (pns_list != NULL) {
350 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
351 }
352 int total = n;
353 bool is_const = true;
354 if (!PY_PARSE_NODE_IS_NULL(pn)) {
355 total += 1;
Damien3a205172013-10-12 15:01:56 +0100356 if (!cpython_c_tuple_is_const(pn)) {
Damien429d7192013-10-04 19:53:11 +0100357 is_const = false;
358 }
359 }
360 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100361 if (!cpython_c_tuple_is_const(pns_list->nodes[i])) {
Damien429d7192013-10-04 19:53:11 +0100362 is_const = false;
363 break;
364 }
365 }
366 if (total > 0 && is_const) {
367 bool need_comma = false;
Damien02f89412013-12-12 15:13:36 +0000368 vstr_t *vstr = vstr_new();
369 vstr_printf(vstr, "(");
Damien429d7192013-10-04 19:53:11 +0100370 if (!PY_PARSE_NODE_IS_NULL(pn)) {
Damien02f89412013-12-12 15:13:36 +0000371 cpython_c_tuple_emit_const(comp, pn, vstr);
Damien429d7192013-10-04 19:53:11 +0100372 need_comma = true;
373 }
374 for (int i = 0; i < n; i++) {
375 if (need_comma) {
Damien02f89412013-12-12 15:13:36 +0000376 vstr_printf(vstr, ", ");
Damien429d7192013-10-04 19:53:11 +0100377 }
Damien02f89412013-12-12 15:13:36 +0000378 cpython_c_tuple_emit_const(comp, pns_list->nodes[i], vstr);
Damien429d7192013-10-04 19:53:11 +0100379 need_comma = true;
380 }
381 if (total == 1) {
Damien02f89412013-12-12 15:13:36 +0000382 vstr_printf(vstr, ",)");
Damien429d7192013-10-04 19:53:11 +0100383 } else {
Damien02f89412013-12-12 15:13:36 +0000384 vstr_printf(vstr, ")");
Damien429d7192013-10-04 19:53:11 +0100385 }
Damien02f89412013-12-12 15:13:36 +0000386 EMIT(load_const_verbatim_start);
387 EMIT(load_const_verbatim_str, vstr_str(vstr));
Damien429d7192013-10-04 19:53:11 +0100388 EMIT(load_const_verbatim_end);
Damien02f89412013-12-12 15:13:36 +0000389 vstr_free(vstr);
Damien429d7192013-10-04 19:53:11 +0100390 } else {
391 if (!PY_PARSE_NODE_IS_NULL(pn)) {
392 compile_node(comp, pn);
393 }
394 for (int i = 0; i < n; i++) {
395 compile_node(comp, pns_list->nodes[i]);
396 }
397 EMIT(build_tuple, total);
398 }
399}
Damien3a205172013-10-12 15:01:56 +0100400#endif
401
402// funnelling all tuple creations through this function is purely so we can optionally agree with CPython
403void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
Damien3ef4abb2013-10-12 16:53:13 +0100404#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100405 cpython_c_tuple(comp, pn, pns_list);
406#else
407 int total = 0;
408 if (!PY_PARSE_NODE_IS_NULL(pn)) {
409 compile_node(comp, pn);
410 total += 1;
411 }
412 if (pns_list != NULL) {
413 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
414 for (int i = 0; i < n; i++) {
415 compile_node(comp, pns_list->nodes[i]);
416 }
417 total += n;
418 }
419 EMIT(build_tuple, total);
420#endif
421}
Damien429d7192013-10-04 19:53:11 +0100422
423void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
424 // a simple tuple expression
Damien429d7192013-10-04 19:53:11 +0100425 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
426}
427
Damien3a205172013-10-12 15:01:56 +0100428static bool node_is_const_false(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100429 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
430 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
431}
432
Damien3a205172013-10-12 15:01:56 +0100433static bool node_is_const_true(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100434 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);
435}
436
Damien3ef4abb2013-10-12 16:53:13 +0100437#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100438// the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
439static 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 +0100440 if (node_is_const_false(pn)) {
441 if (jump_if == false) {
442 EMIT(jump, label);
443 }
444 return;
445 } else if (node_is_const_true(pn)) {
446 if (jump_if == true) {
447 EMIT(jump, label);
448 }
449 return;
450 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
451 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
452 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
453 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
454 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100455 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100456 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100457 cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
Damien429d7192013-10-04 19:53:11 +0100458 }
Damien3a205172013-10-12 15:01:56 +0100459 cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100460 EMIT(label_assign, label2);
461 } else {
462 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100463 cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100464 }
465 }
466 return;
467 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
468 if (jump_if == false) {
469 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100470 cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100471 }
472 } else {
Damienb05d7072013-10-05 13:37:10 +0100473 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100474 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100475 cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
Damien429d7192013-10-04 19:53:11 +0100476 }
Damien3a205172013-10-12 15:01:56 +0100477 cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100478 EMIT(label_assign, label2);
479 }
480 return;
481 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
Damien3a205172013-10-12 15:01:56 +0100482 cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true);
Damien429d7192013-10-04 19:53:11 +0100483 return;
484 }
485 }
486
487 // nothing special, fall back to default compiling for node and jump
488 compile_node(comp, pn);
489 if (jump_if == false) {
490 EMIT(pop_jump_if_false, label);
491 } else {
492 EMIT(pop_jump_if_true, label);
493 }
494}
Damien3a205172013-10-12 15:01:56 +0100495#endif
Damien429d7192013-10-04 19:53:11 +0100496
Damien3a205172013-10-12 15:01:56 +0100497static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
Damien3ef4abb2013-10-12 16:53:13 +0100498#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100499 cpython_c_if_cond(comp, pn, jump_if, label, false);
500#else
501 if (node_is_const_false(pn)) {
502 if (jump_if == false) {
503 EMIT(jump, label);
504 }
505 return;
506 } else if (node_is_const_true(pn)) {
507 if (jump_if == true) {
508 EMIT(jump, label);
509 }
510 return;
511 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
512 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
513 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
514 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
515 if (jump_if == false) {
516 int label2 = comp_next_label(comp);
517 for (int i = 0; i < n - 1; i++) {
518 c_if_cond(comp, pns->nodes[i], true, label2);
519 }
520 c_if_cond(comp, pns->nodes[n - 1], false, label);
521 EMIT(label_assign, label2);
522 } else {
523 for (int i = 0; i < n; i++) {
524 c_if_cond(comp, pns->nodes[i], true, label);
525 }
526 }
527 return;
528 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
529 if (jump_if == false) {
530 for (int i = 0; i < n; i++) {
531 c_if_cond(comp, pns->nodes[i], false, label);
532 }
533 } else {
534 int label2 = comp_next_label(comp);
535 for (int i = 0; i < n - 1; i++) {
536 c_if_cond(comp, pns->nodes[i], false, label2);
537 }
538 c_if_cond(comp, pns->nodes[n - 1], true, label);
539 EMIT(label_assign, label2);
540 }
541 return;
542 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
543 c_if_cond(comp, pns->nodes[0], !jump_if, label);
544 return;
545 }
546 }
547
548 // nothing special, fall back to default compiling for node and jump
549 compile_node(comp, pn);
550 if (jump_if == false) {
551 EMIT(pop_jump_if_false, label);
552 } else {
553 EMIT(pop_jump_if_true, label);
554 }
555#endif
Damien429d7192013-10-04 19:53:11 +0100556}
557
558typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
559void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
560
561void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
562 if (assign_kind != ASSIGN_AUG_STORE) {
563 compile_node(comp, pns->nodes[0]);
564 }
565
566 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
567 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
568 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
569 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
570 if (assign_kind != ASSIGN_AUG_STORE) {
571 for (int i = 0; i < n - 1; i++) {
572 compile_node(comp, pns1->nodes[i]);
573 }
574 }
575 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
576 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
577 }
578 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
579 printf("SyntaxError: can't assign to function call\n");
580 return;
581 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
582 if (assign_kind == ASSIGN_AUG_STORE) {
583 EMIT(rot_three);
584 EMIT(store_subscr);
585 } else {
586 compile_node(comp, pns1->nodes[0]);
587 if (assign_kind == ASSIGN_AUG_LOAD) {
588 EMIT(dup_top_two);
589 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
590 } else {
591 EMIT(store_subscr);
592 }
593 }
594 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
595 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
596 if (assign_kind == ASSIGN_AUG_LOAD) {
597 EMIT(dup_top);
598 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
599 } else {
600 if (assign_kind == ASSIGN_AUG_STORE) {
601 EMIT(rot_two);
602 }
603 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
604 }
605 } else {
606 // shouldn't happen
607 assert(0);
608 }
609 } else {
610 // shouldn't happen
611 assert(0);
612 }
613
614 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
615 // SyntaxError, cannot assign
616 assert(0);
617 }
618}
619
620void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
621 assert(n >= 0);
622 int have_star_index = -1;
623 for (int i = 0; i < n; i++) {
624 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
625 if (have_star_index < 0) {
626 EMIT(unpack_ex, i, n - i - 1);
627 have_star_index = i;
628 } else {
629 printf("SyntaxError: two starred expressions in assignment\n");
630 return;
631 }
632 }
633 }
634 if (have_star_index < 0) {
635 EMIT(unpack_sequence, n);
636 }
637 for (int i = 0; i < n; i++) {
638 if (i == have_star_index) {
639 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
640 } else {
641 c_assign(comp, nodes[i], ASSIGN_STORE);
642 }
643 }
644}
645
646// assigns top of stack to pn
647void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
648 tail_recursion:
649 if (PY_PARSE_NODE_IS_NULL(pn)) {
650 assert(0);
651 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
652 if (PY_PARSE_NODE_IS_ID(pn)) {
653 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
654 switch (assign_kind) {
655 case ASSIGN_STORE:
656 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100657 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100658 break;
659 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100660 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100661 break;
662 }
663 } else {
664 printf("SyntaxError: can't assign to literal\n");
665 return;
666 }
667 } else {
668 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
669 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
670 case PN_power:
671 // lhs is an index or attribute
672 c_assign_power(comp, pns, assign_kind);
673 break;
674
675 case PN_testlist_star_expr:
676 case PN_exprlist:
677 // lhs is a tuple
678 if (assign_kind != ASSIGN_STORE) {
679 goto bad_aug;
680 }
681 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
682 break;
683
684 case PN_atom_paren:
685 // lhs is something in parenthesis
686 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
687 // empty tuple
688 printf("SyntaxError: can't assign to ()\n");
689 return;
690 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
691 pns = (py_parse_node_struct_t*)pns->nodes[0];
692 goto testlist_comp;
693 } else {
694 // parenthesis around 1 item, is just that item
695 pn = pns->nodes[0];
696 goto tail_recursion;
697 }
698 break;
699
700 case PN_atom_bracket:
701 // lhs is something in brackets
702 if (assign_kind != ASSIGN_STORE) {
703 goto bad_aug;
704 }
705 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
706 // empty list, assignment allowed
707 c_assign_tuple(comp, 0, NULL);
708 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
709 pns = (py_parse_node_struct_t*)pns->nodes[0];
710 goto testlist_comp;
711 } else {
712 // brackets around 1 item
713 c_assign_tuple(comp, 1, &pns->nodes[0]);
714 }
715 break;
716
717 default:
718 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
719 assert(0);
720 }
721 return;
722
723 testlist_comp:
724 // lhs is a sequence
725 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
726 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
727 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
728 // sequence of one item, with trailing comma
729 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
730 c_assign_tuple(comp, 1, &pns->nodes[0]);
731 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
732 // sequence of many items
733 // TODO call c_assign_tuple instead
734 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
735 EMIT(unpack_sequence, 1 + n);
736 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
737 for (int i = 0; i < n; i++) {
738 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
739 }
740 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
741 // TODO not implemented
742 assert(0);
743 } else {
744 // sequence with 2 items
745 goto sequence_with_2_items;
746 }
747 } else {
748 // sequence with 2 items
749 sequence_with_2_items:
750 c_assign_tuple(comp, 2, pns->nodes);
751 }
752 return;
753 }
754 return;
755
756 bad_aug:
757 printf("SyntaxError: illegal expression for augmented assignment\n");
758}
759
760// stuff for lambda and comprehensions and generators
761void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
762 // make closed over variables, if any
Damien318aec62013-12-10 18:28:17 +0000763 // ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython)
Damien429d7192013-10-04 19:53:11 +0100764 int nfree = 0;
765 if (comp->scope_cur->kind != SCOPE_MODULE) {
Damien318aec62013-12-10 18:28:17 +0000766 for (int i = 0; i < comp->scope_cur->id_info_len; i++) {
767 id_info_t *id = &comp->scope_cur->id_info[i];
768 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
769 for (int j = 0; j < this_scope->id_info_len; j++) {
770 id_info_t *id2 = &this_scope->id_info[j];
771 if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
772 EMIT(load_closure, id->qstr, id->local_num);
773 nfree += 1;
774 }
775 }
Damien429d7192013-10-04 19:53:11 +0100776 }
777 }
778 }
779 if (nfree > 0) {
780 EMIT(build_tuple, nfree);
781 }
782
783 // make the function/closure
784 if (nfree == 0) {
785 EMIT(make_function, this_scope, n_dict_params, n_default_params);
786 } else {
787 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
788 }
789}
790
791void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100792 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
793 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100794 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
795 // this parameter has a default value
796 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
797 if (comp->have_bare_star) {
798 comp->param_pass_num_dict_params += 1;
799 if (comp->param_pass == 1) {
800 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
801 compile_node(comp, pns->nodes[2]);
802 }
803 } else {
804 comp->param_pass_num_default_params += 1;
805 if (comp->param_pass == 2) {
806 compile_node(comp, pns->nodes[2]);
807 }
808 }
809 }
Damienb14de212013-10-06 00:28:28 +0100810 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
811 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100812 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
813 // bare star
814 comp->have_bare_star = true;
815 }
816 }
817}
818
819// leaves function object on stack
820// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100821qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100822 if (comp->pass == PASS_1) {
823 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100824 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100825 // store the function scope so the compiling function can use it at each pass
826 pns->nodes[4] = (py_parse_node_t)s;
827 }
828
829 // save variables (probably don't need to do this, since we can't have nested definitions..?)
830 bool old_have_bare_star = comp->have_bare_star;
831 int old_param_pass = comp->param_pass;
832 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
833 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
834
835 // compile default parameters
836 comp->have_bare_star = false;
837 comp->param_pass = 1; // pass 1 does any default parameters after bare star
838 comp->param_pass_num_dict_params = 0;
839 comp->param_pass_num_default_params = 0;
840 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
841 comp->have_bare_star = false;
842 comp->param_pass = 2; // pass 2 does any default parameters before bare star
843 comp->param_pass_num_dict_params = 0;
844 comp->param_pass_num_default_params = 0;
845 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
846
847 // get the scope for this function
848 scope_t *fscope = (scope_t*)pns->nodes[4];
849
850 // make the function
851 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
852
853 // restore variables
854 comp->have_bare_star = old_have_bare_star;
855 comp->param_pass = old_param_pass;
856 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
857 comp->param_pass_num_default_params = old_param_pass_num_default_params;
858
859 // return its name (the 'f' in "def f(...):")
860 return fscope->simple_name;
861}
862
863// leaves class object on stack
864// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100865qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100866 if (comp->pass == PASS_1) {
867 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100868 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100869 // store the class scope so the compiling function can use it at each pass
870 pns->nodes[3] = (py_parse_node_t)s;
871 }
872
873 EMIT(load_build_class);
874
875 // scope for this class
876 scope_t *cscope = (scope_t*)pns->nodes[3];
877
878 // compile the class
879 close_over_variables_etc(comp, cscope, 0, 0);
880
881 // get its name
882 EMIT(load_const_id, cscope->simple_name);
883
884 // nodes[1] has parent classes, if any
885 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
886 // no parent classes
887 EMIT(call_function, 2, 0, false, false);
888 } else {
889 // have a parent class or classes
890 // TODO what if we have, eg, *a or **a in the parent list?
891 compile_node(comp, pns->nodes[1]);
892 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
893 }
894
895 // return its name (the 'C' in class C(...):")
896 return cscope->simple_name;
897}
898
Damien6cdd3af2013-10-05 18:08:26 +0100899// returns true if it was a built-in decorator (even if the built-in had an error)
900static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
901 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
902 return false;
903 }
904
905 if (name_len != 2) {
906 printf("SyntaxError: invalid micropython decorator\n");
907 return true;
908 }
909
910 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
Damien5ac1b2e2013-10-18 19:58:12 +0100911 if (attr == comp->qstr_byte_code) {
912 *emit_options = EMIT_OPT_BYTE_CODE;
Damience89a212013-10-15 22:25:17 +0100913#if MICROPY_EMIT_NATIVE
914 } else if (attr == comp->qstr_native) {
Damien6cdd3af2013-10-05 18:08:26 +0100915 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100916 } else if (attr == comp->qstr_viper) {
917 *emit_options = EMIT_OPT_VIPER;
Damience89a212013-10-15 22:25:17 +0100918#endif
Damien3ef4abb2013-10-12 16:53:13 +0100919#if MICROPY_EMIT_INLINE_THUMB
Damien5bfb7592013-10-05 18:41:24 +0100920 } else if (attr == comp->qstr_asm_thumb) {
921 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100922#endif
Damien6cdd3af2013-10-05 18:08:26 +0100923 } else {
Damience89a212013-10-15 22:25:17 +0100924 printf("SyntaxError: invalid micropython decorator '%s'\n", qstr_str(attr));
Damien6cdd3af2013-10-05 18:08:26 +0100925 }
926
927 return true;
928}
929
Damien429d7192013-10-04 19:53:11 +0100930void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
931 // get the list of decorators
932 py_parse_node_t *nodes;
933 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
934
Damien6cdd3af2013-10-05 18:08:26 +0100935 // inherit emit options for this function/class definition
936 uint emit_options = comp->scope_cur->emit_options;
937
938 // compile each decorator
939 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100940 for (int i = 0; i < n; i++) {
941 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
942 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100943
944 // nodes[0] contains the decorator function, which is a dotted name
945 py_parse_node_t *name_nodes;
946 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
947
948 // check for built-in decorators
949 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
950 // this was a built-in
951 num_built_in_decorators += 1;
952
953 } else {
954 // not a built-in, compile normally
955
956 // compile the decorator function
957 compile_node(comp, name_nodes[0]);
958 for (int i = 1; i < name_len; i++) {
959 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
960 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
961 }
962
963 // nodes[1] contains arguments to the decorator function, if any
964 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
965 // call the decorator function with the arguments in nodes[1]
966 compile_node(comp, pns_decorator->nodes[1]);
967 }
Damien429d7192013-10-04 19:53:11 +0100968 }
969 }
970
971 // compile the body (funcdef or classdef) and get its name
972 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
973 qstr body_name = 0;
974 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100975 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100976 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100977 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100978 } else {
979 // shouldn't happen
980 assert(0);
981 }
982
983 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100984 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100985 EMIT(call_function, 1, 0, false, false);
986 }
987
988 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100989 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100990}
991
992void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100993 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100994 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100995 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100996}
997
998void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
999 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +01001000 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +01001001 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
1002 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1003
1004 compile_node(comp, pns->nodes[0]); // base of the power node
1005
1006 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1007 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1008 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
1009 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
1010 for (int i = 0; i < n - 1; i++) {
1011 compile_node(comp, pns1->nodes[i]);
1012 }
1013 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
1014 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
1015 }
1016 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
1017 // SyntaxError: can't delete a function call
1018 assert(0);
1019 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
1020 compile_node(comp, pns1->nodes[0]);
1021 EMIT(delete_subscr);
1022 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
1023 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
1024 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
1025 } else {
1026 // shouldn't happen
1027 assert(0);
1028 }
1029 } else {
1030 // shouldn't happen
1031 assert(0);
1032 }
1033
1034 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1035 // SyntaxError, cannot delete
1036 assert(0);
1037 }
1038 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
1039 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
1040 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
1041 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1042 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
1043
1044 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1045 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1046 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
1047 // sequence of one item, with trailing comma
1048 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
1049 c_del_stmt(comp, pns->nodes[0]);
1050 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
1051 // sequence of many items
1052 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
1053 c_del_stmt(comp, pns->nodes[0]);
1054 for (int i = 0; i < n; i++) {
1055 c_del_stmt(comp, pns1->nodes[i]);
1056 }
1057 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
1058 // TODO not implemented; can't del comprehension?
1059 assert(0);
1060 } else {
1061 // sequence with 2 items
1062 goto sequence_with_2_items;
1063 }
1064 } else {
1065 // sequence with 2 items
1066 sequence_with_2_items:
1067 c_del_stmt(comp, pns->nodes[0]);
1068 c_del_stmt(comp, pns->nodes[1]);
1069 }
1070 } else {
1071 // tuple with 1 element
1072 c_del_stmt(comp, pn);
1073 }
1074 } else {
1075 // not implemented
1076 assert(0);
1077 }
1078}
1079
1080void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1081 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
1082}
1083
1084void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1085 if (comp->break_label == 0) {
1086 printf("ERROR: cannot break from here\n");
1087 }
1088 EMIT(break_loop, comp->break_label);
1089}
1090
1091void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1092 if (comp->continue_label == 0) {
1093 printf("ERROR: cannot continue from here\n");
1094 }
1095 if (comp->except_nest_level > 0) {
1096 EMIT(continue_loop, comp->continue_label);
1097 } else {
1098 EMIT(jump, comp->continue_label);
1099 }
1100}
1101
1102void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien5ac1b2e2013-10-18 19:58:12 +01001103 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
1104 printf("SyntaxError: 'return' outside function\n");
1105 comp->had_error = true;
1106 return;
1107 }
Damien429d7192013-10-04 19:53:11 +01001108 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001109 // no argument to 'return', so return None
Damien429d7192013-10-04 19:53:11 +01001110 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1111 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
1112 // special case when returning an if-expression; to match CPython optimisation
1113 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
1114 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
1115
Damienb05d7072013-10-05 13:37:10 +01001116 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001117 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1118 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
1119 EMIT(return_value);
1120 EMIT(label_assign, l_fail);
1121 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1122 } else {
1123 compile_node(comp, pns->nodes[0]);
1124 }
1125 EMIT(return_value);
1126}
1127
1128void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1129 compile_node(comp, pns->nodes[0]);
1130 EMIT(pop_top);
1131}
1132
1133void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1134 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1135 // raise
1136 EMIT(raise_varargs, 0);
1137 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1138 // raise x from y
1139 pns = (py_parse_node_struct_t*)pns->nodes[0];
1140 compile_node(comp, pns->nodes[0]);
1141 compile_node(comp, pns->nodes[1]);
1142 EMIT(raise_varargs, 2);
1143 } else {
1144 // raise x
1145 compile_node(comp, pns->nodes[0]);
1146 EMIT(raise_varargs, 1);
1147 }
1148}
1149
1150// q1 holds the base, q2 the full name
1151// eg a -> q1=q2=a
1152// a.b.c -> q1=a, q2=a.b.c
1153void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1154 bool is_as = false;
1155 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1156 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1157 // a name of the form x as y; unwrap it
1158 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1159 pn = pns->nodes[0];
1160 is_as = true;
1161 }
1162 if (PY_PARSE_NODE_IS_ID(pn)) {
1163 // just a simple name
1164 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1165 if (!is_as) {
1166 *q1 = *q2;
1167 }
1168 EMIT(import_name, *q2);
1169 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1170 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1171 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1172 // a name of the form a.b.c
1173 if (!is_as) {
1174 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1175 }
1176 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1177 int len = n - 1;
1178 for (int i = 0; i < n; i++) {
1179 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1180 }
1181 char *str = m_new(char, len + 1);
1182 str[0] = 0;
1183 for (int i = 0; i < n; i++) {
1184 if (i > 0) {
1185 strcat(str, ".");
1186 }
1187 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1188 }
1189 *q2 = qstr_from_str_take(str);
1190 EMIT(import_name, *q2);
1191 if (is_as) {
1192 for (int i = 1; i < n; i++) {
1193 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1194 }
1195 }
1196 } else {
1197 // TODO not implemented
1198 assert(0);
1199 }
1200 } else {
1201 // TODO not implemented
1202 assert(0);
1203 }
1204}
1205
1206void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1207 EMIT(load_const_small_int, 0); // ??
1208 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1209 qstr q1, q2;
1210 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001211 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001212}
1213
1214void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1215 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1216}
1217
1218void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1219 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
Damiendb4c3612013-12-10 17:27:24 +00001220 EMIT(load_const_small_int, 0); // level 0 for __import__
1221
1222 // build the "fromlist" tuple
1223#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001224 EMIT(load_const_verbatim_start);
1225 EMIT(load_const_verbatim_str, "('*',)");
1226 EMIT(load_const_verbatim_end);
Damiendb4c3612013-12-10 17:27:24 +00001227#else
1228 EMIT(load_const_str, qstr_from_str_static("*"), false);
1229 EMIT(build_tuple, 1);
1230#endif
1231
1232 // do the import
Damien429d7192013-10-04 19:53:11 +01001233 qstr dummy_q, id1;
1234 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1235 EMIT(import_star);
Damiendb4c3612013-12-10 17:27:24 +00001236
Damien429d7192013-10-04 19:53:11 +01001237 } else {
Damiendb4c3612013-12-10 17:27:24 +00001238 EMIT(load_const_small_int, 0); // level 0 for __import__
1239
1240 // build the "fromlist" tuple
Damien429d7192013-10-04 19:53:11 +01001241 py_parse_node_t *pn_nodes;
1242 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
Damiendb4c3612013-12-10 17:27:24 +00001243#if MICROPY_EMIT_CPYTHON
Damien02f89412013-12-12 15:13:36 +00001244 {
1245 vstr_t *vstr = vstr_new();
1246 vstr_printf(vstr, "(");
1247 for (int i = 0; i < n; i++) {
1248 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1249 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1250 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1251 if (i > 0) {
1252 vstr_printf(vstr, ", ");
1253 }
1254 vstr_printf(vstr, "'");
1255 vstr_printf(vstr, qstr_str(id2));
1256 vstr_printf(vstr, "'");
Damien429d7192013-10-04 19:53:11 +01001257 }
Damien02f89412013-12-12 15:13:36 +00001258 if (n == 1) {
1259 vstr_printf(vstr, ",");
1260 }
1261 vstr_printf(vstr, ")");
1262 EMIT(load_const_verbatim_start);
1263 EMIT(load_const_verbatim_str, vstr_str(vstr));
1264 EMIT(load_const_verbatim_end);
1265 vstr_free(vstr);
Damien429d7192013-10-04 19:53:11 +01001266 }
Damiendb4c3612013-12-10 17:27:24 +00001267#else
1268 for (int i = 0; i < n; i++) {
1269 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1270 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1271 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1272 EMIT(load_const_str, id2, false);
1273 }
1274 EMIT(build_tuple, n);
1275#endif
1276
1277 // do the import
Damien429d7192013-10-04 19:53:11 +01001278 qstr dummy_q, id1;
1279 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1280 for (int i = 0; i < n; i++) {
1281 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1282 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1283 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1284 EMIT(import_from, id2);
1285 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001286 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001287 } else {
Damien4b03e772013-10-05 14:17:09 +01001288 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001289 }
1290 }
1291 EMIT(pop_top);
1292 }
1293}
1294
1295void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001296 if (comp->pass == PASS_1) {
1297 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1298 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1299 } else {
1300 pns = (py_parse_node_struct_t*)pns->nodes[0];
1301 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1302 for (int i = 0; i < num_nodes; i++) {
1303 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1304 }
Damien429d7192013-10-04 19:53:11 +01001305 }
1306 }
1307}
1308
1309void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001310 if (comp->pass == PASS_1) {
1311 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1312 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1313 } else {
1314 pns = (py_parse_node_struct_t*)pns->nodes[0];
1315 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1316 for (int i = 0; i < num_nodes; i++) {
1317 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1318 }
Damien429d7192013-10-04 19:53:11 +01001319 }
1320 }
1321}
1322
1323void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001324 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001325 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001326 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001327 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1328 // assertion message
1329 compile_node(comp, pns->nodes[1]);
1330 EMIT(call_function, 1, 0, false, false);
1331 }
1332 EMIT(raise_varargs, 1);
1333 EMIT(label_assign, l_end);
1334}
1335
1336void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1337 // TODO proper and/or short circuiting
1338
Damienb05d7072013-10-05 13:37:10 +01001339 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001340
Damienb05d7072013-10-05 13:37:10 +01001341 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001342 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1343
1344 compile_node(comp, pns->nodes[1]); // if block
1345 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1346 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001347 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001348 EMIT(jump, l_end);
1349 }
1350 //}
1351 EMIT(label_assign, l_fail);
1352
1353 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1354 // compile elif blocks
1355
1356 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1357
1358 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1359 // multiple elif blocks
1360
1361 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1362 for (int i = 0; i < n; i++) {
1363 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001364 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001365 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1366
1367 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001368 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001369 EMIT(jump, l_end);
1370 }
1371 EMIT(label_assign, l_fail);
1372 }
1373
1374 } else {
1375 // a single elif block
1376
Damienb05d7072013-10-05 13:37:10 +01001377 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001378 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1379
1380 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001381 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001382 EMIT(jump, l_end);
1383 }
1384 EMIT(label_assign, l_fail);
1385 }
1386 }
1387
1388 // compile else block
1389 compile_node(comp, pns->nodes[3]); // can be null
1390
1391 EMIT(label_assign, l_end);
1392}
1393
1394void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1395 int old_break_label = comp->break_label;
1396 int old_continue_label = comp->continue_label;
1397
Damienb05d7072013-10-05 13:37:10 +01001398 int break_label = comp_next_label(comp);
1399 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001400
1401 comp->break_label = break_label;
1402 comp->continue_label = continue_label;
1403
Damience89a212013-10-15 22:25:17 +01001404 // compared to CPython, we have an optimised version of while loops
1405#if MICROPY_EMIT_CPYTHON
1406 int done_label = comp_next_label(comp);
1407 EMIT(setup_loop, break_label);
Damien429d7192013-10-04 19:53:11 +01001408 EMIT(label_assign, continue_label);
1409 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1410 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001411 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001412 EMIT(jump, continue_label);
1413 }
1414 EMIT(label_assign, done_label);
Damien429d7192013-10-04 19:53:11 +01001415 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1416 // this is a small hack to agree with CPython
1417 if (!node_is_const_true(pns->nodes[0])) {
1418 EMIT(pop_block);
1419 }
Damience89a212013-10-15 22:25:17 +01001420#else
1421 int top_label = comp_next_label(comp);
1422 EMIT(jump, continue_label);
1423 EMIT(label_assign, top_label);
1424 compile_node(comp, pns->nodes[1]); // body
1425 EMIT(label_assign, continue_label);
1426 c_if_cond(comp, pns->nodes[0], true, top_label); // condition
1427#endif
1428
1429 // break/continue apply to outer loop (if any) in the else block
1430 comp->break_label = old_break_label;
1431 comp->continue_label = old_continue_label;
Damien429d7192013-10-04 19:53:11 +01001432
1433 compile_node(comp, pns->nodes[2]); // else
1434
1435 EMIT(label_assign, break_label);
Damien429d7192013-10-04 19:53:11 +01001436}
1437
Damienf72fd0e2013-11-06 20:20:49 +00001438// TODO preload end and step onto stack if they are not constants
1439// TODO check if step is negative and do opposite test
1440void compile_for_stmt_optimised_range(compiler_t *comp, py_parse_node_t pn_var, py_parse_node_t pn_start, py_parse_node_t pn_end, py_parse_node_t pn_step, py_parse_node_t pn_body, py_parse_node_t pn_else) {
1441 int old_break_label = comp->break_label;
1442 int old_continue_label = comp->continue_label;
1443
1444 int break_label = comp_next_label(comp);
1445 int continue_label = comp_next_label(comp);
1446
1447 comp->break_label = break_label;
1448 comp->continue_label = continue_label;
1449
1450 int top_label = comp_next_label(comp);
1451
1452 // compile: var = start
1453 compile_node(comp, pn_start);
1454 c_assign(comp, pn_var, ASSIGN_STORE);
1455
1456 EMIT(jump, continue_label);
1457 EMIT(label_assign, top_label);
1458
Damienf3822fc2013-11-09 20:12:03 +00001459 // compile body
1460 compile_node(comp, pn_body);
1461
Damienf72fd0e2013-11-06 20:20:49 +00001462 // compile: var += step
1463 c_assign(comp, pn_var, ASSIGN_AUG_LOAD);
1464 compile_node(comp, pn_step);
1465 EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD);
1466 c_assign(comp, pn_var, ASSIGN_AUG_STORE);
1467
Damienf72fd0e2013-11-06 20:20:49 +00001468 EMIT(label_assign, continue_label);
1469
1470 // compile: if var < end: goto top
1471 compile_node(comp, pn_var);
1472 compile_node(comp, pn_end);
1473 EMIT(compare_op, RT_COMPARE_OP_LESS);
1474 EMIT(pop_jump_if_true, top_label);
1475
1476 // break/continue apply to outer loop (if any) in the else block
1477 comp->break_label = old_break_label;
1478 comp->continue_label = old_continue_label;
1479
1480 compile_node(comp, pn_else);
1481
1482 EMIT(label_assign, break_label);
1483}
1484
Damien429d7192013-10-04 19:53:11 +01001485void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienf72fd0e2013-11-06 20:20:49 +00001486#if !MICROPY_EMIT_CPYTHON
1487 // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
1488 // this is actually slower, but uses no heap memory
1489 // for viper it will be much, much faster
Damiend7933892013-11-28 19:12:18 +00001490 if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ PY_PARSE_NODE_IS_ID(pns->nodes[0]) && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
Damienf72fd0e2013-11-06 20:20:49 +00001491 py_parse_node_struct_t *pns_it = (py_parse_node_struct_t*)pns->nodes[1];
Damiend7933892013-11-28 19:12:18 +00001492 if (PY_PARSE_NODE_IS_ID(pns_it->nodes[0]) && PY_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == comp->qstr_range && PY_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren) && PY_PARSE_NODE_IS_NULL(pns_it->nodes[2])) {
Damienf72fd0e2013-11-06 20:20:49 +00001493 py_parse_node_t pn_range_args = ((py_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
1494 py_parse_node_t *args;
1495 int n_args = list_get(&pn_range_args, PN_arglist, &args);
1496 if (1 <= n_args && n_args <= 3) {
1497 py_parse_node_t pn_range_start;
1498 py_parse_node_t pn_range_end;
1499 py_parse_node_t pn_range_step;
1500 if (n_args == 1) {
1501 pn_range_start = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 0);
1502 pn_range_end = args[0];
1503 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1504 } else if (n_args == 2) {
1505 pn_range_start = args[0];
1506 pn_range_end = args[1];
1507 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1508 } else {
1509 pn_range_start = args[0];
1510 pn_range_end = args[1];
1511 pn_range_step = args[2];
1512 }
1513 compile_for_stmt_optimised_range(comp, pns->nodes[0], pn_range_start, pn_range_end, pn_range_step, pns->nodes[2], pns->nodes[3]);
1514 return;
1515 }
1516 }
1517 }
1518#endif
1519
Damien429d7192013-10-04 19:53:11 +01001520 int old_break_label = comp->break_label;
1521 int old_continue_label = comp->continue_label;
1522
Damienb05d7072013-10-05 13:37:10 +01001523 int for_label = comp_next_label(comp);
1524 int pop_label = comp_next_label(comp);
1525 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001526
Damienb05d7072013-10-05 13:37:10 +01001527 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001528
1529 comp->continue_label = for_label;
1530 comp->break_label = break_label;
1531
Damience89a212013-10-15 22:25:17 +01001532 // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
1533#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001534 EMIT(setup_loop, end_label);
Damience89a212013-10-15 22:25:17 +01001535#endif
1536
Damien429d7192013-10-04 19:53:11 +01001537 compile_node(comp, pns->nodes[1]); // iterator
1538 EMIT(get_iter);
1539 EMIT(label_assign, for_label);
1540 EMIT(for_iter, pop_label);
1541 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1542 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001543 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001544 EMIT(jump, for_label);
1545 }
1546 EMIT(label_assign, pop_label);
1547 EMIT(for_iter_end);
1548
1549 // break/continue apply to outer loop (if any) in the else block
1550 comp->break_label = old_break_label;
1551 comp->continue_label = old_continue_label;
1552
Damience89a212013-10-15 22:25:17 +01001553#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001554 EMIT(pop_block);
Damience89a212013-10-15 22:25:17 +01001555#endif
Damien429d7192013-10-04 19:53:11 +01001556
1557 compile_node(comp, pns->nodes[3]); // else (not tested)
1558
1559 EMIT(label_assign, break_label);
1560 EMIT(label_assign, end_label);
1561}
1562
1563void 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) {
1564 // this function is a bit of a hack at the moment
1565 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1566
1567 // setup code
1568 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001569 int l1 = comp_next_label(comp);
1570 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001571 comp->except_nest_level += 1; // for correct handling of continue
1572 EMIT(setup_except, l1);
1573 compile_node(comp, pn_body); // body
1574 EMIT(pop_block);
1575 EMIT(jump, success_label);
1576 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001577 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001578
1579 for (int i = 0; i < n_except; i++) {
1580 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1581 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1582
1583 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001584 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001585
1586 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1587 // this is a catch all exception handler
1588 if (i + 1 != n_except) {
1589 printf("SyntaxError: default 'except:' must be last\n");
1590 return;
1591 }
1592 } else {
1593 // this exception handler requires a match to a certain type of exception
1594 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1595 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1596 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1597 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1598 // handler binds the exception to a local
1599 pns_exception_expr = pns3->nodes[0];
1600 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1601 }
1602 }
1603 EMIT(dup_top);
1604 compile_node(comp, pns_exception_expr);
1605 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1606 EMIT(pop_jump_if_false, end_finally_label);
1607 }
1608
1609 EMIT(pop_top);
1610
1611 if (qstr_exception_local == 0) {
1612 EMIT(pop_top);
1613 } else {
Damien4b03e772013-10-05 14:17:09 +01001614 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001615 }
1616
1617 EMIT(pop_top);
1618
1619 int l3;
1620 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001621 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001622 EMIT(setup_finally, l3);
1623 }
1624 compile_node(comp, pns_except->nodes[1]);
1625 if (qstr_exception_local != 0) {
1626 EMIT(pop_block);
1627 }
1628 EMIT(pop_except);
1629 if (qstr_exception_local != 0) {
1630 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1631 EMIT(label_assign, l3);
1632 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001633 EMIT(store_id, qstr_exception_local);
1634 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001635 EMIT(end_finally);
1636 }
1637 EMIT(jump, l2);
1638 EMIT(label_assign, end_finally_label);
1639 }
1640
1641 EMIT(end_finally);
1642 EMIT(label_assign, success_label);
1643 comp->except_nest_level -= 1;
1644 compile_node(comp, pn_else); // else block, can be null
1645 EMIT(label_assign, l2);
1646 EMIT(set_stack_size, stack_size);
1647}
1648
1649void 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) {
1650 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1651 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001652 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001653 EMIT(setup_finally, l_finally_block);
1654 if (n_except == 0) {
1655 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1656 compile_node(comp, pn_body);
1657 } else {
1658 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1659 }
1660 EMIT(pop_block);
1661 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1662 EMIT(label_assign, l_finally_block);
1663 compile_node(comp, pn_finally);
1664 EMIT(end_finally);
1665 EMIT(set_stack_size, stack_size);
1666}
1667
1668void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1669 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1670 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1671 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1672 // just try-finally
1673 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1674 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1675 // try-except and possibly else and/or finally
1676 py_parse_node_t *pn_excepts;
1677 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1678 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1679 // no finally
1680 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1681 } else {
1682 // have finally
1683 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1684 }
1685 } else {
1686 // just try-except
1687 py_parse_node_t *pn_excepts;
1688 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1689 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1690 }
1691 } else {
1692 // shouldn't happen
1693 assert(0);
1694 }
1695}
1696
1697void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1698 if (n == 0) {
1699 // no more pre-bits, compile the body of the with
1700 compile_node(comp, body);
1701 } else {
Damienb05d7072013-10-05 13:37:10 +01001702 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001703 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1704 // this pre-bit is of the form "a as b"
1705 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1706 compile_node(comp, pns->nodes[0]);
1707 EMIT(setup_with, l_end);
1708 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1709 } else {
1710 // this pre-bit is just an expression
1711 compile_node(comp, nodes[0]);
1712 EMIT(setup_with, l_end);
1713 EMIT(pop_top);
1714 }
1715 // compile additional pre-bits and the body
1716 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1717 // finish this with block
1718 EMIT(pop_block);
1719 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1720 EMIT(label_assign, l_end);
1721 EMIT(with_cleanup);
1722 EMIT(end_finally);
1723 }
1724}
1725
1726void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1727 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1728 py_parse_node_t *nodes;
1729 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1730 assert(n > 0);
1731
1732 // compile in a nested fashion
1733 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1734}
1735
1736void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1737 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001738 if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
1739 // for REPL, evaluate then print the expression
1740 EMIT(load_id, qstr_from_str_static("__repl_print__"));
1741 compile_node(comp, pns->nodes[0]);
1742 EMIT(call_function, 1, 0, false, false);
1743 EMIT(pop_top);
1744
Damien429d7192013-10-04 19:53:11 +01001745 } else {
Damien5ac1b2e2013-10-18 19:58:12 +01001746 // for non-REPL, evaluate then discard the expression
1747 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1748 // do nothing with a lonely constant
1749 } else {
1750 compile_node(comp, pns->nodes[0]); // just an expression
1751 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1752 }
Damien429d7192013-10-04 19:53:11 +01001753 }
1754 } else {
1755 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1756 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1757 if (kind == PN_expr_stmt_augassign) {
1758 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1759 compile_node(comp, pns1->nodes[1]); // rhs
1760 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1761 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1762 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1763 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1764 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1765 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1766 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1767 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1768 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1769 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1770 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1771 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1772 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1773 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1774 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1775 default: assert(0); // shouldn't happen
1776 }
1777 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1778 } else if (kind == PN_expr_stmt_assign_list) {
1779 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1780 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1781 // following CPython, we store left-most first
1782 if (rhs > 0) {
1783 EMIT(dup_top);
1784 }
1785 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1786 for (int i = 0; i < rhs; i++) {
1787 if (i + 1 < rhs) {
1788 EMIT(dup_top);
1789 }
1790 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1791 }
1792 } else if (kind == PN_expr_stmt_assign) {
1793 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1794 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1795 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1796 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1797 // optimisation for a, b = c, d; to match CPython's optimisation
1798 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1799 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1800 compile_node(comp, pns10->nodes[0]); // rhs
1801 compile_node(comp, pns10->nodes[1]); // rhs
1802 EMIT(rot_two);
1803 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1804 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1805 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1806 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1807 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1808 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1809 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1810 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1811 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1812 compile_node(comp, pns10->nodes[0]); // rhs
1813 compile_node(comp, pns10->nodes[1]); // rhs
1814 compile_node(comp, pns10->nodes[2]); // rhs
1815 EMIT(rot_three);
1816 EMIT(rot_two);
1817 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1818 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1819 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1820 } else {
1821 compile_node(comp, pns1->nodes[0]); // rhs
1822 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1823 }
1824 } else {
1825 // shouldn't happen
1826 assert(0);
1827 }
1828 }
1829}
1830
1831void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1832 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1833 compile_node(comp, pns->nodes[0]);
1834 for (int i = 1; i < num_nodes; i += 1) {
1835 compile_node(comp, pns->nodes[i]);
1836 EMIT(binary_op, binary_op);
1837 }
1838}
1839
1840void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1841 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1842 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1843
1844 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001845 int l_fail = comp_next_label(comp);
1846 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001847 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1848 compile_node(comp, pns->nodes[0]); // success value
1849 EMIT(jump, l_end);
1850 EMIT(label_assign, l_fail);
1851 EMIT(set_stack_size, stack_size); // force stack size reset
1852 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1853 EMIT(label_assign, l_end);
1854}
1855
1856void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1857 // TODO default params etc for lambda; possibly just use funcdef code
1858 //py_parse_node_t pn_params = pns->nodes[0];
1859 //py_parse_node_t pn_body = pns->nodes[1];
1860
1861 if (comp->pass == PASS_1) {
1862 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001863 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 +01001864 // store the lambda scope so the compiling function (this one) can use it at each pass
1865 pns->nodes[2] = (py_parse_node_t)s;
1866 }
1867
1868 // get the scope for this lambda
1869 scope_t *this_scope = (scope_t*)pns->nodes[2];
1870
1871 // make the lambda
1872 close_over_variables_etc(comp, this_scope, 0, 0);
1873}
1874
1875void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001876 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001877 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1878 for (int i = 0; i < n; i += 1) {
1879 compile_node(comp, pns->nodes[i]);
1880 if (i + 1 < n) {
1881 EMIT(jump_if_true_or_pop, l_end);
1882 }
1883 }
1884 EMIT(label_assign, l_end);
1885}
1886
1887void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001888 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001889 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1890 for (int i = 0; i < n; i += 1) {
1891 compile_node(comp, pns->nodes[i]);
1892 if (i + 1 < n) {
1893 EMIT(jump_if_false_or_pop, l_end);
1894 }
1895 }
1896 EMIT(label_assign, l_end);
1897}
1898
1899void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1900 compile_node(comp, pns->nodes[0]);
1901 EMIT(unary_op, RT_UNARY_OP_NOT);
1902}
1903
1904void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1905 int stack_size = EMIT(get_stack_size);
1906 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1907 compile_node(comp, pns->nodes[0]);
1908 bool multi = (num_nodes > 3);
1909 int l_fail = 0;
1910 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001911 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001912 }
1913 for (int i = 1; i + 1 < num_nodes; i += 2) {
1914 compile_node(comp, pns->nodes[i + 1]);
1915 if (i + 2 < num_nodes) {
1916 EMIT(dup_top);
1917 EMIT(rot_three);
1918 }
1919 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1920 EMIT(compare_op, RT_COMPARE_OP_LESS);
1921 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1922 EMIT(compare_op, RT_COMPARE_OP_MORE);
1923 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1924 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1925 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1926 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1927 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1928 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1929 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1930 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1931 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1932 EMIT(compare_op, RT_COMPARE_OP_IN);
1933 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1934 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1935 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1936 if (kind == PN_comp_op_not_in) {
1937 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1938 } else if (kind == PN_comp_op_is) {
1939 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1940 EMIT(compare_op, RT_COMPARE_OP_IS);
1941 } else {
1942 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1943 }
1944 } else {
1945 // shouldn't happen
1946 assert(0);
1947 }
1948 } else {
1949 // shouldn't happen
1950 assert(0);
1951 }
1952 if (i + 2 < num_nodes) {
1953 EMIT(jump_if_false_or_pop, l_fail);
1954 }
1955 }
1956 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001957 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001958 EMIT(jump, l_end);
1959 EMIT(label_assign, l_fail);
1960 EMIT(rot_two);
1961 EMIT(pop_top);
1962 EMIT(label_assign, l_end);
1963 EMIT(set_stack_size, stack_size + 1); // force stack size
1964 }
1965}
1966
1967void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1968 // TODO
1969 assert(0);
1970 compile_node(comp, pns->nodes[0]);
1971 //EMIT(unary_op, "UNARY_STAR");
1972}
1973
1974void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1975 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1976}
1977
1978void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1979 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1980}
1981
1982void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1983 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1984}
1985
1986void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1987 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1988 compile_node(comp, pns->nodes[0]);
1989 for (int i = 1; i + 1 < num_nodes; i += 2) {
1990 compile_node(comp, pns->nodes[i + 1]);
1991 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1992 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1993 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1994 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1995 } else {
1996 // shouldn't happen
1997 assert(0);
1998 }
1999 }
2000}
2001
2002void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2003 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2004 compile_node(comp, pns->nodes[0]);
2005 for (int i = 1; i + 1 < num_nodes; i += 2) {
2006 compile_node(comp, pns->nodes[i + 1]);
2007 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
2008 EMIT(binary_op, RT_BINARY_OP_ADD);
2009 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
2010 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
2011 } else {
2012 // shouldn't happen
2013 assert(0);
2014 }
2015 }
2016}
2017
2018void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
2019 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2020 compile_node(comp, pns->nodes[0]);
2021 for (int i = 1; i + 1 < num_nodes; i += 2) {
2022 compile_node(comp, pns->nodes[i + 1]);
2023 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
2024 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
2025 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
2026 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
2027 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
2028 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
2029 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
2030 EMIT(binary_op, RT_BINARY_OP_MODULO);
2031 } else {
2032 // shouldn't happen
2033 assert(0);
2034 }
2035 }
2036}
2037
2038void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2039 compile_node(comp, pns->nodes[1]);
2040 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
2041 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
2042 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
2043 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
2044 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
2045 EMIT(unary_op, RT_UNARY_OP_INVERT);
2046 } else {
2047 // shouldn't happen
2048 assert(0);
2049 }
2050}
2051
2052void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
2053 // function to call is on top of stack
2054
2055 int old_n_arg_keyword = comp->n_arg_keyword;
2056 bool old_have_star_arg = comp->have_star_arg;
2057 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
2058 comp->n_arg_keyword = 0;
2059 comp->have_star_arg = false;
2060 comp->have_dbl_star_arg = false;
2061
2062 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
2063
2064 // compute number of positional arguments
2065 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
2066 if (comp->have_star_arg) {
2067 n_positional -= 1;
2068 }
2069 if (comp->have_dbl_star_arg) {
2070 n_positional -= 1;
2071 }
2072
2073 if (is_method_call) {
2074 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
2075 } else {
2076 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
2077 }
2078
2079 comp->n_arg_keyword = old_n_arg_keyword;
2080 comp->have_star_arg = old_have_star_arg;
2081 comp->have_dbl_star_arg = old_have_dbl_star_arg;
2082}
2083
2084void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
2085 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2086 for (int i = 0; i < num_nodes; i++) {
2087 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)) {
2088 // optimisation for method calls a.f(...), following PyPy
2089 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
2090 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
2091 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
2092 compile_trailer_paren_helper(comp, pns_paren, true);
2093 i += 1;
2094 } else {
2095 compile_node(comp, pns->nodes[i]);
2096 }
2097 }
2098}
2099
2100void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2101 compile_node(comp, pns->nodes[0]);
2102 EMIT(binary_op, RT_BINARY_OP_POWER);
2103}
2104
2105void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
2106 // a list of strings
Damien63321742013-12-10 17:41:49 +00002107
2108 // check type of list (string or bytes) and count total number of bytes
Damien429d7192013-10-04 19:53:11 +01002109 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
Damien63321742013-12-10 17:41:49 +00002110 int n_bytes = 0;
2111 int string_kind = PY_PARSE_NODE_NULL;
Damien429d7192013-10-04 19:53:11 +01002112 for (int i = 0; i < n; i++) {
Damien429d7192013-10-04 19:53:11 +01002113 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
Damien63321742013-12-10 17:41:49 +00002114 int pn_kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]);
2115 assert(pn_kind == PY_PARSE_NODE_STRING || pn_kind == PY_PARSE_NODE_BYTES);
2116 if (i == 0) {
2117 string_kind = pn_kind;
2118 } else if (pn_kind != string_kind) {
2119 printf("SyntaxError: cannot mix bytes and nonbytes literals\n");
2120 return;
2121 }
Damien429d7192013-10-04 19:53:11 +01002122 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
Damien63321742013-12-10 17:41:49 +00002123 n_bytes += strlen(str);
Damien429d7192013-10-04 19:53:11 +01002124 }
Damien63321742013-12-10 17:41:49 +00002125
2126 // allocate memory for concatenated string/bytes
2127 char *cat_str = m_new(char, n_bytes + 1);
2128 cat_str[0] = '\0';
2129
2130 // concatenate string/bytes
2131 for (int i = 0; i < n; i++) {
2132 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
2133 strcat(cat_str, str);
2134 }
2135
2136 EMIT(load_const_str, qstr_from_str_take(cat_str), string_kind == PY_PARSE_NODE_BYTES);
Damien429d7192013-10-04 19:53:11 +01002137}
2138
2139// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
2140void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
2141 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2142 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2143 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2144
2145 if (comp->pass == PASS_1) {
2146 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01002147 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 +01002148 // store the comprehension scope so the compiling function (this one) can use it at each pass
2149 pns_comp_for->nodes[3] = (py_parse_node_t)s;
2150 }
2151
2152 // get the scope for this comprehension
2153 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
2154
2155 // compile the comprehension
2156 close_over_variables_etc(comp, this_scope, 0, 0);
2157
2158 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
2159 EMIT(get_iter);
2160 EMIT(call_function, 1, 0, false, false);
2161}
2162
2163void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2164 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2165 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01002166 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
2167 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2168 pns = (py_parse_node_struct_t*)pns->nodes[0];
2169 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
2170 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
2171 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2172 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
2173 // tuple of one item, with trailing comma
2174 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01002175 c_tuple(comp, pns->nodes[0], NULL);
2176 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
2177 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01002178 c_tuple(comp, pns->nodes[0], pns2);
2179 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2180 // generator expression
2181 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2182 } else {
2183 // tuple with 2 items
2184 goto tuple_with_2_items;
2185 }
2186 } else {
2187 // tuple with 2 items
2188 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01002189 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
2190 }
2191 } else {
2192 // parenthesis around a single item, is just that item
2193 compile_node(comp, pns->nodes[0]);
2194 }
2195}
2196
2197void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2198 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2199 // empty list
2200 EMIT(build_list, 0);
2201 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2202 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
2203 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
2204 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
2205 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
2206 // list of one item, with trailing comma
2207 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
2208 compile_node(comp, pns2->nodes[0]);
2209 EMIT(build_list, 1);
2210 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
2211 // list of many items
2212 compile_node(comp, pns2->nodes[0]);
2213 compile_generic_all_nodes(comp, pns3);
2214 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2215 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2216 // list comprehension
2217 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2218 } else {
2219 // list with 2 items
2220 goto list_with_2_items;
2221 }
2222 } else {
2223 // list with 2 items
2224 list_with_2_items:
2225 compile_node(comp, pns2->nodes[0]);
2226 compile_node(comp, pns2->nodes[1]);
2227 EMIT(build_list, 2);
2228 }
2229 } else {
2230 // list with 1 item
2231 compile_node(comp, pns->nodes[0]);
2232 EMIT(build_list, 1);
2233 }
2234}
2235
2236void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2237 py_parse_node_t pn = pns->nodes[0];
2238 if (PY_PARSE_NODE_IS_NULL(pn)) {
2239 // empty dict
2240 EMIT(build_map, 0);
2241 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2242 pns = (py_parse_node_struct_t*)pn;
2243 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2244 // dict with one element
2245 EMIT(build_map, 1);
2246 compile_node(comp, pn);
2247 EMIT(store_map);
2248 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2249 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2250 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2251 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2252 // dict/set with multiple elements
2253
2254 // get tail elements (2nd, 3rd, ...)
2255 py_parse_node_t *nodes;
2256 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2257
2258 // first element sets whether it's a dict or set
2259 bool is_dict;
2260 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2261 // a dictionary
2262 EMIT(build_map, 1 + n);
2263 compile_node(comp, pns->nodes[0]);
2264 EMIT(store_map);
2265 is_dict = true;
2266 } else {
2267 // a set
2268 compile_node(comp, pns->nodes[0]); // 1st value of set
2269 is_dict = false;
2270 }
2271
2272 // process rest of elements
2273 for (int i = 0; i < n; i++) {
2274 py_parse_node_t pn = nodes[i];
2275 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2276 compile_node(comp, pn);
2277 if (is_dict) {
2278 if (!is_key_value) {
2279 printf("SyntaxError?: expecting key:value for dictionary");
2280 return;
2281 }
2282 EMIT(store_map);
2283 } else {
2284 if (is_key_value) {
2285 printf("SyntaxError?: expecting just a value for set");
2286 return;
2287 }
2288 }
2289 }
2290
2291 // if it's a set, build it
2292 if (!is_dict) {
2293 EMIT(build_set, 1 + n);
2294 }
2295 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2296 // dict/set comprehension
2297 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2298 // a dictionary comprehension
2299 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2300 } else {
2301 // a set comprehension
2302 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2303 }
2304 } else {
2305 // shouldn't happen
2306 assert(0);
2307 }
2308 } else {
2309 // set with one element
2310 goto set_with_one_element;
2311 }
2312 } else {
2313 // set with one element
2314 set_with_one_element:
2315 compile_node(comp, pn);
2316 EMIT(build_set, 1);
2317 }
2318}
2319
2320void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2321 compile_trailer_paren_helper(comp, pns, false);
2322}
2323
2324void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2325 // object who's index we want is on top of stack
2326 compile_node(comp, pns->nodes[0]); // the index
2327 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2328}
2329
2330void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2331 // object who's attribute we want is on top of stack
2332 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2333}
2334
2335void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2336 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2337 py_parse_node_t pn = pns->nodes[0];
2338 if (PY_PARSE_NODE_IS_NULL(pn)) {
2339 // [?:]
2340 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2341 EMIT(build_slice, 2);
2342 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2343 pns = (py_parse_node_struct_t*)pn;
2344 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2345 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2346 pn = pns->nodes[0];
2347 if (PY_PARSE_NODE_IS_NULL(pn)) {
2348 // [?::]
2349 EMIT(build_slice, 2);
2350 } else {
2351 // [?::x]
2352 compile_node(comp, pn);
2353 EMIT(build_slice, 3);
2354 }
2355 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2356 compile_node(comp, pns->nodes[0]);
2357 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2358 pns = (py_parse_node_struct_t*)pns->nodes[1];
2359 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2360 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2361 // [?:x:]
2362 EMIT(build_slice, 2);
2363 } else {
2364 // [?:x:x]
2365 compile_node(comp, pns->nodes[0]);
2366 EMIT(build_slice, 3);
2367 }
2368 } else {
2369 // [?:x]
2370 compile_node(comp, pn);
2371 EMIT(build_slice, 2);
2372 }
2373 } else {
2374 // [?:x]
2375 compile_node(comp, pn);
2376 EMIT(build_slice, 2);
2377 }
2378}
2379
2380void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2381 compile_node(comp, pns->nodes[0]); // start of slice
2382 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2383 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2384}
2385
2386void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2387 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2388 compile_subscript_3_helper(comp, pns);
2389}
2390
2391void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2392 // if this is called then we are compiling a dict key:value pair
2393 compile_node(comp, pns->nodes[1]); // value
2394 compile_node(comp, pns->nodes[0]); // key
2395}
2396
2397void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002398 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002399 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002400 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002401}
2402
2403void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2404 if (comp->have_star_arg) {
2405 printf("SyntaxError?: can't have multiple *x\n");
2406 return;
2407 }
2408 comp->have_star_arg = true;
2409 compile_node(comp, pns->nodes[0]);
2410}
2411
2412void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2413 if (comp->have_dbl_star_arg) {
2414 printf("SyntaxError?: can't have multiple **x\n");
2415 return;
2416 }
2417 comp->have_dbl_star_arg = true;
2418 compile_node(comp, pns->nodes[0]);
2419}
2420
2421void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2422 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2423 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2424 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2425 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2426 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2427 return;
2428 }
2429 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2430 compile_node(comp, pns2->nodes[0]);
2431 comp->n_arg_keyword += 1;
2432 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2433 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2434 } else {
2435 // shouldn't happen
2436 assert(0);
2437 }
2438}
2439
2440void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2441 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2442 printf("SyntaxError: 'yield' outside function\n");
2443 return;
2444 }
2445 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2446 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2447 EMIT(yield_value);
2448 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2449 pns = (py_parse_node_struct_t*)pns->nodes[0];
2450 compile_node(comp, pns->nodes[0]);
2451 EMIT(get_iter);
2452 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2453 EMIT(yield_from);
2454 } else {
2455 compile_node(comp, pns->nodes[0]);
2456 EMIT(yield_value);
2457 }
2458}
2459
2460typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2461static compile_function_t compile_function[] = {
2462 NULL,
2463#define nc NULL
2464#define c(f) compile_##f
2465#define DEF_RULE(rule, comp, kind, arg...) comp,
2466#include "grammar.h"
2467#undef nc
2468#undef c
2469#undef DEF_RULE
2470};
2471
2472void compile_node(compiler_t *comp, py_parse_node_t pn) {
2473 if (PY_PARSE_NODE_IS_NULL(pn)) {
2474 // pass
2475 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2476 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2477 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002478 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002479 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2480 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2481 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2482 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2483 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002484 case PY_PARSE_NODE_TOKEN:
2485 if (arg == PY_TOKEN_NEWLINE) {
2486 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
Damien5ac1b2e2013-10-18 19:58:12 +01002487 // or when single_input lets through a NEWLINE (user enters a blank line)
Damien91d387d2013-10-09 15:09:52 +01002488 // do nothing
2489 } else {
2490 EMIT(load_const_tok, arg);
2491 }
2492 break;
Damien429d7192013-10-04 19:53:11 +01002493 default: assert(0);
2494 }
2495 } else {
2496 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2497 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2498 if (f == NULL) {
2499 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
Damien5ac1b2e2013-10-18 19:58:12 +01002500 py_parse_node_show(pn, 0);
Damien429d7192013-10-04 19:53:11 +01002501 assert(0);
2502 } else {
2503 f(comp, pns);
2504 }
2505 }
2506}
2507
2508void 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) {
2509 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002510 qstr param_name = 0;
2511 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002512 if (PY_PARSE_NODE_IS_ID(pn)) {
2513 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002514 if (comp->have_bare_star) {
2515 // comes after a bare star, so doesn't count as a parameter
2516 } else {
2517 comp->scope_cur->num_params += 1;
2518 }
Damienb14de212013-10-06 00:28:28 +01002519 } else {
2520 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2521 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2522 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002523 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002524 //int node_index = 1; unused
2525 if (allow_annotations) {
2526 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2527 // this parameter has an annotation
2528 pn_annotation = pns->nodes[1];
2529 }
2530 //node_index = 2; unused
2531 }
2532 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2533 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2534 // this parameter has a default value
2535 if (comp->have_bare_star) {
2536 comp->scope_cur->num_dict_params += 1;
2537 } else {
2538 comp->scope_cur->num_default_params += 1;
2539 }
2540 }
2541 */
2542 if (comp->have_bare_star) {
2543 // comes after a bare star, so doesn't count as a parameter
2544 } else {
2545 comp->scope_cur->num_params += 1;
2546 }
2547 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2548 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2549 // bare star
2550 // TODO see http://www.python.org/dev/peps/pep-3102/
2551 comp->have_bare_star = true;
2552 //assert(comp->scope_cur->num_dict_params == 0);
2553 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2554 // named star
2555 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2556 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2557 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2558 // named star with annotation
2559 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2560 pns = (py_parse_node_struct_t*)pns->nodes[0];
2561 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2562 pn_annotation = pns->nodes[1];
2563 } else {
2564 // shouldn't happen
2565 assert(0);
2566 }
2567 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002568 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002569 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2570 // this parameter has an annotation
2571 pn_annotation = pns->nodes[1];
2572 }
2573 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002574 } else {
Damienb14de212013-10-06 00:28:28 +01002575 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002576 assert(0);
2577 }
Damien429d7192013-10-04 19:53:11 +01002578 }
2579
2580 if (param_name != 0) {
2581 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2582 // TODO this parameter has an annotation
2583 }
2584 bool added;
2585 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2586 if (!added) {
2587 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2588 return;
2589 }
2590 id_info->param = true;
2591 id_info->kind = ID_INFO_KIND_LOCAL;
2592 }
2593}
2594
2595void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2596 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2597}
2598
2599void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2600 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2601}
2602
2603void 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) {
2604 tail_recursion:
2605 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2606 // no more nested if/for; compile inner expression
2607 compile_node(comp, pn_inner_expr);
2608 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2609 EMIT(list_append, for_depth + 2);
2610 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2611 EMIT(map_add, for_depth + 2);
2612 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2613 EMIT(set_add, for_depth + 2);
2614 } else {
2615 EMIT(yield_value);
2616 EMIT(pop_top);
2617 }
2618 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2619 // if condition
2620 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2621 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2622 pn_iter = pns_comp_if->nodes[1];
2623 goto tail_recursion;
2624 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2625 // for loop
2626 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2627 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002628 int l_end2 = comp_next_label(comp);
2629 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002630 EMIT(get_iter);
2631 EMIT(label_assign, l_top2);
2632 EMIT(for_iter, l_end2);
2633 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2634 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2635 EMIT(jump, l_top2);
2636 EMIT(label_assign, l_end2);
2637 EMIT(for_iter_end);
2638 } else {
2639 // shouldn't happen
2640 assert(0);
2641 }
2642}
2643
2644void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2645 // see http://www.python.org/dev/peps/pep-0257/
2646
2647 // look for the first statement
2648 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
Damiene388f102013-12-12 15:24:38 +00002649 // a statement; fall through
Damien429d7192013-10-04 19:53:11 +01002650 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
Damiene388f102013-12-12 15:24:38 +00002651 // file input; find the first non-newline node
2652 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2653 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2654 for (int i = 0; i < num_nodes; i++) {
2655 pn = pns->nodes[i];
2656 if (!(PY_PARSE_NODE_IS_LEAF(pn) && PY_PARSE_NODE_LEAF_KIND(pn) == PY_PARSE_NODE_TOKEN && PY_PARSE_NODE_LEAF_ARG(pn) == PY_TOKEN_NEWLINE)) {
2657 // not a newline, so this is the first statement; finish search
2658 break;
2659 }
2660 }
2661 // if we didn't find a non-newline then it's okay to fall through; pn will be a newline and so doc-string test below will fail gracefully
Damien429d7192013-10-04 19:53:11 +01002662 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
Damiene388f102013-12-12 15:24:38 +00002663 // a list of statements; get the first one
Damien429d7192013-10-04 19:53:11 +01002664 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2665 } else {
2666 return;
2667 }
2668
2669 // check the first statement for a doc string
2670 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2671 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2672 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2673 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2674 if (kind == PY_PARSE_NODE_STRING) {
2675 compile_node(comp, pns->nodes[0]); // a doc string
2676 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002677 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002678 }
2679 }
2680 }
2681}
2682
2683void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2684 comp->pass = pass;
2685 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002686 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002687 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002688
2689 if (comp->pass == PASS_1) {
2690 scope->stack_size = 0;
2691 }
2692
Damien5ac1b2e2013-10-18 19:58:12 +01002693#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01002694 if (comp->pass == PASS_3) {
Damien429d7192013-10-04 19:53:11 +01002695 scope_print_info(scope);
2696 }
Damien5ac1b2e2013-10-18 19:58:12 +01002697#endif
Damien429d7192013-10-04 19:53:11 +01002698
2699 // compile
2700 if (scope->kind == SCOPE_MODULE) {
Damien5ac1b2e2013-10-18 19:58:12 +01002701 if (!comp->is_repl) {
2702 check_for_doc_string(comp, scope->pn);
2703 }
Damien429d7192013-10-04 19:53:11 +01002704 compile_node(comp, scope->pn);
2705 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2706 EMIT(return_value);
2707 } else if (scope->kind == SCOPE_FUNCTION) {
2708 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2709 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2710 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2711
2712 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002713 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002714 if (comp->pass == PASS_1) {
2715 comp->have_bare_star = false;
2716 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2717 }
2718
Damien826005c2013-10-05 23:17:28 +01002719 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002720
2721 compile_node(comp, pns->nodes[3]); // 3 is function body
2722 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002723 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002724 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2725 EMIT(return_value);
2726 }
2727 } else if (scope->kind == SCOPE_LAMBDA) {
2728 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2729 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2730 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2731
2732 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002733 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002734 if (comp->pass == PASS_1) {
2735 comp->have_bare_star = false;
2736 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2737 }
2738
2739 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2740 EMIT(return_value);
2741 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2742 // a bit of a hack at the moment
2743
2744 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2745 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2746 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2747 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2748 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2749
Damien6cdd3af2013-10-05 18:08:26 +01002750 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002751 if (comp->pass == PASS_1) {
2752 bool added;
2753 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2754 assert(added);
2755 id_info->kind = ID_INFO_KIND_LOCAL;
2756 scope->num_params = 1;
2757 }
2758
2759 if (scope->kind == SCOPE_LIST_COMP) {
2760 EMIT(build_list, 0);
2761 } else if (scope->kind == SCOPE_DICT_COMP) {
2762 EMIT(build_map, 0);
2763 } else if (scope->kind == SCOPE_SET_COMP) {
2764 EMIT(build_set, 0);
2765 }
2766
Damienb05d7072013-10-05 13:37:10 +01002767 int l_end = comp_next_label(comp);
2768 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002769 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002770 EMIT(label_assign, l_top);
2771 EMIT(for_iter, l_end);
2772 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2773 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2774 EMIT(jump, l_top);
2775 EMIT(label_assign, l_end);
2776 EMIT(for_iter_end);
2777
2778 if (scope->kind == SCOPE_GEN_EXPR) {
2779 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2780 }
2781 EMIT(return_value);
2782 } else {
2783 assert(scope->kind == SCOPE_CLASS);
2784 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2785 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2786 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2787
2788 if (comp->pass == PASS_1) {
2789 bool added;
2790 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2791 assert(added);
2792 id_info->kind = ID_INFO_KIND_LOCAL;
2793 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2794 assert(added);
2795 id_info->kind = ID_INFO_KIND_LOCAL;
2796 id_info->param = true;
2797 scope->num_params = 1; // __locals__ is the parameter
2798 }
2799
Damien4b03e772013-10-05 14:17:09 +01002800 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002801 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002802 EMIT(load_id, comp->qstr___name__);
2803 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002804 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002805 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002806
2807 check_for_doc_string(comp, pns->nodes[2]);
2808 compile_node(comp, pns->nodes[2]); // 2 is class body
2809
2810 id_info_t *id = scope_find(scope, comp->qstr___class__);
2811 assert(id != NULL);
2812 if (id->kind == ID_INFO_KIND_LOCAL) {
2813 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2814 } else {
Damien27fb45e2013-10-20 15:07:49 +01002815 EMIT(load_closure, comp->qstr___class__, 0); // XXX check this is the correct local num
Damien429d7192013-10-04 19:53:11 +01002816 }
2817 EMIT(return_value);
2818 }
2819
Damien415eb6f2013-10-05 12:19:06 +01002820 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002821
Damien826005c2013-10-05 23:17:28 +01002822}
2823
2824void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2825 comp->pass = pass;
2826 comp->scope_cur = scope;
2827 comp->next_label = 1;
2828
2829 if (scope->kind != SCOPE_FUNCTION) {
2830 printf("Error: inline assembler must be a function\n");
2831 return;
2832 }
2833
Damiena2f2f7d2013-10-06 00:14:13 +01002834 if (comp->pass > PASS_1) {
2835 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2836 }
2837
Damien826005c2013-10-05 23:17:28 +01002838 // get the function definition parse node
2839 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2840 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2841 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2842
Damiena2f2f7d2013-10-06 00:14:13 +01002843 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002844
Damiena2f2f7d2013-10-06 00:14:13 +01002845 // parameters are in pns->nodes[1]
2846 if (comp->pass == PASS_2) {
2847 py_parse_node_t *pn_params;
2848 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2849 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2850 }
2851
Damien826005c2013-10-05 23:17:28 +01002852 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2853
2854 py_parse_node_t pn_body = pns->nodes[3]; // body
2855 py_parse_node_t *nodes;
2856 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2857
Damien826005c2013-10-05 23:17:28 +01002858 if (comp->pass == PASS_3) {
2859 //printf("----\n");
2860 scope_print_info(scope);
2861 }
2862
2863 for (int i = 0; i < num; i++) {
2864 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2865 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2866 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2867 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2868 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2869 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2870 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2871 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2872 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2873 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2874 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2875 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2876 py_parse_node_t *pn_arg;
2877 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2878
2879 // emit instructions
2880 if (strcmp(qstr_str(op), "label") == 0) {
2881 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2882 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2883 return;
2884 }
2885 int lab = comp_next_label(comp);
2886 if (pass > PASS_1) {
2887 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2888 }
2889 } else {
2890 if (pass > PASS_1) {
2891 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2892 }
2893 }
2894 }
2895
2896 if (comp->pass > PASS_1) {
2897 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002898 }
Damien429d7192013-10-04 19:53:11 +01002899}
2900
2901void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2902 // in functions, turn implicit globals into explicit globals
2903 // compute num_locals, and the index of each local
2904 scope->num_locals = 0;
2905 for (int i = 0; i < scope->id_info_len; i++) {
2906 id_info_t *id = &scope->id_info[i];
2907 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2908 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2909 continue;
2910 }
2911 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2912 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2913 }
Damien9ecbcff2013-12-11 00:41:43 +00002914 // note: params always count for 1 local, even if they are a cell
Damien429d7192013-10-04 19:53:11 +01002915 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2916 id->local_num = scope->num_locals;
2917 scope->num_locals += 1;
Damien9ecbcff2013-12-11 00:41:43 +00002918 }
2919 }
2920
2921 // compute the index of cell vars (freevars[idx] in CPython)
2922 int num_closed = 0;
2923 for (int i = 0; i < scope->id_info_len; i++) {
2924 id_info_t *id = &scope->id_info[i];
2925 if (id->kind == ID_INFO_KIND_CELL) {
Damien318aec62013-12-10 18:28:17 +00002926 id->local_num = num_closed;
Damien9ecbcff2013-12-11 00:41:43 +00002927#if !MICROPY_EMIT_CPYTHON
2928 // the cells come right after the fast locals (CPython doesn't add this offset)
2929 id->local_num += scope->num_locals;
2930#endif
Damien318aec62013-12-10 18:28:17 +00002931 num_closed += 1;
Damien9ecbcff2013-12-11 00:41:43 +00002932 }
2933 }
2934 scope->num_cells = num_closed;
2935
2936 // compute the index of free vars (freevars[idx] in CPython)
2937 // make sure they are in the order of the parent scope
2938 if (scope->parent != NULL) {
2939 int num_free = 0;
2940 for (int i = 0; i < scope->parent->id_info_len; i++) {
2941 id_info_t *id = &scope->parent->id_info[i];
2942 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2943 for (int j = 0; j < scope->id_info_len; j++) {
2944 id_info_t *id2 = &scope->id_info[j];
2945 if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
2946 id2->local_num = num_closed + num_free;
2947#if !MICROPY_EMIT_CPYTHON
2948 // the frees come right after the cells (CPython doesn't add this offset)
2949 id2->local_num += scope->num_locals;
2950#endif
2951 num_free += 1;
2952 }
2953 }
2954 }
Damien429d7192013-10-04 19:53:11 +01002955 }
2956 }
2957
2958 // compute flags
2959 //scope->flags = 0; since we set some things in parameters
2960 if (scope->kind != SCOPE_MODULE) {
2961 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2962 }
2963 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) {
2964 assert(scope->parent != NULL);
2965 scope->flags |= SCOPE_FLAG_OPTIMISED;
2966
2967 // TODO possibly other ways it can be nested
2968 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2969 scope->flags |= SCOPE_FLAG_NESTED;
2970 }
2971 }
2972 int num_free = 0;
2973 for (int i = 0; i < scope->id_info_len; i++) {
2974 id_info_t *id = &scope->id_info[i];
2975 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2976 num_free += 1;
2977 }
2978 }
2979 if (num_free == 0) {
2980 scope->flags |= SCOPE_FLAG_NOFREE;
2981 }
2982}
2983
Damien5ac1b2e2013-10-18 19:58:12 +01002984bool py_compile(py_parse_node_t pn, bool is_repl) {
Damien429d7192013-10-04 19:53:11 +01002985 compiler_t *comp = m_new(compiler_t, 1);
2986
Damien6cdd3af2013-10-05 18:08:26 +01002987 comp->qstr___class__ = qstr_from_str_static("__class__");
2988 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2989 comp->qstr___name__ = qstr_from_str_static("__name__");
2990 comp->qstr___module__ = qstr_from_str_static("__module__");
2991 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2992 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2993 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2994 comp->qstr_micropython = qstr_from_str_static("micropython");
Damien5ac1b2e2013-10-18 19:58:12 +01002995 comp->qstr_byte_code = qstr_from_str_static("byte_code");
Damien6cdd3af2013-10-05 18:08:26 +01002996 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002997 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002998 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damiend7933892013-11-28 19:12:18 +00002999 comp->qstr_range = qstr_from_str_static("range");
Damien429d7192013-10-04 19:53:11 +01003000
Damien5ac1b2e2013-10-18 19:58:12 +01003001 comp->is_repl = is_repl;
3002 comp->had_error = false;
3003
Damien429d7192013-10-04 19:53:11 +01003004 comp->break_label = 0;
3005 comp->continue_label = 0;
3006 comp->except_nest_level = 0;
3007 comp->scope_head = NULL;
3008 comp->scope_cur = NULL;
3009
Damien826005c2013-10-05 23:17:28 +01003010 // optimise constants
Damien429d7192013-10-04 19:53:11 +01003011 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01003012
3013 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01003014 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01003015
Damien826005c2013-10-05 23:17:28 +01003016 // compile pass 1
3017 comp->emit = emit_pass1_new(comp->qstr___class__);
3018 comp->emit_method_table = &emit_pass1_method_table;
3019 comp->emit_inline_asm = NULL;
3020 comp->emit_inline_asm_method_table = NULL;
3021 uint max_num_labels = 0;
Damien5ac1b2e2013-10-18 19:58:12 +01003022 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01003023 if (false) {
Damien3ef4abb2013-10-12 16:53:13 +01003024#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003025 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01003026 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01003027#endif
Damien826005c2013-10-05 23:17:28 +01003028 } else {
3029 compile_scope(comp, s, PASS_1);
3030 }
3031
3032 // update maximim number of labels needed
3033 if (comp->next_label > max_num_labels) {
3034 max_num_labels = comp->next_label;
3035 }
Damien429d7192013-10-04 19:53:11 +01003036 }
3037
Damien826005c2013-10-05 23:17:28 +01003038 // compute some things related to scope and identifiers
Damien5ac1b2e2013-10-18 19:58:12 +01003039 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damien429d7192013-10-04 19:53:11 +01003040 compile_scope_compute_things(comp, s);
3041 }
3042
Damien826005c2013-10-05 23:17:28 +01003043 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01003044 emit_pass1_free(comp->emit);
3045
Damien826005c2013-10-05 23:17:28 +01003046 // compile pass 2 and 3
Damien3ef4abb2013-10-12 16:53:13 +01003047#if !MICROPY_EMIT_CPYTHON
Damien6cdd3af2013-10-05 18:08:26 +01003048 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01003049 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01003050#endif
Damien3ef4abb2013-10-12 16:53:13 +01003051#if MICROPY_EMIT_INLINE_THUMB
Damien826005c2013-10-05 23:17:28 +01003052 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01003053#endif
Damien5ac1b2e2013-10-18 19:58:12 +01003054 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01003055 if (false) {
3056 // dummy
3057
Damien3ef4abb2013-10-12 16:53:13 +01003058#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003059 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
3060 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01003061 if (emit_inline_thumb == NULL) {
3062 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
3063 }
3064 comp->emit = NULL;
3065 comp->emit_method_table = NULL;
3066 comp->emit_inline_asm = emit_inline_thumb;
3067 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
3068 compile_scope_inline_asm(comp, s, PASS_2);
3069 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01003070#endif
3071
Damien826005c2013-10-05 23:17:28 +01003072 } else {
Damienc025ebb2013-10-12 14:30:21 +01003073
3074 // choose the emit type
3075
Damien3ef4abb2013-10-12 16:53:13 +01003076#if MICROPY_EMIT_CPYTHON
Damienc025ebb2013-10-12 14:30:21 +01003077 comp->emit = emit_cpython_new(max_num_labels);
3078 comp->emit_method_table = &emit_cpython_method_table;
3079#else
Damien826005c2013-10-05 23:17:28 +01003080 switch (s->emit_options) {
3081 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01003082 case EMIT_OPT_VIPER:
Damien3ef4abb2013-10-12 16:53:13 +01003083#if MICROPY_EMIT_X64
Damiendc833822013-10-06 01:01:01 +01003084 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01003085 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01003086 }
Damien13ed3a62013-10-08 09:05:10 +01003087 comp->emit_method_table = &emit_native_x64_method_table;
Damien3ef4abb2013-10-12 16:53:13 +01003088#elif MICROPY_EMIT_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003089 if (emit_native == NULL) {
3090 emit_native = emit_native_thumb_new(max_num_labels);
3091 }
3092 comp->emit_method_table = &emit_native_thumb_method_table;
3093#endif
3094 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01003095 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01003096 break;
3097
Damien826005c2013-10-05 23:17:28 +01003098 default:
3099 if (emit_bc == NULL) {
3100 emit_bc = emit_bc_new(max_num_labels);
3101 }
3102 comp->emit = emit_bc;
3103 comp->emit_method_table = &emit_bc_method_table;
3104 break;
3105 }
Damienc025ebb2013-10-12 14:30:21 +01003106#endif
3107
3108 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01003109 compile_scope(comp, s, PASS_2);
3110 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01003111 }
Damien429d7192013-10-04 19:53:11 +01003112 }
3113
3114 m_free(comp);
Damien5ac1b2e2013-10-18 19:58:12 +01003115
3116 return !comp->had_error;
Damien429d7192013-10-04 19:53:11 +01003117}