blob: 42bac7d28acaea7d7472e46dd3eb97b59b11dd4a [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_str, vstr_str(vstr));
Damien02f89412013-12-12 15:13:36 +0000387 vstr_free(vstr);
Damien429d7192013-10-04 19:53:11 +0100388 } else {
389 if (!PY_PARSE_NODE_IS_NULL(pn)) {
390 compile_node(comp, pn);
391 }
392 for (int i = 0; i < n; i++) {
393 compile_node(comp, pns_list->nodes[i]);
394 }
395 EMIT(build_tuple, total);
396 }
397}
Damien3a205172013-10-12 15:01:56 +0100398#endif
399
400// funnelling all tuple creations through this function is purely so we can optionally agree with CPython
401void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
Damien3ef4abb2013-10-12 16:53:13 +0100402#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100403 cpython_c_tuple(comp, pn, pns_list);
404#else
405 int total = 0;
406 if (!PY_PARSE_NODE_IS_NULL(pn)) {
407 compile_node(comp, pn);
408 total += 1;
409 }
410 if (pns_list != NULL) {
411 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
412 for (int i = 0; i < n; i++) {
413 compile_node(comp, pns_list->nodes[i]);
414 }
415 total += n;
416 }
417 EMIT(build_tuple, total);
418#endif
419}
Damien429d7192013-10-04 19:53:11 +0100420
421void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
422 // a simple tuple expression
Damien429d7192013-10-04 19:53:11 +0100423 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
424}
425
Damien3a205172013-10-12 15:01:56 +0100426static bool node_is_const_false(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100427 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
428 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
429}
430
Damien3a205172013-10-12 15:01:56 +0100431static bool node_is_const_true(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100432 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);
433}
434
Damien3ef4abb2013-10-12 16:53:13 +0100435#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100436// the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
437static 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 +0100438 if (node_is_const_false(pn)) {
439 if (jump_if == false) {
440 EMIT(jump, label);
441 }
442 return;
443 } else if (node_is_const_true(pn)) {
444 if (jump_if == true) {
445 EMIT(jump, label);
446 }
447 return;
448 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
449 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
450 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
451 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
452 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100453 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100454 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100455 cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
Damien429d7192013-10-04 19:53:11 +0100456 }
Damien3a205172013-10-12 15:01:56 +0100457 cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100458 EMIT(label_assign, label2);
459 } else {
460 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100461 cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100462 }
463 }
464 return;
465 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
466 if (jump_if == false) {
467 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100468 cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100469 }
470 } else {
Damienb05d7072013-10-05 13:37:10 +0100471 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100472 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100473 cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
Damien429d7192013-10-04 19:53:11 +0100474 }
Damien3a205172013-10-12 15:01:56 +0100475 cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100476 EMIT(label_assign, label2);
477 }
478 return;
479 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
Damien3a205172013-10-12 15:01:56 +0100480 cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true);
Damien429d7192013-10-04 19:53:11 +0100481 return;
482 }
483 }
484
485 // nothing special, fall back to default compiling for node and jump
486 compile_node(comp, pn);
487 if (jump_if == false) {
488 EMIT(pop_jump_if_false, label);
489 } else {
490 EMIT(pop_jump_if_true, label);
491 }
492}
Damien3a205172013-10-12 15:01:56 +0100493#endif
Damien429d7192013-10-04 19:53:11 +0100494
Damien3a205172013-10-12 15:01:56 +0100495static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
Damien3ef4abb2013-10-12 16:53:13 +0100496#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100497 cpython_c_if_cond(comp, pn, jump_if, label, false);
498#else
499 if (node_is_const_false(pn)) {
500 if (jump_if == false) {
501 EMIT(jump, label);
502 }
503 return;
504 } else if (node_is_const_true(pn)) {
505 if (jump_if == true) {
506 EMIT(jump, label);
507 }
508 return;
509 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
510 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
511 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
512 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
513 if (jump_if == false) {
514 int label2 = comp_next_label(comp);
515 for (int i = 0; i < n - 1; i++) {
516 c_if_cond(comp, pns->nodes[i], true, label2);
517 }
518 c_if_cond(comp, pns->nodes[n - 1], false, label);
519 EMIT(label_assign, label2);
520 } else {
521 for (int i = 0; i < n; i++) {
522 c_if_cond(comp, pns->nodes[i], true, label);
523 }
524 }
525 return;
526 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
527 if (jump_if == false) {
528 for (int i = 0; i < n; i++) {
529 c_if_cond(comp, pns->nodes[i], false, label);
530 }
531 } else {
532 int label2 = comp_next_label(comp);
533 for (int i = 0; i < n - 1; i++) {
534 c_if_cond(comp, pns->nodes[i], false, label2);
535 }
536 c_if_cond(comp, pns->nodes[n - 1], true, label);
537 EMIT(label_assign, label2);
538 }
539 return;
540 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
541 c_if_cond(comp, pns->nodes[0], !jump_if, label);
542 return;
543 }
544 }
545
546 // nothing special, fall back to default compiling for node and jump
547 compile_node(comp, pn);
548 if (jump_if == false) {
549 EMIT(pop_jump_if_false, label);
550 } else {
551 EMIT(pop_jump_if_true, label);
552 }
553#endif
Damien429d7192013-10-04 19:53:11 +0100554}
555
556typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
557void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
558
559void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
560 if (assign_kind != ASSIGN_AUG_STORE) {
561 compile_node(comp, pns->nodes[0]);
562 }
563
564 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
565 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
566 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
567 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
568 if (assign_kind != ASSIGN_AUG_STORE) {
569 for (int i = 0; i < n - 1; i++) {
570 compile_node(comp, pns1->nodes[i]);
571 }
572 }
573 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
574 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
575 }
576 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
577 printf("SyntaxError: can't assign to function call\n");
578 return;
579 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
580 if (assign_kind == ASSIGN_AUG_STORE) {
581 EMIT(rot_three);
582 EMIT(store_subscr);
583 } else {
584 compile_node(comp, pns1->nodes[0]);
585 if (assign_kind == ASSIGN_AUG_LOAD) {
586 EMIT(dup_top_two);
587 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
588 } else {
589 EMIT(store_subscr);
590 }
591 }
592 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
593 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
594 if (assign_kind == ASSIGN_AUG_LOAD) {
595 EMIT(dup_top);
596 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
597 } else {
598 if (assign_kind == ASSIGN_AUG_STORE) {
599 EMIT(rot_two);
600 }
601 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
602 }
603 } else {
604 // shouldn't happen
605 assert(0);
606 }
607 } else {
608 // shouldn't happen
609 assert(0);
610 }
611
612 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
613 // SyntaxError, cannot assign
614 assert(0);
615 }
616}
617
618void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
619 assert(n >= 0);
620 int have_star_index = -1;
621 for (int i = 0; i < n; i++) {
622 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
623 if (have_star_index < 0) {
624 EMIT(unpack_ex, i, n - i - 1);
625 have_star_index = i;
626 } else {
627 printf("SyntaxError: two starred expressions in assignment\n");
628 return;
629 }
630 }
631 }
632 if (have_star_index < 0) {
633 EMIT(unpack_sequence, n);
634 }
635 for (int i = 0; i < n; i++) {
636 if (i == have_star_index) {
637 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
638 } else {
639 c_assign(comp, nodes[i], ASSIGN_STORE);
640 }
641 }
642}
643
644// assigns top of stack to pn
645void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
646 tail_recursion:
647 if (PY_PARSE_NODE_IS_NULL(pn)) {
648 assert(0);
649 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
650 if (PY_PARSE_NODE_IS_ID(pn)) {
651 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
652 switch (assign_kind) {
653 case ASSIGN_STORE:
654 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100655 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100656 break;
657 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100658 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100659 break;
660 }
661 } else {
662 printf("SyntaxError: can't assign to literal\n");
663 return;
664 }
665 } else {
666 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
667 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
668 case PN_power:
669 // lhs is an index or attribute
670 c_assign_power(comp, pns, assign_kind);
671 break;
672
673 case PN_testlist_star_expr:
674 case PN_exprlist:
675 // lhs is a tuple
676 if (assign_kind != ASSIGN_STORE) {
677 goto bad_aug;
678 }
679 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
680 break;
681
682 case PN_atom_paren:
683 // lhs is something in parenthesis
684 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
685 // empty tuple
686 printf("SyntaxError: can't assign to ()\n");
687 return;
688 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
689 pns = (py_parse_node_struct_t*)pns->nodes[0];
690 goto testlist_comp;
691 } else {
692 // parenthesis around 1 item, is just that item
693 pn = pns->nodes[0];
694 goto tail_recursion;
695 }
696 break;
697
698 case PN_atom_bracket:
699 // lhs is something in brackets
700 if (assign_kind != ASSIGN_STORE) {
701 goto bad_aug;
702 }
703 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
704 // empty list, assignment allowed
705 c_assign_tuple(comp, 0, NULL);
706 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
707 pns = (py_parse_node_struct_t*)pns->nodes[0];
708 goto testlist_comp;
709 } else {
710 // brackets around 1 item
711 c_assign_tuple(comp, 1, &pns->nodes[0]);
712 }
713 break;
714
715 default:
716 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
717 assert(0);
718 }
719 return;
720
721 testlist_comp:
722 // lhs is a sequence
723 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
724 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
725 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
726 // sequence of one item, with trailing comma
727 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
728 c_assign_tuple(comp, 1, &pns->nodes[0]);
729 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
730 // sequence of many items
731 // TODO call c_assign_tuple instead
732 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
733 EMIT(unpack_sequence, 1 + n);
734 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
735 for (int i = 0; i < n; i++) {
736 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
737 }
738 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
739 // TODO not implemented
740 assert(0);
741 } else {
742 // sequence with 2 items
743 goto sequence_with_2_items;
744 }
745 } else {
746 // sequence with 2 items
747 sequence_with_2_items:
748 c_assign_tuple(comp, 2, pns->nodes);
749 }
750 return;
751 }
752 return;
753
754 bad_aug:
755 printf("SyntaxError: illegal expression for augmented assignment\n");
756}
757
758// stuff for lambda and comprehensions and generators
759void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
760 // make closed over variables, if any
Damien318aec62013-12-10 18:28:17 +0000761 // ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython)
Damien429d7192013-10-04 19:53:11 +0100762 int nfree = 0;
763 if (comp->scope_cur->kind != SCOPE_MODULE) {
Damien318aec62013-12-10 18:28:17 +0000764 for (int i = 0; i < comp->scope_cur->id_info_len; i++) {
765 id_info_t *id = &comp->scope_cur->id_info[i];
766 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
767 for (int j = 0; j < this_scope->id_info_len; j++) {
768 id_info_t *id2 = &this_scope->id_info[j];
769 if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
770 EMIT(load_closure, id->qstr, id->local_num);
771 nfree += 1;
772 }
773 }
Damien429d7192013-10-04 19:53:11 +0100774 }
775 }
776 }
777 if (nfree > 0) {
778 EMIT(build_tuple, nfree);
779 }
780
781 // make the function/closure
782 if (nfree == 0) {
783 EMIT(make_function, this_scope, n_dict_params, n_default_params);
784 } else {
785 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
786 }
787}
788
789void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100790 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
791 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100792 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
793 // this parameter has a default value
794 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
795 if (comp->have_bare_star) {
796 comp->param_pass_num_dict_params += 1;
797 if (comp->param_pass == 1) {
798 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
799 compile_node(comp, pns->nodes[2]);
800 }
801 } else {
802 comp->param_pass_num_default_params += 1;
803 if (comp->param_pass == 2) {
804 compile_node(comp, pns->nodes[2]);
805 }
806 }
807 }
Damienb14de212013-10-06 00:28:28 +0100808 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
809 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100810 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
811 // bare star
812 comp->have_bare_star = true;
813 }
814 }
815}
816
817// leaves function object on stack
818// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100819qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100820 if (comp->pass == PASS_1) {
821 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100822 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100823 // store the function scope so the compiling function can use it at each pass
824 pns->nodes[4] = (py_parse_node_t)s;
825 }
826
827 // save variables (probably don't need to do this, since we can't have nested definitions..?)
828 bool old_have_bare_star = comp->have_bare_star;
829 int old_param_pass = comp->param_pass;
830 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
831 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
832
833 // compile default parameters
834 comp->have_bare_star = false;
835 comp->param_pass = 1; // pass 1 does any default parameters after bare star
836 comp->param_pass_num_dict_params = 0;
837 comp->param_pass_num_default_params = 0;
838 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
839 comp->have_bare_star = false;
840 comp->param_pass = 2; // pass 2 does any default parameters before bare star
841 comp->param_pass_num_dict_params = 0;
842 comp->param_pass_num_default_params = 0;
843 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
844
845 // get the scope for this function
846 scope_t *fscope = (scope_t*)pns->nodes[4];
847
848 // make the function
849 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
850
851 // restore variables
852 comp->have_bare_star = old_have_bare_star;
853 comp->param_pass = old_param_pass;
854 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
855 comp->param_pass_num_default_params = old_param_pass_num_default_params;
856
857 // return its name (the 'f' in "def f(...):")
858 return fscope->simple_name;
859}
860
861// leaves class object on stack
862// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100863qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100864 if (comp->pass == PASS_1) {
865 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100866 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100867 // store the class scope so the compiling function can use it at each pass
868 pns->nodes[3] = (py_parse_node_t)s;
869 }
870
871 EMIT(load_build_class);
872
873 // scope for this class
874 scope_t *cscope = (scope_t*)pns->nodes[3];
875
876 // compile the class
877 close_over_variables_etc(comp, cscope, 0, 0);
878
879 // get its name
880 EMIT(load_const_id, cscope->simple_name);
881
882 // nodes[1] has parent classes, if any
883 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
884 // no parent classes
885 EMIT(call_function, 2, 0, false, false);
886 } else {
887 // have a parent class or classes
888 // TODO what if we have, eg, *a or **a in the parent list?
889 compile_node(comp, pns->nodes[1]);
890 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
891 }
892
893 // return its name (the 'C' in class C(...):")
894 return cscope->simple_name;
895}
896
Damien6cdd3af2013-10-05 18:08:26 +0100897// returns true if it was a built-in decorator (even if the built-in had an error)
898static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
899 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
900 return false;
901 }
902
903 if (name_len != 2) {
904 printf("SyntaxError: invalid micropython decorator\n");
905 return true;
906 }
907
908 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
Damien5ac1b2e2013-10-18 19:58:12 +0100909 if (attr == comp->qstr_byte_code) {
910 *emit_options = EMIT_OPT_BYTE_CODE;
Damience89a212013-10-15 22:25:17 +0100911#if MICROPY_EMIT_NATIVE
912 } else if (attr == comp->qstr_native) {
Damien6cdd3af2013-10-05 18:08:26 +0100913 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100914 } else if (attr == comp->qstr_viper) {
915 *emit_options = EMIT_OPT_VIPER;
Damience89a212013-10-15 22:25:17 +0100916#endif
Damien3ef4abb2013-10-12 16:53:13 +0100917#if MICROPY_EMIT_INLINE_THUMB
Damien5bfb7592013-10-05 18:41:24 +0100918 } else if (attr == comp->qstr_asm_thumb) {
919 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100920#endif
Damien6cdd3af2013-10-05 18:08:26 +0100921 } else {
Damience89a212013-10-15 22:25:17 +0100922 printf("SyntaxError: invalid micropython decorator '%s'\n", qstr_str(attr));
Damien6cdd3af2013-10-05 18:08:26 +0100923 }
924
925 return true;
926}
927
Damien429d7192013-10-04 19:53:11 +0100928void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
929 // get the list of decorators
930 py_parse_node_t *nodes;
931 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
932
Damien6cdd3af2013-10-05 18:08:26 +0100933 // inherit emit options for this function/class definition
934 uint emit_options = comp->scope_cur->emit_options;
935
936 // compile each decorator
937 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100938 for (int i = 0; i < n; i++) {
939 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
940 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100941
942 // nodes[0] contains the decorator function, which is a dotted name
943 py_parse_node_t *name_nodes;
944 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
945
946 // check for built-in decorators
947 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
948 // this was a built-in
949 num_built_in_decorators += 1;
950
951 } else {
952 // not a built-in, compile normally
953
954 // compile the decorator function
955 compile_node(comp, name_nodes[0]);
956 for (int i = 1; i < name_len; i++) {
957 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
958 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
959 }
960
961 // nodes[1] contains arguments to the decorator function, if any
962 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
963 // call the decorator function with the arguments in nodes[1]
964 compile_node(comp, pns_decorator->nodes[1]);
965 }
Damien429d7192013-10-04 19:53:11 +0100966 }
967 }
968
969 // compile the body (funcdef or classdef) and get its name
970 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
971 qstr body_name = 0;
972 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100973 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100974 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100975 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100976 } else {
977 // shouldn't happen
978 assert(0);
979 }
980
981 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100982 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100983 EMIT(call_function, 1, 0, false, false);
984 }
985
986 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100987 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100988}
989
990void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100991 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100992 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100993 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100994}
995
996void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
997 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100998 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100999 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
1000 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1001
1002 compile_node(comp, pns->nodes[0]); // base of the power node
1003
1004 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1005 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1006 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
1007 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
1008 for (int i = 0; i < n - 1; i++) {
1009 compile_node(comp, pns1->nodes[i]);
1010 }
1011 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
1012 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
1013 }
1014 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
1015 // SyntaxError: can't delete a function call
1016 assert(0);
1017 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
1018 compile_node(comp, pns1->nodes[0]);
1019 EMIT(delete_subscr);
1020 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
1021 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
1022 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
1023 } else {
1024 // shouldn't happen
1025 assert(0);
1026 }
1027 } else {
1028 // shouldn't happen
1029 assert(0);
1030 }
1031
1032 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1033 // SyntaxError, cannot delete
1034 assert(0);
1035 }
1036 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
1037 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
1038 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
1039 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1040 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
1041
1042 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1043 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1044 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
1045 // sequence of one item, with trailing comma
1046 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
1047 c_del_stmt(comp, pns->nodes[0]);
1048 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
1049 // sequence of many items
1050 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
1051 c_del_stmt(comp, pns->nodes[0]);
1052 for (int i = 0; i < n; i++) {
1053 c_del_stmt(comp, pns1->nodes[i]);
1054 }
1055 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
1056 // TODO not implemented; can't del comprehension?
1057 assert(0);
1058 } else {
1059 // sequence with 2 items
1060 goto sequence_with_2_items;
1061 }
1062 } else {
1063 // sequence with 2 items
1064 sequence_with_2_items:
1065 c_del_stmt(comp, pns->nodes[0]);
1066 c_del_stmt(comp, pns->nodes[1]);
1067 }
1068 } else {
1069 // tuple with 1 element
1070 c_del_stmt(comp, pn);
1071 }
1072 } else {
1073 // not implemented
1074 assert(0);
1075 }
1076}
1077
1078void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1079 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
1080}
1081
1082void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1083 if (comp->break_label == 0) {
1084 printf("ERROR: cannot break from here\n");
1085 }
1086 EMIT(break_loop, comp->break_label);
1087}
1088
1089void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1090 if (comp->continue_label == 0) {
1091 printf("ERROR: cannot continue from here\n");
1092 }
1093 if (comp->except_nest_level > 0) {
1094 EMIT(continue_loop, comp->continue_label);
1095 } else {
1096 EMIT(jump, comp->continue_label);
1097 }
1098}
1099
1100void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien5ac1b2e2013-10-18 19:58:12 +01001101 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
1102 printf("SyntaxError: 'return' outside function\n");
1103 comp->had_error = true;
1104 return;
1105 }
Damien429d7192013-10-04 19:53:11 +01001106 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001107 // no argument to 'return', so return None
Damien429d7192013-10-04 19:53:11 +01001108 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1109 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
1110 // special case when returning an if-expression; to match CPython optimisation
1111 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
1112 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
1113
Damienb05d7072013-10-05 13:37:10 +01001114 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001115 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1116 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
1117 EMIT(return_value);
1118 EMIT(label_assign, l_fail);
1119 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1120 } else {
1121 compile_node(comp, pns->nodes[0]);
1122 }
1123 EMIT(return_value);
1124}
1125
1126void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1127 compile_node(comp, pns->nodes[0]);
1128 EMIT(pop_top);
1129}
1130
1131void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1132 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1133 // raise
1134 EMIT(raise_varargs, 0);
1135 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1136 // raise x from y
1137 pns = (py_parse_node_struct_t*)pns->nodes[0];
1138 compile_node(comp, pns->nodes[0]);
1139 compile_node(comp, pns->nodes[1]);
1140 EMIT(raise_varargs, 2);
1141 } else {
1142 // raise x
1143 compile_node(comp, pns->nodes[0]);
1144 EMIT(raise_varargs, 1);
1145 }
1146}
1147
1148// q1 holds the base, q2 the full name
1149// eg a -> q1=q2=a
1150// a.b.c -> q1=a, q2=a.b.c
1151void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1152 bool is_as = false;
1153 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1154 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1155 // a name of the form x as y; unwrap it
1156 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1157 pn = pns->nodes[0];
1158 is_as = true;
1159 }
1160 if (PY_PARSE_NODE_IS_ID(pn)) {
1161 // just a simple name
1162 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1163 if (!is_as) {
1164 *q1 = *q2;
1165 }
1166 EMIT(import_name, *q2);
1167 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1168 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1169 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1170 // a name of the form a.b.c
1171 if (!is_as) {
1172 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1173 }
1174 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1175 int len = n - 1;
1176 for (int i = 0; i < n; i++) {
1177 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1178 }
1179 char *str = m_new(char, len + 1);
1180 str[0] = 0;
1181 for (int i = 0; i < n; i++) {
1182 if (i > 0) {
1183 strcat(str, ".");
1184 }
1185 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1186 }
1187 *q2 = qstr_from_str_take(str);
1188 EMIT(import_name, *q2);
1189 if (is_as) {
1190 for (int i = 1; i < n; i++) {
1191 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1192 }
1193 }
1194 } else {
1195 // TODO not implemented
1196 assert(0);
1197 }
1198 } else {
1199 // TODO not implemented
1200 assert(0);
1201 }
1202}
1203
1204void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1205 EMIT(load_const_small_int, 0); // ??
1206 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1207 qstr q1, q2;
1208 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001209 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001210}
1211
1212void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1213 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1214}
1215
1216void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1217 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
Damiendb4c3612013-12-10 17:27:24 +00001218 EMIT(load_const_small_int, 0); // level 0 for __import__
1219
1220 // build the "fromlist" tuple
1221#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001222 EMIT(load_const_verbatim_str, "('*',)");
Damiendb4c3612013-12-10 17:27:24 +00001223#else
1224 EMIT(load_const_str, qstr_from_str_static("*"), false);
1225 EMIT(build_tuple, 1);
1226#endif
1227
1228 // do the import
Damien429d7192013-10-04 19:53:11 +01001229 qstr dummy_q, id1;
1230 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1231 EMIT(import_star);
Damiendb4c3612013-12-10 17:27:24 +00001232
Damien429d7192013-10-04 19:53:11 +01001233 } else {
Damiendb4c3612013-12-10 17:27:24 +00001234 EMIT(load_const_small_int, 0); // level 0 for __import__
1235
1236 // build the "fromlist" tuple
Damien429d7192013-10-04 19:53:11 +01001237 py_parse_node_t *pn_nodes;
1238 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
Damiendb4c3612013-12-10 17:27:24 +00001239#if MICROPY_EMIT_CPYTHON
Damien02f89412013-12-12 15:13:36 +00001240 {
1241 vstr_t *vstr = vstr_new();
1242 vstr_printf(vstr, "(");
1243 for (int i = 0; i < n; i++) {
1244 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1245 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1246 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1247 if (i > 0) {
1248 vstr_printf(vstr, ", ");
1249 }
1250 vstr_printf(vstr, "'");
1251 vstr_printf(vstr, qstr_str(id2));
1252 vstr_printf(vstr, "'");
Damien429d7192013-10-04 19:53:11 +01001253 }
Damien02f89412013-12-12 15:13:36 +00001254 if (n == 1) {
1255 vstr_printf(vstr, ",");
1256 }
1257 vstr_printf(vstr, ")");
Damien02f89412013-12-12 15:13:36 +00001258 EMIT(load_const_verbatim_str, vstr_str(vstr));
Damien02f89412013-12-12 15:13:36 +00001259 vstr_free(vstr);
Damien429d7192013-10-04 19:53:11 +01001260 }
Damiendb4c3612013-12-10 17:27:24 +00001261#else
1262 for (int i = 0; i < n; i++) {
1263 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1264 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1265 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1266 EMIT(load_const_str, id2, false);
1267 }
1268 EMIT(build_tuple, n);
1269#endif
1270
1271 // do the import
Damien429d7192013-10-04 19:53:11 +01001272 qstr dummy_q, id1;
1273 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1274 for (int i = 0; i < n; i++) {
1275 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1276 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1277 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1278 EMIT(import_from, id2);
1279 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001280 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001281 } else {
Damien4b03e772013-10-05 14:17:09 +01001282 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001283 }
1284 }
1285 EMIT(pop_top);
1286 }
1287}
1288
1289void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001290 if (comp->pass == PASS_1) {
1291 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1292 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1293 } else {
1294 pns = (py_parse_node_struct_t*)pns->nodes[0];
1295 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1296 for (int i = 0; i < num_nodes; i++) {
1297 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1298 }
Damien429d7192013-10-04 19:53:11 +01001299 }
1300 }
1301}
1302
1303void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001304 if (comp->pass == PASS_1) {
1305 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1306 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1307 } else {
1308 pns = (py_parse_node_struct_t*)pns->nodes[0];
1309 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1310 for (int i = 0; i < num_nodes; i++) {
1311 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1312 }
Damien429d7192013-10-04 19:53:11 +01001313 }
1314 }
1315}
1316
1317void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001318 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001319 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001320 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001321 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1322 // assertion message
1323 compile_node(comp, pns->nodes[1]);
1324 EMIT(call_function, 1, 0, false, false);
1325 }
1326 EMIT(raise_varargs, 1);
1327 EMIT(label_assign, l_end);
1328}
1329
1330void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1331 // TODO proper and/or short circuiting
1332
Damienb05d7072013-10-05 13:37:10 +01001333 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001334
Damienb05d7072013-10-05 13:37:10 +01001335 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001336 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1337
1338 compile_node(comp, pns->nodes[1]); // if block
1339 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1340 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001341 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001342 EMIT(jump, l_end);
1343 }
1344 //}
1345 EMIT(label_assign, l_fail);
1346
1347 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1348 // compile elif blocks
1349
1350 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1351
1352 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1353 // multiple elif blocks
1354
1355 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1356 for (int i = 0; i < n; i++) {
1357 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001358 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001359 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1360
1361 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001362 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001363 EMIT(jump, l_end);
1364 }
1365 EMIT(label_assign, l_fail);
1366 }
1367
1368 } else {
1369 // a single elif block
1370
Damienb05d7072013-10-05 13:37:10 +01001371 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001372 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1373
1374 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001375 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001376 EMIT(jump, l_end);
1377 }
1378 EMIT(label_assign, l_fail);
1379 }
1380 }
1381
1382 // compile else block
1383 compile_node(comp, pns->nodes[3]); // can be null
1384
1385 EMIT(label_assign, l_end);
1386}
1387
1388void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1389 int old_break_label = comp->break_label;
1390 int old_continue_label = comp->continue_label;
1391
Damienb05d7072013-10-05 13:37:10 +01001392 int break_label = comp_next_label(comp);
1393 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001394
1395 comp->break_label = break_label;
1396 comp->continue_label = continue_label;
1397
Damience89a212013-10-15 22:25:17 +01001398 // compared to CPython, we have an optimised version of while loops
1399#if MICROPY_EMIT_CPYTHON
1400 int done_label = comp_next_label(comp);
1401 EMIT(setup_loop, break_label);
Damien429d7192013-10-04 19:53:11 +01001402 EMIT(label_assign, continue_label);
1403 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1404 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001405 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001406 EMIT(jump, continue_label);
1407 }
1408 EMIT(label_assign, done_label);
Damien429d7192013-10-04 19:53:11 +01001409 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1410 // this is a small hack to agree with CPython
1411 if (!node_is_const_true(pns->nodes[0])) {
1412 EMIT(pop_block);
1413 }
Damience89a212013-10-15 22:25:17 +01001414#else
1415 int top_label = comp_next_label(comp);
1416 EMIT(jump, continue_label);
1417 EMIT(label_assign, top_label);
1418 compile_node(comp, pns->nodes[1]); // body
1419 EMIT(label_assign, continue_label);
1420 c_if_cond(comp, pns->nodes[0], true, top_label); // condition
1421#endif
1422
1423 // break/continue apply to outer loop (if any) in the else block
1424 comp->break_label = old_break_label;
1425 comp->continue_label = old_continue_label;
Damien429d7192013-10-04 19:53:11 +01001426
1427 compile_node(comp, pns->nodes[2]); // else
1428
1429 EMIT(label_assign, break_label);
Damien429d7192013-10-04 19:53:11 +01001430}
1431
Damienf72fd0e2013-11-06 20:20:49 +00001432// TODO preload end and step onto stack if they are not constants
1433// TODO check if step is negative and do opposite test
1434void 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) {
1435 int old_break_label = comp->break_label;
1436 int old_continue_label = comp->continue_label;
1437
1438 int break_label = comp_next_label(comp);
1439 int continue_label = comp_next_label(comp);
1440
1441 comp->break_label = break_label;
1442 comp->continue_label = continue_label;
1443
1444 int top_label = comp_next_label(comp);
1445
1446 // compile: var = start
1447 compile_node(comp, pn_start);
1448 c_assign(comp, pn_var, ASSIGN_STORE);
1449
1450 EMIT(jump, continue_label);
1451 EMIT(label_assign, top_label);
1452
Damienf3822fc2013-11-09 20:12:03 +00001453 // compile body
1454 compile_node(comp, pn_body);
1455
Damienf72fd0e2013-11-06 20:20:49 +00001456 // compile: var += step
1457 c_assign(comp, pn_var, ASSIGN_AUG_LOAD);
1458 compile_node(comp, pn_step);
1459 EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD);
1460 c_assign(comp, pn_var, ASSIGN_AUG_STORE);
1461
Damienf72fd0e2013-11-06 20:20:49 +00001462 EMIT(label_assign, continue_label);
1463
1464 // compile: if var < end: goto top
1465 compile_node(comp, pn_var);
1466 compile_node(comp, pn_end);
1467 EMIT(compare_op, RT_COMPARE_OP_LESS);
1468 EMIT(pop_jump_if_true, top_label);
1469
1470 // break/continue apply to outer loop (if any) in the else block
1471 comp->break_label = old_break_label;
1472 comp->continue_label = old_continue_label;
1473
1474 compile_node(comp, pn_else);
1475
1476 EMIT(label_assign, break_label);
1477}
1478
Damien429d7192013-10-04 19:53:11 +01001479void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienf72fd0e2013-11-06 20:20:49 +00001480#if !MICROPY_EMIT_CPYTHON
1481 // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
1482 // this is actually slower, but uses no heap memory
1483 // for viper it will be much, much faster
Damiend7933892013-11-28 19:12:18 +00001484 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 +00001485 py_parse_node_struct_t *pns_it = (py_parse_node_struct_t*)pns->nodes[1];
Damiend7933892013-11-28 19:12:18 +00001486 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 +00001487 py_parse_node_t pn_range_args = ((py_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
1488 py_parse_node_t *args;
1489 int n_args = list_get(&pn_range_args, PN_arglist, &args);
1490 if (1 <= n_args && n_args <= 3) {
1491 py_parse_node_t pn_range_start;
1492 py_parse_node_t pn_range_end;
1493 py_parse_node_t pn_range_step;
1494 if (n_args == 1) {
1495 pn_range_start = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 0);
1496 pn_range_end = args[0];
1497 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1498 } else if (n_args == 2) {
1499 pn_range_start = args[0];
1500 pn_range_end = args[1];
1501 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1502 } else {
1503 pn_range_start = args[0];
1504 pn_range_end = args[1];
1505 pn_range_step = args[2];
1506 }
1507 compile_for_stmt_optimised_range(comp, pns->nodes[0], pn_range_start, pn_range_end, pn_range_step, pns->nodes[2], pns->nodes[3]);
1508 return;
1509 }
1510 }
1511 }
1512#endif
1513
Damien429d7192013-10-04 19:53:11 +01001514 int old_break_label = comp->break_label;
1515 int old_continue_label = comp->continue_label;
1516
Damienb05d7072013-10-05 13:37:10 +01001517 int for_label = comp_next_label(comp);
1518 int pop_label = comp_next_label(comp);
1519 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001520
Damienb05d7072013-10-05 13:37:10 +01001521 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001522
1523 comp->continue_label = for_label;
1524 comp->break_label = break_label;
1525
Damience89a212013-10-15 22:25:17 +01001526 // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
1527#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001528 EMIT(setup_loop, end_label);
Damience89a212013-10-15 22:25:17 +01001529#endif
1530
Damien429d7192013-10-04 19:53:11 +01001531 compile_node(comp, pns->nodes[1]); // iterator
1532 EMIT(get_iter);
1533 EMIT(label_assign, for_label);
1534 EMIT(for_iter, pop_label);
1535 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1536 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001537 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001538 EMIT(jump, for_label);
1539 }
1540 EMIT(label_assign, pop_label);
1541 EMIT(for_iter_end);
1542
1543 // break/continue apply to outer loop (if any) in the else block
1544 comp->break_label = old_break_label;
1545 comp->continue_label = old_continue_label;
1546
Damience89a212013-10-15 22:25:17 +01001547#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001548 EMIT(pop_block);
Damience89a212013-10-15 22:25:17 +01001549#endif
Damien429d7192013-10-04 19:53:11 +01001550
1551 compile_node(comp, pns->nodes[3]); // else (not tested)
1552
1553 EMIT(label_assign, break_label);
1554 EMIT(label_assign, end_label);
1555}
1556
1557void 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) {
1558 // this function is a bit of a hack at the moment
1559 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1560
1561 // setup code
1562 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001563 int l1 = comp_next_label(comp);
1564 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001565 comp->except_nest_level += 1; // for correct handling of continue
1566 EMIT(setup_except, l1);
1567 compile_node(comp, pn_body); // body
1568 EMIT(pop_block);
1569 EMIT(jump, success_label);
1570 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001571 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001572
1573 for (int i = 0; i < n_except; i++) {
1574 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1575 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1576
1577 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001578 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001579
1580 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1581 // this is a catch all exception handler
1582 if (i + 1 != n_except) {
1583 printf("SyntaxError: default 'except:' must be last\n");
1584 return;
1585 }
1586 } else {
1587 // this exception handler requires a match to a certain type of exception
1588 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1589 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1590 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1591 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1592 // handler binds the exception to a local
1593 pns_exception_expr = pns3->nodes[0];
1594 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1595 }
1596 }
1597 EMIT(dup_top);
1598 compile_node(comp, pns_exception_expr);
1599 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1600 EMIT(pop_jump_if_false, end_finally_label);
1601 }
1602
1603 EMIT(pop_top);
1604
1605 if (qstr_exception_local == 0) {
1606 EMIT(pop_top);
1607 } else {
Damien4b03e772013-10-05 14:17:09 +01001608 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001609 }
1610
1611 EMIT(pop_top);
1612
Damiene2880aa2013-12-20 14:22:59 +00001613 int l3 = 0;
Damien429d7192013-10-04 19:53:11 +01001614 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001615 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001616 EMIT(setup_finally, l3);
1617 }
1618 compile_node(comp, pns_except->nodes[1]);
1619 if (qstr_exception_local != 0) {
1620 EMIT(pop_block);
1621 }
1622 EMIT(pop_except);
1623 if (qstr_exception_local != 0) {
1624 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1625 EMIT(label_assign, l3);
1626 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001627 EMIT(store_id, qstr_exception_local);
1628 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001629 EMIT(end_finally);
1630 }
1631 EMIT(jump, l2);
1632 EMIT(label_assign, end_finally_label);
1633 }
1634
1635 EMIT(end_finally);
1636 EMIT(label_assign, success_label);
1637 comp->except_nest_level -= 1;
1638 compile_node(comp, pn_else); // else block, can be null
1639 EMIT(label_assign, l2);
1640 EMIT(set_stack_size, stack_size);
1641}
1642
1643void 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) {
1644 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1645 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001646 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001647 EMIT(setup_finally, l_finally_block);
1648 if (n_except == 0) {
1649 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1650 compile_node(comp, pn_body);
1651 } else {
1652 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1653 }
1654 EMIT(pop_block);
1655 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1656 EMIT(label_assign, l_finally_block);
1657 compile_node(comp, pn_finally);
1658 EMIT(end_finally);
1659 EMIT(set_stack_size, stack_size);
1660}
1661
1662void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1663 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1664 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1665 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1666 // just try-finally
1667 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1668 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1669 // try-except and possibly else and/or finally
1670 py_parse_node_t *pn_excepts;
1671 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1672 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1673 // no finally
1674 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1675 } else {
1676 // have finally
1677 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1678 }
1679 } else {
1680 // just try-except
1681 py_parse_node_t *pn_excepts;
1682 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1683 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1684 }
1685 } else {
1686 // shouldn't happen
1687 assert(0);
1688 }
1689}
1690
1691void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1692 if (n == 0) {
1693 // no more pre-bits, compile the body of the with
1694 compile_node(comp, body);
1695 } else {
Damienb05d7072013-10-05 13:37:10 +01001696 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001697 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1698 // this pre-bit is of the form "a as b"
1699 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1700 compile_node(comp, pns->nodes[0]);
1701 EMIT(setup_with, l_end);
1702 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1703 } else {
1704 // this pre-bit is just an expression
1705 compile_node(comp, nodes[0]);
1706 EMIT(setup_with, l_end);
1707 EMIT(pop_top);
1708 }
1709 // compile additional pre-bits and the body
1710 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1711 // finish this with block
1712 EMIT(pop_block);
1713 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1714 EMIT(label_assign, l_end);
1715 EMIT(with_cleanup);
1716 EMIT(end_finally);
1717 }
1718}
1719
1720void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1721 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1722 py_parse_node_t *nodes;
1723 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1724 assert(n > 0);
1725
1726 // compile in a nested fashion
1727 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1728}
1729
1730void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1731 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001732 if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
1733 // for REPL, evaluate then print the expression
1734 EMIT(load_id, qstr_from_str_static("__repl_print__"));
1735 compile_node(comp, pns->nodes[0]);
1736 EMIT(call_function, 1, 0, false, false);
1737 EMIT(pop_top);
1738
Damien429d7192013-10-04 19:53:11 +01001739 } else {
Damien5ac1b2e2013-10-18 19:58:12 +01001740 // for non-REPL, evaluate then discard the expression
1741 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1742 // do nothing with a lonely constant
1743 } else {
1744 compile_node(comp, pns->nodes[0]); // just an expression
1745 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1746 }
Damien429d7192013-10-04 19:53:11 +01001747 }
1748 } else {
1749 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1750 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1751 if (kind == PN_expr_stmt_augassign) {
1752 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1753 compile_node(comp, pns1->nodes[1]); // rhs
1754 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1755 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1756 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1757 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1758 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1759 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1760 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1761 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1762 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1763 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1764 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1765 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1766 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1767 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1768 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1769 default: assert(0); // shouldn't happen
1770 }
1771 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1772 } else if (kind == PN_expr_stmt_assign_list) {
1773 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1774 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1775 // following CPython, we store left-most first
1776 if (rhs > 0) {
1777 EMIT(dup_top);
1778 }
1779 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1780 for (int i = 0; i < rhs; i++) {
1781 if (i + 1 < rhs) {
1782 EMIT(dup_top);
1783 }
1784 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1785 }
1786 } else if (kind == PN_expr_stmt_assign) {
1787 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1788 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1789 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1790 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1791 // optimisation for a, b = c, d; to match CPython's optimisation
1792 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1793 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1794 compile_node(comp, pns10->nodes[0]); // rhs
1795 compile_node(comp, pns10->nodes[1]); // rhs
1796 EMIT(rot_two);
1797 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1798 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1799 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1800 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1801 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1802 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1803 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1804 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1805 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1806 compile_node(comp, pns10->nodes[0]); // rhs
1807 compile_node(comp, pns10->nodes[1]); // rhs
1808 compile_node(comp, pns10->nodes[2]); // rhs
1809 EMIT(rot_three);
1810 EMIT(rot_two);
1811 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1812 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1813 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1814 } else {
1815 compile_node(comp, pns1->nodes[0]); // rhs
1816 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1817 }
1818 } else {
1819 // shouldn't happen
1820 assert(0);
1821 }
1822 }
1823}
1824
1825void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1826 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1827 compile_node(comp, pns->nodes[0]);
1828 for (int i = 1; i < num_nodes; i += 1) {
1829 compile_node(comp, pns->nodes[i]);
1830 EMIT(binary_op, binary_op);
1831 }
1832}
1833
1834void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1835 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1836 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1837
1838 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001839 int l_fail = comp_next_label(comp);
1840 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001841 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1842 compile_node(comp, pns->nodes[0]); // success value
1843 EMIT(jump, l_end);
1844 EMIT(label_assign, l_fail);
1845 EMIT(set_stack_size, stack_size); // force stack size reset
1846 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1847 EMIT(label_assign, l_end);
1848}
1849
1850void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1851 // TODO default params etc for lambda; possibly just use funcdef code
1852 //py_parse_node_t pn_params = pns->nodes[0];
1853 //py_parse_node_t pn_body = pns->nodes[1];
1854
1855 if (comp->pass == PASS_1) {
1856 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001857 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 +01001858 // store the lambda scope so the compiling function (this one) can use it at each pass
1859 pns->nodes[2] = (py_parse_node_t)s;
1860 }
1861
1862 // get the scope for this lambda
1863 scope_t *this_scope = (scope_t*)pns->nodes[2];
1864
1865 // make the lambda
1866 close_over_variables_etc(comp, this_scope, 0, 0);
1867}
1868
1869void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001870 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001871 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1872 for (int i = 0; i < n; i += 1) {
1873 compile_node(comp, pns->nodes[i]);
1874 if (i + 1 < n) {
1875 EMIT(jump_if_true_or_pop, l_end);
1876 }
1877 }
1878 EMIT(label_assign, l_end);
1879}
1880
1881void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001882 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001883 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1884 for (int i = 0; i < n; i += 1) {
1885 compile_node(comp, pns->nodes[i]);
1886 if (i + 1 < n) {
1887 EMIT(jump_if_false_or_pop, l_end);
1888 }
1889 }
1890 EMIT(label_assign, l_end);
1891}
1892
1893void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1894 compile_node(comp, pns->nodes[0]);
1895 EMIT(unary_op, RT_UNARY_OP_NOT);
1896}
1897
1898void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1899 int stack_size = EMIT(get_stack_size);
1900 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1901 compile_node(comp, pns->nodes[0]);
1902 bool multi = (num_nodes > 3);
1903 int l_fail = 0;
1904 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001905 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001906 }
1907 for (int i = 1; i + 1 < num_nodes; i += 2) {
1908 compile_node(comp, pns->nodes[i + 1]);
1909 if (i + 2 < num_nodes) {
1910 EMIT(dup_top);
1911 EMIT(rot_three);
1912 }
1913 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1914 EMIT(compare_op, RT_COMPARE_OP_LESS);
1915 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1916 EMIT(compare_op, RT_COMPARE_OP_MORE);
1917 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1918 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1919 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1920 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1921 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1922 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1923 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1924 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1925 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1926 EMIT(compare_op, RT_COMPARE_OP_IN);
1927 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1928 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1929 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1930 if (kind == PN_comp_op_not_in) {
1931 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1932 } else if (kind == PN_comp_op_is) {
1933 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1934 EMIT(compare_op, RT_COMPARE_OP_IS);
1935 } else {
1936 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1937 }
1938 } else {
1939 // shouldn't happen
1940 assert(0);
1941 }
1942 } else {
1943 // shouldn't happen
1944 assert(0);
1945 }
1946 if (i + 2 < num_nodes) {
1947 EMIT(jump_if_false_or_pop, l_fail);
1948 }
1949 }
1950 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001951 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001952 EMIT(jump, l_end);
1953 EMIT(label_assign, l_fail);
1954 EMIT(rot_two);
1955 EMIT(pop_top);
1956 EMIT(label_assign, l_end);
1957 EMIT(set_stack_size, stack_size + 1); // force stack size
1958 }
1959}
1960
1961void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1962 // TODO
1963 assert(0);
1964 compile_node(comp, pns->nodes[0]);
1965 //EMIT(unary_op, "UNARY_STAR");
1966}
1967
1968void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1969 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1970}
1971
1972void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1973 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1974}
1975
1976void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1977 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1978}
1979
1980void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1981 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1982 compile_node(comp, pns->nodes[0]);
1983 for (int i = 1; i + 1 < num_nodes; i += 2) {
1984 compile_node(comp, pns->nodes[i + 1]);
1985 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1986 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1987 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1988 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1989 } else {
1990 // shouldn't happen
1991 assert(0);
1992 }
1993 }
1994}
1995
1996void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1997 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1998 compile_node(comp, pns->nodes[0]);
1999 for (int i = 1; i + 1 < num_nodes; i += 2) {
2000 compile_node(comp, pns->nodes[i + 1]);
2001 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
2002 EMIT(binary_op, RT_BINARY_OP_ADD);
2003 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
2004 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
2005 } else {
2006 // shouldn't happen
2007 assert(0);
2008 }
2009 }
2010}
2011
2012void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
2013 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2014 compile_node(comp, pns->nodes[0]);
2015 for (int i = 1; i + 1 < num_nodes; i += 2) {
2016 compile_node(comp, pns->nodes[i + 1]);
2017 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
2018 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
2019 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
2020 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
2021 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
2022 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
2023 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
2024 EMIT(binary_op, RT_BINARY_OP_MODULO);
2025 } else {
2026 // shouldn't happen
2027 assert(0);
2028 }
2029 }
2030}
2031
2032void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2033 compile_node(comp, pns->nodes[1]);
2034 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
2035 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
2036 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
2037 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
2038 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
2039 EMIT(unary_op, RT_UNARY_OP_INVERT);
2040 } else {
2041 // shouldn't happen
2042 assert(0);
2043 }
2044}
2045
2046void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
2047 // function to call is on top of stack
2048
2049 int old_n_arg_keyword = comp->n_arg_keyword;
2050 bool old_have_star_arg = comp->have_star_arg;
2051 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
2052 comp->n_arg_keyword = 0;
2053 comp->have_star_arg = false;
2054 comp->have_dbl_star_arg = false;
2055
2056 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
2057
2058 // compute number of positional arguments
2059 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
2060 if (comp->have_star_arg) {
2061 n_positional -= 1;
2062 }
2063 if (comp->have_dbl_star_arg) {
2064 n_positional -= 1;
2065 }
2066
2067 if (is_method_call) {
2068 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
2069 } else {
2070 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
2071 }
2072
2073 comp->n_arg_keyword = old_n_arg_keyword;
2074 comp->have_star_arg = old_have_star_arg;
2075 comp->have_dbl_star_arg = old_have_dbl_star_arg;
2076}
2077
2078void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
2079 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2080 for (int i = 0; i < num_nodes; i++) {
2081 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)) {
2082 // optimisation for method calls a.f(...), following PyPy
2083 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
2084 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
2085 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
2086 compile_trailer_paren_helper(comp, pns_paren, true);
2087 i += 1;
2088 } else {
2089 compile_node(comp, pns->nodes[i]);
2090 }
2091 }
2092}
2093
2094void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2095 compile_node(comp, pns->nodes[0]);
2096 EMIT(binary_op, RT_BINARY_OP_POWER);
2097}
2098
2099void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
2100 // a list of strings
Damien63321742013-12-10 17:41:49 +00002101
2102 // check type of list (string or bytes) and count total number of bytes
Damien429d7192013-10-04 19:53:11 +01002103 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
Damien63321742013-12-10 17:41:49 +00002104 int n_bytes = 0;
2105 int string_kind = PY_PARSE_NODE_NULL;
Damien429d7192013-10-04 19:53:11 +01002106 for (int i = 0; i < n; i++) {
Damien429d7192013-10-04 19:53:11 +01002107 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
Damien63321742013-12-10 17:41:49 +00002108 int pn_kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]);
2109 assert(pn_kind == PY_PARSE_NODE_STRING || pn_kind == PY_PARSE_NODE_BYTES);
2110 if (i == 0) {
2111 string_kind = pn_kind;
2112 } else if (pn_kind != string_kind) {
2113 printf("SyntaxError: cannot mix bytes and nonbytes literals\n");
2114 return;
2115 }
Damien429d7192013-10-04 19:53:11 +01002116 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
Damien63321742013-12-10 17:41:49 +00002117 n_bytes += strlen(str);
Damien429d7192013-10-04 19:53:11 +01002118 }
Damien63321742013-12-10 17:41:49 +00002119
2120 // allocate memory for concatenated string/bytes
2121 char *cat_str = m_new(char, n_bytes + 1);
2122 cat_str[0] = '\0';
2123
2124 // concatenate string/bytes
2125 for (int i = 0; i < n; i++) {
2126 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
2127 strcat(cat_str, str);
2128 }
2129
2130 EMIT(load_const_str, qstr_from_str_take(cat_str), string_kind == PY_PARSE_NODE_BYTES);
Damien429d7192013-10-04 19:53:11 +01002131}
2132
2133// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
2134void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
2135 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2136 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2137 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2138
2139 if (comp->pass == PASS_1) {
2140 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01002141 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 +01002142 // store the comprehension scope so the compiling function (this one) can use it at each pass
2143 pns_comp_for->nodes[3] = (py_parse_node_t)s;
2144 }
2145
2146 // get the scope for this comprehension
2147 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
2148
2149 // compile the comprehension
2150 close_over_variables_etc(comp, this_scope, 0, 0);
2151
2152 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
2153 EMIT(get_iter);
2154 EMIT(call_function, 1, 0, false, false);
2155}
2156
2157void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2158 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2159 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01002160 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
2161 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2162 pns = (py_parse_node_struct_t*)pns->nodes[0];
2163 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
2164 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
2165 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2166 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
2167 // tuple of one item, with trailing comma
2168 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01002169 c_tuple(comp, pns->nodes[0], NULL);
2170 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
2171 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01002172 c_tuple(comp, pns->nodes[0], pns2);
2173 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2174 // generator expression
2175 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2176 } else {
2177 // tuple with 2 items
2178 goto tuple_with_2_items;
2179 }
2180 } else {
2181 // tuple with 2 items
2182 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01002183 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
2184 }
2185 } else {
2186 // parenthesis around a single item, is just that item
2187 compile_node(comp, pns->nodes[0]);
2188 }
2189}
2190
2191void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2192 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2193 // empty list
2194 EMIT(build_list, 0);
2195 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2196 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
2197 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
2198 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
2199 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
2200 // list of one item, with trailing comma
2201 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
2202 compile_node(comp, pns2->nodes[0]);
2203 EMIT(build_list, 1);
2204 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
2205 // list of many items
2206 compile_node(comp, pns2->nodes[0]);
2207 compile_generic_all_nodes(comp, pns3);
2208 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2209 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2210 // list comprehension
2211 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2212 } else {
2213 // list with 2 items
2214 goto list_with_2_items;
2215 }
2216 } else {
2217 // list with 2 items
2218 list_with_2_items:
2219 compile_node(comp, pns2->nodes[0]);
2220 compile_node(comp, pns2->nodes[1]);
2221 EMIT(build_list, 2);
2222 }
2223 } else {
2224 // list with 1 item
2225 compile_node(comp, pns->nodes[0]);
2226 EMIT(build_list, 1);
2227 }
2228}
2229
2230void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2231 py_parse_node_t pn = pns->nodes[0];
2232 if (PY_PARSE_NODE_IS_NULL(pn)) {
2233 // empty dict
2234 EMIT(build_map, 0);
2235 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2236 pns = (py_parse_node_struct_t*)pn;
2237 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2238 // dict with one element
2239 EMIT(build_map, 1);
2240 compile_node(comp, pn);
2241 EMIT(store_map);
2242 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2243 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2244 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2245 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2246 // dict/set with multiple elements
2247
2248 // get tail elements (2nd, 3rd, ...)
2249 py_parse_node_t *nodes;
2250 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2251
2252 // first element sets whether it's a dict or set
2253 bool is_dict;
2254 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2255 // a dictionary
2256 EMIT(build_map, 1 + n);
2257 compile_node(comp, pns->nodes[0]);
2258 EMIT(store_map);
2259 is_dict = true;
2260 } else {
2261 // a set
2262 compile_node(comp, pns->nodes[0]); // 1st value of set
2263 is_dict = false;
2264 }
2265
2266 // process rest of elements
2267 for (int i = 0; i < n; i++) {
2268 py_parse_node_t pn = nodes[i];
2269 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2270 compile_node(comp, pn);
2271 if (is_dict) {
2272 if (!is_key_value) {
2273 printf("SyntaxError?: expecting key:value for dictionary");
2274 return;
2275 }
2276 EMIT(store_map);
2277 } else {
2278 if (is_key_value) {
2279 printf("SyntaxError?: expecting just a value for set");
2280 return;
2281 }
2282 }
2283 }
2284
2285 // if it's a set, build it
2286 if (!is_dict) {
2287 EMIT(build_set, 1 + n);
2288 }
2289 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2290 // dict/set comprehension
2291 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2292 // a dictionary comprehension
2293 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2294 } else {
2295 // a set comprehension
2296 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2297 }
2298 } else {
2299 // shouldn't happen
2300 assert(0);
2301 }
2302 } else {
2303 // set with one element
2304 goto set_with_one_element;
2305 }
2306 } else {
2307 // set with one element
2308 set_with_one_element:
2309 compile_node(comp, pn);
2310 EMIT(build_set, 1);
2311 }
2312}
2313
2314void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2315 compile_trailer_paren_helper(comp, pns, false);
2316}
2317
2318void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2319 // object who's index we want is on top of stack
2320 compile_node(comp, pns->nodes[0]); // the index
2321 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2322}
2323
2324void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2325 // object who's attribute we want is on top of stack
2326 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2327}
2328
2329void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2330 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2331 py_parse_node_t pn = pns->nodes[0];
2332 if (PY_PARSE_NODE_IS_NULL(pn)) {
2333 // [?:]
2334 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2335 EMIT(build_slice, 2);
2336 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2337 pns = (py_parse_node_struct_t*)pn;
2338 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2339 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2340 pn = pns->nodes[0];
2341 if (PY_PARSE_NODE_IS_NULL(pn)) {
2342 // [?::]
2343 EMIT(build_slice, 2);
2344 } else {
2345 // [?::x]
2346 compile_node(comp, pn);
2347 EMIT(build_slice, 3);
2348 }
2349 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2350 compile_node(comp, pns->nodes[0]);
2351 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2352 pns = (py_parse_node_struct_t*)pns->nodes[1];
2353 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2354 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2355 // [?:x:]
2356 EMIT(build_slice, 2);
2357 } else {
2358 // [?:x:x]
2359 compile_node(comp, pns->nodes[0]);
2360 EMIT(build_slice, 3);
2361 }
2362 } else {
2363 // [?:x]
2364 compile_node(comp, pn);
2365 EMIT(build_slice, 2);
2366 }
2367 } else {
2368 // [?:x]
2369 compile_node(comp, pn);
2370 EMIT(build_slice, 2);
2371 }
2372}
2373
2374void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2375 compile_node(comp, pns->nodes[0]); // start of slice
2376 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2377 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2378}
2379
2380void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2381 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2382 compile_subscript_3_helper(comp, pns);
2383}
2384
2385void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2386 // if this is called then we are compiling a dict key:value pair
2387 compile_node(comp, pns->nodes[1]); // value
2388 compile_node(comp, pns->nodes[0]); // key
2389}
2390
2391void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002392 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002393 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002394 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002395}
2396
2397void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2398 if (comp->have_star_arg) {
2399 printf("SyntaxError?: can't have multiple *x\n");
2400 return;
2401 }
2402 comp->have_star_arg = true;
2403 compile_node(comp, pns->nodes[0]);
2404}
2405
2406void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2407 if (comp->have_dbl_star_arg) {
2408 printf("SyntaxError?: can't have multiple **x\n");
2409 return;
2410 }
2411 comp->have_dbl_star_arg = true;
2412 compile_node(comp, pns->nodes[0]);
2413}
2414
2415void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2416 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2417 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2418 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2419 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2420 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2421 return;
2422 }
2423 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2424 compile_node(comp, pns2->nodes[0]);
2425 comp->n_arg_keyword += 1;
2426 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2427 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2428 } else {
2429 // shouldn't happen
2430 assert(0);
2431 }
2432}
2433
2434void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2435 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2436 printf("SyntaxError: 'yield' outside function\n");
2437 return;
2438 }
2439 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2440 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2441 EMIT(yield_value);
2442 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2443 pns = (py_parse_node_struct_t*)pns->nodes[0];
2444 compile_node(comp, pns->nodes[0]);
2445 EMIT(get_iter);
2446 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2447 EMIT(yield_from);
2448 } else {
2449 compile_node(comp, pns->nodes[0]);
2450 EMIT(yield_value);
2451 }
2452}
2453
2454typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2455static compile_function_t compile_function[] = {
2456 NULL,
2457#define nc NULL
2458#define c(f) compile_##f
2459#define DEF_RULE(rule, comp, kind, arg...) comp,
2460#include "grammar.h"
2461#undef nc
2462#undef c
2463#undef DEF_RULE
2464};
2465
2466void compile_node(compiler_t *comp, py_parse_node_t pn) {
2467 if (PY_PARSE_NODE_IS_NULL(pn)) {
2468 // pass
2469 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2470 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2471 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002472 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002473 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2474 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2475 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2476 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2477 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002478 case PY_PARSE_NODE_TOKEN:
2479 if (arg == PY_TOKEN_NEWLINE) {
2480 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
Damien5ac1b2e2013-10-18 19:58:12 +01002481 // or when single_input lets through a NEWLINE (user enters a blank line)
Damien91d387d2013-10-09 15:09:52 +01002482 // do nothing
2483 } else {
2484 EMIT(load_const_tok, arg);
2485 }
2486 break;
Damien429d7192013-10-04 19:53:11 +01002487 default: assert(0);
2488 }
2489 } else {
2490 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2491 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2492 if (f == NULL) {
2493 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
Damien5ac1b2e2013-10-18 19:58:12 +01002494 py_parse_node_show(pn, 0);
Damien429d7192013-10-04 19:53:11 +01002495 assert(0);
2496 } else {
2497 f(comp, pns);
2498 }
2499 }
2500}
2501
2502void 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) {
2503 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002504 qstr param_name = 0;
2505 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002506 if (PY_PARSE_NODE_IS_ID(pn)) {
2507 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002508 if (comp->have_bare_star) {
2509 // comes after a bare star, so doesn't count as a parameter
2510 } else {
2511 comp->scope_cur->num_params += 1;
2512 }
Damienb14de212013-10-06 00:28:28 +01002513 } else {
2514 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2515 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2516 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002517 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002518 //int node_index = 1; unused
2519 if (allow_annotations) {
2520 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2521 // this parameter has an annotation
2522 pn_annotation = pns->nodes[1];
2523 }
2524 //node_index = 2; unused
2525 }
2526 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2527 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2528 // this parameter has a default value
2529 if (comp->have_bare_star) {
2530 comp->scope_cur->num_dict_params += 1;
2531 } else {
2532 comp->scope_cur->num_default_params += 1;
2533 }
2534 }
2535 */
2536 if (comp->have_bare_star) {
2537 // comes after a bare star, so doesn't count as a parameter
2538 } else {
2539 comp->scope_cur->num_params += 1;
2540 }
2541 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2542 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2543 // bare star
2544 // TODO see http://www.python.org/dev/peps/pep-3102/
2545 comp->have_bare_star = true;
2546 //assert(comp->scope_cur->num_dict_params == 0);
2547 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2548 // named star
2549 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2550 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2551 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2552 // named star with annotation
2553 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2554 pns = (py_parse_node_struct_t*)pns->nodes[0];
2555 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2556 pn_annotation = pns->nodes[1];
2557 } else {
2558 // shouldn't happen
2559 assert(0);
2560 }
2561 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002562 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002563 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2564 // this parameter has an annotation
2565 pn_annotation = pns->nodes[1];
2566 }
2567 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002568 } else {
Damienb14de212013-10-06 00:28:28 +01002569 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002570 assert(0);
2571 }
Damien429d7192013-10-04 19:53:11 +01002572 }
2573
2574 if (param_name != 0) {
2575 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2576 // TODO this parameter has an annotation
2577 }
2578 bool added;
2579 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2580 if (!added) {
2581 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2582 return;
2583 }
2584 id_info->param = true;
2585 id_info->kind = ID_INFO_KIND_LOCAL;
2586 }
2587}
2588
2589void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2590 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2591}
2592
2593void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2594 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2595}
2596
2597void 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) {
2598 tail_recursion:
2599 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2600 // no more nested if/for; compile inner expression
2601 compile_node(comp, pn_inner_expr);
2602 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2603 EMIT(list_append, for_depth + 2);
2604 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2605 EMIT(map_add, for_depth + 2);
2606 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2607 EMIT(set_add, for_depth + 2);
2608 } else {
2609 EMIT(yield_value);
2610 EMIT(pop_top);
2611 }
2612 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2613 // if condition
2614 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2615 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2616 pn_iter = pns_comp_if->nodes[1];
2617 goto tail_recursion;
2618 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2619 // for loop
2620 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2621 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002622 int l_end2 = comp_next_label(comp);
2623 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002624 EMIT(get_iter);
2625 EMIT(label_assign, l_top2);
2626 EMIT(for_iter, l_end2);
2627 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2628 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2629 EMIT(jump, l_top2);
2630 EMIT(label_assign, l_end2);
2631 EMIT(for_iter_end);
2632 } else {
2633 // shouldn't happen
2634 assert(0);
2635 }
2636}
2637
2638void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2639 // see http://www.python.org/dev/peps/pep-0257/
2640
2641 // look for the first statement
2642 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
Damiene388f102013-12-12 15:24:38 +00002643 // a statement; fall through
Damien429d7192013-10-04 19:53:11 +01002644 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
Damiene388f102013-12-12 15:24:38 +00002645 // file input; find the first non-newline node
2646 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2647 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2648 for (int i = 0; i < num_nodes; i++) {
2649 pn = pns->nodes[i];
2650 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)) {
2651 // not a newline, so this is the first statement; finish search
2652 break;
2653 }
2654 }
2655 // 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 +01002656 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
Damiene388f102013-12-12 15:24:38 +00002657 // a list of statements; get the first one
Damien429d7192013-10-04 19:53:11 +01002658 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2659 } else {
2660 return;
2661 }
2662
2663 // check the first statement for a doc string
2664 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2665 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2666 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2667 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2668 if (kind == PY_PARSE_NODE_STRING) {
2669 compile_node(comp, pns->nodes[0]); // a doc string
2670 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002671 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002672 }
2673 }
2674 }
2675}
2676
2677void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2678 comp->pass = pass;
2679 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002680 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002681 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002682
2683 if (comp->pass == PASS_1) {
2684 scope->stack_size = 0;
2685 }
2686
Damien5ac1b2e2013-10-18 19:58:12 +01002687#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01002688 if (comp->pass == PASS_3) {
Damien429d7192013-10-04 19:53:11 +01002689 scope_print_info(scope);
2690 }
Damien5ac1b2e2013-10-18 19:58:12 +01002691#endif
Damien429d7192013-10-04 19:53:11 +01002692
2693 // compile
2694 if (scope->kind == SCOPE_MODULE) {
Damien5ac1b2e2013-10-18 19:58:12 +01002695 if (!comp->is_repl) {
2696 check_for_doc_string(comp, scope->pn);
2697 }
Damien429d7192013-10-04 19:53:11 +01002698 compile_node(comp, scope->pn);
2699 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2700 EMIT(return_value);
2701 } else if (scope->kind == SCOPE_FUNCTION) {
2702 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2703 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2704 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2705
2706 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002707 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002708 if (comp->pass == PASS_1) {
2709 comp->have_bare_star = false;
2710 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2711 }
2712
Damien826005c2013-10-05 23:17:28 +01002713 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002714
2715 compile_node(comp, pns->nodes[3]); // 3 is function body
2716 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002717 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002718 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2719 EMIT(return_value);
2720 }
2721 } else if (scope->kind == SCOPE_LAMBDA) {
2722 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2723 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2724 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2725
2726 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002727 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002728 if (comp->pass == PASS_1) {
2729 comp->have_bare_star = false;
2730 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2731 }
2732
2733 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2734 EMIT(return_value);
2735 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2736 // a bit of a hack at the moment
2737
2738 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2739 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2740 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2741 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2742 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2743
Damien6cdd3af2013-10-05 18:08:26 +01002744 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002745 if (comp->pass == PASS_1) {
2746 bool added;
2747 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2748 assert(added);
2749 id_info->kind = ID_INFO_KIND_LOCAL;
2750 scope->num_params = 1;
2751 }
2752
2753 if (scope->kind == SCOPE_LIST_COMP) {
2754 EMIT(build_list, 0);
2755 } else if (scope->kind == SCOPE_DICT_COMP) {
2756 EMIT(build_map, 0);
2757 } else if (scope->kind == SCOPE_SET_COMP) {
2758 EMIT(build_set, 0);
2759 }
2760
Damienb05d7072013-10-05 13:37:10 +01002761 int l_end = comp_next_label(comp);
2762 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002763 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002764 EMIT(label_assign, l_top);
2765 EMIT(for_iter, l_end);
2766 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2767 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2768 EMIT(jump, l_top);
2769 EMIT(label_assign, l_end);
2770 EMIT(for_iter_end);
2771
2772 if (scope->kind == SCOPE_GEN_EXPR) {
2773 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2774 }
2775 EMIT(return_value);
2776 } else {
2777 assert(scope->kind == SCOPE_CLASS);
2778 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2779 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2780 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2781
2782 if (comp->pass == PASS_1) {
2783 bool added;
2784 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2785 assert(added);
2786 id_info->kind = ID_INFO_KIND_LOCAL;
2787 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2788 assert(added);
2789 id_info->kind = ID_INFO_KIND_LOCAL;
2790 id_info->param = true;
2791 scope->num_params = 1; // __locals__ is the parameter
2792 }
2793
Damien4b03e772013-10-05 14:17:09 +01002794 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002795 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002796 EMIT(load_id, comp->qstr___name__);
2797 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002798 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002799 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002800
2801 check_for_doc_string(comp, pns->nodes[2]);
2802 compile_node(comp, pns->nodes[2]); // 2 is class body
2803
2804 id_info_t *id = scope_find(scope, comp->qstr___class__);
2805 assert(id != NULL);
2806 if (id->kind == ID_INFO_KIND_LOCAL) {
2807 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2808 } else {
Damien27fb45e2013-10-20 15:07:49 +01002809 EMIT(load_closure, comp->qstr___class__, 0); // XXX check this is the correct local num
Damien429d7192013-10-04 19:53:11 +01002810 }
2811 EMIT(return_value);
2812 }
2813
Damien415eb6f2013-10-05 12:19:06 +01002814 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002815
Damien826005c2013-10-05 23:17:28 +01002816}
2817
2818void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2819 comp->pass = pass;
2820 comp->scope_cur = scope;
2821 comp->next_label = 1;
2822
2823 if (scope->kind != SCOPE_FUNCTION) {
2824 printf("Error: inline assembler must be a function\n");
2825 return;
2826 }
2827
Damiena2f2f7d2013-10-06 00:14:13 +01002828 if (comp->pass > PASS_1) {
2829 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2830 }
2831
Damien826005c2013-10-05 23:17:28 +01002832 // get the function definition parse node
2833 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2834 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2835 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2836
Damiena2f2f7d2013-10-06 00:14:13 +01002837 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002838
Damiena2f2f7d2013-10-06 00:14:13 +01002839 // parameters are in pns->nodes[1]
2840 if (comp->pass == PASS_2) {
2841 py_parse_node_t *pn_params;
2842 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2843 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2844 }
2845
Damien826005c2013-10-05 23:17:28 +01002846 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2847
2848 py_parse_node_t pn_body = pns->nodes[3]; // body
2849 py_parse_node_t *nodes;
2850 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2851
Damien826005c2013-10-05 23:17:28 +01002852 if (comp->pass == PASS_3) {
2853 //printf("----\n");
2854 scope_print_info(scope);
2855 }
2856
2857 for (int i = 0; i < num; i++) {
2858 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2859 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2860 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2861 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2862 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2863 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2864 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2865 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2866 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2867 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2868 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2869 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2870 py_parse_node_t *pn_arg;
2871 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2872
2873 // emit instructions
2874 if (strcmp(qstr_str(op), "label") == 0) {
2875 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2876 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2877 return;
2878 }
2879 int lab = comp_next_label(comp);
2880 if (pass > PASS_1) {
2881 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2882 }
2883 } else {
2884 if (pass > PASS_1) {
2885 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2886 }
2887 }
2888 }
2889
2890 if (comp->pass > PASS_1) {
2891 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002892 }
Damien429d7192013-10-04 19:53:11 +01002893}
2894
2895void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2896 // in functions, turn implicit globals into explicit globals
2897 // compute num_locals, and the index of each local
2898 scope->num_locals = 0;
2899 for (int i = 0; i < scope->id_info_len; i++) {
2900 id_info_t *id = &scope->id_info[i];
2901 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2902 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2903 continue;
2904 }
2905 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2906 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2907 }
Damien9ecbcff2013-12-11 00:41:43 +00002908 // note: params always count for 1 local, even if they are a cell
Damien429d7192013-10-04 19:53:11 +01002909 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2910 id->local_num = scope->num_locals;
2911 scope->num_locals += 1;
Damien9ecbcff2013-12-11 00:41:43 +00002912 }
2913 }
2914
2915 // compute the index of cell vars (freevars[idx] in CPython)
2916 int num_closed = 0;
2917 for (int i = 0; i < scope->id_info_len; i++) {
2918 id_info_t *id = &scope->id_info[i];
2919 if (id->kind == ID_INFO_KIND_CELL) {
Damien318aec62013-12-10 18:28:17 +00002920 id->local_num = num_closed;
Damien9ecbcff2013-12-11 00:41:43 +00002921#if !MICROPY_EMIT_CPYTHON
2922 // the cells come right after the fast locals (CPython doesn't add this offset)
2923 id->local_num += scope->num_locals;
2924#endif
Damien318aec62013-12-10 18:28:17 +00002925 num_closed += 1;
Damien9ecbcff2013-12-11 00:41:43 +00002926 }
2927 }
2928 scope->num_cells = num_closed;
2929
2930 // compute the index of free vars (freevars[idx] in CPython)
2931 // make sure they are in the order of the parent scope
2932 if (scope->parent != NULL) {
2933 int num_free = 0;
2934 for (int i = 0; i < scope->parent->id_info_len; i++) {
2935 id_info_t *id = &scope->parent->id_info[i];
2936 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2937 for (int j = 0; j < scope->id_info_len; j++) {
2938 id_info_t *id2 = &scope->id_info[j];
2939 if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
2940 id2->local_num = num_closed + num_free;
2941#if !MICROPY_EMIT_CPYTHON
2942 // the frees come right after the cells (CPython doesn't add this offset)
2943 id2->local_num += scope->num_locals;
2944#endif
2945 num_free += 1;
2946 }
2947 }
2948 }
Damien429d7192013-10-04 19:53:11 +01002949 }
2950 }
2951
2952 // compute flags
2953 //scope->flags = 0; since we set some things in parameters
2954 if (scope->kind != SCOPE_MODULE) {
2955 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2956 }
2957 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) {
2958 assert(scope->parent != NULL);
2959 scope->flags |= SCOPE_FLAG_OPTIMISED;
2960
2961 // TODO possibly other ways it can be nested
2962 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2963 scope->flags |= SCOPE_FLAG_NESTED;
2964 }
2965 }
2966 int num_free = 0;
2967 for (int i = 0; i < scope->id_info_len; i++) {
2968 id_info_t *id = &scope->id_info[i];
2969 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2970 num_free += 1;
2971 }
2972 }
2973 if (num_free == 0) {
2974 scope->flags |= SCOPE_FLAG_NOFREE;
2975 }
2976}
2977
Damien5ac1b2e2013-10-18 19:58:12 +01002978bool py_compile(py_parse_node_t pn, bool is_repl) {
Damien429d7192013-10-04 19:53:11 +01002979 compiler_t *comp = m_new(compiler_t, 1);
2980
Damien6cdd3af2013-10-05 18:08:26 +01002981 comp->qstr___class__ = qstr_from_str_static("__class__");
2982 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2983 comp->qstr___name__ = qstr_from_str_static("__name__");
2984 comp->qstr___module__ = qstr_from_str_static("__module__");
2985 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2986 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2987 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2988 comp->qstr_micropython = qstr_from_str_static("micropython");
Damien5ac1b2e2013-10-18 19:58:12 +01002989 comp->qstr_byte_code = qstr_from_str_static("byte_code");
Damien6cdd3af2013-10-05 18:08:26 +01002990 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002991 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002992 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damiend7933892013-11-28 19:12:18 +00002993 comp->qstr_range = qstr_from_str_static("range");
Damien429d7192013-10-04 19:53:11 +01002994
Damien5ac1b2e2013-10-18 19:58:12 +01002995 comp->is_repl = is_repl;
2996 comp->had_error = false;
2997
Damien429d7192013-10-04 19:53:11 +01002998 comp->break_label = 0;
2999 comp->continue_label = 0;
3000 comp->except_nest_level = 0;
3001 comp->scope_head = NULL;
3002 comp->scope_cur = NULL;
3003
Damien826005c2013-10-05 23:17:28 +01003004 // optimise constants
Damien429d7192013-10-04 19:53:11 +01003005 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01003006
3007 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01003008 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01003009
Damien826005c2013-10-05 23:17:28 +01003010 // compile pass 1
3011 comp->emit = emit_pass1_new(comp->qstr___class__);
3012 comp->emit_method_table = &emit_pass1_method_table;
3013 comp->emit_inline_asm = NULL;
3014 comp->emit_inline_asm_method_table = NULL;
3015 uint max_num_labels = 0;
Damien5ac1b2e2013-10-18 19:58:12 +01003016 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01003017 if (false) {
Damien3ef4abb2013-10-12 16:53:13 +01003018#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003019 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01003020 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01003021#endif
Damien826005c2013-10-05 23:17:28 +01003022 } else {
3023 compile_scope(comp, s, PASS_1);
3024 }
3025
3026 // update maximim number of labels needed
3027 if (comp->next_label > max_num_labels) {
3028 max_num_labels = comp->next_label;
3029 }
Damien429d7192013-10-04 19:53:11 +01003030 }
3031
Damien826005c2013-10-05 23:17:28 +01003032 // compute some things related to scope and identifiers
Damien5ac1b2e2013-10-18 19:58:12 +01003033 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damien429d7192013-10-04 19:53:11 +01003034 compile_scope_compute_things(comp, s);
3035 }
3036
Damien826005c2013-10-05 23:17:28 +01003037 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01003038 emit_pass1_free(comp->emit);
3039
Damien826005c2013-10-05 23:17:28 +01003040 // compile pass 2 and 3
Damien3ef4abb2013-10-12 16:53:13 +01003041#if !MICROPY_EMIT_CPYTHON
Damien6cdd3af2013-10-05 18:08:26 +01003042 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01003043 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01003044#endif
Damien3ef4abb2013-10-12 16:53:13 +01003045#if MICROPY_EMIT_INLINE_THUMB
Damien826005c2013-10-05 23:17:28 +01003046 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01003047#endif
Damien5ac1b2e2013-10-18 19:58:12 +01003048 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01003049 if (false) {
3050 // dummy
3051
Damien3ef4abb2013-10-12 16:53:13 +01003052#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003053 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
3054 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01003055 if (emit_inline_thumb == NULL) {
3056 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
3057 }
3058 comp->emit = NULL;
3059 comp->emit_method_table = NULL;
3060 comp->emit_inline_asm = emit_inline_thumb;
3061 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
3062 compile_scope_inline_asm(comp, s, PASS_2);
3063 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01003064#endif
3065
Damien826005c2013-10-05 23:17:28 +01003066 } else {
Damienc025ebb2013-10-12 14:30:21 +01003067
3068 // choose the emit type
3069
Damien3ef4abb2013-10-12 16:53:13 +01003070#if MICROPY_EMIT_CPYTHON
Damienc025ebb2013-10-12 14:30:21 +01003071 comp->emit = emit_cpython_new(max_num_labels);
3072 comp->emit_method_table = &emit_cpython_method_table;
3073#else
Damien826005c2013-10-05 23:17:28 +01003074 switch (s->emit_options) {
3075 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01003076 case EMIT_OPT_VIPER:
Damien3ef4abb2013-10-12 16:53:13 +01003077#if MICROPY_EMIT_X64
Damiendc833822013-10-06 01:01:01 +01003078 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01003079 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01003080 }
Damien13ed3a62013-10-08 09:05:10 +01003081 comp->emit_method_table = &emit_native_x64_method_table;
Damien3ef4abb2013-10-12 16:53:13 +01003082#elif MICROPY_EMIT_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003083 if (emit_native == NULL) {
3084 emit_native = emit_native_thumb_new(max_num_labels);
3085 }
3086 comp->emit_method_table = &emit_native_thumb_method_table;
3087#endif
3088 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01003089 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01003090 break;
3091
Damien826005c2013-10-05 23:17:28 +01003092 default:
3093 if (emit_bc == NULL) {
3094 emit_bc = emit_bc_new(max_num_labels);
3095 }
3096 comp->emit = emit_bc;
3097 comp->emit_method_table = &emit_bc_method_table;
3098 break;
3099 }
Damienc025ebb2013-10-12 14:30:21 +01003100#endif
3101
3102 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01003103 compile_scope(comp, s, PASS_2);
3104 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01003105 }
Damien429d7192013-10-04 19:53:11 +01003106 }
3107
3108 m_free(comp);
Damien5ac1b2e2013-10-18 19:58:12 +01003109
3110 return !comp->had_error;
Damien429d7192013-10-04 19:53:11 +01003111}