blob: 17aa20d249191df04c4440d0ca3cac6ef38792cb [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
Damien3a205172013-10-12 15:01:56 +0100285static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100286 assert(PY_PARSE_NODE_IS_LEAF(pn));
287 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
288 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
289 case PY_PARSE_NODE_ID: assert(0);
290 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_verbatim_int, arg); break;
291 case PY_PARSE_NODE_INTEGER: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
292 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
293 case PY_PARSE_NODE_STRING: EMIT(load_const_verbatim_quoted_str, arg, false); break;
294 case PY_PARSE_NODE_BYTES: EMIT(load_const_verbatim_quoted_str, arg, true); break;
295 case PY_PARSE_NODE_TOKEN:
296 switch (arg) {
297 case PY_TOKEN_KW_FALSE: EMIT(load_const_verbatim_str, "False"); break;
298 case PY_TOKEN_KW_NONE: EMIT(load_const_verbatim_str, "None"); break;
299 case PY_TOKEN_KW_TRUE: EMIT(load_const_verbatim_str, "True"); break;
300 default: assert(0);
301 }
302 break;
303 default: assert(0);
304 }
305}
306
Damien3a205172013-10-12 15:01:56 +0100307static 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 +0100308 int n = 0;
309 if (pns_list != NULL) {
310 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
311 }
312 int total = n;
313 bool is_const = true;
314 if (!PY_PARSE_NODE_IS_NULL(pn)) {
315 total += 1;
Damien3a205172013-10-12 15:01:56 +0100316 if (!cpython_c_tuple_is_const(pn)) {
Damien429d7192013-10-04 19:53:11 +0100317 is_const = false;
318 }
319 }
320 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100321 if (!cpython_c_tuple_is_const(pns_list->nodes[i])) {
Damien429d7192013-10-04 19:53:11 +0100322 is_const = false;
323 break;
324 }
325 }
326 if (total > 0 && is_const) {
327 bool need_comma = false;
328 EMIT(load_const_verbatim_start);
329 EMIT(load_const_verbatim_str, "(");
330 if (!PY_PARSE_NODE_IS_NULL(pn)) {
Damien3a205172013-10-12 15:01:56 +0100331 cpython_c_tuple_emit_const(comp, pn);
Damien429d7192013-10-04 19:53:11 +0100332 need_comma = true;
333 }
334 for (int i = 0; i < n; i++) {
335 if (need_comma) {
336 EMIT(load_const_verbatim_str, ", ");
337 }
Damien3a205172013-10-12 15:01:56 +0100338 cpython_c_tuple_emit_const(comp, pns_list->nodes[i]);
Damien429d7192013-10-04 19:53:11 +0100339 need_comma = true;
340 }
341 if (total == 1) {
342 EMIT(load_const_verbatim_str, ",)");
343 } else {
344 EMIT(load_const_verbatim_str, ")");
345 }
346 EMIT(load_const_verbatim_end);
347 } else {
348 if (!PY_PARSE_NODE_IS_NULL(pn)) {
349 compile_node(comp, pn);
350 }
351 for (int i = 0; i < n; i++) {
352 compile_node(comp, pns_list->nodes[i]);
353 }
354 EMIT(build_tuple, total);
355 }
356}
Damien3a205172013-10-12 15:01:56 +0100357#endif
358
359// funnelling all tuple creations through this function is purely so we can optionally agree with CPython
360void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
Damien3ef4abb2013-10-12 16:53:13 +0100361#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100362 cpython_c_tuple(comp, pn, pns_list);
363#else
364 int total = 0;
365 if (!PY_PARSE_NODE_IS_NULL(pn)) {
366 compile_node(comp, pn);
367 total += 1;
368 }
369 if (pns_list != NULL) {
370 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
371 for (int i = 0; i < n; i++) {
372 compile_node(comp, pns_list->nodes[i]);
373 }
374 total += n;
375 }
376 EMIT(build_tuple, total);
377#endif
378}
Damien429d7192013-10-04 19:53:11 +0100379
380void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
381 // a simple tuple expression
Damien429d7192013-10-04 19:53:11 +0100382 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
383}
384
Damien3a205172013-10-12 15:01:56 +0100385static bool node_is_const_false(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100386 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
387 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
388}
389
Damien3a205172013-10-12 15:01:56 +0100390static bool node_is_const_true(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100391 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);
392}
393
Damien3ef4abb2013-10-12 16:53:13 +0100394#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100395// the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
396static 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 +0100397 if (node_is_const_false(pn)) {
398 if (jump_if == false) {
399 EMIT(jump, label);
400 }
401 return;
402 } else if (node_is_const_true(pn)) {
403 if (jump_if == true) {
404 EMIT(jump, label);
405 }
406 return;
407 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
408 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
409 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
410 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
411 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100412 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100413 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100414 cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
Damien429d7192013-10-04 19:53:11 +0100415 }
Damien3a205172013-10-12 15:01:56 +0100416 cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100417 EMIT(label_assign, label2);
418 } else {
419 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100420 cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100421 }
422 }
423 return;
424 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
425 if (jump_if == false) {
426 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100427 cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100428 }
429 } else {
Damienb05d7072013-10-05 13:37:10 +0100430 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100431 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100432 cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
Damien429d7192013-10-04 19:53:11 +0100433 }
Damien3a205172013-10-12 15:01:56 +0100434 cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100435 EMIT(label_assign, label2);
436 }
437 return;
438 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
Damien3a205172013-10-12 15:01:56 +0100439 cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true);
Damien429d7192013-10-04 19:53:11 +0100440 return;
441 }
442 }
443
444 // nothing special, fall back to default compiling for node and jump
445 compile_node(comp, pn);
446 if (jump_if == false) {
447 EMIT(pop_jump_if_false, label);
448 } else {
449 EMIT(pop_jump_if_true, label);
450 }
451}
Damien3a205172013-10-12 15:01:56 +0100452#endif
Damien429d7192013-10-04 19:53:11 +0100453
Damien3a205172013-10-12 15:01:56 +0100454static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
Damien3ef4abb2013-10-12 16:53:13 +0100455#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100456 cpython_c_if_cond(comp, pn, jump_if, label, false);
457#else
458 if (node_is_const_false(pn)) {
459 if (jump_if == false) {
460 EMIT(jump, label);
461 }
462 return;
463 } else if (node_is_const_true(pn)) {
464 if (jump_if == true) {
465 EMIT(jump, label);
466 }
467 return;
468 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
469 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
470 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
471 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
472 if (jump_if == false) {
473 int label2 = comp_next_label(comp);
474 for (int i = 0; i < n - 1; i++) {
475 c_if_cond(comp, pns->nodes[i], true, label2);
476 }
477 c_if_cond(comp, pns->nodes[n - 1], false, label);
478 EMIT(label_assign, label2);
479 } else {
480 for (int i = 0; i < n; i++) {
481 c_if_cond(comp, pns->nodes[i], true, label);
482 }
483 }
484 return;
485 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
486 if (jump_if == false) {
487 for (int i = 0; i < n; i++) {
488 c_if_cond(comp, pns->nodes[i], false, label);
489 }
490 } else {
491 int label2 = comp_next_label(comp);
492 for (int i = 0; i < n - 1; i++) {
493 c_if_cond(comp, pns->nodes[i], false, label2);
494 }
495 c_if_cond(comp, pns->nodes[n - 1], true, label);
496 EMIT(label_assign, label2);
497 }
498 return;
499 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
500 c_if_cond(comp, pns->nodes[0], !jump_if, label);
501 return;
502 }
503 }
504
505 // nothing special, fall back to default compiling for node and jump
506 compile_node(comp, pn);
507 if (jump_if == false) {
508 EMIT(pop_jump_if_false, label);
509 } else {
510 EMIT(pop_jump_if_true, label);
511 }
512#endif
Damien429d7192013-10-04 19:53:11 +0100513}
514
515typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
516void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
517
518void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
519 if (assign_kind != ASSIGN_AUG_STORE) {
520 compile_node(comp, pns->nodes[0]);
521 }
522
523 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
524 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
525 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
526 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
527 if (assign_kind != ASSIGN_AUG_STORE) {
528 for (int i = 0; i < n - 1; i++) {
529 compile_node(comp, pns1->nodes[i]);
530 }
531 }
532 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
533 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
534 }
535 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
536 printf("SyntaxError: can't assign to function call\n");
537 return;
538 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
539 if (assign_kind == ASSIGN_AUG_STORE) {
540 EMIT(rot_three);
541 EMIT(store_subscr);
542 } else {
543 compile_node(comp, pns1->nodes[0]);
544 if (assign_kind == ASSIGN_AUG_LOAD) {
545 EMIT(dup_top_two);
546 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
547 } else {
548 EMIT(store_subscr);
549 }
550 }
551 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
552 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
553 if (assign_kind == ASSIGN_AUG_LOAD) {
554 EMIT(dup_top);
555 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
556 } else {
557 if (assign_kind == ASSIGN_AUG_STORE) {
558 EMIT(rot_two);
559 }
560 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
561 }
562 } else {
563 // shouldn't happen
564 assert(0);
565 }
566 } else {
567 // shouldn't happen
568 assert(0);
569 }
570
571 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
572 // SyntaxError, cannot assign
573 assert(0);
574 }
575}
576
577void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
578 assert(n >= 0);
579 int have_star_index = -1;
580 for (int i = 0; i < n; i++) {
581 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
582 if (have_star_index < 0) {
583 EMIT(unpack_ex, i, n - i - 1);
584 have_star_index = i;
585 } else {
586 printf("SyntaxError: two starred expressions in assignment\n");
587 return;
588 }
589 }
590 }
591 if (have_star_index < 0) {
592 EMIT(unpack_sequence, n);
593 }
594 for (int i = 0; i < n; i++) {
595 if (i == have_star_index) {
596 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
597 } else {
598 c_assign(comp, nodes[i], ASSIGN_STORE);
599 }
600 }
601}
602
603// assigns top of stack to pn
604void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
605 tail_recursion:
606 if (PY_PARSE_NODE_IS_NULL(pn)) {
607 assert(0);
608 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
609 if (PY_PARSE_NODE_IS_ID(pn)) {
610 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
611 switch (assign_kind) {
612 case ASSIGN_STORE:
613 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100614 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100615 break;
616 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100617 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100618 break;
619 }
620 } else {
621 printf("SyntaxError: can't assign to literal\n");
622 return;
623 }
624 } else {
625 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
626 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
627 case PN_power:
628 // lhs is an index or attribute
629 c_assign_power(comp, pns, assign_kind);
630 break;
631
632 case PN_testlist_star_expr:
633 case PN_exprlist:
634 // lhs is a tuple
635 if (assign_kind != ASSIGN_STORE) {
636 goto bad_aug;
637 }
638 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
639 break;
640
641 case PN_atom_paren:
642 // lhs is something in parenthesis
643 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
644 // empty tuple
645 printf("SyntaxError: can't assign to ()\n");
646 return;
647 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
648 pns = (py_parse_node_struct_t*)pns->nodes[0];
649 goto testlist_comp;
650 } else {
651 // parenthesis around 1 item, is just that item
652 pn = pns->nodes[0];
653 goto tail_recursion;
654 }
655 break;
656
657 case PN_atom_bracket:
658 // lhs is something in brackets
659 if (assign_kind != ASSIGN_STORE) {
660 goto bad_aug;
661 }
662 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
663 // empty list, assignment allowed
664 c_assign_tuple(comp, 0, NULL);
665 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
666 pns = (py_parse_node_struct_t*)pns->nodes[0];
667 goto testlist_comp;
668 } else {
669 // brackets around 1 item
670 c_assign_tuple(comp, 1, &pns->nodes[0]);
671 }
672 break;
673
674 default:
675 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
676 assert(0);
677 }
678 return;
679
680 testlist_comp:
681 // lhs is a sequence
682 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
683 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
684 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
685 // sequence of one item, with trailing comma
686 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
687 c_assign_tuple(comp, 1, &pns->nodes[0]);
688 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
689 // sequence of many items
690 // TODO call c_assign_tuple instead
691 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
692 EMIT(unpack_sequence, 1 + n);
693 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
694 for (int i = 0; i < n; i++) {
695 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
696 }
697 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
698 // TODO not implemented
699 assert(0);
700 } else {
701 // sequence with 2 items
702 goto sequence_with_2_items;
703 }
704 } else {
705 // sequence with 2 items
706 sequence_with_2_items:
707 c_assign_tuple(comp, 2, pns->nodes);
708 }
709 return;
710 }
711 return;
712
713 bad_aug:
714 printf("SyntaxError: illegal expression for augmented assignment\n");
715}
716
717// stuff for lambda and comprehensions and generators
718void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
719 // make closed over variables, if any
Damien318aec62013-12-10 18:28:17 +0000720 // ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython)
Damien429d7192013-10-04 19:53:11 +0100721 int nfree = 0;
722 if (comp->scope_cur->kind != SCOPE_MODULE) {
Damien318aec62013-12-10 18:28:17 +0000723 for (int i = 0; i < comp->scope_cur->id_info_len; i++) {
724 id_info_t *id = &comp->scope_cur->id_info[i];
725 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
726 for (int j = 0; j < this_scope->id_info_len; j++) {
727 id_info_t *id2 = &this_scope->id_info[j];
728 if (id2->kind == ID_INFO_KIND_FREE && id->qstr == id2->qstr) {
729 EMIT(load_closure, id->qstr, id->local_num);
730 nfree += 1;
731 }
732 }
Damien429d7192013-10-04 19:53:11 +0100733 }
734 }
735 }
736 if (nfree > 0) {
737 EMIT(build_tuple, nfree);
738 }
739
740 // make the function/closure
741 if (nfree == 0) {
742 EMIT(make_function, this_scope, n_dict_params, n_default_params);
743 } else {
744 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
745 }
746}
747
748void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100749 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
750 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100751 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
752 // this parameter has a default value
753 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
754 if (comp->have_bare_star) {
755 comp->param_pass_num_dict_params += 1;
756 if (comp->param_pass == 1) {
757 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
758 compile_node(comp, pns->nodes[2]);
759 }
760 } else {
761 comp->param_pass_num_default_params += 1;
762 if (comp->param_pass == 2) {
763 compile_node(comp, pns->nodes[2]);
764 }
765 }
766 }
Damienb14de212013-10-06 00:28:28 +0100767 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
768 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100769 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
770 // bare star
771 comp->have_bare_star = true;
772 }
773 }
774}
775
776// leaves function object on stack
777// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100778qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100779 if (comp->pass == PASS_1) {
780 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100781 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100782 // store the function scope so the compiling function can use it at each pass
783 pns->nodes[4] = (py_parse_node_t)s;
784 }
785
786 // save variables (probably don't need to do this, since we can't have nested definitions..?)
787 bool old_have_bare_star = comp->have_bare_star;
788 int old_param_pass = comp->param_pass;
789 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
790 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
791
792 // compile default parameters
793 comp->have_bare_star = false;
794 comp->param_pass = 1; // pass 1 does any default parameters after bare star
795 comp->param_pass_num_dict_params = 0;
796 comp->param_pass_num_default_params = 0;
797 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
798 comp->have_bare_star = false;
799 comp->param_pass = 2; // pass 2 does any default parameters before bare star
800 comp->param_pass_num_dict_params = 0;
801 comp->param_pass_num_default_params = 0;
802 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
803
804 // get the scope for this function
805 scope_t *fscope = (scope_t*)pns->nodes[4];
806
807 // make the function
808 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
809
810 // restore variables
811 comp->have_bare_star = old_have_bare_star;
812 comp->param_pass = old_param_pass;
813 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
814 comp->param_pass_num_default_params = old_param_pass_num_default_params;
815
816 // return its name (the 'f' in "def f(...):")
817 return fscope->simple_name;
818}
819
820// leaves class object on stack
821// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100822qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100823 if (comp->pass == PASS_1) {
824 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100825 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100826 // store the class scope so the compiling function can use it at each pass
827 pns->nodes[3] = (py_parse_node_t)s;
828 }
829
830 EMIT(load_build_class);
831
832 // scope for this class
833 scope_t *cscope = (scope_t*)pns->nodes[3];
834
835 // compile the class
836 close_over_variables_etc(comp, cscope, 0, 0);
837
838 // get its name
839 EMIT(load_const_id, cscope->simple_name);
840
841 // nodes[1] has parent classes, if any
842 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
843 // no parent classes
844 EMIT(call_function, 2, 0, false, false);
845 } else {
846 // have a parent class or classes
847 // TODO what if we have, eg, *a or **a in the parent list?
848 compile_node(comp, pns->nodes[1]);
849 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
850 }
851
852 // return its name (the 'C' in class C(...):")
853 return cscope->simple_name;
854}
855
Damien6cdd3af2013-10-05 18:08:26 +0100856// returns true if it was a built-in decorator (even if the built-in had an error)
857static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
858 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
859 return false;
860 }
861
862 if (name_len != 2) {
863 printf("SyntaxError: invalid micropython decorator\n");
864 return true;
865 }
866
867 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
Damien5ac1b2e2013-10-18 19:58:12 +0100868 if (attr == comp->qstr_byte_code) {
869 *emit_options = EMIT_OPT_BYTE_CODE;
Damience89a212013-10-15 22:25:17 +0100870#if MICROPY_EMIT_NATIVE
871 } else if (attr == comp->qstr_native) {
Damien6cdd3af2013-10-05 18:08:26 +0100872 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100873 } else if (attr == comp->qstr_viper) {
874 *emit_options = EMIT_OPT_VIPER;
Damience89a212013-10-15 22:25:17 +0100875#endif
Damien3ef4abb2013-10-12 16:53:13 +0100876#if MICROPY_EMIT_INLINE_THUMB
Damien5bfb7592013-10-05 18:41:24 +0100877 } else if (attr == comp->qstr_asm_thumb) {
878 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100879#endif
Damien6cdd3af2013-10-05 18:08:26 +0100880 } else {
Damience89a212013-10-15 22:25:17 +0100881 printf("SyntaxError: invalid micropython decorator '%s'\n", qstr_str(attr));
Damien6cdd3af2013-10-05 18:08:26 +0100882 }
883
884 return true;
885}
886
Damien429d7192013-10-04 19:53:11 +0100887void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
888 // get the list of decorators
889 py_parse_node_t *nodes;
890 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
891
Damien6cdd3af2013-10-05 18:08:26 +0100892 // inherit emit options for this function/class definition
893 uint emit_options = comp->scope_cur->emit_options;
894
895 // compile each decorator
896 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100897 for (int i = 0; i < n; i++) {
898 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
899 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100900
901 // nodes[0] contains the decorator function, which is a dotted name
902 py_parse_node_t *name_nodes;
903 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
904
905 // check for built-in decorators
906 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
907 // this was a built-in
908 num_built_in_decorators += 1;
909
910 } else {
911 // not a built-in, compile normally
912
913 // compile the decorator function
914 compile_node(comp, name_nodes[0]);
915 for (int i = 1; i < name_len; i++) {
916 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
917 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
918 }
919
920 // nodes[1] contains arguments to the decorator function, if any
921 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
922 // call the decorator function with the arguments in nodes[1]
923 compile_node(comp, pns_decorator->nodes[1]);
924 }
Damien429d7192013-10-04 19:53:11 +0100925 }
926 }
927
928 // compile the body (funcdef or classdef) and get its name
929 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
930 qstr body_name = 0;
931 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100932 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100933 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100934 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100935 } else {
936 // shouldn't happen
937 assert(0);
938 }
939
940 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100941 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100942 EMIT(call_function, 1, 0, false, false);
943 }
944
945 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100946 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100947}
948
949void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100950 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100951 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100952 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100953}
954
955void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
956 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100957 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100958 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
959 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
960
961 compile_node(comp, pns->nodes[0]); // base of the power node
962
963 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
964 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
965 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
966 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
967 for (int i = 0; i < n - 1; i++) {
968 compile_node(comp, pns1->nodes[i]);
969 }
970 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
971 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
972 }
973 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
974 // SyntaxError: can't delete a function call
975 assert(0);
976 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
977 compile_node(comp, pns1->nodes[0]);
978 EMIT(delete_subscr);
979 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
980 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
981 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
982 } else {
983 // shouldn't happen
984 assert(0);
985 }
986 } else {
987 // shouldn't happen
988 assert(0);
989 }
990
991 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
992 // SyntaxError, cannot delete
993 assert(0);
994 }
995 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
996 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
997 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
998 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
999 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
1000
1001 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1002 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1003 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
1004 // sequence of one item, with trailing comma
1005 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
1006 c_del_stmt(comp, pns->nodes[0]);
1007 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
1008 // sequence of many items
1009 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
1010 c_del_stmt(comp, pns->nodes[0]);
1011 for (int i = 0; i < n; i++) {
1012 c_del_stmt(comp, pns1->nodes[i]);
1013 }
1014 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
1015 // TODO not implemented; can't del comprehension?
1016 assert(0);
1017 } else {
1018 // sequence with 2 items
1019 goto sequence_with_2_items;
1020 }
1021 } else {
1022 // sequence with 2 items
1023 sequence_with_2_items:
1024 c_del_stmt(comp, pns->nodes[0]);
1025 c_del_stmt(comp, pns->nodes[1]);
1026 }
1027 } else {
1028 // tuple with 1 element
1029 c_del_stmt(comp, pn);
1030 }
1031 } else {
1032 // not implemented
1033 assert(0);
1034 }
1035}
1036
1037void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1038 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
1039}
1040
1041void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1042 if (comp->break_label == 0) {
1043 printf("ERROR: cannot break from here\n");
1044 }
1045 EMIT(break_loop, comp->break_label);
1046}
1047
1048void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1049 if (comp->continue_label == 0) {
1050 printf("ERROR: cannot continue from here\n");
1051 }
1052 if (comp->except_nest_level > 0) {
1053 EMIT(continue_loop, comp->continue_label);
1054 } else {
1055 EMIT(jump, comp->continue_label);
1056 }
1057}
1058
1059void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien5ac1b2e2013-10-18 19:58:12 +01001060 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
1061 printf("SyntaxError: 'return' outside function\n");
1062 comp->had_error = true;
1063 return;
1064 }
Damien429d7192013-10-04 19:53:11 +01001065 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001066 // no argument to 'return', so return None
Damien429d7192013-10-04 19:53:11 +01001067 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1068 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
1069 // special case when returning an if-expression; to match CPython optimisation
1070 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
1071 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
1072
Damienb05d7072013-10-05 13:37:10 +01001073 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001074 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1075 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
1076 EMIT(return_value);
1077 EMIT(label_assign, l_fail);
1078 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1079 } else {
1080 compile_node(comp, pns->nodes[0]);
1081 }
1082 EMIT(return_value);
1083}
1084
1085void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1086 compile_node(comp, pns->nodes[0]);
1087 EMIT(pop_top);
1088}
1089
1090void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1091 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1092 // raise
1093 EMIT(raise_varargs, 0);
1094 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1095 // raise x from y
1096 pns = (py_parse_node_struct_t*)pns->nodes[0];
1097 compile_node(comp, pns->nodes[0]);
1098 compile_node(comp, pns->nodes[1]);
1099 EMIT(raise_varargs, 2);
1100 } else {
1101 // raise x
1102 compile_node(comp, pns->nodes[0]);
1103 EMIT(raise_varargs, 1);
1104 }
1105}
1106
1107// q1 holds the base, q2 the full name
1108// eg a -> q1=q2=a
1109// a.b.c -> q1=a, q2=a.b.c
1110void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1111 bool is_as = false;
1112 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1113 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1114 // a name of the form x as y; unwrap it
1115 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1116 pn = pns->nodes[0];
1117 is_as = true;
1118 }
1119 if (PY_PARSE_NODE_IS_ID(pn)) {
1120 // just a simple name
1121 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1122 if (!is_as) {
1123 *q1 = *q2;
1124 }
1125 EMIT(import_name, *q2);
1126 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1127 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1128 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1129 // a name of the form a.b.c
1130 if (!is_as) {
1131 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1132 }
1133 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1134 int len = n - 1;
1135 for (int i = 0; i < n; i++) {
1136 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1137 }
1138 char *str = m_new(char, len + 1);
1139 str[0] = 0;
1140 for (int i = 0; i < n; i++) {
1141 if (i > 0) {
1142 strcat(str, ".");
1143 }
1144 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1145 }
1146 *q2 = qstr_from_str_take(str);
1147 EMIT(import_name, *q2);
1148 if (is_as) {
1149 for (int i = 1; i < n; i++) {
1150 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1151 }
1152 }
1153 } else {
1154 // TODO not implemented
1155 assert(0);
1156 }
1157 } else {
1158 // TODO not implemented
1159 assert(0);
1160 }
1161}
1162
1163void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1164 EMIT(load_const_small_int, 0); // ??
1165 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1166 qstr q1, q2;
1167 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001168 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001169}
1170
1171void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1172 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1173}
1174
1175void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1176 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
Damiendb4c3612013-12-10 17:27:24 +00001177 EMIT(load_const_small_int, 0); // level 0 for __import__
1178
1179 // build the "fromlist" tuple
1180#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001181 EMIT(load_const_verbatim_start);
1182 EMIT(load_const_verbatim_str, "('*',)");
1183 EMIT(load_const_verbatim_end);
Damiendb4c3612013-12-10 17:27:24 +00001184#else
1185 EMIT(load_const_str, qstr_from_str_static("*"), false);
1186 EMIT(build_tuple, 1);
1187#endif
1188
1189 // do the import
Damien429d7192013-10-04 19:53:11 +01001190 qstr dummy_q, id1;
1191 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1192 EMIT(import_star);
Damiendb4c3612013-12-10 17:27:24 +00001193
Damien429d7192013-10-04 19:53:11 +01001194 } else {
Damiendb4c3612013-12-10 17:27:24 +00001195 EMIT(load_const_small_int, 0); // level 0 for __import__
1196
1197 // build the "fromlist" tuple
Damien429d7192013-10-04 19:53:11 +01001198 py_parse_node_t *pn_nodes;
1199 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
Damiendb4c3612013-12-10 17:27:24 +00001200#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001201 EMIT(load_const_verbatim_start);
1202 EMIT(load_const_verbatim_str, "(");
1203 for (int i = 0; i < n; i++) {
1204 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1205 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1206 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1207 if (i > 0) {
1208 EMIT(load_const_verbatim_str, ", ");
1209 }
1210 EMIT(load_const_verbatim_str, "'");
1211 EMIT(load_const_verbatim_str, qstr_str(id2));
1212 EMIT(load_const_verbatim_str, "'");
1213 }
1214 if (n == 1) {
1215 EMIT(load_const_verbatim_str, ",");
1216 }
1217 EMIT(load_const_verbatim_str, ")");
1218 EMIT(load_const_verbatim_end);
Damiendb4c3612013-12-10 17:27:24 +00001219#else
1220 for (int i = 0; i < n; i++) {
1221 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1222 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1223 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1224 EMIT(load_const_str, id2, false);
1225 }
1226 EMIT(build_tuple, n);
1227#endif
1228
1229 // do the import
Damien429d7192013-10-04 19:53:11 +01001230 qstr dummy_q, id1;
1231 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1232 for (int i = 0; i < n; i++) {
1233 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1234 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1235 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1236 EMIT(import_from, id2);
1237 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001238 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001239 } else {
Damien4b03e772013-10-05 14:17:09 +01001240 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001241 }
1242 }
1243 EMIT(pop_top);
1244 }
1245}
1246
1247void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001248 if (comp->pass == PASS_1) {
1249 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1250 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1251 } else {
1252 pns = (py_parse_node_struct_t*)pns->nodes[0];
1253 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1254 for (int i = 0; i < num_nodes; i++) {
1255 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1256 }
Damien429d7192013-10-04 19:53:11 +01001257 }
1258 }
1259}
1260
1261void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001262 if (comp->pass == PASS_1) {
1263 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1264 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1265 } else {
1266 pns = (py_parse_node_struct_t*)pns->nodes[0];
1267 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1268 for (int i = 0; i < num_nodes; i++) {
1269 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1270 }
Damien429d7192013-10-04 19:53:11 +01001271 }
1272 }
1273}
1274
1275void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001276 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001277 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001278 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001279 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1280 // assertion message
1281 compile_node(comp, pns->nodes[1]);
1282 EMIT(call_function, 1, 0, false, false);
1283 }
1284 EMIT(raise_varargs, 1);
1285 EMIT(label_assign, l_end);
1286}
1287
1288void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1289 // TODO proper and/or short circuiting
1290
Damienb05d7072013-10-05 13:37:10 +01001291 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001292
Damienb05d7072013-10-05 13:37:10 +01001293 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001294 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1295
1296 compile_node(comp, pns->nodes[1]); // if block
1297 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1298 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001299 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001300 EMIT(jump, l_end);
1301 }
1302 //}
1303 EMIT(label_assign, l_fail);
1304
1305 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1306 // compile elif blocks
1307
1308 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1309
1310 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1311 // multiple elif blocks
1312
1313 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1314 for (int i = 0; i < n; i++) {
1315 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001316 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001317 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1318
1319 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001320 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001321 EMIT(jump, l_end);
1322 }
1323 EMIT(label_assign, l_fail);
1324 }
1325
1326 } else {
1327 // a single elif block
1328
Damienb05d7072013-10-05 13:37:10 +01001329 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001330 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1331
1332 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001333 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001334 EMIT(jump, l_end);
1335 }
1336 EMIT(label_assign, l_fail);
1337 }
1338 }
1339
1340 // compile else block
1341 compile_node(comp, pns->nodes[3]); // can be null
1342
1343 EMIT(label_assign, l_end);
1344}
1345
1346void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1347 int old_break_label = comp->break_label;
1348 int old_continue_label = comp->continue_label;
1349
Damienb05d7072013-10-05 13:37:10 +01001350 int break_label = comp_next_label(comp);
1351 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001352
1353 comp->break_label = break_label;
1354 comp->continue_label = continue_label;
1355
Damience89a212013-10-15 22:25:17 +01001356 // compared to CPython, we have an optimised version of while loops
1357#if MICROPY_EMIT_CPYTHON
1358 int done_label = comp_next_label(comp);
1359 EMIT(setup_loop, break_label);
Damien429d7192013-10-04 19:53:11 +01001360 EMIT(label_assign, continue_label);
1361 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1362 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001363 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001364 EMIT(jump, continue_label);
1365 }
1366 EMIT(label_assign, done_label);
Damien429d7192013-10-04 19:53:11 +01001367 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1368 // this is a small hack to agree with CPython
1369 if (!node_is_const_true(pns->nodes[0])) {
1370 EMIT(pop_block);
1371 }
Damience89a212013-10-15 22:25:17 +01001372#else
1373 int top_label = comp_next_label(comp);
1374 EMIT(jump, continue_label);
1375 EMIT(label_assign, top_label);
1376 compile_node(comp, pns->nodes[1]); // body
1377 EMIT(label_assign, continue_label);
1378 c_if_cond(comp, pns->nodes[0], true, top_label); // condition
1379#endif
1380
1381 // break/continue apply to outer loop (if any) in the else block
1382 comp->break_label = old_break_label;
1383 comp->continue_label = old_continue_label;
Damien429d7192013-10-04 19:53:11 +01001384
1385 compile_node(comp, pns->nodes[2]); // else
1386
1387 EMIT(label_assign, break_label);
Damien429d7192013-10-04 19:53:11 +01001388}
1389
Damienf72fd0e2013-11-06 20:20:49 +00001390// TODO preload end and step onto stack if they are not constants
1391// TODO check if step is negative and do opposite test
1392void 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) {
1393 int old_break_label = comp->break_label;
1394 int old_continue_label = comp->continue_label;
1395
1396 int break_label = comp_next_label(comp);
1397 int continue_label = comp_next_label(comp);
1398
1399 comp->break_label = break_label;
1400 comp->continue_label = continue_label;
1401
1402 int top_label = comp_next_label(comp);
1403
1404 // compile: var = start
1405 compile_node(comp, pn_start);
1406 c_assign(comp, pn_var, ASSIGN_STORE);
1407
1408 EMIT(jump, continue_label);
1409 EMIT(label_assign, top_label);
1410
Damienf3822fc2013-11-09 20:12:03 +00001411 // compile body
1412 compile_node(comp, pn_body);
1413
Damienf72fd0e2013-11-06 20:20:49 +00001414 // compile: var += step
1415 c_assign(comp, pn_var, ASSIGN_AUG_LOAD);
1416 compile_node(comp, pn_step);
1417 EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD);
1418 c_assign(comp, pn_var, ASSIGN_AUG_STORE);
1419
Damienf72fd0e2013-11-06 20:20:49 +00001420 EMIT(label_assign, continue_label);
1421
1422 // compile: if var < end: goto top
1423 compile_node(comp, pn_var);
1424 compile_node(comp, pn_end);
1425 EMIT(compare_op, RT_COMPARE_OP_LESS);
1426 EMIT(pop_jump_if_true, top_label);
1427
1428 // break/continue apply to outer loop (if any) in the else block
1429 comp->break_label = old_break_label;
1430 comp->continue_label = old_continue_label;
1431
1432 compile_node(comp, pn_else);
1433
1434 EMIT(label_assign, break_label);
1435}
1436
Damien429d7192013-10-04 19:53:11 +01001437void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienf72fd0e2013-11-06 20:20:49 +00001438#if !MICROPY_EMIT_CPYTHON
1439 // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
1440 // this is actually slower, but uses no heap memory
1441 // for viper it will be much, much faster
Damiend7933892013-11-28 19:12:18 +00001442 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 +00001443 py_parse_node_struct_t *pns_it = (py_parse_node_struct_t*)pns->nodes[1];
Damiend7933892013-11-28 19:12:18 +00001444 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 +00001445 py_parse_node_t pn_range_args = ((py_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
1446 py_parse_node_t *args;
1447 int n_args = list_get(&pn_range_args, PN_arglist, &args);
1448 if (1 <= n_args && n_args <= 3) {
1449 py_parse_node_t pn_range_start;
1450 py_parse_node_t pn_range_end;
1451 py_parse_node_t pn_range_step;
1452 if (n_args == 1) {
1453 pn_range_start = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 0);
1454 pn_range_end = args[0];
1455 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1456 } else if (n_args == 2) {
1457 pn_range_start = args[0];
1458 pn_range_end = args[1];
1459 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1460 } else {
1461 pn_range_start = args[0];
1462 pn_range_end = args[1];
1463 pn_range_step = args[2];
1464 }
1465 compile_for_stmt_optimised_range(comp, pns->nodes[0], pn_range_start, pn_range_end, pn_range_step, pns->nodes[2], pns->nodes[3]);
1466 return;
1467 }
1468 }
1469 }
1470#endif
1471
Damien429d7192013-10-04 19:53:11 +01001472 int old_break_label = comp->break_label;
1473 int old_continue_label = comp->continue_label;
1474
Damienb05d7072013-10-05 13:37:10 +01001475 int for_label = comp_next_label(comp);
1476 int pop_label = comp_next_label(comp);
1477 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001478
Damienb05d7072013-10-05 13:37:10 +01001479 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001480
1481 comp->continue_label = for_label;
1482 comp->break_label = break_label;
1483
Damience89a212013-10-15 22:25:17 +01001484 // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
1485#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001486 EMIT(setup_loop, end_label);
Damience89a212013-10-15 22:25:17 +01001487#endif
1488
Damien429d7192013-10-04 19:53:11 +01001489 compile_node(comp, pns->nodes[1]); // iterator
1490 EMIT(get_iter);
1491 EMIT(label_assign, for_label);
1492 EMIT(for_iter, pop_label);
1493 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1494 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001495 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001496 EMIT(jump, for_label);
1497 }
1498 EMIT(label_assign, pop_label);
1499 EMIT(for_iter_end);
1500
1501 // break/continue apply to outer loop (if any) in the else block
1502 comp->break_label = old_break_label;
1503 comp->continue_label = old_continue_label;
1504
Damience89a212013-10-15 22:25:17 +01001505#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001506 EMIT(pop_block);
Damience89a212013-10-15 22:25:17 +01001507#endif
Damien429d7192013-10-04 19:53:11 +01001508
1509 compile_node(comp, pns->nodes[3]); // else (not tested)
1510
1511 EMIT(label_assign, break_label);
1512 EMIT(label_assign, end_label);
1513}
1514
1515void 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) {
1516 // this function is a bit of a hack at the moment
1517 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1518
1519 // setup code
1520 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001521 int l1 = comp_next_label(comp);
1522 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001523 comp->except_nest_level += 1; // for correct handling of continue
1524 EMIT(setup_except, l1);
1525 compile_node(comp, pn_body); // body
1526 EMIT(pop_block);
1527 EMIT(jump, success_label);
1528 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001529 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001530
1531 for (int i = 0; i < n_except; i++) {
1532 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1533 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1534
1535 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001536 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001537
1538 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1539 // this is a catch all exception handler
1540 if (i + 1 != n_except) {
1541 printf("SyntaxError: default 'except:' must be last\n");
1542 return;
1543 }
1544 } else {
1545 // this exception handler requires a match to a certain type of exception
1546 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1547 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1548 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1549 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1550 // handler binds the exception to a local
1551 pns_exception_expr = pns3->nodes[0];
1552 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1553 }
1554 }
1555 EMIT(dup_top);
1556 compile_node(comp, pns_exception_expr);
1557 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1558 EMIT(pop_jump_if_false, end_finally_label);
1559 }
1560
1561 EMIT(pop_top);
1562
1563 if (qstr_exception_local == 0) {
1564 EMIT(pop_top);
1565 } else {
Damien4b03e772013-10-05 14:17:09 +01001566 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001567 }
1568
1569 EMIT(pop_top);
1570
1571 int l3;
1572 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001573 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001574 EMIT(setup_finally, l3);
1575 }
1576 compile_node(comp, pns_except->nodes[1]);
1577 if (qstr_exception_local != 0) {
1578 EMIT(pop_block);
1579 }
1580 EMIT(pop_except);
1581 if (qstr_exception_local != 0) {
1582 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1583 EMIT(label_assign, l3);
1584 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001585 EMIT(store_id, qstr_exception_local);
1586 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001587 EMIT(end_finally);
1588 }
1589 EMIT(jump, l2);
1590 EMIT(label_assign, end_finally_label);
1591 }
1592
1593 EMIT(end_finally);
1594 EMIT(label_assign, success_label);
1595 comp->except_nest_level -= 1;
1596 compile_node(comp, pn_else); // else block, can be null
1597 EMIT(label_assign, l2);
1598 EMIT(set_stack_size, stack_size);
1599}
1600
1601void 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) {
1602 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1603 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001604 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001605 EMIT(setup_finally, l_finally_block);
1606 if (n_except == 0) {
1607 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1608 compile_node(comp, pn_body);
1609 } else {
1610 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1611 }
1612 EMIT(pop_block);
1613 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1614 EMIT(label_assign, l_finally_block);
1615 compile_node(comp, pn_finally);
1616 EMIT(end_finally);
1617 EMIT(set_stack_size, stack_size);
1618}
1619
1620void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1621 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1622 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1623 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1624 // just try-finally
1625 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1626 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1627 // try-except and possibly else and/or finally
1628 py_parse_node_t *pn_excepts;
1629 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1630 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1631 // no finally
1632 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1633 } else {
1634 // have finally
1635 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1636 }
1637 } else {
1638 // just try-except
1639 py_parse_node_t *pn_excepts;
1640 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1641 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1642 }
1643 } else {
1644 // shouldn't happen
1645 assert(0);
1646 }
1647}
1648
1649void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1650 if (n == 0) {
1651 // no more pre-bits, compile the body of the with
1652 compile_node(comp, body);
1653 } else {
Damienb05d7072013-10-05 13:37:10 +01001654 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001655 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1656 // this pre-bit is of the form "a as b"
1657 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1658 compile_node(comp, pns->nodes[0]);
1659 EMIT(setup_with, l_end);
1660 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1661 } else {
1662 // this pre-bit is just an expression
1663 compile_node(comp, nodes[0]);
1664 EMIT(setup_with, l_end);
1665 EMIT(pop_top);
1666 }
1667 // compile additional pre-bits and the body
1668 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1669 // finish this with block
1670 EMIT(pop_block);
1671 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1672 EMIT(label_assign, l_end);
1673 EMIT(with_cleanup);
1674 EMIT(end_finally);
1675 }
1676}
1677
1678void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1679 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1680 py_parse_node_t *nodes;
1681 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1682 assert(n > 0);
1683
1684 // compile in a nested fashion
1685 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1686}
1687
1688void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1689 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001690 if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
1691 // for REPL, evaluate then print the expression
1692 EMIT(load_id, qstr_from_str_static("__repl_print__"));
1693 compile_node(comp, pns->nodes[0]);
1694 EMIT(call_function, 1, 0, false, false);
1695 EMIT(pop_top);
1696
Damien429d7192013-10-04 19:53:11 +01001697 } else {
Damien5ac1b2e2013-10-18 19:58:12 +01001698 // for non-REPL, evaluate then discard the expression
1699 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1700 // do nothing with a lonely constant
1701 } else {
1702 compile_node(comp, pns->nodes[0]); // just an expression
1703 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1704 }
Damien429d7192013-10-04 19:53:11 +01001705 }
1706 } else {
1707 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1708 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1709 if (kind == PN_expr_stmt_augassign) {
1710 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1711 compile_node(comp, pns1->nodes[1]); // rhs
1712 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1713 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1714 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1715 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1716 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1717 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1718 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1719 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1720 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1721 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1722 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1723 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1724 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1725 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1726 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1727 default: assert(0); // shouldn't happen
1728 }
1729 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1730 } else if (kind == PN_expr_stmt_assign_list) {
1731 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1732 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1733 // following CPython, we store left-most first
1734 if (rhs > 0) {
1735 EMIT(dup_top);
1736 }
1737 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1738 for (int i = 0; i < rhs; i++) {
1739 if (i + 1 < rhs) {
1740 EMIT(dup_top);
1741 }
1742 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1743 }
1744 } else if (kind == PN_expr_stmt_assign) {
1745 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1746 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1747 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1748 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1749 // optimisation for a, b = c, d; to match CPython's optimisation
1750 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1751 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1752 compile_node(comp, pns10->nodes[0]); // rhs
1753 compile_node(comp, pns10->nodes[1]); // rhs
1754 EMIT(rot_two);
1755 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1756 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1757 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1758 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1759 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1760 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1761 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1762 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1763 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1764 compile_node(comp, pns10->nodes[0]); // rhs
1765 compile_node(comp, pns10->nodes[1]); // rhs
1766 compile_node(comp, pns10->nodes[2]); // rhs
1767 EMIT(rot_three);
1768 EMIT(rot_two);
1769 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1770 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1771 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1772 } else {
1773 compile_node(comp, pns1->nodes[0]); // rhs
1774 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1775 }
1776 } else {
1777 // shouldn't happen
1778 assert(0);
1779 }
1780 }
1781}
1782
1783void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1784 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1785 compile_node(comp, pns->nodes[0]);
1786 for (int i = 1; i < num_nodes; i += 1) {
1787 compile_node(comp, pns->nodes[i]);
1788 EMIT(binary_op, binary_op);
1789 }
1790}
1791
1792void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1793 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1794 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1795
1796 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001797 int l_fail = comp_next_label(comp);
1798 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001799 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1800 compile_node(comp, pns->nodes[0]); // success value
1801 EMIT(jump, l_end);
1802 EMIT(label_assign, l_fail);
1803 EMIT(set_stack_size, stack_size); // force stack size reset
1804 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1805 EMIT(label_assign, l_end);
1806}
1807
1808void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1809 // TODO default params etc for lambda; possibly just use funcdef code
1810 //py_parse_node_t pn_params = pns->nodes[0];
1811 //py_parse_node_t pn_body = pns->nodes[1];
1812
1813 if (comp->pass == PASS_1) {
1814 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001815 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 +01001816 // store the lambda scope so the compiling function (this one) can use it at each pass
1817 pns->nodes[2] = (py_parse_node_t)s;
1818 }
1819
1820 // get the scope for this lambda
1821 scope_t *this_scope = (scope_t*)pns->nodes[2];
1822
1823 // make the lambda
1824 close_over_variables_etc(comp, this_scope, 0, 0);
1825}
1826
1827void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001828 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001829 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1830 for (int i = 0; i < n; i += 1) {
1831 compile_node(comp, pns->nodes[i]);
1832 if (i + 1 < n) {
1833 EMIT(jump_if_true_or_pop, l_end);
1834 }
1835 }
1836 EMIT(label_assign, l_end);
1837}
1838
1839void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001840 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001841 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1842 for (int i = 0; i < n; i += 1) {
1843 compile_node(comp, pns->nodes[i]);
1844 if (i + 1 < n) {
1845 EMIT(jump_if_false_or_pop, l_end);
1846 }
1847 }
1848 EMIT(label_assign, l_end);
1849}
1850
1851void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1852 compile_node(comp, pns->nodes[0]);
1853 EMIT(unary_op, RT_UNARY_OP_NOT);
1854}
1855
1856void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1857 int stack_size = EMIT(get_stack_size);
1858 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1859 compile_node(comp, pns->nodes[0]);
1860 bool multi = (num_nodes > 3);
1861 int l_fail = 0;
1862 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001863 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001864 }
1865 for (int i = 1; i + 1 < num_nodes; i += 2) {
1866 compile_node(comp, pns->nodes[i + 1]);
1867 if (i + 2 < num_nodes) {
1868 EMIT(dup_top);
1869 EMIT(rot_three);
1870 }
1871 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1872 EMIT(compare_op, RT_COMPARE_OP_LESS);
1873 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1874 EMIT(compare_op, RT_COMPARE_OP_MORE);
1875 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1876 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1877 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1878 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1879 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1880 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1881 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1882 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1883 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1884 EMIT(compare_op, RT_COMPARE_OP_IN);
1885 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1886 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1887 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1888 if (kind == PN_comp_op_not_in) {
1889 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1890 } else if (kind == PN_comp_op_is) {
1891 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1892 EMIT(compare_op, RT_COMPARE_OP_IS);
1893 } else {
1894 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1895 }
1896 } else {
1897 // shouldn't happen
1898 assert(0);
1899 }
1900 } else {
1901 // shouldn't happen
1902 assert(0);
1903 }
1904 if (i + 2 < num_nodes) {
1905 EMIT(jump_if_false_or_pop, l_fail);
1906 }
1907 }
1908 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001909 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001910 EMIT(jump, l_end);
1911 EMIT(label_assign, l_fail);
1912 EMIT(rot_two);
1913 EMIT(pop_top);
1914 EMIT(label_assign, l_end);
1915 EMIT(set_stack_size, stack_size + 1); // force stack size
1916 }
1917}
1918
1919void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1920 // TODO
1921 assert(0);
1922 compile_node(comp, pns->nodes[0]);
1923 //EMIT(unary_op, "UNARY_STAR");
1924}
1925
1926void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1927 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1928}
1929
1930void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1931 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1932}
1933
1934void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1935 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1936}
1937
1938void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1939 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1940 compile_node(comp, pns->nodes[0]);
1941 for (int i = 1; i + 1 < num_nodes; i += 2) {
1942 compile_node(comp, pns->nodes[i + 1]);
1943 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1944 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1945 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1946 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1947 } else {
1948 // shouldn't happen
1949 assert(0);
1950 }
1951 }
1952}
1953
1954void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1955 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1956 compile_node(comp, pns->nodes[0]);
1957 for (int i = 1; i + 1 < num_nodes; i += 2) {
1958 compile_node(comp, pns->nodes[i + 1]);
1959 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
1960 EMIT(binary_op, RT_BINARY_OP_ADD);
1961 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1962 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1963 } else {
1964 // shouldn't happen
1965 assert(0);
1966 }
1967 }
1968}
1969
1970void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1971 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1972 compile_node(comp, pns->nodes[0]);
1973 for (int i = 1; i + 1 < num_nodes; i += 2) {
1974 compile_node(comp, pns->nodes[i + 1]);
1975 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1976 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1977 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1978 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1979 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1980 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1981 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1982 EMIT(binary_op, RT_BINARY_OP_MODULO);
1983 } else {
1984 // shouldn't happen
1985 assert(0);
1986 }
1987 }
1988}
1989
1990void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1991 compile_node(comp, pns->nodes[1]);
1992 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1993 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1994 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1995 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1996 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1997 EMIT(unary_op, RT_UNARY_OP_INVERT);
1998 } else {
1999 // shouldn't happen
2000 assert(0);
2001 }
2002}
2003
2004void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
2005 // function to call is on top of stack
2006
2007 int old_n_arg_keyword = comp->n_arg_keyword;
2008 bool old_have_star_arg = comp->have_star_arg;
2009 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
2010 comp->n_arg_keyword = 0;
2011 comp->have_star_arg = false;
2012 comp->have_dbl_star_arg = false;
2013
2014 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
2015
2016 // compute number of positional arguments
2017 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
2018 if (comp->have_star_arg) {
2019 n_positional -= 1;
2020 }
2021 if (comp->have_dbl_star_arg) {
2022 n_positional -= 1;
2023 }
2024
2025 if (is_method_call) {
2026 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
2027 } else {
2028 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
2029 }
2030
2031 comp->n_arg_keyword = old_n_arg_keyword;
2032 comp->have_star_arg = old_have_star_arg;
2033 comp->have_dbl_star_arg = old_have_dbl_star_arg;
2034}
2035
2036void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
2037 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2038 for (int i = 0; i < num_nodes; i++) {
2039 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)) {
2040 // optimisation for method calls a.f(...), following PyPy
2041 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
2042 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
2043 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
2044 compile_trailer_paren_helper(comp, pns_paren, true);
2045 i += 1;
2046 } else {
2047 compile_node(comp, pns->nodes[i]);
2048 }
2049 }
2050}
2051
2052void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2053 compile_node(comp, pns->nodes[0]);
2054 EMIT(binary_op, RT_BINARY_OP_POWER);
2055}
2056
2057void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
2058 // a list of strings
Damien63321742013-12-10 17:41:49 +00002059
2060 // check type of list (string or bytes) and count total number of bytes
Damien429d7192013-10-04 19:53:11 +01002061 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
Damien63321742013-12-10 17:41:49 +00002062 int n_bytes = 0;
2063 int string_kind = PY_PARSE_NODE_NULL;
Damien429d7192013-10-04 19:53:11 +01002064 for (int i = 0; i < n; i++) {
Damien429d7192013-10-04 19:53:11 +01002065 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
Damien63321742013-12-10 17:41:49 +00002066 int pn_kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]);
2067 assert(pn_kind == PY_PARSE_NODE_STRING || pn_kind == PY_PARSE_NODE_BYTES);
2068 if (i == 0) {
2069 string_kind = pn_kind;
2070 } else if (pn_kind != string_kind) {
2071 printf("SyntaxError: cannot mix bytes and nonbytes literals\n");
2072 return;
2073 }
Damien429d7192013-10-04 19:53:11 +01002074 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
Damien63321742013-12-10 17:41:49 +00002075 n_bytes += strlen(str);
Damien429d7192013-10-04 19:53:11 +01002076 }
Damien63321742013-12-10 17:41:49 +00002077
2078 // allocate memory for concatenated string/bytes
2079 char *cat_str = m_new(char, n_bytes + 1);
2080 cat_str[0] = '\0';
2081
2082 // concatenate string/bytes
2083 for (int i = 0; i < n; i++) {
2084 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
2085 strcat(cat_str, str);
2086 }
2087
2088 EMIT(load_const_str, qstr_from_str_take(cat_str), string_kind == PY_PARSE_NODE_BYTES);
Damien429d7192013-10-04 19:53:11 +01002089}
2090
2091// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
2092void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
2093 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2094 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2095 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2096
2097 if (comp->pass == PASS_1) {
2098 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01002099 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 +01002100 // store the comprehension scope so the compiling function (this one) can use it at each pass
2101 pns_comp_for->nodes[3] = (py_parse_node_t)s;
2102 }
2103
2104 // get the scope for this comprehension
2105 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
2106
2107 // compile the comprehension
2108 close_over_variables_etc(comp, this_scope, 0, 0);
2109
2110 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
2111 EMIT(get_iter);
2112 EMIT(call_function, 1, 0, false, false);
2113}
2114
2115void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2116 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2117 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01002118 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
2119 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2120 pns = (py_parse_node_struct_t*)pns->nodes[0];
2121 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
2122 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
2123 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2124 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
2125 // tuple of one item, with trailing comma
2126 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01002127 c_tuple(comp, pns->nodes[0], NULL);
2128 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
2129 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01002130 c_tuple(comp, pns->nodes[0], pns2);
2131 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2132 // generator expression
2133 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2134 } else {
2135 // tuple with 2 items
2136 goto tuple_with_2_items;
2137 }
2138 } else {
2139 // tuple with 2 items
2140 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01002141 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
2142 }
2143 } else {
2144 // parenthesis around a single item, is just that item
2145 compile_node(comp, pns->nodes[0]);
2146 }
2147}
2148
2149void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2150 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2151 // empty list
2152 EMIT(build_list, 0);
2153 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2154 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
2155 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
2156 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
2157 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
2158 // list of one item, with trailing comma
2159 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
2160 compile_node(comp, pns2->nodes[0]);
2161 EMIT(build_list, 1);
2162 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
2163 // list of many items
2164 compile_node(comp, pns2->nodes[0]);
2165 compile_generic_all_nodes(comp, pns3);
2166 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2167 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2168 // list comprehension
2169 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2170 } else {
2171 // list with 2 items
2172 goto list_with_2_items;
2173 }
2174 } else {
2175 // list with 2 items
2176 list_with_2_items:
2177 compile_node(comp, pns2->nodes[0]);
2178 compile_node(comp, pns2->nodes[1]);
2179 EMIT(build_list, 2);
2180 }
2181 } else {
2182 // list with 1 item
2183 compile_node(comp, pns->nodes[0]);
2184 EMIT(build_list, 1);
2185 }
2186}
2187
2188void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2189 py_parse_node_t pn = pns->nodes[0];
2190 if (PY_PARSE_NODE_IS_NULL(pn)) {
2191 // empty dict
2192 EMIT(build_map, 0);
2193 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2194 pns = (py_parse_node_struct_t*)pn;
2195 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2196 // dict with one element
2197 EMIT(build_map, 1);
2198 compile_node(comp, pn);
2199 EMIT(store_map);
2200 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2201 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2202 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2203 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2204 // dict/set with multiple elements
2205
2206 // get tail elements (2nd, 3rd, ...)
2207 py_parse_node_t *nodes;
2208 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2209
2210 // first element sets whether it's a dict or set
2211 bool is_dict;
2212 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2213 // a dictionary
2214 EMIT(build_map, 1 + n);
2215 compile_node(comp, pns->nodes[0]);
2216 EMIT(store_map);
2217 is_dict = true;
2218 } else {
2219 // a set
2220 compile_node(comp, pns->nodes[0]); // 1st value of set
2221 is_dict = false;
2222 }
2223
2224 // process rest of elements
2225 for (int i = 0; i < n; i++) {
2226 py_parse_node_t pn = nodes[i];
2227 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2228 compile_node(comp, pn);
2229 if (is_dict) {
2230 if (!is_key_value) {
2231 printf("SyntaxError?: expecting key:value for dictionary");
2232 return;
2233 }
2234 EMIT(store_map);
2235 } else {
2236 if (is_key_value) {
2237 printf("SyntaxError?: expecting just a value for set");
2238 return;
2239 }
2240 }
2241 }
2242
2243 // if it's a set, build it
2244 if (!is_dict) {
2245 EMIT(build_set, 1 + n);
2246 }
2247 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2248 // dict/set comprehension
2249 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2250 // a dictionary comprehension
2251 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2252 } else {
2253 // a set comprehension
2254 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2255 }
2256 } else {
2257 // shouldn't happen
2258 assert(0);
2259 }
2260 } else {
2261 // set with one element
2262 goto set_with_one_element;
2263 }
2264 } else {
2265 // set with one element
2266 set_with_one_element:
2267 compile_node(comp, pn);
2268 EMIT(build_set, 1);
2269 }
2270}
2271
2272void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2273 compile_trailer_paren_helper(comp, pns, false);
2274}
2275
2276void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2277 // object who's index we want is on top of stack
2278 compile_node(comp, pns->nodes[0]); // the index
2279 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2280}
2281
2282void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2283 // object who's attribute we want is on top of stack
2284 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2285}
2286
2287void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2288 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2289 py_parse_node_t pn = pns->nodes[0];
2290 if (PY_PARSE_NODE_IS_NULL(pn)) {
2291 // [?:]
2292 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2293 EMIT(build_slice, 2);
2294 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2295 pns = (py_parse_node_struct_t*)pn;
2296 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2297 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2298 pn = pns->nodes[0];
2299 if (PY_PARSE_NODE_IS_NULL(pn)) {
2300 // [?::]
2301 EMIT(build_slice, 2);
2302 } else {
2303 // [?::x]
2304 compile_node(comp, pn);
2305 EMIT(build_slice, 3);
2306 }
2307 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2308 compile_node(comp, pns->nodes[0]);
2309 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2310 pns = (py_parse_node_struct_t*)pns->nodes[1];
2311 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2312 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2313 // [?:x:]
2314 EMIT(build_slice, 2);
2315 } else {
2316 // [?:x:x]
2317 compile_node(comp, pns->nodes[0]);
2318 EMIT(build_slice, 3);
2319 }
2320 } else {
2321 // [?:x]
2322 compile_node(comp, pn);
2323 EMIT(build_slice, 2);
2324 }
2325 } else {
2326 // [?:x]
2327 compile_node(comp, pn);
2328 EMIT(build_slice, 2);
2329 }
2330}
2331
2332void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2333 compile_node(comp, pns->nodes[0]); // start of slice
2334 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2335 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2336}
2337
2338void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2339 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2340 compile_subscript_3_helper(comp, pns);
2341}
2342
2343void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2344 // if this is called then we are compiling a dict key:value pair
2345 compile_node(comp, pns->nodes[1]); // value
2346 compile_node(comp, pns->nodes[0]); // key
2347}
2348
2349void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002350 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002351 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002352 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002353}
2354
2355void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2356 if (comp->have_star_arg) {
2357 printf("SyntaxError?: can't have multiple *x\n");
2358 return;
2359 }
2360 comp->have_star_arg = true;
2361 compile_node(comp, pns->nodes[0]);
2362}
2363
2364void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2365 if (comp->have_dbl_star_arg) {
2366 printf("SyntaxError?: can't have multiple **x\n");
2367 return;
2368 }
2369 comp->have_dbl_star_arg = true;
2370 compile_node(comp, pns->nodes[0]);
2371}
2372
2373void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2374 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2375 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2376 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2377 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2378 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2379 return;
2380 }
2381 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2382 compile_node(comp, pns2->nodes[0]);
2383 comp->n_arg_keyword += 1;
2384 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2385 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2386 } else {
2387 // shouldn't happen
2388 assert(0);
2389 }
2390}
2391
2392void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2393 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2394 printf("SyntaxError: 'yield' outside function\n");
2395 return;
2396 }
2397 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2398 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2399 EMIT(yield_value);
2400 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2401 pns = (py_parse_node_struct_t*)pns->nodes[0];
2402 compile_node(comp, pns->nodes[0]);
2403 EMIT(get_iter);
2404 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2405 EMIT(yield_from);
2406 } else {
2407 compile_node(comp, pns->nodes[0]);
2408 EMIT(yield_value);
2409 }
2410}
2411
2412typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2413static compile_function_t compile_function[] = {
2414 NULL,
2415#define nc NULL
2416#define c(f) compile_##f
2417#define DEF_RULE(rule, comp, kind, arg...) comp,
2418#include "grammar.h"
2419#undef nc
2420#undef c
2421#undef DEF_RULE
2422};
2423
2424void compile_node(compiler_t *comp, py_parse_node_t pn) {
2425 if (PY_PARSE_NODE_IS_NULL(pn)) {
2426 // pass
2427 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2428 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2429 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002430 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002431 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2432 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2433 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2434 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2435 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002436 case PY_PARSE_NODE_TOKEN:
2437 if (arg == PY_TOKEN_NEWLINE) {
2438 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
Damien5ac1b2e2013-10-18 19:58:12 +01002439 // or when single_input lets through a NEWLINE (user enters a blank line)
Damien91d387d2013-10-09 15:09:52 +01002440 // do nothing
2441 } else {
2442 EMIT(load_const_tok, arg);
2443 }
2444 break;
Damien429d7192013-10-04 19:53:11 +01002445 default: assert(0);
2446 }
2447 } else {
2448 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2449 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2450 if (f == NULL) {
2451 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
Damien5ac1b2e2013-10-18 19:58:12 +01002452 py_parse_node_show(pn, 0);
Damien429d7192013-10-04 19:53:11 +01002453 assert(0);
2454 } else {
2455 f(comp, pns);
2456 }
2457 }
2458}
2459
2460void 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) {
2461 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002462 qstr param_name = 0;
2463 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002464 if (PY_PARSE_NODE_IS_ID(pn)) {
2465 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002466 if (comp->have_bare_star) {
2467 // comes after a bare star, so doesn't count as a parameter
2468 } else {
2469 comp->scope_cur->num_params += 1;
2470 }
Damienb14de212013-10-06 00:28:28 +01002471 } else {
2472 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2473 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2474 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002475 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002476 //int node_index = 1; unused
2477 if (allow_annotations) {
2478 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2479 // this parameter has an annotation
2480 pn_annotation = pns->nodes[1];
2481 }
2482 //node_index = 2; unused
2483 }
2484 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2485 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2486 // this parameter has a default value
2487 if (comp->have_bare_star) {
2488 comp->scope_cur->num_dict_params += 1;
2489 } else {
2490 comp->scope_cur->num_default_params += 1;
2491 }
2492 }
2493 */
2494 if (comp->have_bare_star) {
2495 // comes after a bare star, so doesn't count as a parameter
2496 } else {
2497 comp->scope_cur->num_params += 1;
2498 }
2499 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2500 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2501 // bare star
2502 // TODO see http://www.python.org/dev/peps/pep-3102/
2503 comp->have_bare_star = true;
2504 //assert(comp->scope_cur->num_dict_params == 0);
2505 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2506 // named star
2507 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2508 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2509 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2510 // named star with annotation
2511 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2512 pns = (py_parse_node_struct_t*)pns->nodes[0];
2513 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2514 pn_annotation = pns->nodes[1];
2515 } else {
2516 // shouldn't happen
2517 assert(0);
2518 }
2519 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002520 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002521 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2522 // this parameter has an annotation
2523 pn_annotation = pns->nodes[1];
2524 }
2525 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002526 } else {
Damienb14de212013-10-06 00:28:28 +01002527 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002528 assert(0);
2529 }
Damien429d7192013-10-04 19:53:11 +01002530 }
2531
2532 if (param_name != 0) {
2533 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2534 // TODO this parameter has an annotation
2535 }
2536 bool added;
2537 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2538 if (!added) {
2539 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2540 return;
2541 }
2542 id_info->param = true;
2543 id_info->kind = ID_INFO_KIND_LOCAL;
2544 }
2545}
2546
2547void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2548 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2549}
2550
2551void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2552 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2553}
2554
2555void 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) {
2556 tail_recursion:
2557 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2558 // no more nested if/for; compile inner expression
2559 compile_node(comp, pn_inner_expr);
2560 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2561 EMIT(list_append, for_depth + 2);
2562 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2563 EMIT(map_add, for_depth + 2);
2564 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2565 EMIT(set_add, for_depth + 2);
2566 } else {
2567 EMIT(yield_value);
2568 EMIT(pop_top);
2569 }
2570 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2571 // if condition
2572 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2573 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2574 pn_iter = pns_comp_if->nodes[1];
2575 goto tail_recursion;
2576 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2577 // for loop
2578 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2579 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002580 int l_end2 = comp_next_label(comp);
2581 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002582 EMIT(get_iter);
2583 EMIT(label_assign, l_top2);
2584 EMIT(for_iter, l_end2);
2585 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2586 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2587 EMIT(jump, l_top2);
2588 EMIT(label_assign, l_end2);
2589 EMIT(for_iter_end);
2590 } else {
2591 // shouldn't happen
2592 assert(0);
2593 }
2594}
2595
2596void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2597 // see http://www.python.org/dev/peps/pep-0257/
2598
2599 // look for the first statement
2600 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2601 // fall through
2602 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2603 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2604 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2605 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2606 } else {
2607 return;
2608 }
2609
2610 // check the first statement for a doc string
2611 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2612 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2613 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2614 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2615 if (kind == PY_PARSE_NODE_STRING) {
2616 compile_node(comp, pns->nodes[0]); // a doc string
2617 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002618 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002619 }
2620 }
2621 }
2622}
2623
2624void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2625 comp->pass = pass;
2626 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002627 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002628 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002629
2630 if (comp->pass == PASS_1) {
2631 scope->stack_size = 0;
2632 }
2633
Damien5ac1b2e2013-10-18 19:58:12 +01002634#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01002635 if (comp->pass == PASS_3) {
Damien429d7192013-10-04 19:53:11 +01002636 scope_print_info(scope);
2637 }
Damien5ac1b2e2013-10-18 19:58:12 +01002638#endif
Damien429d7192013-10-04 19:53:11 +01002639
2640 // compile
2641 if (scope->kind == SCOPE_MODULE) {
Damien5ac1b2e2013-10-18 19:58:12 +01002642 if (!comp->is_repl) {
2643 check_for_doc_string(comp, scope->pn);
2644 }
Damien429d7192013-10-04 19:53:11 +01002645 compile_node(comp, scope->pn);
2646 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2647 EMIT(return_value);
2648 } else if (scope->kind == SCOPE_FUNCTION) {
2649 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2650 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2651 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2652
2653 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002654 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002655 if (comp->pass == PASS_1) {
2656 comp->have_bare_star = false;
2657 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2658 }
2659
Damien826005c2013-10-05 23:17:28 +01002660 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002661
2662 compile_node(comp, pns->nodes[3]); // 3 is function body
2663 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002664 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002665 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2666 EMIT(return_value);
2667 }
2668 } else if (scope->kind == SCOPE_LAMBDA) {
2669 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2670 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2671 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2672
2673 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002674 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002675 if (comp->pass == PASS_1) {
2676 comp->have_bare_star = false;
2677 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2678 }
2679
2680 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2681 EMIT(return_value);
2682 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2683 // a bit of a hack at the moment
2684
2685 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2686 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2687 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2688 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2689 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2690
Damien6cdd3af2013-10-05 18:08:26 +01002691 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002692 if (comp->pass == PASS_1) {
2693 bool added;
2694 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2695 assert(added);
2696 id_info->kind = ID_INFO_KIND_LOCAL;
2697 scope->num_params = 1;
2698 }
2699
2700 if (scope->kind == SCOPE_LIST_COMP) {
2701 EMIT(build_list, 0);
2702 } else if (scope->kind == SCOPE_DICT_COMP) {
2703 EMIT(build_map, 0);
2704 } else if (scope->kind == SCOPE_SET_COMP) {
2705 EMIT(build_set, 0);
2706 }
2707
Damienb05d7072013-10-05 13:37:10 +01002708 int l_end = comp_next_label(comp);
2709 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002710 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002711 EMIT(label_assign, l_top);
2712 EMIT(for_iter, l_end);
2713 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2714 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2715 EMIT(jump, l_top);
2716 EMIT(label_assign, l_end);
2717 EMIT(for_iter_end);
2718
2719 if (scope->kind == SCOPE_GEN_EXPR) {
2720 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2721 }
2722 EMIT(return_value);
2723 } else {
2724 assert(scope->kind == SCOPE_CLASS);
2725 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2726 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2727 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2728
2729 if (comp->pass == PASS_1) {
2730 bool added;
2731 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2732 assert(added);
2733 id_info->kind = ID_INFO_KIND_LOCAL;
2734 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2735 assert(added);
2736 id_info->kind = ID_INFO_KIND_LOCAL;
2737 id_info->param = true;
2738 scope->num_params = 1; // __locals__ is the parameter
2739 }
2740
Damien4b03e772013-10-05 14:17:09 +01002741 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002742 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002743 EMIT(load_id, comp->qstr___name__);
2744 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002745 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002746 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002747
2748 check_for_doc_string(comp, pns->nodes[2]);
2749 compile_node(comp, pns->nodes[2]); // 2 is class body
2750
2751 id_info_t *id = scope_find(scope, comp->qstr___class__);
2752 assert(id != NULL);
2753 if (id->kind == ID_INFO_KIND_LOCAL) {
2754 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2755 } else {
Damien27fb45e2013-10-20 15:07:49 +01002756 EMIT(load_closure, comp->qstr___class__, 0); // XXX check this is the correct local num
Damien429d7192013-10-04 19:53:11 +01002757 }
2758 EMIT(return_value);
2759 }
2760
Damien415eb6f2013-10-05 12:19:06 +01002761 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002762
Damien826005c2013-10-05 23:17:28 +01002763}
2764
2765void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2766 comp->pass = pass;
2767 comp->scope_cur = scope;
2768 comp->next_label = 1;
2769
2770 if (scope->kind != SCOPE_FUNCTION) {
2771 printf("Error: inline assembler must be a function\n");
2772 return;
2773 }
2774
Damiena2f2f7d2013-10-06 00:14:13 +01002775 if (comp->pass > PASS_1) {
2776 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2777 }
2778
Damien826005c2013-10-05 23:17:28 +01002779 // get the function definition parse node
2780 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2781 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2782 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2783
Damiena2f2f7d2013-10-06 00:14:13 +01002784 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002785
Damiena2f2f7d2013-10-06 00:14:13 +01002786 // parameters are in pns->nodes[1]
2787 if (comp->pass == PASS_2) {
2788 py_parse_node_t *pn_params;
2789 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2790 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2791 }
2792
Damien826005c2013-10-05 23:17:28 +01002793 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2794
2795 py_parse_node_t pn_body = pns->nodes[3]; // body
2796 py_parse_node_t *nodes;
2797 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2798
Damien826005c2013-10-05 23:17:28 +01002799 if (comp->pass == PASS_3) {
2800 //printf("----\n");
2801 scope_print_info(scope);
2802 }
2803
2804 for (int i = 0; i < num; i++) {
2805 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2806 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2807 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2808 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2809 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2810 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2811 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2812 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2813 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2814 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2815 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2816 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2817 py_parse_node_t *pn_arg;
2818 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2819
2820 // emit instructions
2821 if (strcmp(qstr_str(op), "label") == 0) {
2822 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2823 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2824 return;
2825 }
2826 int lab = comp_next_label(comp);
2827 if (pass > PASS_1) {
2828 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2829 }
2830 } else {
2831 if (pass > PASS_1) {
2832 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2833 }
2834 }
2835 }
2836
2837 if (comp->pass > PASS_1) {
2838 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002839 }
Damien429d7192013-10-04 19:53:11 +01002840}
2841
2842void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2843 // in functions, turn implicit globals into explicit globals
2844 // compute num_locals, and the index of each local
Damien318aec62013-12-10 18:28:17 +00002845 // compute the index of free and cell vars (freevars[idx] in CPython)
Damien429d7192013-10-04 19:53:11 +01002846 scope->num_locals = 0;
Damien318aec62013-12-10 18:28:17 +00002847 int num_closed = 0;
Damien429d7192013-10-04 19:53:11 +01002848 for (int i = 0; i < scope->id_info_len; i++) {
2849 id_info_t *id = &scope->id_info[i];
2850 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2851 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2852 continue;
2853 }
2854 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2855 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2856 }
2857 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2858 id->local_num = scope->num_locals;
2859 scope->num_locals += 1;
Damien318aec62013-12-10 18:28:17 +00002860 } else if (id->kind == ID_INFO_KIND_CELL) {
2861 id->local_num = num_closed;
2862 num_closed += 1;
2863 } else if (id->kind == ID_INFO_KIND_FREE) {
2864 id_info_t *id_parent = scope_find_local_in_parent(scope, id->qstr);
2865 assert(id_parent != NULL); // should never be NULL
2866 id->local_num = id_parent->local_num;
Damien429d7192013-10-04 19:53:11 +01002867 }
2868 }
2869
2870 // compute flags
2871 //scope->flags = 0; since we set some things in parameters
2872 if (scope->kind != SCOPE_MODULE) {
2873 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2874 }
2875 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) {
2876 assert(scope->parent != NULL);
2877 scope->flags |= SCOPE_FLAG_OPTIMISED;
2878
2879 // TODO possibly other ways it can be nested
2880 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2881 scope->flags |= SCOPE_FLAG_NESTED;
2882 }
2883 }
2884 int num_free = 0;
2885 for (int i = 0; i < scope->id_info_len; i++) {
2886 id_info_t *id = &scope->id_info[i];
2887 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2888 num_free += 1;
2889 }
2890 }
2891 if (num_free == 0) {
2892 scope->flags |= SCOPE_FLAG_NOFREE;
2893 }
2894}
2895
Damien5ac1b2e2013-10-18 19:58:12 +01002896bool py_compile(py_parse_node_t pn, bool is_repl) {
Damien429d7192013-10-04 19:53:11 +01002897 compiler_t *comp = m_new(compiler_t, 1);
2898
Damien6cdd3af2013-10-05 18:08:26 +01002899 comp->qstr___class__ = qstr_from_str_static("__class__");
2900 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2901 comp->qstr___name__ = qstr_from_str_static("__name__");
2902 comp->qstr___module__ = qstr_from_str_static("__module__");
2903 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2904 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2905 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2906 comp->qstr_micropython = qstr_from_str_static("micropython");
Damien5ac1b2e2013-10-18 19:58:12 +01002907 comp->qstr_byte_code = qstr_from_str_static("byte_code");
Damien6cdd3af2013-10-05 18:08:26 +01002908 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002909 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002910 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damiend7933892013-11-28 19:12:18 +00002911 comp->qstr_range = qstr_from_str_static("range");
Damien429d7192013-10-04 19:53:11 +01002912
Damien5ac1b2e2013-10-18 19:58:12 +01002913 comp->is_repl = is_repl;
2914 comp->had_error = false;
2915
Damien429d7192013-10-04 19:53:11 +01002916 comp->break_label = 0;
2917 comp->continue_label = 0;
2918 comp->except_nest_level = 0;
2919 comp->scope_head = NULL;
2920 comp->scope_cur = NULL;
2921
Damien826005c2013-10-05 23:17:28 +01002922 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002923 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002924
2925 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002926 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002927
Damien826005c2013-10-05 23:17:28 +01002928 // compile pass 1
2929 comp->emit = emit_pass1_new(comp->qstr___class__);
2930 comp->emit_method_table = &emit_pass1_method_table;
2931 comp->emit_inline_asm = NULL;
2932 comp->emit_inline_asm_method_table = NULL;
2933 uint max_num_labels = 0;
Damien5ac1b2e2013-10-18 19:58:12 +01002934 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002935 if (false) {
Damien3ef4abb2013-10-12 16:53:13 +01002936#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002937 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01002938 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01002939#endif
Damien826005c2013-10-05 23:17:28 +01002940 } else {
2941 compile_scope(comp, s, PASS_1);
2942 }
2943
2944 // update maximim number of labels needed
2945 if (comp->next_label > max_num_labels) {
2946 max_num_labels = comp->next_label;
2947 }
Damien429d7192013-10-04 19:53:11 +01002948 }
2949
Damien826005c2013-10-05 23:17:28 +01002950 // compute some things related to scope and identifiers
Damien5ac1b2e2013-10-18 19:58:12 +01002951 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damien429d7192013-10-04 19:53:11 +01002952 compile_scope_compute_things(comp, s);
2953 }
2954
Damien826005c2013-10-05 23:17:28 +01002955 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002956 emit_pass1_free(comp->emit);
2957
Damien826005c2013-10-05 23:17:28 +01002958 // compile pass 2 and 3
Damien3ef4abb2013-10-12 16:53:13 +01002959#if !MICROPY_EMIT_CPYTHON
Damien6cdd3af2013-10-05 18:08:26 +01002960 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01002961 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002962#endif
Damien3ef4abb2013-10-12 16:53:13 +01002963#if MICROPY_EMIT_INLINE_THUMB
Damien826005c2013-10-05 23:17:28 +01002964 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002965#endif
Damien5ac1b2e2013-10-18 19:58:12 +01002966 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002967 if (false) {
2968 // dummy
2969
Damien3ef4abb2013-10-12 16:53:13 +01002970#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002971 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2972 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01002973 if (emit_inline_thumb == NULL) {
2974 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2975 }
2976 comp->emit = NULL;
2977 comp->emit_method_table = NULL;
2978 comp->emit_inline_asm = emit_inline_thumb;
2979 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2980 compile_scope_inline_asm(comp, s, PASS_2);
2981 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01002982#endif
2983
Damien826005c2013-10-05 23:17:28 +01002984 } else {
Damienc025ebb2013-10-12 14:30:21 +01002985
2986 // choose the emit type
2987
Damien3ef4abb2013-10-12 16:53:13 +01002988#if MICROPY_EMIT_CPYTHON
Damienc025ebb2013-10-12 14:30:21 +01002989 comp->emit = emit_cpython_new(max_num_labels);
2990 comp->emit_method_table = &emit_cpython_method_table;
2991#else
Damien826005c2013-10-05 23:17:28 +01002992 switch (s->emit_options) {
2993 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01002994 case EMIT_OPT_VIPER:
Damien3ef4abb2013-10-12 16:53:13 +01002995#if MICROPY_EMIT_X64
Damiendc833822013-10-06 01:01:01 +01002996 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01002997 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01002998 }
Damien13ed3a62013-10-08 09:05:10 +01002999 comp->emit_method_table = &emit_native_x64_method_table;
Damien3ef4abb2013-10-12 16:53:13 +01003000#elif MICROPY_EMIT_THUMB
Damienc025ebb2013-10-12 14:30:21 +01003001 if (emit_native == NULL) {
3002 emit_native = emit_native_thumb_new(max_num_labels);
3003 }
3004 comp->emit_method_table = &emit_native_thumb_method_table;
3005#endif
3006 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01003007 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01003008 break;
3009
Damien826005c2013-10-05 23:17:28 +01003010 default:
3011 if (emit_bc == NULL) {
3012 emit_bc = emit_bc_new(max_num_labels);
3013 }
3014 comp->emit = emit_bc;
3015 comp->emit_method_table = &emit_bc_method_table;
3016 break;
3017 }
Damienc025ebb2013-10-12 14:30:21 +01003018#endif
3019
3020 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01003021 compile_scope(comp, s, PASS_2);
3022 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01003023 }
Damien429d7192013-10-04 19:53:11 +01003024 }
3025
3026 m_free(comp);
Damien5ac1b2e2013-10-18 19:58:12 +01003027
3028 return !comp->had_error;
Damien429d7192013-10-04 19:53:11 +01003029}