blob: a01f5f4c5849db700f67094809fea5ad1b258db0 [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;
Damien429d7192013-10-04 19:53:11 +010051
Damien5ac1b2e2013-10-18 19:58:12 +010052 bool is_repl;
Damien429d7192013-10-04 19:53:11 +010053 pass_kind_t pass;
Damien5ac1b2e2013-10-18 19:58:12 +010054 bool had_error; // try to keep compiler clean from nlr
Damien429d7192013-10-04 19:53:11 +010055
Damienb05d7072013-10-05 13:37:10 +010056 int next_label;
Damienb05d7072013-10-05 13:37:10 +010057
Damien429d7192013-10-04 19:53:11 +010058 int break_label;
59 int continue_label;
60 int except_nest_level;
61
62 int n_arg_keyword;
63 bool have_star_arg;
64 bool have_dbl_star_arg;
65 bool have_bare_star;
66 int param_pass;
67 int param_pass_num_dict_params;
68 int param_pass_num_default_params;
69
70 scope_t *scope_head;
71 scope_t *scope_cur;
72
Damien6cdd3af2013-10-05 18:08:26 +010073 emit_t *emit; // current emitter
74 const emit_method_table_t *emit_method_table; // current emit method table
Damien826005c2013-10-05 23:17:28 +010075
76 emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
77 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 +010078} compiler_t;
79
80py_parse_node_t fold_constants(py_parse_node_t pn) {
81 if (PY_PARSE_NODE_IS_STRUCT(pn)) {
82 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
83 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
84
85 // fold arguments first
86 for (int i = 0; i < n; i++) {
87 pns->nodes[i] = fold_constants(pns->nodes[i]);
88 }
89
90 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
91 case PN_shift_expr:
92 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
93 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
94 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
95 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_LESS)) {
Damien3ef4abb2013-10-12 16:53:13 +010096#if MICROPY_EMIT_CPYTHON
Damien0efb3a12013-10-12 16:16:56 +010097 // can overflow; enabled only to compare with CPython
98 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 << arg1);
99#endif
Damien429d7192013-10-04 19:53:11 +0100100 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_MORE)) {
101 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 >> arg1);
102 } else {
103 // shouldn't happen
104 assert(0);
105 }
106 }
107 break;
108
109 case PN_arith_expr:
Damien0efb3a12013-10-12 16:16:56 +0100110 // overflow checking here relies on SMALL_INT being strictly smaller than machine_int_t
Damien429d7192013-10-04 19:53:11 +0100111 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 +0100112 machine_int_t arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
113 machine_int_t arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
114 machine_int_t res;
Damien429d7192013-10-04 19:53:11 +0100115 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PLUS)) {
Damien0efb3a12013-10-12 16:16:56 +0100116 res = arg0 + arg1;
Damien429d7192013-10-04 19:53:11 +0100117 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_MINUS)) {
Damien0efb3a12013-10-12 16:16:56 +0100118 res = arg0 - arg1;
Damien429d7192013-10-04 19:53:11 +0100119 } else {
120 // shouldn't happen
121 assert(0);
Damien0efb3a12013-10-12 16:16:56 +0100122 res = 0;
123 }
124 if (PY_FIT_SMALL_INT(res)) {
125 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, res);
Damien429d7192013-10-04 19:53:11 +0100126 }
127 }
128 break;
129
130 case PN_term:
Damien429d7192013-10-04 19:53:11 +0100131 if (n == 3 && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[0]) && PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[2])) {
132 int arg0 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
133 int arg1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
134 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
Damien3ef4abb2013-10-12 16:53:13 +0100135#if MICROPY_EMIT_CPYTHON
Damien0efb3a12013-10-12 16:16:56 +0100136 // can overflow; enabled only to compare with CPython
Damien429d7192013-10-04 19:53:11 +0100137 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 * arg1);
Damien0efb3a12013-10-12 16:16:56 +0100138#endif
Damien429d7192013-10-04 19:53:11 +0100139 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_SLASH)) {
140 ; // pass
Damien0efb3a12013-10-12 16:16:56 +0100141 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_PERCENT)) {
142 // XXX implement this properly as Python's % operator acts differently to C's
143 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 % arg1);
144 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_DBL_SLASH)) {
145 // XXX implement this properly as Python's // operator acts differently to C's
146 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg0 / arg1);
Damien429d7192013-10-04 19:53:11 +0100147 } else {
148 // shouldn't happen
149 assert(0);
150 }
151 }
152 break;
153
154 case PN_factor_2:
155 if (PY_PARSE_NODE_IS_SMALL_INT(pns->nodes[1])) {
156 machine_int_t arg = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
157 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
158 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, arg);
159 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
160 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, -arg);
161 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
162 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ~arg);
163 } else {
164 // shouldn't happen
165 assert(0);
166 }
167 }
168 break;
169
Damien3ef4abb2013-10-12 16:53:13 +0100170#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +0100171 case PN_power:
Damien0efb3a12013-10-12 16:16:56 +0100172 // can overflow; enabled only to compare with CPython
Damien429d7192013-10-04 19:53:11 +0100173 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])) {
174 py_parse_node_struct_t* pns2 = (py_parse_node_struct_t*)pns->nodes[2];
175 if (PY_PARSE_NODE_IS_SMALL_INT(pns2->nodes[0])) {
176 int power = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
177 if (power >= 0) {
178 int ans = 1;
179 int base = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
180 for (; power > 0; power--) {
181 ans *= base;
182 }
183 pn = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, ans);
184 }
185 }
186 }
187 break;
Damien0efb3a12013-10-12 16:16:56 +0100188#endif
Damien429d7192013-10-04 19:53:11 +0100189 }
190 }
191
192 return pn;
193}
194
195void compile_node(compiler_t *comp, py_parse_node_t pn);
196
Damienb05d7072013-10-05 13:37:10 +0100197static int comp_next_label(compiler_t *comp) {
198 return comp->next_label++;
199}
200
Damien6cdd3af2013-10-05 18:08:26 +0100201static 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 +0100202 scope_t *scope = scope_new(kind, pn, rt_get_unique_code_id(kind == SCOPE_MODULE), emit_options);
Damien429d7192013-10-04 19:53:11 +0100203 scope->parent = comp->scope_cur;
204 scope->next = NULL;
205 if (comp->scope_head == NULL) {
206 comp->scope_head = scope;
207 } else {
208 scope_t *s = comp->scope_head;
209 while (s->next != NULL) {
210 s = s->next;
211 }
212 s->next = scope;
213 }
214 return scope;
215}
216
Damienb05d7072013-10-05 13:37:10 +0100217static int list_len(py_parse_node_t pn, int pn_kind) {
Damien429d7192013-10-04 19:53:11 +0100218 if (PY_PARSE_NODE_IS_NULL(pn)) {
219 return 0;
220 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
221 return 1;
222 } else {
223 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
224 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
225 return 1;
226 } else {
227 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
228 }
229 }
230}
231
Damienb05d7072013-10-05 13:37:10 +0100232static 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 +0100233 if (PY_PARSE_NODE_IS_STRUCT(pn) && PY_PARSE_NODE_STRUCT_KIND((py_parse_node_struct_t*)pn) == pn_list_kind) {
234 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
235 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
236 for (int i = 0; i < num_nodes; i++) {
237 f(comp, pns->nodes[i]);
238 }
239 } else if (!PY_PARSE_NODE_IS_NULL(pn)) {
240 f(comp, pn);
241 }
242}
243
Damienb05d7072013-10-05 13:37:10 +0100244static int list_get(py_parse_node_t *pn, int pn_kind, py_parse_node_t **nodes) {
Damien429d7192013-10-04 19:53:11 +0100245 if (PY_PARSE_NODE_IS_NULL(*pn)) {
246 *nodes = NULL;
247 return 0;
248 } else if (PY_PARSE_NODE_IS_LEAF(*pn)) {
249 *nodes = pn;
250 return 1;
251 } else {
252 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)(*pn);
253 if (PY_PARSE_NODE_STRUCT_KIND(pns) != pn_kind) {
254 *nodes = pn;
255 return 1;
256 } else {
257 *nodes = pns->nodes;
258 return PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
259 }
260 }
261}
262
263void compile_do_nothing(compiler_t *comp, py_parse_node_struct_t *pns) {
264}
265
266void compile_generic_all_nodes(compiler_t *comp, py_parse_node_struct_t *pns) {
267 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
268 for (int i = 0; i < num_nodes; i++) {
269 compile_node(comp, pns->nodes[i]);
270 }
271}
272
Damien3ef4abb2013-10-12 16:53:13 +0100273#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100274static bool cpython_c_tuple_is_const(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100275 if (!PY_PARSE_NODE_IS_LEAF(pn)) {
276 return false;
277 }
278 if (PY_PARSE_NODE_IS_ID(pn)) {
279 return false;
280 }
281 return true;
282}
283
Damien3a205172013-10-12 15:01:56 +0100284static void cpython_c_tuple_emit_const(compiler_t *comp, py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100285 assert(PY_PARSE_NODE_IS_LEAF(pn));
286 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
287 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
288 case PY_PARSE_NODE_ID: assert(0);
289 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_verbatim_int, arg); break;
290 case PY_PARSE_NODE_INTEGER: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
291 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_verbatim_str, qstr_str(arg)); break;
292 case PY_PARSE_NODE_STRING: EMIT(load_const_verbatim_quoted_str, arg, false); break;
293 case PY_PARSE_NODE_BYTES: EMIT(load_const_verbatim_quoted_str, arg, true); break;
294 case PY_PARSE_NODE_TOKEN:
295 switch (arg) {
296 case PY_TOKEN_KW_FALSE: EMIT(load_const_verbatim_str, "False"); break;
297 case PY_TOKEN_KW_NONE: EMIT(load_const_verbatim_str, "None"); break;
298 case PY_TOKEN_KW_TRUE: EMIT(load_const_verbatim_str, "True"); break;
299 default: assert(0);
300 }
301 break;
302 default: assert(0);
303 }
304}
305
Damien3a205172013-10-12 15:01:56 +0100306static 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 +0100307 int n = 0;
308 if (pns_list != NULL) {
309 n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
310 }
311 int total = n;
312 bool is_const = true;
313 if (!PY_PARSE_NODE_IS_NULL(pn)) {
314 total += 1;
Damien3a205172013-10-12 15:01:56 +0100315 if (!cpython_c_tuple_is_const(pn)) {
Damien429d7192013-10-04 19:53:11 +0100316 is_const = false;
317 }
318 }
319 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100320 if (!cpython_c_tuple_is_const(pns_list->nodes[i])) {
Damien429d7192013-10-04 19:53:11 +0100321 is_const = false;
322 break;
323 }
324 }
325 if (total > 0 && is_const) {
326 bool need_comma = false;
327 EMIT(load_const_verbatim_start);
328 EMIT(load_const_verbatim_str, "(");
329 if (!PY_PARSE_NODE_IS_NULL(pn)) {
Damien3a205172013-10-12 15:01:56 +0100330 cpython_c_tuple_emit_const(comp, pn);
Damien429d7192013-10-04 19:53:11 +0100331 need_comma = true;
332 }
333 for (int i = 0; i < n; i++) {
334 if (need_comma) {
335 EMIT(load_const_verbatim_str, ", ");
336 }
Damien3a205172013-10-12 15:01:56 +0100337 cpython_c_tuple_emit_const(comp, pns_list->nodes[i]);
Damien429d7192013-10-04 19:53:11 +0100338 need_comma = true;
339 }
340 if (total == 1) {
341 EMIT(load_const_verbatim_str, ",)");
342 } else {
343 EMIT(load_const_verbatim_str, ")");
344 }
345 EMIT(load_const_verbatim_end);
346 } else {
347 if (!PY_PARSE_NODE_IS_NULL(pn)) {
348 compile_node(comp, pn);
349 }
350 for (int i = 0; i < n; i++) {
351 compile_node(comp, pns_list->nodes[i]);
352 }
353 EMIT(build_tuple, total);
354 }
355}
Damien3a205172013-10-12 15:01:56 +0100356#endif
357
358// funnelling all tuple creations through this function is purely so we can optionally agree with CPython
359void c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_struct_t *pns_list) {
Damien3ef4abb2013-10-12 16:53:13 +0100360#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100361 cpython_c_tuple(comp, pn, pns_list);
362#else
363 int total = 0;
364 if (!PY_PARSE_NODE_IS_NULL(pn)) {
365 compile_node(comp, pn);
366 total += 1;
367 }
368 if (pns_list != NULL) {
369 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_list);
370 for (int i = 0; i < n; i++) {
371 compile_node(comp, pns_list->nodes[i]);
372 }
373 total += n;
374 }
375 EMIT(build_tuple, total);
376#endif
377}
Damien429d7192013-10-04 19:53:11 +0100378
379void compile_generic_tuple(compiler_t *comp, py_parse_node_struct_t *pns) {
380 // a simple tuple expression
Damien429d7192013-10-04 19:53:11 +0100381 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
382}
383
Damien3a205172013-10-12 15:01:56 +0100384static bool node_is_const_false(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100385 return PY_PARSE_NODE_IS_TOKEN_KIND(pn, PY_TOKEN_KW_FALSE);
386 // untested: || (PY_PARSE_NODE_IS_SMALL_INT(pn) && PY_PARSE_NODE_LEAF_ARG(pn) == 1);
387}
388
Damien3a205172013-10-12 15:01:56 +0100389static bool node_is_const_true(py_parse_node_t pn) {
Damien429d7192013-10-04 19:53:11 +0100390 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);
391}
392
Damien3ef4abb2013-10-12 16:53:13 +0100393#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100394// the is_nested variable is purely to match with CPython, which doesn't fully optimise not's
395static 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 +0100396 if (node_is_const_false(pn)) {
397 if (jump_if == false) {
398 EMIT(jump, label);
399 }
400 return;
401 } else if (node_is_const_true(pn)) {
402 if (jump_if == true) {
403 EMIT(jump, label);
404 }
405 return;
406 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
407 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
408 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
409 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
410 if (jump_if == false) {
Damienb05d7072013-10-05 13:37:10 +0100411 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100412 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100413 cpython_c_if_cond(comp, pns->nodes[i], true, label2, true);
Damien429d7192013-10-04 19:53:11 +0100414 }
Damien3a205172013-10-12 15:01:56 +0100415 cpython_c_if_cond(comp, pns->nodes[n - 1], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100416 EMIT(label_assign, label2);
417 } else {
418 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100419 cpython_c_if_cond(comp, pns->nodes[i], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100420 }
421 }
422 return;
423 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
424 if (jump_if == false) {
425 for (int i = 0; i < n; i++) {
Damien3a205172013-10-12 15:01:56 +0100426 cpython_c_if_cond(comp, pns->nodes[i], false, label, true);
Damien429d7192013-10-04 19:53:11 +0100427 }
428 } else {
Damienb05d7072013-10-05 13:37:10 +0100429 int label2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +0100430 for (int i = 0; i < n - 1; i++) {
Damien3a205172013-10-12 15:01:56 +0100431 cpython_c_if_cond(comp, pns->nodes[i], false, label2, true);
Damien429d7192013-10-04 19:53:11 +0100432 }
Damien3a205172013-10-12 15:01:56 +0100433 cpython_c_if_cond(comp, pns->nodes[n - 1], true, label, true);
Damien429d7192013-10-04 19:53:11 +0100434 EMIT(label_assign, label2);
435 }
436 return;
437 } else if (!is_nested && PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
Damien3a205172013-10-12 15:01:56 +0100438 cpython_c_if_cond(comp, pns->nodes[0], !jump_if, label, true);
Damien429d7192013-10-04 19:53:11 +0100439 return;
440 }
441 }
442
443 // nothing special, fall back to default compiling for node and jump
444 compile_node(comp, pn);
445 if (jump_if == false) {
446 EMIT(pop_jump_if_false, label);
447 } else {
448 EMIT(pop_jump_if_true, label);
449 }
450}
Damien3a205172013-10-12 15:01:56 +0100451#endif
Damien429d7192013-10-04 19:53:11 +0100452
Damien3a205172013-10-12 15:01:56 +0100453static void c_if_cond(compiler_t *comp, py_parse_node_t pn, bool jump_if, int label) {
Damien3ef4abb2013-10-12 16:53:13 +0100454#if MICROPY_EMIT_CPYTHON
Damien3a205172013-10-12 15:01:56 +0100455 cpython_c_if_cond(comp, pn, jump_if, label, false);
456#else
457 if (node_is_const_false(pn)) {
458 if (jump_if == false) {
459 EMIT(jump, label);
460 }
461 return;
462 } else if (node_is_const_true(pn)) {
463 if (jump_if == true) {
464 EMIT(jump, label);
465 }
466 return;
467 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
468 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
469 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
470 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_or_test) {
471 if (jump_if == false) {
472 int label2 = comp_next_label(comp);
473 for (int i = 0; i < n - 1; i++) {
474 c_if_cond(comp, pns->nodes[i], true, label2);
475 }
476 c_if_cond(comp, pns->nodes[n - 1], false, label);
477 EMIT(label_assign, label2);
478 } else {
479 for (int i = 0; i < n; i++) {
480 c_if_cond(comp, pns->nodes[i], true, label);
481 }
482 }
483 return;
484 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_and_test) {
485 if (jump_if == false) {
486 for (int i = 0; i < n; i++) {
487 c_if_cond(comp, pns->nodes[i], false, label);
488 }
489 } else {
490 int label2 = comp_next_label(comp);
491 for (int i = 0; i < n - 1; i++) {
492 c_if_cond(comp, pns->nodes[i], false, label2);
493 }
494 c_if_cond(comp, pns->nodes[n - 1], true, label);
495 EMIT(label_assign, label2);
496 }
497 return;
498 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_not_test_2) {
499 c_if_cond(comp, pns->nodes[0], !jump_if, label);
500 return;
501 }
502 }
503
504 // nothing special, fall back to default compiling for node and jump
505 compile_node(comp, pn);
506 if (jump_if == false) {
507 EMIT(pop_jump_if_false, label);
508 } else {
509 EMIT(pop_jump_if_true, label);
510 }
511#endif
Damien429d7192013-10-04 19:53:11 +0100512}
513
514typedef enum { ASSIGN_STORE, ASSIGN_AUG_LOAD, ASSIGN_AUG_STORE } assign_kind_t;
515void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t kind);
516
517void c_assign_power(compiler_t *comp, py_parse_node_struct_t *pns, assign_kind_t assign_kind) {
518 if (assign_kind != ASSIGN_AUG_STORE) {
519 compile_node(comp, pns->nodes[0]);
520 }
521
522 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
523 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
524 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
525 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
526 if (assign_kind != ASSIGN_AUG_STORE) {
527 for (int i = 0; i < n - 1; i++) {
528 compile_node(comp, pns1->nodes[i]);
529 }
530 }
531 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
532 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
533 }
534 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
535 printf("SyntaxError: can't assign to function call\n");
536 return;
537 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
538 if (assign_kind == ASSIGN_AUG_STORE) {
539 EMIT(rot_three);
540 EMIT(store_subscr);
541 } else {
542 compile_node(comp, pns1->nodes[0]);
543 if (assign_kind == ASSIGN_AUG_LOAD) {
544 EMIT(dup_top_two);
545 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
546 } else {
547 EMIT(store_subscr);
548 }
549 }
550 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
551 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
552 if (assign_kind == ASSIGN_AUG_LOAD) {
553 EMIT(dup_top);
554 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
555 } else {
556 if (assign_kind == ASSIGN_AUG_STORE) {
557 EMIT(rot_two);
558 }
559 EMIT(store_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
560 }
561 } else {
562 // shouldn't happen
563 assert(0);
564 }
565 } else {
566 // shouldn't happen
567 assert(0);
568 }
569
570 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
571 // SyntaxError, cannot assign
572 assert(0);
573 }
574}
575
576void c_assign_tuple(compiler_t *comp, int n, py_parse_node_t *nodes) {
577 assert(n >= 0);
578 int have_star_index = -1;
579 for (int i = 0; i < n; i++) {
580 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_star_expr)) {
581 if (have_star_index < 0) {
582 EMIT(unpack_ex, i, n - i - 1);
583 have_star_index = i;
584 } else {
585 printf("SyntaxError: two starred expressions in assignment\n");
586 return;
587 }
588 }
589 }
590 if (have_star_index < 0) {
591 EMIT(unpack_sequence, n);
592 }
593 for (int i = 0; i < n; i++) {
594 if (i == have_star_index) {
595 c_assign(comp, ((py_parse_node_struct_t*)nodes[i])->nodes[0], ASSIGN_STORE);
596 } else {
597 c_assign(comp, nodes[i], ASSIGN_STORE);
598 }
599 }
600}
601
602// assigns top of stack to pn
603void c_assign(compiler_t *comp, py_parse_node_t pn, assign_kind_t assign_kind) {
604 tail_recursion:
605 if (PY_PARSE_NODE_IS_NULL(pn)) {
606 assert(0);
607 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
608 if (PY_PARSE_NODE_IS_ID(pn)) {
609 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
610 switch (assign_kind) {
611 case ASSIGN_STORE:
612 case ASSIGN_AUG_STORE:
Damien4b03e772013-10-05 14:17:09 +0100613 EMIT(store_id, arg);
Damien429d7192013-10-04 19:53:11 +0100614 break;
615 case ASSIGN_AUG_LOAD:
Damien4b03e772013-10-05 14:17:09 +0100616 EMIT(load_id, arg);
Damien429d7192013-10-04 19:53:11 +0100617 break;
618 }
619 } else {
620 printf("SyntaxError: can't assign to literal\n");
621 return;
622 }
623 } else {
624 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
625 switch (PY_PARSE_NODE_STRUCT_KIND(pns)) {
626 case PN_power:
627 // lhs is an index or attribute
628 c_assign_power(comp, pns, assign_kind);
629 break;
630
631 case PN_testlist_star_expr:
632 case PN_exprlist:
633 // lhs is a tuple
634 if (assign_kind != ASSIGN_STORE) {
635 goto bad_aug;
636 }
637 c_assign_tuple(comp, PY_PARSE_NODE_STRUCT_NUM_NODES(pns), pns->nodes);
638 break;
639
640 case PN_atom_paren:
641 // lhs is something in parenthesis
642 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
643 // empty tuple
644 printf("SyntaxError: can't assign to ()\n");
645 return;
646 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
647 pns = (py_parse_node_struct_t*)pns->nodes[0];
648 goto testlist_comp;
649 } else {
650 // parenthesis around 1 item, is just that item
651 pn = pns->nodes[0];
652 goto tail_recursion;
653 }
654 break;
655
656 case PN_atom_bracket:
657 // lhs is something in brackets
658 if (assign_kind != ASSIGN_STORE) {
659 goto bad_aug;
660 }
661 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
662 // empty list, assignment allowed
663 c_assign_tuple(comp, 0, NULL);
664 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
665 pns = (py_parse_node_struct_t*)pns->nodes[0];
666 goto testlist_comp;
667 } else {
668 // brackets around 1 item
669 c_assign_tuple(comp, 1, &pns->nodes[0]);
670 }
671 break;
672
673 default:
674 printf("unknown assign, %u\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
675 assert(0);
676 }
677 return;
678
679 testlist_comp:
680 // lhs is a sequence
681 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
682 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
683 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
684 // sequence of one item, with trailing comma
685 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
686 c_assign_tuple(comp, 1, &pns->nodes[0]);
687 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
688 // sequence of many items
689 // TODO call c_assign_tuple instead
690 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns2);
691 EMIT(unpack_sequence, 1 + n);
692 c_assign(comp, pns->nodes[0], ASSIGN_STORE);
693 for (int i = 0; i < n; i++) {
694 c_assign(comp, pns2->nodes[i], ASSIGN_STORE);
695 }
696 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
697 // TODO not implemented
698 assert(0);
699 } else {
700 // sequence with 2 items
701 goto sequence_with_2_items;
702 }
703 } else {
704 // sequence with 2 items
705 sequence_with_2_items:
706 c_assign_tuple(comp, 2, pns->nodes);
707 }
708 return;
709 }
710 return;
711
712 bad_aug:
713 printf("SyntaxError: illegal expression for augmented assignment\n");
714}
715
716// stuff for lambda and comprehensions and generators
717void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_params, int n_default_params) {
718 // make closed over variables, if any
719 int nfree = 0;
720 if (comp->scope_cur->kind != SCOPE_MODULE) {
721 for (int i = 0; i < this_scope->id_info_len; i++) {
722 id_info_t *id_info = &this_scope->id_info[i];
723 if (id_info->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +0100724 EMIT(load_closure, id_info->qstr, id_info->local_num);
Damien429d7192013-10-04 19:53:11 +0100725 nfree += 1;
726 }
727 }
728 }
729 if (nfree > 0) {
730 EMIT(build_tuple, nfree);
731 }
732
733 // make the function/closure
734 if (nfree == 0) {
735 EMIT(make_function, this_scope, n_dict_params, n_default_params);
736 } else {
737 EMIT(make_closure, this_scope, n_dict_params, n_default_params);
738 }
739}
740
741void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
Damienb14de212013-10-06 00:28:28 +0100742 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
743 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100744 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
745 // this parameter has a default value
746 // in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
747 if (comp->have_bare_star) {
748 comp->param_pass_num_dict_params += 1;
749 if (comp->param_pass == 1) {
750 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
751 compile_node(comp, pns->nodes[2]);
752 }
753 } else {
754 comp->param_pass_num_default_params += 1;
755 if (comp->param_pass == 2) {
756 compile_node(comp, pns->nodes[2]);
757 }
758 }
759 }
Damienb14de212013-10-06 00:28:28 +0100760 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
761 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
Damien429d7192013-10-04 19:53:11 +0100762 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
763 // bare star
764 comp->have_bare_star = true;
765 }
766 }
767}
768
769// leaves function object on stack
770// returns function name
Damien6cdd3af2013-10-05 18:08:26 +0100771qstr compile_funcdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100772 if (comp->pass == PASS_1) {
773 // create a new scope for this function
Damien6cdd3af2013-10-05 18:08:26 +0100774 scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100775 // store the function scope so the compiling function can use it at each pass
776 pns->nodes[4] = (py_parse_node_t)s;
777 }
778
779 // save variables (probably don't need to do this, since we can't have nested definitions..?)
780 bool old_have_bare_star = comp->have_bare_star;
781 int old_param_pass = comp->param_pass;
782 int old_param_pass_num_dict_params = comp->param_pass_num_dict_params;
783 int old_param_pass_num_default_params = comp->param_pass_num_default_params;
784
785 // compile default parameters
786 comp->have_bare_star = false;
787 comp->param_pass = 1; // pass 1 does any default parameters after bare star
788 comp->param_pass_num_dict_params = 0;
789 comp->param_pass_num_default_params = 0;
790 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
791 comp->have_bare_star = false;
792 comp->param_pass = 2; // pass 2 does any default parameters before bare star
793 comp->param_pass_num_dict_params = 0;
794 comp->param_pass_num_default_params = 0;
795 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param);
796
797 // get the scope for this function
798 scope_t *fscope = (scope_t*)pns->nodes[4];
799
800 // make the function
801 close_over_variables_etc(comp, fscope, comp->param_pass_num_dict_params, comp->param_pass_num_default_params);
802
803 // restore variables
804 comp->have_bare_star = old_have_bare_star;
805 comp->param_pass = old_param_pass;
806 comp->param_pass_num_dict_params = old_param_pass_num_dict_params;
807 comp->param_pass_num_default_params = old_param_pass_num_default_params;
808
809 // return its name (the 'f' in "def f(...):")
810 return fscope->simple_name;
811}
812
813// leaves class object on stack
814// returns class name
Damien6cdd3af2013-10-05 18:08:26 +0100815qstr compile_classdef_helper(compiler_t *comp, py_parse_node_struct_t *pns, uint emit_options) {
Damien429d7192013-10-04 19:53:11 +0100816 if (comp->pass == PASS_1) {
817 // create a new scope for this class
Damien6cdd3af2013-10-05 18:08:26 +0100818 scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (py_parse_node_t)pns, emit_options);
Damien429d7192013-10-04 19:53:11 +0100819 // store the class scope so the compiling function can use it at each pass
820 pns->nodes[3] = (py_parse_node_t)s;
821 }
822
823 EMIT(load_build_class);
824
825 // scope for this class
826 scope_t *cscope = (scope_t*)pns->nodes[3];
827
828 // compile the class
829 close_over_variables_etc(comp, cscope, 0, 0);
830
831 // get its name
832 EMIT(load_const_id, cscope->simple_name);
833
834 // nodes[1] has parent classes, if any
835 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
836 // no parent classes
837 EMIT(call_function, 2, 0, false, false);
838 } else {
839 // have a parent class or classes
840 // TODO what if we have, eg, *a or **a in the parent list?
841 compile_node(comp, pns->nodes[1]);
842 EMIT(call_function, 2 + list_len(pns->nodes[1], PN_arglist), 0, false, false);
843 }
844
845 // return its name (the 'C' in class C(...):")
846 return cscope->simple_name;
847}
848
Damien6cdd3af2013-10-05 18:08:26 +0100849// returns true if it was a built-in decorator (even if the built-in had an error)
850static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_node_t *name_nodes, uint *emit_options) {
851 if (PY_PARSE_NODE_LEAF_ARG(name_nodes[0]) != comp->qstr_micropython) {
852 return false;
853 }
854
855 if (name_len != 2) {
856 printf("SyntaxError: invalid micropython decorator\n");
857 return true;
858 }
859
860 qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
Damien5ac1b2e2013-10-18 19:58:12 +0100861 if (attr == comp->qstr_byte_code) {
862 *emit_options = EMIT_OPT_BYTE_CODE;
Damience89a212013-10-15 22:25:17 +0100863#if MICROPY_EMIT_NATIVE
864 } else if (attr == comp->qstr_native) {
Damien6cdd3af2013-10-05 18:08:26 +0100865 *emit_options = EMIT_OPT_NATIVE_PYTHON;
Damien7af3d192013-10-07 00:02:49 +0100866 } else if (attr == comp->qstr_viper) {
867 *emit_options = EMIT_OPT_VIPER;
Damience89a212013-10-15 22:25:17 +0100868#endif
Damien3ef4abb2013-10-12 16:53:13 +0100869#if MICROPY_EMIT_INLINE_THUMB
Damien5bfb7592013-10-05 18:41:24 +0100870 } else if (attr == comp->qstr_asm_thumb) {
871 *emit_options = EMIT_OPT_ASM_THUMB;
Damienc025ebb2013-10-12 14:30:21 +0100872#endif
Damien6cdd3af2013-10-05 18:08:26 +0100873 } else {
Damience89a212013-10-15 22:25:17 +0100874 printf("SyntaxError: invalid micropython decorator '%s'\n", qstr_str(attr));
Damien6cdd3af2013-10-05 18:08:26 +0100875 }
876
877 return true;
878}
879
Damien429d7192013-10-04 19:53:11 +0100880void compile_decorated(compiler_t *comp, py_parse_node_struct_t *pns) {
881 // get the list of decorators
882 py_parse_node_t *nodes;
883 int n = list_get(&pns->nodes[0], PN_decorators, &nodes);
884
Damien6cdd3af2013-10-05 18:08:26 +0100885 // inherit emit options for this function/class definition
886 uint emit_options = comp->scope_cur->emit_options;
887
888 // compile each decorator
889 int num_built_in_decorators = 0;
Damien429d7192013-10-04 19:53:11 +0100890 for (int i = 0; i < n; i++) {
891 assert(PY_PARSE_NODE_IS_STRUCT_KIND(nodes[i], PN_decorator)); // should be
892 py_parse_node_struct_t *pns_decorator = (py_parse_node_struct_t*)nodes[i];
Damien6cdd3af2013-10-05 18:08:26 +0100893
894 // nodes[0] contains the decorator function, which is a dotted name
895 py_parse_node_t *name_nodes;
896 int name_len = list_get(&pns_decorator->nodes[0], PN_dotted_name, &name_nodes);
897
898 // check for built-in decorators
899 if (compile_built_in_decorator(comp, name_len, name_nodes, &emit_options)) {
900 // this was a built-in
901 num_built_in_decorators += 1;
902
903 } else {
904 // not a built-in, compile normally
905
906 // compile the decorator function
907 compile_node(comp, name_nodes[0]);
908 for (int i = 1; i < name_len; i++) {
909 assert(PY_PARSE_NODE_IS_ID(name_nodes[i])); // should be
910 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(name_nodes[i]));
911 }
912
913 // nodes[1] contains arguments to the decorator function, if any
914 if (!PY_PARSE_NODE_IS_NULL(pns_decorator->nodes[1])) {
915 // call the decorator function with the arguments in nodes[1]
916 compile_node(comp, pns_decorator->nodes[1]);
917 }
Damien429d7192013-10-04 19:53:11 +0100918 }
919 }
920
921 // compile the body (funcdef or classdef) and get its name
922 py_parse_node_struct_t *pns_body = (py_parse_node_struct_t*)pns->nodes[1];
923 qstr body_name = 0;
924 if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_funcdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100925 body_name = compile_funcdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100926 } else if (PY_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef) {
Damien6cdd3af2013-10-05 18:08:26 +0100927 body_name = compile_classdef_helper(comp, pns_body, emit_options);
Damien429d7192013-10-04 19:53:11 +0100928 } else {
929 // shouldn't happen
930 assert(0);
931 }
932
933 // call each decorator
Damien6cdd3af2013-10-05 18:08:26 +0100934 for (int i = 0; i < n - num_built_in_decorators; i++) {
Damien429d7192013-10-04 19:53:11 +0100935 EMIT(call_function, 1, 0, false, false);
936 }
937
938 // store func/class object into name
Damien4b03e772013-10-05 14:17:09 +0100939 EMIT(store_id, body_name);
Damien429d7192013-10-04 19:53:11 +0100940}
941
942void compile_funcdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +0100943 qstr fname = compile_funcdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +0100944 // store function object into function name
Damien4b03e772013-10-05 14:17:09 +0100945 EMIT(store_id, fname);
Damien429d7192013-10-04 19:53:11 +0100946}
947
948void c_del_stmt(compiler_t *comp, py_parse_node_t pn) {
949 if (PY_PARSE_NODE_IS_ID(pn)) {
Damien4b03e772013-10-05 14:17:09 +0100950 EMIT(delete_id, PY_PARSE_NODE_LEAF_ARG(pn));
Damien429d7192013-10-04 19:53:11 +0100951 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_power)) {
952 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
953
954 compile_node(comp, pns->nodes[0]); // base of the power node
955
956 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
957 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
958 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_power_trailers) {
959 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
960 for (int i = 0; i < n - 1; i++) {
961 compile_node(comp, pns1->nodes[i]);
962 }
963 assert(PY_PARSE_NODE_IS_STRUCT(pns1->nodes[n - 1]));
964 pns1 = (py_parse_node_struct_t*)pns1->nodes[n - 1];
965 }
966 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_paren) {
967 // SyntaxError: can't delete a function call
968 assert(0);
969 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_bracket) {
970 compile_node(comp, pns1->nodes[0]);
971 EMIT(delete_subscr);
972 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
973 assert(PY_PARSE_NODE_IS_ID(pns1->nodes[0]));
974 EMIT(delete_attr, PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0]));
975 } else {
976 // shouldn't happen
977 assert(0);
978 }
979 } else {
980 // shouldn't happen
981 assert(0);
982 }
983
984 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
985 // SyntaxError, cannot delete
986 assert(0);
987 }
988 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_paren)) {
989 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
990 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_testlist_comp)) {
991 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
992 // TODO perhaps factorise testlist_comp code with other uses of PN_testlist_comp
993
994 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
995 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
996 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3b) {
997 // sequence of one item, with trailing comma
998 assert(PY_PARSE_NODE_IS_NULL(pns1->nodes[0]));
999 c_del_stmt(comp, pns->nodes[0]);
1000 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_testlist_comp_3c) {
1001 // sequence of many items
1002 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1);
1003 c_del_stmt(comp, pns->nodes[0]);
1004 for (int i = 0; i < n; i++) {
1005 c_del_stmt(comp, pns1->nodes[i]);
1006 }
1007 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
1008 // TODO not implemented; can't del comprehension?
1009 assert(0);
1010 } else {
1011 // sequence with 2 items
1012 goto sequence_with_2_items;
1013 }
1014 } else {
1015 // sequence with 2 items
1016 sequence_with_2_items:
1017 c_del_stmt(comp, pns->nodes[0]);
1018 c_del_stmt(comp, pns->nodes[1]);
1019 }
1020 } else {
1021 // tuple with 1 element
1022 c_del_stmt(comp, pn);
1023 }
1024 } else {
1025 // not implemented
1026 assert(0);
1027 }
1028}
1029
1030void compile_del_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1031 apply_to_single_or_list(comp, pns->nodes[0], PN_exprlist, c_del_stmt);
1032}
1033
1034void compile_break_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1035 if (comp->break_label == 0) {
1036 printf("ERROR: cannot break from here\n");
1037 }
1038 EMIT(break_loop, comp->break_label);
1039}
1040
1041void compile_continue_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1042 if (comp->continue_label == 0) {
1043 printf("ERROR: cannot continue from here\n");
1044 }
1045 if (comp->except_nest_level > 0) {
1046 EMIT(continue_loop, comp->continue_label);
1047 } else {
1048 EMIT(jump, comp->continue_label);
1049 }
1050}
1051
1052void compile_return_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien5ac1b2e2013-10-18 19:58:12 +01001053 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
1054 printf("SyntaxError: 'return' outside function\n");
1055 comp->had_error = true;
1056 return;
1057 }
Damien429d7192013-10-04 19:53:11 +01001058 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001059 // no argument to 'return', so return None
Damien429d7192013-10-04 19:53:11 +01001060 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1061 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_test_if_expr)) {
1062 // special case when returning an if-expression; to match CPython optimisation
1063 py_parse_node_struct_t *pns_test_if_expr = (py_parse_node_struct_t*)pns->nodes[0];
1064 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns_test_if_expr->nodes[1];
1065
Damienb05d7072013-10-05 13:37:10 +01001066 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001067 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1068 compile_node(comp, pns_test_if_expr->nodes[0]); // success value
1069 EMIT(return_value);
1070 EMIT(label_assign, l_fail);
1071 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1072 } else {
1073 compile_node(comp, pns->nodes[0]);
1074 }
1075 EMIT(return_value);
1076}
1077
1078void compile_yield_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1079 compile_node(comp, pns->nodes[0]);
1080 EMIT(pop_top);
1081}
1082
1083void compile_raise_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1084 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1085 // raise
1086 EMIT(raise_varargs, 0);
1087 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_raise_stmt_arg)) {
1088 // raise x from y
1089 pns = (py_parse_node_struct_t*)pns->nodes[0];
1090 compile_node(comp, pns->nodes[0]);
1091 compile_node(comp, pns->nodes[1]);
1092 EMIT(raise_varargs, 2);
1093 } else {
1094 // raise x
1095 compile_node(comp, pns->nodes[0]);
1096 EMIT(raise_varargs, 1);
1097 }
1098}
1099
1100// q1 holds the base, q2 the full name
1101// eg a -> q1=q2=a
1102// a.b.c -> q1=a, q2=a.b.c
1103void do_import_name(compiler_t *comp, py_parse_node_t pn, qstr *q1, qstr *q2) {
1104 bool is_as = false;
1105 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dotted_as_name)) {
1106 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1107 // a name of the form x as y; unwrap it
1108 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[1]);
1109 pn = pns->nodes[0];
1110 is_as = true;
1111 }
1112 if (PY_PARSE_NODE_IS_ID(pn)) {
1113 // just a simple name
1114 *q2 = PY_PARSE_NODE_LEAF_ARG(pn);
1115 if (!is_as) {
1116 *q1 = *q2;
1117 }
1118 EMIT(import_name, *q2);
1119 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
1120 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
1121 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dotted_name) {
1122 // a name of the form a.b.c
1123 if (!is_as) {
1124 *q1 = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
1125 }
1126 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1127 int len = n - 1;
1128 for (int i = 0; i < n; i++) {
1129 len += strlen(qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1130 }
1131 char *str = m_new(char, len + 1);
1132 str[0] = 0;
1133 for (int i = 0; i < n; i++) {
1134 if (i > 0) {
1135 strcat(str, ".");
1136 }
1137 strcat(str, qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i])));
1138 }
1139 *q2 = qstr_from_str_take(str);
1140 EMIT(import_name, *q2);
1141 if (is_as) {
1142 for (int i = 1; i < n; i++) {
1143 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1144 }
1145 }
1146 } else {
1147 // TODO not implemented
1148 assert(0);
1149 }
1150 } else {
1151 // TODO not implemented
1152 assert(0);
1153 }
1154}
1155
1156void compile_dotted_as_name(compiler_t *comp, py_parse_node_t pn) {
1157 EMIT(load_const_small_int, 0); // ??
1158 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1159 qstr q1, q2;
1160 do_import_name(comp, pn, &q1, &q2);
Damien4b03e772013-10-05 14:17:09 +01001161 EMIT(store_id, q1);
Damien429d7192013-10-04 19:53:11 +01001162}
1163
1164void compile_import_name(compiler_t *comp, py_parse_node_struct_t *pns) {
1165 apply_to_single_or_list(comp, pns->nodes[0], PN_dotted_as_names, compile_dotted_as_name);
1166}
1167
1168void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1169 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], PY_TOKEN_OP_STAR)) {
1170 EMIT(load_const_small_int, 0); // what's this for??
1171 EMIT(load_const_verbatim_start);
1172 EMIT(load_const_verbatim_str, "('*',)");
1173 EMIT(load_const_verbatim_end);
1174 qstr dummy_q, id1;
1175 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1176 EMIT(import_star);
1177 } else {
1178 py_parse_node_t *pn_nodes;
1179 int n = list_get(&pns->nodes[1], PN_import_as_names, &pn_nodes);
1180
1181 EMIT(load_const_small_int, 0); // what's this for??
1182 EMIT(load_const_verbatim_start);
1183 EMIT(load_const_verbatim_str, "(");
1184 for (int i = 0; i < n; i++) {
1185 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1186 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1187 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1188 if (i > 0) {
1189 EMIT(load_const_verbatim_str, ", ");
1190 }
1191 EMIT(load_const_verbatim_str, "'");
1192 EMIT(load_const_verbatim_str, qstr_str(id2));
1193 EMIT(load_const_verbatim_str, "'");
1194 }
1195 if (n == 1) {
1196 EMIT(load_const_verbatim_str, ",");
1197 }
1198 EMIT(load_const_verbatim_str, ")");
1199 EMIT(load_const_verbatim_end);
1200 qstr dummy_q, id1;
1201 do_import_name(comp, pns->nodes[0], &dummy_q, &id1);
1202 for (int i = 0; i < n; i++) {
1203 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_nodes[i], PN_import_as_name));
1204 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pn_nodes[i];
1205 qstr id2 = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[0]); // should be id
1206 EMIT(import_from, id2);
1207 if (PY_PARSE_NODE_IS_NULL(pns3->nodes[1])) {
Damien4b03e772013-10-05 14:17:09 +01001208 EMIT(store_id, id2);
Damien429d7192013-10-04 19:53:11 +01001209 } else {
Damien4b03e772013-10-05 14:17:09 +01001210 EMIT(store_id, PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]));
Damien429d7192013-10-04 19:53:11 +01001211 }
1212 }
1213 EMIT(pop_top);
1214 }
1215}
1216
1217void compile_global_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001218 if (comp->pass == PASS_1) {
1219 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1220 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1221 } else {
1222 pns = (py_parse_node_struct_t*)pns->nodes[0];
1223 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1224 for (int i = 0; i < num_nodes; i++) {
1225 scope_declare_global(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1226 }
Damien429d7192013-10-04 19:53:11 +01001227 }
1228 }
1229}
1230
1231void compile_nonlocal_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien415eb6f2013-10-05 12:19:06 +01001232 if (comp->pass == PASS_1) {
1233 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
1234 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
1235 } else {
1236 pns = (py_parse_node_struct_t*)pns->nodes[0];
1237 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1238 for (int i = 0; i < num_nodes; i++) {
1239 scope_declare_nonlocal(comp->scope_cur, PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1240 }
Damien429d7192013-10-04 19:53:11 +01001241 }
1242 }
1243}
1244
1245void compile_assert_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001246 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001247 c_if_cond(comp, pns->nodes[0], true, l_end);
Damien4b03e772013-10-05 14:17:09 +01001248 EMIT(load_id, comp->qstr_assertion_error);
Damien429d7192013-10-04 19:53:11 +01001249 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
1250 // assertion message
1251 compile_node(comp, pns->nodes[1]);
1252 EMIT(call_function, 1, 0, false, false);
1253 }
1254 EMIT(raise_varargs, 1);
1255 EMIT(label_assign, l_end);
1256}
1257
1258void compile_if_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1259 // TODO proper and/or short circuiting
1260
Damienb05d7072013-10-05 13:37:10 +01001261 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001262
Damienb05d7072013-10-05 13:37:10 +01001263 int l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001264 c_if_cond(comp, pns->nodes[0], false, l_fail); // if condition
1265
1266 compile_node(comp, pns->nodes[1]); // if block
1267 //if (!(PY_PARSE_NODE_IS_NULL(pns->nodes[2]) && PY_PARSE_NODE_IS_NULL(pns->nodes[3]))) { // optimisation; doesn't align with CPython
1268 // jump over elif/else blocks if they exist
Damien415eb6f2013-10-05 12:19:06 +01001269 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001270 EMIT(jump, l_end);
1271 }
1272 //}
1273 EMIT(label_assign, l_fail);
1274
1275 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
1276 // compile elif blocks
1277
1278 py_parse_node_struct_t *pns_elif = (py_parse_node_struct_t*)pns->nodes[2];
1279
1280 if (PY_PARSE_NODE_STRUCT_KIND(pns_elif) == PN_if_stmt_elif_list) {
1281 // multiple elif blocks
1282
1283 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns_elif);
1284 for (int i = 0; i < n; i++) {
1285 py_parse_node_struct_t *pns_elif2 = (py_parse_node_struct_t*)pns_elif->nodes[i];
Damienb05d7072013-10-05 13:37:10 +01001286 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001287 c_if_cond(comp, pns_elif2->nodes[0], false, l_fail); // elif condition
1288
1289 compile_node(comp, pns_elif2->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001290 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001291 EMIT(jump, l_end);
1292 }
1293 EMIT(label_assign, l_fail);
1294 }
1295
1296 } else {
1297 // a single elif block
1298
Damienb05d7072013-10-05 13:37:10 +01001299 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001300 c_if_cond(comp, pns_elif->nodes[0], false, l_fail); // elif condition
1301
1302 compile_node(comp, pns_elif->nodes[1]); // elif block
Damien415eb6f2013-10-05 12:19:06 +01001303 if (!EMIT(last_emit_was_return_value)) { // simple optimisation to align with CPython
Damien429d7192013-10-04 19:53:11 +01001304 EMIT(jump, l_end);
1305 }
1306 EMIT(label_assign, l_fail);
1307 }
1308 }
1309
1310 // compile else block
1311 compile_node(comp, pns->nodes[3]); // can be null
1312
1313 EMIT(label_assign, l_end);
1314}
1315
1316void compile_while_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1317 int old_break_label = comp->break_label;
1318 int old_continue_label = comp->continue_label;
1319
Damienb05d7072013-10-05 13:37:10 +01001320 int break_label = comp_next_label(comp);
1321 int continue_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001322
1323 comp->break_label = break_label;
1324 comp->continue_label = continue_label;
1325
Damience89a212013-10-15 22:25:17 +01001326 // compared to CPython, we have an optimised version of while loops
1327#if MICROPY_EMIT_CPYTHON
1328 int done_label = comp_next_label(comp);
1329 EMIT(setup_loop, break_label);
Damien429d7192013-10-04 19:53:11 +01001330 EMIT(label_assign, continue_label);
1331 c_if_cond(comp, pns->nodes[0], false, done_label); // condition
1332 compile_node(comp, pns->nodes[1]); // body
Damien415eb6f2013-10-05 12:19:06 +01001333 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001334 EMIT(jump, continue_label);
1335 }
1336 EMIT(label_assign, done_label);
Damien429d7192013-10-04 19:53:11 +01001337 // CPython does not emit POP_BLOCK if the condition was a constant; don't undertand why
1338 // this is a small hack to agree with CPython
1339 if (!node_is_const_true(pns->nodes[0])) {
1340 EMIT(pop_block);
1341 }
Damience89a212013-10-15 22:25:17 +01001342#else
1343 int top_label = comp_next_label(comp);
1344 EMIT(jump, continue_label);
1345 EMIT(label_assign, top_label);
1346 compile_node(comp, pns->nodes[1]); // body
1347 EMIT(label_assign, continue_label);
1348 c_if_cond(comp, pns->nodes[0], true, top_label); // condition
1349#endif
1350
1351 // break/continue apply to outer loop (if any) in the else block
1352 comp->break_label = old_break_label;
1353 comp->continue_label = old_continue_label;
Damien429d7192013-10-04 19:53:11 +01001354
1355 compile_node(comp, pns->nodes[2]); // else
1356
1357 EMIT(label_assign, break_label);
Damien429d7192013-10-04 19:53:11 +01001358}
1359
Damienf72fd0e2013-11-06 20:20:49 +00001360// TODO preload end and step onto stack if they are not constants
1361// TODO check if step is negative and do opposite test
1362void 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) {
1363 int old_break_label = comp->break_label;
1364 int old_continue_label = comp->continue_label;
1365
1366 int break_label = comp_next_label(comp);
1367 int continue_label = comp_next_label(comp);
1368
1369 comp->break_label = break_label;
1370 comp->continue_label = continue_label;
1371
1372 int top_label = comp_next_label(comp);
1373
1374 // compile: var = start
1375 compile_node(comp, pn_start);
1376 c_assign(comp, pn_var, ASSIGN_STORE);
1377
1378 EMIT(jump, continue_label);
1379 EMIT(label_assign, top_label);
1380
Damienf3822fc2013-11-09 20:12:03 +00001381 // compile body
1382 compile_node(comp, pn_body);
1383
Damienf72fd0e2013-11-06 20:20:49 +00001384 // compile: var += step
1385 c_assign(comp, pn_var, ASSIGN_AUG_LOAD);
1386 compile_node(comp, pn_step);
1387 EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD);
1388 c_assign(comp, pn_var, ASSIGN_AUG_STORE);
1389
Damienf72fd0e2013-11-06 20:20:49 +00001390 EMIT(label_assign, continue_label);
1391
1392 // compile: if var < end: goto top
1393 compile_node(comp, pn_var);
1394 compile_node(comp, pn_end);
1395 EMIT(compare_op, RT_COMPARE_OP_LESS);
1396 EMIT(pop_jump_if_true, top_label);
1397
1398 // break/continue apply to outer loop (if any) in the else block
1399 comp->break_label = old_break_label;
1400 comp->continue_label = old_continue_label;
1401
1402 compile_node(comp, pn_else);
1403
1404 EMIT(label_assign, break_label);
1405}
1406
Damien429d7192013-10-04 19:53:11 +01001407void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienf72fd0e2013-11-06 20:20:49 +00001408#if !MICROPY_EMIT_CPYTHON
1409 // this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
1410 // this is actually slower, but uses no heap memory
1411 // for viper it will be much, much faster
1412 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
1413 py_parse_node_struct_t *pns_it = (py_parse_node_struct_t*)pns->nodes[1];
1414 if (PY_PARSE_NODE_IS_ID(pns_it->nodes[0]) && PY_PARSE_NODE_IS_STRUCT_KIND(pns_it->nodes[1], PN_trailer_paren) && PY_PARSE_NODE_IS_NULL(pns_it->nodes[2])) {
1415 py_parse_node_t pn_range_args = ((py_parse_node_struct_t*)pns_it->nodes[1])->nodes[0];
1416 py_parse_node_t *args;
1417 int n_args = list_get(&pn_range_args, PN_arglist, &args);
1418 if (1 <= n_args && n_args <= 3) {
1419 py_parse_node_t pn_range_start;
1420 py_parse_node_t pn_range_end;
1421 py_parse_node_t pn_range_step;
1422 if (n_args == 1) {
1423 pn_range_start = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 0);
1424 pn_range_end = args[0];
1425 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1426 } else if (n_args == 2) {
1427 pn_range_start = args[0];
1428 pn_range_end = args[1];
1429 pn_range_step = py_parse_node_new_leaf(PY_PARSE_NODE_SMALL_INT, 1);
1430 } else {
1431 pn_range_start = args[0];
1432 pn_range_end = args[1];
1433 pn_range_step = args[2];
1434 }
1435 compile_for_stmt_optimised_range(comp, pns->nodes[0], pn_range_start, pn_range_end, pn_range_step, pns->nodes[2], pns->nodes[3]);
1436 return;
1437 }
1438 }
1439 }
1440#endif
1441
Damien429d7192013-10-04 19:53:11 +01001442 int old_break_label = comp->break_label;
1443 int old_continue_label = comp->continue_label;
1444
Damienb05d7072013-10-05 13:37:10 +01001445 int for_label = comp_next_label(comp);
1446 int pop_label = comp_next_label(comp);
1447 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001448
Damienb05d7072013-10-05 13:37:10 +01001449 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001450
1451 comp->continue_label = for_label;
1452 comp->break_label = break_label;
1453
Damience89a212013-10-15 22:25:17 +01001454 // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
1455#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001456 EMIT(setup_loop, end_label);
Damience89a212013-10-15 22:25:17 +01001457#endif
1458
Damien429d7192013-10-04 19:53:11 +01001459 compile_node(comp, pns->nodes[1]); // iterator
1460 EMIT(get_iter);
1461 EMIT(label_assign, for_label);
1462 EMIT(for_iter, pop_label);
1463 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1464 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001465 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001466 EMIT(jump, for_label);
1467 }
1468 EMIT(label_assign, pop_label);
1469 EMIT(for_iter_end);
1470
1471 // break/continue apply to outer loop (if any) in the else block
1472 comp->break_label = old_break_label;
1473 comp->continue_label = old_continue_label;
1474
Damience89a212013-10-15 22:25:17 +01001475#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001476 EMIT(pop_block);
Damience89a212013-10-15 22:25:17 +01001477#endif
Damien429d7192013-10-04 19:53:11 +01001478
1479 compile_node(comp, pns->nodes[3]); // else (not tested)
1480
1481 EMIT(label_assign, break_label);
1482 EMIT(label_assign, end_label);
1483}
1484
1485void 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) {
1486 // this function is a bit of a hack at the moment
1487 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1488
1489 // setup code
1490 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001491 int l1 = comp_next_label(comp);
1492 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001493 comp->except_nest_level += 1; // for correct handling of continue
1494 EMIT(setup_except, l1);
1495 compile_node(comp, pn_body); // body
1496 EMIT(pop_block);
1497 EMIT(jump, success_label);
1498 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001499 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001500
1501 for (int i = 0; i < n_except; i++) {
1502 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1503 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1504
1505 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001506 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001507
1508 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1509 // this is a catch all exception handler
1510 if (i + 1 != n_except) {
1511 printf("SyntaxError: default 'except:' must be last\n");
1512 return;
1513 }
1514 } else {
1515 // this exception handler requires a match to a certain type of exception
1516 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1517 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1518 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1519 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1520 // handler binds the exception to a local
1521 pns_exception_expr = pns3->nodes[0];
1522 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1523 }
1524 }
1525 EMIT(dup_top);
1526 compile_node(comp, pns_exception_expr);
1527 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1528 EMIT(pop_jump_if_false, end_finally_label);
1529 }
1530
1531 EMIT(pop_top);
1532
1533 if (qstr_exception_local == 0) {
1534 EMIT(pop_top);
1535 } else {
Damien4b03e772013-10-05 14:17:09 +01001536 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001537 }
1538
1539 EMIT(pop_top);
1540
1541 int l3;
1542 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001543 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001544 EMIT(setup_finally, l3);
1545 }
1546 compile_node(comp, pns_except->nodes[1]);
1547 if (qstr_exception_local != 0) {
1548 EMIT(pop_block);
1549 }
1550 EMIT(pop_except);
1551 if (qstr_exception_local != 0) {
1552 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1553 EMIT(label_assign, l3);
1554 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001555 EMIT(store_id, qstr_exception_local);
1556 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001557 EMIT(end_finally);
1558 }
1559 EMIT(jump, l2);
1560 EMIT(label_assign, end_finally_label);
1561 }
1562
1563 EMIT(end_finally);
1564 EMIT(label_assign, success_label);
1565 comp->except_nest_level -= 1;
1566 compile_node(comp, pn_else); // else block, can be null
1567 EMIT(label_assign, l2);
1568 EMIT(set_stack_size, stack_size);
1569}
1570
1571void 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) {
1572 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1573 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001574 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001575 EMIT(setup_finally, l_finally_block);
1576 if (n_except == 0) {
1577 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1578 compile_node(comp, pn_body);
1579 } else {
1580 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1581 }
1582 EMIT(pop_block);
1583 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1584 EMIT(label_assign, l_finally_block);
1585 compile_node(comp, pn_finally);
1586 EMIT(end_finally);
1587 EMIT(set_stack_size, stack_size);
1588}
1589
1590void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1591 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1592 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1593 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1594 // just try-finally
1595 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1596 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1597 // try-except and possibly else and/or finally
1598 py_parse_node_t *pn_excepts;
1599 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1600 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1601 // no finally
1602 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1603 } else {
1604 // have finally
1605 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1606 }
1607 } else {
1608 // just try-except
1609 py_parse_node_t *pn_excepts;
1610 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1611 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1612 }
1613 } else {
1614 // shouldn't happen
1615 assert(0);
1616 }
1617}
1618
1619void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1620 if (n == 0) {
1621 // no more pre-bits, compile the body of the with
1622 compile_node(comp, body);
1623 } else {
Damienb05d7072013-10-05 13:37:10 +01001624 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001625 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1626 // this pre-bit is of the form "a as b"
1627 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1628 compile_node(comp, pns->nodes[0]);
1629 EMIT(setup_with, l_end);
1630 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1631 } else {
1632 // this pre-bit is just an expression
1633 compile_node(comp, nodes[0]);
1634 EMIT(setup_with, l_end);
1635 EMIT(pop_top);
1636 }
1637 // compile additional pre-bits and the body
1638 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1639 // finish this with block
1640 EMIT(pop_block);
1641 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1642 EMIT(label_assign, l_end);
1643 EMIT(with_cleanup);
1644 EMIT(end_finally);
1645 }
1646}
1647
1648void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1649 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1650 py_parse_node_t *nodes;
1651 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1652 assert(n > 0);
1653
1654 // compile in a nested fashion
1655 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1656}
1657
1658void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1659 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001660 if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
1661 // for REPL, evaluate then print the expression
1662 EMIT(load_id, qstr_from_str_static("__repl_print__"));
1663 compile_node(comp, pns->nodes[0]);
1664 EMIT(call_function, 1, 0, false, false);
1665 EMIT(pop_top);
1666
Damien429d7192013-10-04 19:53:11 +01001667 } else {
Damien5ac1b2e2013-10-18 19:58:12 +01001668 // for non-REPL, evaluate then discard the expression
1669 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1670 // do nothing with a lonely constant
1671 } else {
1672 compile_node(comp, pns->nodes[0]); // just an expression
1673 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1674 }
Damien429d7192013-10-04 19:53:11 +01001675 }
1676 } else {
1677 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1678 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1679 if (kind == PN_expr_stmt_augassign) {
1680 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1681 compile_node(comp, pns1->nodes[1]); // rhs
1682 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1683 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1684 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1685 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1686 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1687 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1688 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1689 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1690 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1691 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1692 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1693 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1694 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1695 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1696 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1697 default: assert(0); // shouldn't happen
1698 }
1699 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1700 } else if (kind == PN_expr_stmt_assign_list) {
1701 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1702 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1703 // following CPython, we store left-most first
1704 if (rhs > 0) {
1705 EMIT(dup_top);
1706 }
1707 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1708 for (int i = 0; i < rhs; i++) {
1709 if (i + 1 < rhs) {
1710 EMIT(dup_top);
1711 }
1712 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1713 }
1714 } else if (kind == PN_expr_stmt_assign) {
1715 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1716 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1717 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1718 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1719 // optimisation for a, b = c, d; to match CPython's optimisation
1720 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1721 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1722 compile_node(comp, pns10->nodes[0]); // rhs
1723 compile_node(comp, pns10->nodes[1]); // rhs
1724 EMIT(rot_two);
1725 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1726 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1727 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1728 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1729 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1730 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1731 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1732 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1733 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1734 compile_node(comp, pns10->nodes[0]); // rhs
1735 compile_node(comp, pns10->nodes[1]); // rhs
1736 compile_node(comp, pns10->nodes[2]); // rhs
1737 EMIT(rot_three);
1738 EMIT(rot_two);
1739 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1740 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1741 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1742 } else {
1743 compile_node(comp, pns1->nodes[0]); // rhs
1744 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1745 }
1746 } else {
1747 // shouldn't happen
1748 assert(0);
1749 }
1750 }
1751}
1752
1753void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1754 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1755 compile_node(comp, pns->nodes[0]);
1756 for (int i = 1; i < num_nodes; i += 1) {
1757 compile_node(comp, pns->nodes[i]);
1758 EMIT(binary_op, binary_op);
1759 }
1760}
1761
1762void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1763 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1764 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1765
1766 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001767 int l_fail = comp_next_label(comp);
1768 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001769 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1770 compile_node(comp, pns->nodes[0]); // success value
1771 EMIT(jump, l_end);
1772 EMIT(label_assign, l_fail);
1773 EMIT(set_stack_size, stack_size); // force stack size reset
1774 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1775 EMIT(label_assign, l_end);
1776}
1777
1778void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1779 // TODO default params etc for lambda; possibly just use funcdef code
1780 //py_parse_node_t pn_params = pns->nodes[0];
1781 //py_parse_node_t pn_body = pns->nodes[1];
1782
1783 if (comp->pass == PASS_1) {
1784 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001785 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 +01001786 // store the lambda scope so the compiling function (this one) can use it at each pass
1787 pns->nodes[2] = (py_parse_node_t)s;
1788 }
1789
1790 // get the scope for this lambda
1791 scope_t *this_scope = (scope_t*)pns->nodes[2];
1792
1793 // make the lambda
1794 close_over_variables_etc(comp, this_scope, 0, 0);
1795}
1796
1797void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001798 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001799 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1800 for (int i = 0; i < n; i += 1) {
1801 compile_node(comp, pns->nodes[i]);
1802 if (i + 1 < n) {
1803 EMIT(jump_if_true_or_pop, l_end);
1804 }
1805 }
1806 EMIT(label_assign, l_end);
1807}
1808
1809void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001810 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001811 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1812 for (int i = 0; i < n; i += 1) {
1813 compile_node(comp, pns->nodes[i]);
1814 if (i + 1 < n) {
1815 EMIT(jump_if_false_or_pop, l_end);
1816 }
1817 }
1818 EMIT(label_assign, l_end);
1819}
1820
1821void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1822 compile_node(comp, pns->nodes[0]);
1823 EMIT(unary_op, RT_UNARY_OP_NOT);
1824}
1825
1826void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1827 int stack_size = EMIT(get_stack_size);
1828 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1829 compile_node(comp, pns->nodes[0]);
1830 bool multi = (num_nodes > 3);
1831 int l_fail = 0;
1832 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001833 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001834 }
1835 for (int i = 1; i + 1 < num_nodes; i += 2) {
1836 compile_node(comp, pns->nodes[i + 1]);
1837 if (i + 2 < num_nodes) {
1838 EMIT(dup_top);
1839 EMIT(rot_three);
1840 }
1841 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1842 EMIT(compare_op, RT_COMPARE_OP_LESS);
1843 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1844 EMIT(compare_op, RT_COMPARE_OP_MORE);
1845 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1846 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1847 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1848 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1849 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1850 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1851 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1852 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1853 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1854 EMIT(compare_op, RT_COMPARE_OP_IN);
1855 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1856 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1857 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1858 if (kind == PN_comp_op_not_in) {
1859 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1860 } else if (kind == PN_comp_op_is) {
1861 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1862 EMIT(compare_op, RT_COMPARE_OP_IS);
1863 } else {
1864 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1865 }
1866 } else {
1867 // shouldn't happen
1868 assert(0);
1869 }
1870 } else {
1871 // shouldn't happen
1872 assert(0);
1873 }
1874 if (i + 2 < num_nodes) {
1875 EMIT(jump_if_false_or_pop, l_fail);
1876 }
1877 }
1878 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001879 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001880 EMIT(jump, l_end);
1881 EMIT(label_assign, l_fail);
1882 EMIT(rot_two);
1883 EMIT(pop_top);
1884 EMIT(label_assign, l_end);
1885 EMIT(set_stack_size, stack_size + 1); // force stack size
1886 }
1887}
1888
1889void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1890 // TODO
1891 assert(0);
1892 compile_node(comp, pns->nodes[0]);
1893 //EMIT(unary_op, "UNARY_STAR");
1894}
1895
1896void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1897 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1898}
1899
1900void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1901 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1902}
1903
1904void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1905 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1906}
1907
1908void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1909 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1910 compile_node(comp, pns->nodes[0]);
1911 for (int i = 1; i + 1 < num_nodes; i += 2) {
1912 compile_node(comp, pns->nodes[i + 1]);
1913 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1914 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1915 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1916 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1917 } else {
1918 // shouldn't happen
1919 assert(0);
1920 }
1921 }
1922}
1923
1924void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1925 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1926 compile_node(comp, pns->nodes[0]);
1927 for (int i = 1; i + 1 < num_nodes; i += 2) {
1928 compile_node(comp, pns->nodes[i + 1]);
1929 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
1930 EMIT(binary_op, RT_BINARY_OP_ADD);
1931 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1932 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1933 } else {
1934 // shouldn't happen
1935 assert(0);
1936 }
1937 }
1938}
1939
1940void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1941 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1942 compile_node(comp, pns->nodes[0]);
1943 for (int i = 1; i + 1 < num_nodes; i += 2) {
1944 compile_node(comp, pns->nodes[i + 1]);
1945 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1946 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1947 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1948 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1949 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1950 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1951 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1952 EMIT(binary_op, RT_BINARY_OP_MODULO);
1953 } else {
1954 // shouldn't happen
1955 assert(0);
1956 }
1957 }
1958}
1959
1960void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1961 compile_node(comp, pns->nodes[1]);
1962 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1963 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1964 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1965 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1966 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1967 EMIT(unary_op, RT_UNARY_OP_INVERT);
1968 } else {
1969 // shouldn't happen
1970 assert(0);
1971 }
1972}
1973
1974void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
1975 // function to call is on top of stack
1976
1977 int old_n_arg_keyword = comp->n_arg_keyword;
1978 bool old_have_star_arg = comp->have_star_arg;
1979 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
1980 comp->n_arg_keyword = 0;
1981 comp->have_star_arg = false;
1982 comp->have_dbl_star_arg = false;
1983
1984 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
1985
1986 // compute number of positional arguments
1987 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
1988 if (comp->have_star_arg) {
1989 n_positional -= 1;
1990 }
1991 if (comp->have_dbl_star_arg) {
1992 n_positional -= 1;
1993 }
1994
1995 if (is_method_call) {
1996 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1997 } else {
1998 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1999 }
2000
2001 comp->n_arg_keyword = old_n_arg_keyword;
2002 comp->have_star_arg = old_have_star_arg;
2003 comp->have_dbl_star_arg = old_have_dbl_star_arg;
2004}
2005
2006void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
2007 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2008 for (int i = 0; i < num_nodes; i++) {
2009 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)) {
2010 // optimisation for method calls a.f(...), following PyPy
2011 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
2012 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
2013 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
2014 compile_trailer_paren_helper(comp, pns_paren, true);
2015 i += 1;
2016 } else {
2017 compile_node(comp, pns->nodes[i]);
2018 }
2019 }
2020}
2021
2022void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2023 compile_node(comp, pns->nodes[0]);
2024 EMIT(binary_op, RT_BINARY_OP_POWER);
2025}
2026
2027void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
2028 // a list of strings
2029 EMIT(load_const_verbatim_start);
2030 EMIT(load_const_verbatim_str, "'");
2031 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
2032 for (int i = 0; i < n; i++) {
2033 // TODO allow concatenation of either strings or bytes, but not mixed
2034 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
2035 assert(PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]) == PY_PARSE_NODE_STRING);
2036 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
2037 EMIT(load_const_verbatim_strn, str, strlen(str));
2038 }
2039 EMIT(load_const_verbatim_str, "'");
2040 EMIT(load_const_verbatim_end);
2041}
2042
2043// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
2044void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
2045 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2046 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2047 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2048
2049 if (comp->pass == PASS_1) {
2050 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01002051 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 +01002052 // store the comprehension scope so the compiling function (this one) can use it at each pass
2053 pns_comp_for->nodes[3] = (py_parse_node_t)s;
2054 }
2055
2056 // get the scope for this comprehension
2057 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
2058
2059 // compile the comprehension
2060 close_over_variables_etc(comp, this_scope, 0, 0);
2061
2062 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
2063 EMIT(get_iter);
2064 EMIT(call_function, 1, 0, false, false);
2065}
2066
2067void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2068 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2069 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01002070 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
2071 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2072 pns = (py_parse_node_struct_t*)pns->nodes[0];
2073 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
2074 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
2075 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2076 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
2077 // tuple of one item, with trailing comma
2078 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01002079 c_tuple(comp, pns->nodes[0], NULL);
2080 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
2081 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01002082 c_tuple(comp, pns->nodes[0], pns2);
2083 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2084 // generator expression
2085 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2086 } else {
2087 // tuple with 2 items
2088 goto tuple_with_2_items;
2089 }
2090 } else {
2091 // tuple with 2 items
2092 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01002093 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
2094 }
2095 } else {
2096 // parenthesis around a single item, is just that item
2097 compile_node(comp, pns->nodes[0]);
2098 }
2099}
2100
2101void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2102 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2103 // empty list
2104 EMIT(build_list, 0);
2105 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2106 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
2107 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
2108 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
2109 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
2110 // list of one item, with trailing comma
2111 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
2112 compile_node(comp, pns2->nodes[0]);
2113 EMIT(build_list, 1);
2114 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
2115 // list of many items
2116 compile_node(comp, pns2->nodes[0]);
2117 compile_generic_all_nodes(comp, pns3);
2118 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2119 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2120 // list comprehension
2121 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2122 } else {
2123 // list with 2 items
2124 goto list_with_2_items;
2125 }
2126 } else {
2127 // list with 2 items
2128 list_with_2_items:
2129 compile_node(comp, pns2->nodes[0]);
2130 compile_node(comp, pns2->nodes[1]);
2131 EMIT(build_list, 2);
2132 }
2133 } else {
2134 // list with 1 item
2135 compile_node(comp, pns->nodes[0]);
2136 EMIT(build_list, 1);
2137 }
2138}
2139
2140void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2141 py_parse_node_t pn = pns->nodes[0];
2142 if (PY_PARSE_NODE_IS_NULL(pn)) {
2143 // empty dict
2144 EMIT(build_map, 0);
2145 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2146 pns = (py_parse_node_struct_t*)pn;
2147 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2148 // dict with one element
2149 EMIT(build_map, 1);
2150 compile_node(comp, pn);
2151 EMIT(store_map);
2152 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2153 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2154 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2155 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2156 // dict/set with multiple elements
2157
2158 // get tail elements (2nd, 3rd, ...)
2159 py_parse_node_t *nodes;
2160 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2161
2162 // first element sets whether it's a dict or set
2163 bool is_dict;
2164 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2165 // a dictionary
2166 EMIT(build_map, 1 + n);
2167 compile_node(comp, pns->nodes[0]);
2168 EMIT(store_map);
2169 is_dict = true;
2170 } else {
2171 // a set
2172 compile_node(comp, pns->nodes[0]); // 1st value of set
2173 is_dict = false;
2174 }
2175
2176 // process rest of elements
2177 for (int i = 0; i < n; i++) {
2178 py_parse_node_t pn = nodes[i];
2179 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2180 compile_node(comp, pn);
2181 if (is_dict) {
2182 if (!is_key_value) {
2183 printf("SyntaxError?: expecting key:value for dictionary");
2184 return;
2185 }
2186 EMIT(store_map);
2187 } else {
2188 if (is_key_value) {
2189 printf("SyntaxError?: expecting just a value for set");
2190 return;
2191 }
2192 }
2193 }
2194
2195 // if it's a set, build it
2196 if (!is_dict) {
2197 EMIT(build_set, 1 + n);
2198 }
2199 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2200 // dict/set comprehension
2201 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2202 // a dictionary comprehension
2203 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2204 } else {
2205 // a set comprehension
2206 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2207 }
2208 } else {
2209 // shouldn't happen
2210 assert(0);
2211 }
2212 } else {
2213 // set with one element
2214 goto set_with_one_element;
2215 }
2216 } else {
2217 // set with one element
2218 set_with_one_element:
2219 compile_node(comp, pn);
2220 EMIT(build_set, 1);
2221 }
2222}
2223
2224void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2225 compile_trailer_paren_helper(comp, pns, false);
2226}
2227
2228void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2229 // object who's index we want is on top of stack
2230 compile_node(comp, pns->nodes[0]); // the index
2231 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2232}
2233
2234void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2235 // object who's attribute we want is on top of stack
2236 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2237}
2238
2239void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2240 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2241 py_parse_node_t pn = pns->nodes[0];
2242 if (PY_PARSE_NODE_IS_NULL(pn)) {
2243 // [?:]
2244 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2245 EMIT(build_slice, 2);
2246 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2247 pns = (py_parse_node_struct_t*)pn;
2248 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2249 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2250 pn = pns->nodes[0];
2251 if (PY_PARSE_NODE_IS_NULL(pn)) {
2252 // [?::]
2253 EMIT(build_slice, 2);
2254 } else {
2255 // [?::x]
2256 compile_node(comp, pn);
2257 EMIT(build_slice, 3);
2258 }
2259 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2260 compile_node(comp, pns->nodes[0]);
2261 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2262 pns = (py_parse_node_struct_t*)pns->nodes[1];
2263 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2264 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2265 // [?:x:]
2266 EMIT(build_slice, 2);
2267 } else {
2268 // [?:x:x]
2269 compile_node(comp, pns->nodes[0]);
2270 EMIT(build_slice, 3);
2271 }
2272 } else {
2273 // [?:x]
2274 compile_node(comp, pn);
2275 EMIT(build_slice, 2);
2276 }
2277 } else {
2278 // [?:x]
2279 compile_node(comp, pn);
2280 EMIT(build_slice, 2);
2281 }
2282}
2283
2284void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2285 compile_node(comp, pns->nodes[0]); // start of slice
2286 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2287 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2288}
2289
2290void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2291 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2292 compile_subscript_3_helper(comp, pns);
2293}
2294
2295void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2296 // if this is called then we are compiling a dict key:value pair
2297 compile_node(comp, pns->nodes[1]); // value
2298 compile_node(comp, pns->nodes[0]); // key
2299}
2300
2301void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002302 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002303 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002304 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002305}
2306
2307void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2308 if (comp->have_star_arg) {
2309 printf("SyntaxError?: can't have multiple *x\n");
2310 return;
2311 }
2312 comp->have_star_arg = true;
2313 compile_node(comp, pns->nodes[0]);
2314}
2315
2316void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2317 if (comp->have_dbl_star_arg) {
2318 printf("SyntaxError?: can't have multiple **x\n");
2319 return;
2320 }
2321 comp->have_dbl_star_arg = true;
2322 compile_node(comp, pns->nodes[0]);
2323}
2324
2325void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2326 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2327 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2328 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2329 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2330 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2331 return;
2332 }
2333 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2334 compile_node(comp, pns2->nodes[0]);
2335 comp->n_arg_keyword += 1;
2336 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2337 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2338 } else {
2339 // shouldn't happen
2340 assert(0);
2341 }
2342}
2343
2344void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2345 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2346 printf("SyntaxError: 'yield' outside function\n");
2347 return;
2348 }
2349 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2350 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2351 EMIT(yield_value);
2352 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2353 pns = (py_parse_node_struct_t*)pns->nodes[0];
2354 compile_node(comp, pns->nodes[0]);
2355 EMIT(get_iter);
2356 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2357 EMIT(yield_from);
2358 } else {
2359 compile_node(comp, pns->nodes[0]);
2360 EMIT(yield_value);
2361 }
2362}
2363
2364typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2365static compile_function_t compile_function[] = {
2366 NULL,
2367#define nc NULL
2368#define c(f) compile_##f
2369#define DEF_RULE(rule, comp, kind, arg...) comp,
2370#include "grammar.h"
2371#undef nc
2372#undef c
2373#undef DEF_RULE
2374};
2375
2376void compile_node(compiler_t *comp, py_parse_node_t pn) {
2377 if (PY_PARSE_NODE_IS_NULL(pn)) {
2378 // pass
2379 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2380 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2381 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002382 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002383 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2384 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2385 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2386 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2387 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002388 case PY_PARSE_NODE_TOKEN:
2389 if (arg == PY_TOKEN_NEWLINE) {
2390 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
Damien5ac1b2e2013-10-18 19:58:12 +01002391 // or when single_input lets through a NEWLINE (user enters a blank line)
Damien91d387d2013-10-09 15:09:52 +01002392 // do nothing
2393 } else {
2394 EMIT(load_const_tok, arg);
2395 }
2396 break;
Damien429d7192013-10-04 19:53:11 +01002397 default: assert(0);
2398 }
2399 } else {
2400 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2401 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2402 if (f == NULL) {
2403 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
Damien5ac1b2e2013-10-18 19:58:12 +01002404 py_parse_node_show(pn, 0);
Damien429d7192013-10-04 19:53:11 +01002405 assert(0);
2406 } else {
2407 f(comp, pns);
2408 }
2409 }
2410}
2411
2412void 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) {
2413 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002414 qstr param_name = 0;
2415 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002416 if (PY_PARSE_NODE_IS_ID(pn)) {
2417 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002418 if (comp->have_bare_star) {
2419 // comes after a bare star, so doesn't count as a parameter
2420 } else {
2421 comp->scope_cur->num_params += 1;
2422 }
Damienb14de212013-10-06 00:28:28 +01002423 } else {
2424 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2425 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2426 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002427 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002428 //int node_index = 1; unused
2429 if (allow_annotations) {
2430 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2431 // this parameter has an annotation
2432 pn_annotation = pns->nodes[1];
2433 }
2434 //node_index = 2; unused
2435 }
2436 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2437 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2438 // this parameter has a default value
2439 if (comp->have_bare_star) {
2440 comp->scope_cur->num_dict_params += 1;
2441 } else {
2442 comp->scope_cur->num_default_params += 1;
2443 }
2444 }
2445 */
2446 if (comp->have_bare_star) {
2447 // comes after a bare star, so doesn't count as a parameter
2448 } else {
2449 comp->scope_cur->num_params += 1;
2450 }
2451 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2452 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2453 // bare star
2454 // TODO see http://www.python.org/dev/peps/pep-3102/
2455 comp->have_bare_star = true;
2456 //assert(comp->scope_cur->num_dict_params == 0);
2457 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2458 // named star
2459 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2460 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2461 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2462 // named star with annotation
2463 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2464 pns = (py_parse_node_struct_t*)pns->nodes[0];
2465 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2466 pn_annotation = pns->nodes[1];
2467 } else {
2468 // shouldn't happen
2469 assert(0);
2470 }
2471 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002472 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002473 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2474 // this parameter has an annotation
2475 pn_annotation = pns->nodes[1];
2476 }
2477 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002478 } else {
Damienb14de212013-10-06 00:28:28 +01002479 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002480 assert(0);
2481 }
Damien429d7192013-10-04 19:53:11 +01002482 }
2483
2484 if (param_name != 0) {
2485 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2486 // TODO this parameter has an annotation
2487 }
2488 bool added;
2489 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2490 if (!added) {
2491 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2492 return;
2493 }
2494 id_info->param = true;
2495 id_info->kind = ID_INFO_KIND_LOCAL;
2496 }
2497}
2498
2499void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2500 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2501}
2502
2503void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2504 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2505}
2506
2507void 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) {
2508 tail_recursion:
2509 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2510 // no more nested if/for; compile inner expression
2511 compile_node(comp, pn_inner_expr);
2512 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2513 EMIT(list_append, for_depth + 2);
2514 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2515 EMIT(map_add, for_depth + 2);
2516 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2517 EMIT(set_add, for_depth + 2);
2518 } else {
2519 EMIT(yield_value);
2520 EMIT(pop_top);
2521 }
2522 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2523 // if condition
2524 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2525 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2526 pn_iter = pns_comp_if->nodes[1];
2527 goto tail_recursion;
2528 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2529 // for loop
2530 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2531 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002532 int l_end2 = comp_next_label(comp);
2533 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002534 EMIT(get_iter);
2535 EMIT(label_assign, l_top2);
2536 EMIT(for_iter, l_end2);
2537 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2538 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2539 EMIT(jump, l_top2);
2540 EMIT(label_assign, l_end2);
2541 EMIT(for_iter_end);
2542 } else {
2543 // shouldn't happen
2544 assert(0);
2545 }
2546}
2547
2548void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2549 // see http://www.python.org/dev/peps/pep-0257/
2550
2551 // look for the first statement
2552 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2553 // fall through
2554 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2555 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2556 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2557 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2558 } else {
2559 return;
2560 }
2561
2562 // check the first statement for a doc string
2563 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2564 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2565 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2566 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2567 if (kind == PY_PARSE_NODE_STRING) {
2568 compile_node(comp, pns->nodes[0]); // a doc string
2569 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002570 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002571 }
2572 }
2573 }
2574}
2575
2576void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2577 comp->pass = pass;
2578 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002579 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002580 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002581
2582 if (comp->pass == PASS_1) {
2583 scope->stack_size = 0;
2584 }
2585
Damien5ac1b2e2013-10-18 19:58:12 +01002586#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01002587 if (comp->pass == PASS_3) {
Damien429d7192013-10-04 19:53:11 +01002588 scope_print_info(scope);
2589 }
Damien5ac1b2e2013-10-18 19:58:12 +01002590#endif
Damien429d7192013-10-04 19:53:11 +01002591
2592 // compile
2593 if (scope->kind == SCOPE_MODULE) {
Damien5ac1b2e2013-10-18 19:58:12 +01002594 if (!comp->is_repl) {
2595 check_for_doc_string(comp, scope->pn);
2596 }
Damien429d7192013-10-04 19:53:11 +01002597 compile_node(comp, scope->pn);
2598 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2599 EMIT(return_value);
2600 } else if (scope->kind == SCOPE_FUNCTION) {
2601 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2602 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2603 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2604
2605 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002606 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002607 if (comp->pass == PASS_1) {
2608 comp->have_bare_star = false;
2609 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2610 }
2611
Damien826005c2013-10-05 23:17:28 +01002612 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002613
2614 compile_node(comp, pns->nodes[3]); // 3 is function body
2615 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002616 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002617 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2618 EMIT(return_value);
2619 }
2620 } else if (scope->kind == SCOPE_LAMBDA) {
2621 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2622 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2623 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2624
2625 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002626 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002627 if (comp->pass == PASS_1) {
2628 comp->have_bare_star = false;
2629 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2630 }
2631
2632 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2633 EMIT(return_value);
2634 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2635 // a bit of a hack at the moment
2636
2637 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2638 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2639 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2640 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2641 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2642
Damien6cdd3af2013-10-05 18:08:26 +01002643 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002644 if (comp->pass == PASS_1) {
2645 bool added;
2646 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2647 assert(added);
2648 id_info->kind = ID_INFO_KIND_LOCAL;
2649 scope->num_params = 1;
2650 }
2651
2652 if (scope->kind == SCOPE_LIST_COMP) {
2653 EMIT(build_list, 0);
2654 } else if (scope->kind == SCOPE_DICT_COMP) {
2655 EMIT(build_map, 0);
2656 } else if (scope->kind == SCOPE_SET_COMP) {
2657 EMIT(build_set, 0);
2658 }
2659
Damienb05d7072013-10-05 13:37:10 +01002660 int l_end = comp_next_label(comp);
2661 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002662 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002663 EMIT(label_assign, l_top);
2664 EMIT(for_iter, l_end);
2665 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2666 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2667 EMIT(jump, l_top);
2668 EMIT(label_assign, l_end);
2669 EMIT(for_iter_end);
2670
2671 if (scope->kind == SCOPE_GEN_EXPR) {
2672 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2673 }
2674 EMIT(return_value);
2675 } else {
2676 assert(scope->kind == SCOPE_CLASS);
2677 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2678 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2679 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2680
2681 if (comp->pass == PASS_1) {
2682 bool added;
2683 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2684 assert(added);
2685 id_info->kind = ID_INFO_KIND_LOCAL;
2686 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2687 assert(added);
2688 id_info->kind = ID_INFO_KIND_LOCAL;
2689 id_info->param = true;
2690 scope->num_params = 1; // __locals__ is the parameter
2691 }
2692
Damien4b03e772013-10-05 14:17:09 +01002693 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002694 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002695 EMIT(load_id, comp->qstr___name__);
2696 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002697 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002698 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002699
2700 check_for_doc_string(comp, pns->nodes[2]);
2701 compile_node(comp, pns->nodes[2]); // 2 is class body
2702
2703 id_info_t *id = scope_find(scope, comp->qstr___class__);
2704 assert(id != NULL);
2705 if (id->kind == ID_INFO_KIND_LOCAL) {
2706 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2707 } else {
Damien27fb45e2013-10-20 15:07:49 +01002708 EMIT(load_closure, comp->qstr___class__, 0); // XXX check this is the correct local num
Damien429d7192013-10-04 19:53:11 +01002709 }
2710 EMIT(return_value);
2711 }
2712
Damien415eb6f2013-10-05 12:19:06 +01002713 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002714
Damien826005c2013-10-05 23:17:28 +01002715}
2716
2717void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2718 comp->pass = pass;
2719 comp->scope_cur = scope;
2720 comp->next_label = 1;
2721
2722 if (scope->kind != SCOPE_FUNCTION) {
2723 printf("Error: inline assembler must be a function\n");
2724 return;
2725 }
2726
Damiena2f2f7d2013-10-06 00:14:13 +01002727 if (comp->pass > PASS_1) {
2728 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2729 }
2730
Damien826005c2013-10-05 23:17:28 +01002731 // get the function definition parse node
2732 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2733 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2734 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2735
Damiena2f2f7d2013-10-06 00:14:13 +01002736 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002737
Damiena2f2f7d2013-10-06 00:14:13 +01002738 // parameters are in pns->nodes[1]
2739 if (comp->pass == PASS_2) {
2740 py_parse_node_t *pn_params;
2741 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2742 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2743 }
2744
Damien826005c2013-10-05 23:17:28 +01002745 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2746
2747 py_parse_node_t pn_body = pns->nodes[3]; // body
2748 py_parse_node_t *nodes;
2749 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2750
Damien826005c2013-10-05 23:17:28 +01002751 if (comp->pass == PASS_3) {
2752 //printf("----\n");
2753 scope_print_info(scope);
2754 }
2755
2756 for (int i = 0; i < num; i++) {
2757 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2758 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2759 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2760 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2761 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2762 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2763 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2764 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2765 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2766 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2767 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2768 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2769 py_parse_node_t *pn_arg;
2770 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2771
2772 // emit instructions
2773 if (strcmp(qstr_str(op), "label") == 0) {
2774 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2775 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2776 return;
2777 }
2778 int lab = comp_next_label(comp);
2779 if (pass > PASS_1) {
2780 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2781 }
2782 } else {
2783 if (pass > PASS_1) {
2784 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2785 }
2786 }
2787 }
2788
2789 if (comp->pass > PASS_1) {
2790 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002791 }
Damien429d7192013-10-04 19:53:11 +01002792}
2793
2794void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2795 // in functions, turn implicit globals into explicit globals
2796 // compute num_locals, and the index of each local
2797 scope->num_locals = 0;
2798 for (int i = 0; i < scope->id_info_len; i++) {
2799 id_info_t *id = &scope->id_info[i];
2800 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2801 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2802 continue;
2803 }
2804 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2805 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2806 }
2807 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2808 id->local_num = scope->num_locals;
2809 scope->num_locals += 1;
2810 }
2811 }
2812
Damien27fb45e2013-10-20 15:07:49 +01002813 // TODO compute the index of free and cell vars (freevars[idx] in CPython)
2814
Damien429d7192013-10-04 19:53:11 +01002815 // compute flags
2816 //scope->flags = 0; since we set some things in parameters
2817 if (scope->kind != SCOPE_MODULE) {
2818 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2819 }
2820 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) {
2821 assert(scope->parent != NULL);
2822 scope->flags |= SCOPE_FLAG_OPTIMISED;
2823
2824 // TODO possibly other ways it can be nested
2825 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2826 scope->flags |= SCOPE_FLAG_NESTED;
2827 }
2828 }
2829 int num_free = 0;
2830 for (int i = 0; i < scope->id_info_len; i++) {
2831 id_info_t *id = &scope->id_info[i];
2832 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2833 num_free += 1;
2834 }
2835 }
2836 if (num_free == 0) {
2837 scope->flags |= SCOPE_FLAG_NOFREE;
2838 }
2839}
2840
Damien5ac1b2e2013-10-18 19:58:12 +01002841bool py_compile(py_parse_node_t pn, bool is_repl) {
Damien429d7192013-10-04 19:53:11 +01002842 compiler_t *comp = m_new(compiler_t, 1);
2843
Damien6cdd3af2013-10-05 18:08:26 +01002844 comp->qstr___class__ = qstr_from_str_static("__class__");
2845 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2846 comp->qstr___name__ = qstr_from_str_static("__name__");
2847 comp->qstr___module__ = qstr_from_str_static("__module__");
2848 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2849 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2850 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2851 comp->qstr_micropython = qstr_from_str_static("micropython");
Damien5ac1b2e2013-10-18 19:58:12 +01002852 comp->qstr_byte_code = qstr_from_str_static("byte_code");
Damien6cdd3af2013-10-05 18:08:26 +01002853 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002854 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002855 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damien429d7192013-10-04 19:53:11 +01002856
Damien5ac1b2e2013-10-18 19:58:12 +01002857 comp->is_repl = is_repl;
2858 comp->had_error = false;
2859
Damien429d7192013-10-04 19:53:11 +01002860 comp->break_label = 0;
2861 comp->continue_label = 0;
2862 comp->except_nest_level = 0;
2863 comp->scope_head = NULL;
2864 comp->scope_cur = NULL;
2865
Damien826005c2013-10-05 23:17:28 +01002866 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002867 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002868
2869 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002870 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002871
Damien826005c2013-10-05 23:17:28 +01002872 // compile pass 1
2873 comp->emit = emit_pass1_new(comp->qstr___class__);
2874 comp->emit_method_table = &emit_pass1_method_table;
2875 comp->emit_inline_asm = NULL;
2876 comp->emit_inline_asm_method_table = NULL;
2877 uint max_num_labels = 0;
Damien5ac1b2e2013-10-18 19:58:12 +01002878 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002879 if (false) {
Damien3ef4abb2013-10-12 16:53:13 +01002880#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002881 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01002882 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01002883#endif
Damien826005c2013-10-05 23:17:28 +01002884 } else {
2885 compile_scope(comp, s, PASS_1);
2886 }
2887
2888 // update maximim number of labels needed
2889 if (comp->next_label > max_num_labels) {
2890 max_num_labels = comp->next_label;
2891 }
Damien429d7192013-10-04 19:53:11 +01002892 }
2893
Damien826005c2013-10-05 23:17:28 +01002894 // compute some things related to scope and identifiers
Damien5ac1b2e2013-10-18 19:58:12 +01002895 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damien429d7192013-10-04 19:53:11 +01002896 compile_scope_compute_things(comp, s);
2897 }
2898
Damien826005c2013-10-05 23:17:28 +01002899 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002900 emit_pass1_free(comp->emit);
2901
Damien826005c2013-10-05 23:17:28 +01002902 // compile pass 2 and 3
Damien3ef4abb2013-10-12 16:53:13 +01002903#if !MICROPY_EMIT_CPYTHON
Damien6cdd3af2013-10-05 18:08:26 +01002904 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01002905 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002906#endif
Damien3ef4abb2013-10-12 16:53:13 +01002907#if MICROPY_EMIT_INLINE_THUMB
Damien826005c2013-10-05 23:17:28 +01002908 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002909#endif
Damien5ac1b2e2013-10-18 19:58:12 +01002910 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002911 if (false) {
2912 // dummy
2913
Damien3ef4abb2013-10-12 16:53:13 +01002914#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002915 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2916 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01002917 if (emit_inline_thumb == NULL) {
2918 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2919 }
2920 comp->emit = NULL;
2921 comp->emit_method_table = NULL;
2922 comp->emit_inline_asm = emit_inline_thumb;
2923 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2924 compile_scope_inline_asm(comp, s, PASS_2);
2925 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01002926#endif
2927
Damien826005c2013-10-05 23:17:28 +01002928 } else {
Damienc025ebb2013-10-12 14:30:21 +01002929
2930 // choose the emit type
2931
Damien3ef4abb2013-10-12 16:53:13 +01002932#if MICROPY_EMIT_CPYTHON
Damienc025ebb2013-10-12 14:30:21 +01002933 comp->emit = emit_cpython_new(max_num_labels);
2934 comp->emit_method_table = &emit_cpython_method_table;
2935#else
Damien826005c2013-10-05 23:17:28 +01002936 switch (s->emit_options) {
2937 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01002938 case EMIT_OPT_VIPER:
Damien3ef4abb2013-10-12 16:53:13 +01002939#if MICROPY_EMIT_X64
Damiendc833822013-10-06 01:01:01 +01002940 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01002941 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01002942 }
Damien13ed3a62013-10-08 09:05:10 +01002943 comp->emit_method_table = &emit_native_x64_method_table;
Damien3ef4abb2013-10-12 16:53:13 +01002944#elif MICROPY_EMIT_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002945 if (emit_native == NULL) {
2946 emit_native = emit_native_thumb_new(max_num_labels);
2947 }
2948 comp->emit_method_table = &emit_native_thumb_method_table;
2949#endif
2950 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01002951 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01002952 break;
2953
Damien826005c2013-10-05 23:17:28 +01002954 default:
2955 if (emit_bc == NULL) {
2956 emit_bc = emit_bc_new(max_num_labels);
2957 }
2958 comp->emit = emit_bc;
2959 comp->emit_method_table = &emit_bc_method_table;
2960 break;
2961 }
Damienc025ebb2013-10-12 14:30:21 +01002962#endif
2963
2964 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01002965 compile_scope(comp, s, PASS_2);
2966 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01002967 }
Damien429d7192013-10-04 19:53:11 +01002968 }
2969
2970 m_free(comp);
Damien5ac1b2e2013-10-18 19:58:12 +01002971
2972 return !comp->had_error;
Damien429d7192013-10-04 19:53:11 +01002973}