blob: d622242b629464cfdfd2752d2105d420b1523dea [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) {
724 EMIT(load_closure, id_info->qstr);
725 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
1360void compile_for_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1361 int old_break_label = comp->break_label;
1362 int old_continue_label = comp->continue_label;
1363
Damienb05d7072013-10-05 13:37:10 +01001364 int for_label = comp_next_label(comp);
1365 int pop_label = comp_next_label(comp);
1366 int end_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001367
Damienb05d7072013-10-05 13:37:10 +01001368 int break_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001369
1370 comp->continue_label = for_label;
1371 comp->break_label = break_label;
1372
Damience89a212013-10-15 22:25:17 +01001373 // I don't think our implementation needs SETUP_LOOP/POP_BLOCK for for-statements
1374#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001375 EMIT(setup_loop, end_label);
Damience89a212013-10-15 22:25:17 +01001376#endif
1377
Damien429d7192013-10-04 19:53:11 +01001378 compile_node(comp, pns->nodes[1]); // iterator
1379 EMIT(get_iter);
1380 EMIT(label_assign, for_label);
1381 EMIT(for_iter, pop_label);
1382 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
1383 compile_node(comp, pns->nodes[2]); // body
Damien415eb6f2013-10-05 12:19:06 +01001384 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01001385 EMIT(jump, for_label);
1386 }
1387 EMIT(label_assign, pop_label);
1388 EMIT(for_iter_end);
1389
1390 // break/continue apply to outer loop (if any) in the else block
1391 comp->break_label = old_break_label;
1392 comp->continue_label = old_continue_label;
1393
Damience89a212013-10-15 22:25:17 +01001394#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01001395 EMIT(pop_block);
Damience89a212013-10-15 22:25:17 +01001396#endif
Damien429d7192013-10-04 19:53:11 +01001397
1398 compile_node(comp, pns->nodes[3]); // else (not tested)
1399
1400 EMIT(label_assign, break_label);
1401 EMIT(label_assign, end_label);
1402}
1403
1404void 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) {
1405 // this function is a bit of a hack at the moment
1406 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1407
1408 // setup code
1409 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001410 int l1 = comp_next_label(comp);
1411 int success_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001412 comp->except_nest_level += 1; // for correct handling of continue
1413 EMIT(setup_except, l1);
1414 compile_node(comp, pn_body); // body
1415 EMIT(pop_block);
1416 EMIT(jump, success_label);
1417 EMIT(label_assign, l1);
Damienb05d7072013-10-05 13:37:10 +01001418 int l2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001419
1420 for (int i = 0; i < n_except; i++) {
1421 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pn_excepts[i], PN_try_stmt_except)); // should be
1422 py_parse_node_struct_t *pns_except = (py_parse_node_struct_t*)pn_excepts[i];
1423
1424 qstr qstr_exception_local = 0;
Damienb05d7072013-10-05 13:37:10 +01001425 int end_finally_label = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001426
1427 if (PY_PARSE_NODE_IS_NULL(pns_except->nodes[0])) {
1428 // this is a catch all exception handler
1429 if (i + 1 != n_except) {
1430 printf("SyntaxError: default 'except:' must be last\n");
1431 return;
1432 }
1433 } else {
1434 // this exception handler requires a match to a certain type of exception
1435 py_parse_node_t pns_exception_expr = pns_except->nodes[0];
1436 if (PY_PARSE_NODE_IS_STRUCT(pns_exception_expr)) {
1437 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns_exception_expr;
1438 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_try_stmt_as_name) {
1439 // handler binds the exception to a local
1440 pns_exception_expr = pns3->nodes[0];
1441 qstr_exception_local = PY_PARSE_NODE_LEAF_ARG(pns3->nodes[1]);
1442 }
1443 }
1444 EMIT(dup_top);
1445 compile_node(comp, pns_exception_expr);
1446 EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
1447 EMIT(pop_jump_if_false, end_finally_label);
1448 }
1449
1450 EMIT(pop_top);
1451
1452 if (qstr_exception_local == 0) {
1453 EMIT(pop_top);
1454 } else {
Damien4b03e772013-10-05 14:17:09 +01001455 EMIT(store_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001456 }
1457
1458 EMIT(pop_top);
1459
1460 int l3;
1461 if (qstr_exception_local != 0) {
Damienb05d7072013-10-05 13:37:10 +01001462 l3 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001463 EMIT(setup_finally, l3);
1464 }
1465 compile_node(comp, pns_except->nodes[1]);
1466 if (qstr_exception_local != 0) {
1467 EMIT(pop_block);
1468 }
1469 EMIT(pop_except);
1470 if (qstr_exception_local != 0) {
1471 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1472 EMIT(label_assign, l3);
1473 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
Damien4b03e772013-10-05 14:17:09 +01001474 EMIT(store_id, qstr_exception_local);
1475 EMIT(delete_id, qstr_exception_local);
Damien429d7192013-10-04 19:53:11 +01001476 EMIT(end_finally);
1477 }
1478 EMIT(jump, l2);
1479 EMIT(label_assign, end_finally_label);
1480 }
1481
1482 EMIT(end_finally);
1483 EMIT(label_assign, success_label);
1484 comp->except_nest_level -= 1;
1485 compile_node(comp, pn_else); // else block, can be null
1486 EMIT(label_assign, l2);
1487 EMIT(set_stack_size, stack_size);
1488}
1489
1490void 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) {
1491 // don't understand how the stack works with exceptions, so we force it to return to the correct value
1492 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001493 int l_finally_block = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001494 EMIT(setup_finally, l_finally_block);
1495 if (n_except == 0) {
1496 assert(PY_PARSE_NODE_IS_NULL(pn_else));
1497 compile_node(comp, pn_body);
1498 } else {
1499 compile_try_except(comp, pn_body, n_except, pn_except, pn_else);
1500 }
1501 EMIT(pop_block);
1502 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1503 EMIT(label_assign, l_finally_block);
1504 compile_node(comp, pn_finally);
1505 EMIT(end_finally);
1506 EMIT(set_stack_size, stack_size);
1507}
1508
1509void compile_try_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1510 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1511 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1512 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_finally) {
1513 // just try-finally
1514 compile_try_finally(comp, pns->nodes[0], 0, NULL, PY_PARSE_NODE_NULL, pns2->nodes[0]);
1515 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_try_stmt_except_and_more) {
1516 // try-except and possibly else and/or finally
1517 py_parse_node_t *pn_excepts;
1518 int n_except = list_get(&pns2->nodes[0], PN_try_stmt_except_list, &pn_excepts);
1519 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[2])) {
1520 // no finally
1521 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1]);
1522 } else {
1523 // have finally
1524 compile_try_finally(comp, pns->nodes[0], n_except, pn_excepts, pns2->nodes[1], ((py_parse_node_struct_t*)pns2->nodes[2])->nodes[0]);
1525 }
1526 } else {
1527 // just try-except
1528 py_parse_node_t *pn_excepts;
1529 int n_except = list_get(&pns->nodes[1], PN_try_stmt_except_list, &pn_excepts);
1530 compile_try_except(comp, pns->nodes[0], n_except, pn_excepts, PY_PARSE_NODE_NULL);
1531 }
1532 } else {
1533 // shouldn't happen
1534 assert(0);
1535 }
1536}
1537
1538void compile_with_stmt_helper(compiler_t *comp, int n, py_parse_node_t *nodes, py_parse_node_t body) {
1539 if (n == 0) {
1540 // no more pre-bits, compile the body of the with
1541 compile_node(comp, body);
1542 } else {
Damienb05d7072013-10-05 13:37:10 +01001543 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001544 if (PY_PARSE_NODE_IS_STRUCT_KIND(nodes[0], PN_with_item)) {
1545 // this pre-bit is of the form "a as b"
1546 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)nodes[0];
1547 compile_node(comp, pns->nodes[0]);
1548 EMIT(setup_with, l_end);
1549 c_assign(comp, pns->nodes[1], ASSIGN_STORE);
1550 } else {
1551 // this pre-bit is just an expression
1552 compile_node(comp, nodes[0]);
1553 EMIT(setup_with, l_end);
1554 EMIT(pop_top);
1555 }
1556 // compile additional pre-bits and the body
1557 compile_with_stmt_helper(comp, n - 1, nodes + 1, body);
1558 // finish this with block
1559 EMIT(pop_block);
1560 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
1561 EMIT(label_assign, l_end);
1562 EMIT(with_cleanup);
1563 EMIT(end_finally);
1564 }
1565}
1566
1567void compile_with_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1568 // get the nodes for the pre-bit of the with (the a as b, c as d, ... bit)
1569 py_parse_node_t *nodes;
1570 int n = list_get(&pns->nodes[0], PN_with_stmt_list, &nodes);
1571 assert(n > 0);
1572
1573 // compile in a nested fashion
1574 compile_with_stmt_helper(comp, n, nodes, pns->nodes[1]);
1575}
1576
1577void compile_expr_stmt(compiler_t *comp, py_parse_node_struct_t *pns) {
1578 if (PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
Damien5ac1b2e2013-10-18 19:58:12 +01001579 if (comp->is_repl && comp->scope_cur->kind == SCOPE_MODULE) {
1580 // for REPL, evaluate then print the expression
1581 EMIT(load_id, qstr_from_str_static("__repl_print__"));
1582 compile_node(comp, pns->nodes[0]);
1583 EMIT(call_function, 1, 0, false, false);
1584 EMIT(pop_top);
1585
Damien429d7192013-10-04 19:53:11 +01001586 } else {
Damien5ac1b2e2013-10-18 19:58:12 +01001587 // for non-REPL, evaluate then discard the expression
1588 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
1589 // do nothing with a lonely constant
1590 } else {
1591 compile_node(comp, pns->nodes[0]); // just an expression
1592 EMIT(pop_top); // discard last result since this is a statement and leaves nothing on the stack
1593 }
Damien429d7192013-10-04 19:53:11 +01001594 }
1595 } else {
1596 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
1597 int kind = PY_PARSE_NODE_STRUCT_KIND(pns1);
1598 if (kind == PN_expr_stmt_augassign) {
1599 c_assign(comp, pns->nodes[0], ASSIGN_AUG_LOAD); // lhs load for aug assign
1600 compile_node(comp, pns1->nodes[1]); // rhs
1601 assert(PY_PARSE_NODE_IS_TOKEN(pns1->nodes[0]));
1602 // note that we don't really need to implement separate inplace ops, just normal binary ops will suffice
1603 switch (PY_PARSE_NODE_LEAF_ARG(pns1->nodes[0])) {
1604 case PY_TOKEN_DEL_PIPE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_OR); break;
1605 case PY_TOKEN_DEL_CARET_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_XOR); break;
1606 case PY_TOKEN_DEL_AMPERSAND_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_AND); break;
1607 case PY_TOKEN_DEL_DBL_LESS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_LSHIFT); break;
1608 case PY_TOKEN_DEL_DBL_MORE_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_RSHIFT); break;
1609 case PY_TOKEN_DEL_PLUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_ADD); break;
1610 case PY_TOKEN_DEL_MINUS_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_SUBTRACT); break;
1611 case PY_TOKEN_DEL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MULTIPLY); break;
1612 case PY_TOKEN_DEL_DBL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_FLOOR_DIVIDE); break;
1613 case PY_TOKEN_DEL_SLASH_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_TRUE_DIVIDE); break;
1614 case PY_TOKEN_DEL_PERCENT_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_MODULO); break;
1615 case PY_TOKEN_DEL_DBL_STAR_EQUAL: EMIT(binary_op, RT_BINARY_OP_INPLACE_POWER); break;
1616 default: assert(0); // shouldn't happen
1617 }
1618 c_assign(comp, pns->nodes[0], ASSIGN_AUG_STORE); // lhs store for aug assign
1619 } else if (kind == PN_expr_stmt_assign_list) {
1620 int rhs = PY_PARSE_NODE_STRUCT_NUM_NODES(pns1) - 1;
1621 compile_node(comp, ((py_parse_node_struct_t*)pns1->nodes[rhs])->nodes[0]); // rhs
1622 // following CPython, we store left-most first
1623 if (rhs > 0) {
1624 EMIT(dup_top);
1625 }
1626 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1627 for (int i = 0; i < rhs; i++) {
1628 if (i + 1 < rhs) {
1629 EMIT(dup_top);
1630 }
1631 c_assign(comp, ((py_parse_node_struct_t*)pns1->nodes[i])->nodes[0], ASSIGN_STORE); // middle store
1632 }
1633 } else if (kind == PN_expr_stmt_assign) {
1634 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1635 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1636 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 2
1637 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 2) {
1638 // optimisation for a, b = c, d; to match CPython's optimisation
1639 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1640 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1641 compile_node(comp, pns10->nodes[0]); // rhs
1642 compile_node(comp, pns10->nodes[1]); // rhs
1643 EMIT(rot_two);
1644 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1645 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1646 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns1->nodes[0], PN_testlist_star_expr)
1647 && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_star_expr)
1648 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns1->nodes[0]) == 3
1649 && PY_PARSE_NODE_STRUCT_NUM_NODES((py_parse_node_struct_t*)pns->nodes[0]) == 3) {
1650 // optimisation for a, b, c = d, e, f; to match CPython's optimisation
1651 py_parse_node_struct_t* pns10 = (py_parse_node_struct_t*)pns1->nodes[0];
1652 py_parse_node_struct_t* pns0 = (py_parse_node_struct_t*)pns->nodes[0];
1653 compile_node(comp, pns10->nodes[0]); // rhs
1654 compile_node(comp, pns10->nodes[1]); // rhs
1655 compile_node(comp, pns10->nodes[2]); // rhs
1656 EMIT(rot_three);
1657 EMIT(rot_two);
1658 c_assign(comp, pns0->nodes[0], ASSIGN_STORE); // lhs store
1659 c_assign(comp, pns0->nodes[1], ASSIGN_STORE); // lhs store
1660 c_assign(comp, pns0->nodes[2], ASSIGN_STORE); // lhs store
1661 } else {
1662 compile_node(comp, pns1->nodes[0]); // rhs
1663 c_assign(comp, pns->nodes[0], ASSIGN_STORE); // lhs store
1664 }
1665 } else {
1666 // shouldn't happen
1667 assert(0);
1668 }
1669 }
1670}
1671
1672void c_binary_op(compiler_t *comp, py_parse_node_struct_t *pns, rt_binary_op_t binary_op) {
1673 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1674 compile_node(comp, pns->nodes[0]);
1675 for (int i = 1; i < num_nodes; i += 1) {
1676 compile_node(comp, pns->nodes[i]);
1677 EMIT(binary_op, binary_op);
1678 }
1679}
1680
1681void compile_test_if_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1682 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_test_if_else));
1683 py_parse_node_struct_t *pns_test_if_else = (py_parse_node_struct_t*)pns->nodes[1];
1684
1685 int stack_size = EMIT(get_stack_size);
Damienb05d7072013-10-05 13:37:10 +01001686 int l_fail = comp_next_label(comp);
1687 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001688 c_if_cond(comp, pns_test_if_else->nodes[0], false, l_fail); // condition
1689 compile_node(comp, pns->nodes[0]); // success value
1690 EMIT(jump, l_end);
1691 EMIT(label_assign, l_fail);
1692 EMIT(set_stack_size, stack_size); // force stack size reset
1693 compile_node(comp, pns_test_if_else->nodes[1]); // failure value
1694 EMIT(label_assign, l_end);
1695}
1696
1697void compile_lambdef(compiler_t *comp, py_parse_node_struct_t *pns) {
1698 // TODO default params etc for lambda; possibly just use funcdef code
1699 //py_parse_node_t pn_params = pns->nodes[0];
1700 //py_parse_node_t pn_body = pns->nodes[1];
1701
1702 if (comp->pass == PASS_1) {
1703 // create a new scope for this lambda
Damien6cdd3af2013-10-05 18:08:26 +01001704 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 +01001705 // store the lambda scope so the compiling function (this one) can use it at each pass
1706 pns->nodes[2] = (py_parse_node_t)s;
1707 }
1708
1709 // get the scope for this lambda
1710 scope_t *this_scope = (scope_t*)pns->nodes[2];
1711
1712 // make the lambda
1713 close_over_variables_etc(comp, this_scope, 0, 0);
1714}
1715
1716void compile_or_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001717 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001718 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1719 for (int i = 0; i < n; i += 1) {
1720 compile_node(comp, pns->nodes[i]);
1721 if (i + 1 < n) {
1722 EMIT(jump_if_true_or_pop, l_end);
1723 }
1724 }
1725 EMIT(label_assign, l_end);
1726}
1727
1728void compile_and_test(compiler_t *comp, py_parse_node_struct_t *pns) {
Damienb05d7072013-10-05 13:37:10 +01001729 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001730 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1731 for (int i = 0; i < n; i += 1) {
1732 compile_node(comp, pns->nodes[i]);
1733 if (i + 1 < n) {
1734 EMIT(jump_if_false_or_pop, l_end);
1735 }
1736 }
1737 EMIT(label_assign, l_end);
1738}
1739
1740void compile_not_test_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1741 compile_node(comp, pns->nodes[0]);
1742 EMIT(unary_op, RT_UNARY_OP_NOT);
1743}
1744
1745void compile_comparison(compiler_t *comp, py_parse_node_struct_t *pns) {
1746 int stack_size = EMIT(get_stack_size);
1747 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1748 compile_node(comp, pns->nodes[0]);
1749 bool multi = (num_nodes > 3);
1750 int l_fail = 0;
1751 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001752 l_fail = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001753 }
1754 for (int i = 1; i + 1 < num_nodes; i += 2) {
1755 compile_node(comp, pns->nodes[i + 1]);
1756 if (i + 2 < num_nodes) {
1757 EMIT(dup_top);
1758 EMIT(rot_three);
1759 }
1760 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS)) {
1761 EMIT(compare_op, RT_COMPARE_OP_LESS);
1762 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE)) {
1763 EMIT(compare_op, RT_COMPARE_OP_MORE);
1764 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_EQUAL)) {
1765 EMIT(compare_op, RT_COMPARE_OP_EQUAL);
1766 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_LESS_EQUAL)) {
1767 EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
1768 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MORE_EQUAL)) {
1769 EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
1770 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_NOT_EQUAL)) {
1771 EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
1772 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_KW_IN)) {
1773 EMIT(compare_op, RT_COMPARE_OP_IN);
1774 } else if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
1775 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[i];
1776 int kind = PY_PARSE_NODE_STRUCT_KIND(pns2);
1777 if (kind == PN_comp_op_not_in) {
1778 EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
1779 } else if (kind == PN_comp_op_is) {
1780 if (PY_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
1781 EMIT(compare_op, RT_COMPARE_OP_IS);
1782 } else {
1783 EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
1784 }
1785 } else {
1786 // shouldn't happen
1787 assert(0);
1788 }
1789 } else {
1790 // shouldn't happen
1791 assert(0);
1792 }
1793 if (i + 2 < num_nodes) {
1794 EMIT(jump_if_false_or_pop, l_fail);
1795 }
1796 }
1797 if (multi) {
Damienb05d7072013-10-05 13:37:10 +01001798 int l_end = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01001799 EMIT(jump, l_end);
1800 EMIT(label_assign, l_fail);
1801 EMIT(rot_two);
1802 EMIT(pop_top);
1803 EMIT(label_assign, l_end);
1804 EMIT(set_stack_size, stack_size + 1); // force stack size
1805 }
1806}
1807
1808void compile_star_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1809 // TODO
1810 assert(0);
1811 compile_node(comp, pns->nodes[0]);
1812 //EMIT(unary_op, "UNARY_STAR");
1813}
1814
1815void compile_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1816 c_binary_op(comp, pns, RT_BINARY_OP_OR);
1817}
1818
1819void compile_xor_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1820 c_binary_op(comp, pns, RT_BINARY_OP_XOR);
1821}
1822
1823void compile_and_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1824 c_binary_op(comp, pns, RT_BINARY_OP_AND);
1825}
1826
1827void compile_shift_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1828 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1829 compile_node(comp, pns->nodes[0]);
1830 for (int i = 1; i + 1 < num_nodes; i += 2) {
1831 compile_node(comp, pns->nodes[i + 1]);
1832 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_LESS)) {
1833 EMIT(binary_op, RT_BINARY_OP_LSHIFT);
1834 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_MORE)) {
1835 EMIT(binary_op, RT_BINARY_OP_RSHIFT);
1836 } else {
1837 // shouldn't happen
1838 assert(0);
1839 }
1840 }
1841}
1842
1843void compile_arith_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
1844 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1845 compile_node(comp, pns->nodes[0]);
1846 for (int i = 1; i + 1 < num_nodes; i += 2) {
1847 compile_node(comp, pns->nodes[i + 1]);
1848 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PLUS)) {
1849 EMIT(binary_op, RT_BINARY_OP_ADD);
1850 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_MINUS)) {
1851 EMIT(binary_op, RT_BINARY_OP_SUBTRACT);
1852 } else {
1853 // shouldn't happen
1854 assert(0);
1855 }
1856 }
1857}
1858
1859void compile_term(compiler_t *comp, py_parse_node_struct_t *pns) {
1860 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1861 compile_node(comp, pns->nodes[0]);
1862 for (int i = 1; i + 1 < num_nodes; i += 2) {
1863 compile_node(comp, pns->nodes[i + 1]);
1864 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_STAR)) {
1865 EMIT(binary_op, RT_BINARY_OP_MULTIPLY);
1866 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_DBL_SLASH)) {
1867 EMIT(binary_op, RT_BINARY_OP_FLOOR_DIVIDE);
1868 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_SLASH)) {
1869 EMIT(binary_op, RT_BINARY_OP_TRUE_DIVIDE);
1870 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], PY_TOKEN_OP_PERCENT)) {
1871 EMIT(binary_op, RT_BINARY_OP_MODULO);
1872 } else {
1873 // shouldn't happen
1874 assert(0);
1875 }
1876 }
1877}
1878
1879void compile_factor_2(compiler_t *comp, py_parse_node_struct_t *pns) {
1880 compile_node(comp, pns->nodes[1]);
1881 if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_PLUS)) {
1882 EMIT(unary_op, RT_UNARY_OP_POSITIVE);
1883 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_MINUS)) {
1884 EMIT(unary_op, RT_UNARY_OP_NEGATIVE);
1885 } else if (PY_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[0], PY_TOKEN_OP_TILDE)) {
1886 EMIT(unary_op, RT_UNARY_OP_INVERT);
1887 } else {
1888 // shouldn't happen
1889 assert(0);
1890 }
1891}
1892
1893void compile_trailer_paren_helper(compiler_t *comp, py_parse_node_struct_t *pns, bool is_method_call) {
1894 // function to call is on top of stack
1895
1896 int old_n_arg_keyword = comp->n_arg_keyword;
1897 bool old_have_star_arg = comp->have_star_arg;
1898 bool old_have_dbl_star_arg = comp->have_dbl_star_arg;
1899 comp->n_arg_keyword = 0;
1900 comp->have_star_arg = false;
1901 comp->have_dbl_star_arg = false;
1902
1903 compile_node(comp, pns->nodes[0]); // arguments to function call; can be null
1904
1905 // compute number of positional arguments
1906 int n_positional = list_len(pns->nodes[0], PN_arglist) - comp->n_arg_keyword;
1907 if (comp->have_star_arg) {
1908 n_positional -= 1;
1909 }
1910 if (comp->have_dbl_star_arg) {
1911 n_positional -= 1;
1912 }
1913
1914 if (is_method_call) {
1915 EMIT(call_method, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1916 } else {
1917 EMIT(call_function, n_positional, comp->n_arg_keyword, comp->have_star_arg, comp->have_dbl_star_arg);
1918 }
1919
1920 comp->n_arg_keyword = old_n_arg_keyword;
1921 comp->have_star_arg = old_have_star_arg;
1922 comp->have_dbl_star_arg = old_have_dbl_star_arg;
1923}
1924
1925void compile_power_trailers(compiler_t *comp, py_parse_node_struct_t *pns) {
1926 int num_nodes = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1927 for (int i = 0; i < num_nodes; i++) {
1928 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)) {
1929 // optimisation for method calls a.f(...), following PyPy
1930 py_parse_node_struct_t *pns_period = (py_parse_node_struct_t*)pns->nodes[i];
1931 py_parse_node_struct_t *pns_paren = (py_parse_node_struct_t*)pns->nodes[i + 1];
1932 EMIT(load_method, PY_PARSE_NODE_LEAF_ARG(pns_period->nodes[0])); // get the method
1933 compile_trailer_paren_helper(comp, pns_paren, true);
1934 i += 1;
1935 } else {
1936 compile_node(comp, pns->nodes[i]);
1937 }
1938 }
1939}
1940
1941void compile_power_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
1942 compile_node(comp, pns->nodes[0]);
1943 EMIT(binary_op, RT_BINARY_OP_POWER);
1944}
1945
1946void compile_atom_string(compiler_t *comp, py_parse_node_struct_t *pns) {
1947 // a list of strings
1948 EMIT(load_const_verbatim_start);
1949 EMIT(load_const_verbatim_str, "'");
1950 int n = PY_PARSE_NODE_STRUCT_NUM_NODES(pns);
1951 for (int i = 0; i < n; i++) {
1952 // TODO allow concatenation of either strings or bytes, but not mixed
1953 assert(PY_PARSE_NODE_IS_LEAF(pns->nodes[i]));
1954 assert(PY_PARSE_NODE_LEAF_KIND(pns->nodes[i]) == PY_PARSE_NODE_STRING);
1955 const char *str = qstr_str(PY_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
1956 EMIT(load_const_verbatim_strn, str, strlen(str));
1957 }
1958 EMIT(load_const_verbatim_str, "'");
1959 EMIT(load_const_verbatim_end);
1960}
1961
1962// pns needs to have 2 nodes, first is lhs of comprehension, second is PN_comp_for node
1963void compile_comprehension(compiler_t *comp, py_parse_node_struct_t *pns, scope_kind_t kind) {
1964 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
1965 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
1966 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
1967
1968 if (comp->pass == PASS_1) {
1969 // create a new scope for this comprehension
Damien6cdd3af2013-10-05 18:08:26 +01001970 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 +01001971 // store the comprehension scope so the compiling function (this one) can use it at each pass
1972 pns_comp_for->nodes[3] = (py_parse_node_t)s;
1973 }
1974
1975 // get the scope for this comprehension
1976 scope_t *this_scope = (scope_t*)pns_comp_for->nodes[3];
1977
1978 // compile the comprehension
1979 close_over_variables_etc(comp, this_scope, 0, 0);
1980
1981 compile_node(comp, pns_comp_for->nodes[1]); // source of the iterator
1982 EMIT(get_iter);
1983 EMIT(call_function, 1, 0, false, false);
1984}
1985
1986void compile_atom_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
1987 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
1988 // an empty tuple
Damien429d7192013-10-04 19:53:11 +01001989 c_tuple(comp, PY_PARSE_NODE_NULL, NULL);
1990 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
1991 pns = (py_parse_node_struct_t*)pns->nodes[0];
1992 assert(!PY_PARSE_NODE_IS_NULL(pns->nodes[1]));
1993 if (PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])) {
1994 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
1995 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3b) {
1996 // tuple of one item, with trailing comma
1997 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[0]));
Damien429d7192013-10-04 19:53:11 +01001998 c_tuple(comp, pns->nodes[0], NULL);
1999 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_testlist_comp_3c) {
2000 // tuple of many items
Damien429d7192013-10-04 19:53:11 +01002001 c_tuple(comp, pns->nodes[0], pns2);
2002 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2003 // generator expression
2004 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2005 } else {
2006 // tuple with 2 items
2007 goto tuple_with_2_items;
2008 }
2009 } else {
2010 // tuple with 2 items
2011 tuple_with_2_items:
Damien429d7192013-10-04 19:53:11 +01002012 c_tuple(comp, PY_PARSE_NODE_NULL, pns);
2013 }
2014 } else {
2015 // parenthesis around a single item, is just that item
2016 compile_node(comp, pns->nodes[0]);
2017 }
2018}
2019
2020void compile_atom_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2021 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2022 // empty list
2023 EMIT(build_list, 0);
2024 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
2025 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[0];
2026 if (PY_PARSE_NODE_IS_STRUCT(pns2->nodes[1])) {
2027 py_parse_node_struct_t *pns3 = (py_parse_node_struct_t*)pns2->nodes[1];
2028 if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3b) {
2029 // list of one item, with trailing comma
2030 assert(PY_PARSE_NODE_IS_NULL(pns3->nodes[0]));
2031 compile_node(comp, pns2->nodes[0]);
2032 EMIT(build_list, 1);
2033 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_testlist_comp_3c) {
2034 // list of many items
2035 compile_node(comp, pns2->nodes[0]);
2036 compile_generic_all_nodes(comp, pns3);
2037 EMIT(build_list, 1 + PY_PARSE_NODE_STRUCT_NUM_NODES(pns3));
2038 } else if (PY_PARSE_NODE_STRUCT_KIND(pns3) == PN_comp_for) {
2039 // list comprehension
2040 compile_comprehension(comp, pns2, SCOPE_LIST_COMP);
2041 } else {
2042 // list with 2 items
2043 goto list_with_2_items;
2044 }
2045 } else {
2046 // list with 2 items
2047 list_with_2_items:
2048 compile_node(comp, pns2->nodes[0]);
2049 compile_node(comp, pns2->nodes[1]);
2050 EMIT(build_list, 2);
2051 }
2052 } else {
2053 // list with 1 item
2054 compile_node(comp, pns->nodes[0]);
2055 EMIT(build_list, 1);
2056 }
2057}
2058
2059void compile_atom_brace(compiler_t *comp, py_parse_node_struct_t *pns) {
2060 py_parse_node_t pn = pns->nodes[0];
2061 if (PY_PARSE_NODE_IS_NULL(pn)) {
2062 // empty dict
2063 EMIT(build_map, 0);
2064 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2065 pns = (py_parse_node_struct_t*)pn;
2066 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker_item) {
2067 // dict with one element
2068 EMIT(build_map, 1);
2069 compile_node(comp, pn);
2070 EMIT(store_map);
2071 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
2072 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
2073 py_parse_node_struct_t *pns1 = (py_parse_node_struct_t*)pns->nodes[1];
2074 if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
2075 // dict/set with multiple elements
2076
2077 // get tail elements (2nd, 3rd, ...)
2078 py_parse_node_t *nodes;
2079 int n = list_get(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
2080
2081 // first element sets whether it's a dict or set
2082 bool is_dict;
2083 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2084 // a dictionary
2085 EMIT(build_map, 1 + n);
2086 compile_node(comp, pns->nodes[0]);
2087 EMIT(store_map);
2088 is_dict = true;
2089 } else {
2090 // a set
2091 compile_node(comp, pns->nodes[0]); // 1st value of set
2092 is_dict = false;
2093 }
2094
2095 // process rest of elements
2096 for (int i = 0; i < n; i++) {
2097 py_parse_node_t pn = nodes[i];
2098 bool is_key_value = PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_dictorsetmaker_item);
2099 compile_node(comp, pn);
2100 if (is_dict) {
2101 if (!is_key_value) {
2102 printf("SyntaxError?: expecting key:value for dictionary");
2103 return;
2104 }
2105 EMIT(store_map);
2106 } else {
2107 if (is_key_value) {
2108 printf("SyntaxError?: expecting just a value for set");
2109 return;
2110 }
2111 }
2112 }
2113
2114 // if it's a set, build it
2115 if (!is_dict) {
2116 EMIT(build_set, 1 + n);
2117 }
2118 } else if (PY_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
2119 // dict/set comprehension
2120 if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) {
2121 // a dictionary comprehension
2122 compile_comprehension(comp, pns, SCOPE_DICT_COMP);
2123 } else {
2124 // a set comprehension
2125 compile_comprehension(comp, pns, SCOPE_SET_COMP);
2126 }
2127 } else {
2128 // shouldn't happen
2129 assert(0);
2130 }
2131 } else {
2132 // set with one element
2133 goto set_with_one_element;
2134 }
2135 } else {
2136 // set with one element
2137 set_with_one_element:
2138 compile_node(comp, pn);
2139 EMIT(build_set, 1);
2140 }
2141}
2142
2143void compile_trailer_paren(compiler_t *comp, py_parse_node_struct_t *pns) {
2144 compile_trailer_paren_helper(comp, pns, false);
2145}
2146
2147void compile_trailer_bracket(compiler_t *comp, py_parse_node_struct_t *pns) {
2148 // object who's index we want is on top of stack
2149 compile_node(comp, pns->nodes[0]); // the index
2150 EMIT(binary_op, RT_BINARY_OP_SUBSCR);
2151}
2152
2153void compile_trailer_period(compiler_t *comp, py_parse_node_struct_t *pns) {
2154 // object who's attribute we want is on top of stack
2155 EMIT(load_attr, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get
2156}
2157
2158void compile_subscript_3_helper(compiler_t *comp, py_parse_node_struct_t *pns) {
2159 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3); // should always be
2160 py_parse_node_t pn = pns->nodes[0];
2161 if (PY_PARSE_NODE_IS_NULL(pn)) {
2162 // [?:]
2163 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2164 EMIT(build_slice, 2);
2165 } else if (PY_PARSE_NODE_IS_STRUCT(pn)) {
2166 pns = (py_parse_node_struct_t*)pn;
2167 if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3c) {
2168 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2169 pn = pns->nodes[0];
2170 if (PY_PARSE_NODE_IS_NULL(pn)) {
2171 // [?::]
2172 EMIT(build_slice, 2);
2173 } else {
2174 // [?::x]
2175 compile_node(comp, pn);
2176 EMIT(build_slice, 3);
2177 }
2178 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_subscript_3d) {
2179 compile_node(comp, pns->nodes[0]);
2180 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2181 pns = (py_parse_node_struct_t*)pns->nodes[1];
2182 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_sliceop); // should always be
2183 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2184 // [?:x:]
2185 EMIT(build_slice, 2);
2186 } else {
2187 // [?:x:x]
2188 compile_node(comp, pns->nodes[0]);
2189 EMIT(build_slice, 3);
2190 }
2191 } else {
2192 // [?:x]
2193 compile_node(comp, pn);
2194 EMIT(build_slice, 2);
2195 }
2196 } else {
2197 // [?:x]
2198 compile_node(comp, pn);
2199 EMIT(build_slice, 2);
2200 }
2201}
2202
2203void compile_subscript_2(compiler_t *comp, py_parse_node_struct_t *pns) {
2204 compile_node(comp, pns->nodes[0]); // start of slice
2205 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2206 compile_subscript_3_helper(comp, (py_parse_node_struct_t*)pns->nodes[1]);
2207}
2208
2209void compile_subscript_3(compiler_t *comp, py_parse_node_struct_t *pns) {
2210 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2211 compile_subscript_3_helper(comp, pns);
2212}
2213
2214void compile_dictorsetmaker_item(compiler_t *comp, py_parse_node_struct_t *pns) {
2215 // if this is called then we are compiling a dict key:value pair
2216 compile_node(comp, pns->nodes[1]); // value
2217 compile_node(comp, pns->nodes[0]); // key
2218}
2219
2220void compile_classdef(compiler_t *comp, py_parse_node_struct_t *pns) {
Damien6cdd3af2013-10-05 18:08:26 +01002221 qstr cname = compile_classdef_helper(comp, pns, comp->scope_cur->emit_options);
Damien429d7192013-10-04 19:53:11 +01002222 // store class object into class name
Damien4b03e772013-10-05 14:17:09 +01002223 EMIT(store_id, cname);
Damien429d7192013-10-04 19:53:11 +01002224}
2225
2226void compile_arglist_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2227 if (comp->have_star_arg) {
2228 printf("SyntaxError?: can't have multiple *x\n");
2229 return;
2230 }
2231 comp->have_star_arg = true;
2232 compile_node(comp, pns->nodes[0]);
2233}
2234
2235void compile_arglist_dbl_star(compiler_t *comp, py_parse_node_struct_t *pns) {
2236 if (comp->have_dbl_star_arg) {
2237 printf("SyntaxError?: can't have multiple **x\n");
2238 return;
2239 }
2240 comp->have_dbl_star_arg = true;
2241 compile_node(comp, pns->nodes[0]);
2242}
2243
2244void compile_argument(compiler_t *comp, py_parse_node_struct_t *pns) {
2245 assert(PY_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should always be
2246 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)pns->nodes[1];
2247 if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_argument_3) {
2248 if (!PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2249 printf("SyntaxError?: lhs of keyword argument must be an id\n");
2250 return;
2251 }
2252 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
2253 compile_node(comp, pns2->nodes[0]);
2254 comp->n_arg_keyword += 1;
2255 } else if (PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
2256 compile_comprehension(comp, pns, SCOPE_GEN_EXPR);
2257 } else {
2258 // shouldn't happen
2259 assert(0);
2260 }
2261}
2262
2263void compile_yield_expr(compiler_t *comp, py_parse_node_struct_t *pns) {
2264 if (comp->scope_cur->kind != SCOPE_FUNCTION) {
2265 printf("SyntaxError: 'yield' outside function\n");
2266 return;
2267 }
2268 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2269 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2270 EMIT(yield_value);
2271 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
2272 pns = (py_parse_node_struct_t*)pns->nodes[0];
2273 compile_node(comp, pns->nodes[0]);
2274 EMIT(get_iter);
2275 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2276 EMIT(yield_from);
2277 } else {
2278 compile_node(comp, pns->nodes[0]);
2279 EMIT(yield_value);
2280 }
2281}
2282
2283typedef void (*compile_function_t)(compiler_t*, py_parse_node_struct_t*);
2284static compile_function_t compile_function[] = {
2285 NULL,
2286#define nc NULL
2287#define c(f) compile_##f
2288#define DEF_RULE(rule, comp, kind, arg...) comp,
2289#include "grammar.h"
2290#undef nc
2291#undef c
2292#undef DEF_RULE
2293};
2294
2295void compile_node(compiler_t *comp, py_parse_node_t pn) {
2296 if (PY_PARSE_NODE_IS_NULL(pn)) {
2297 // pass
2298 } else if (PY_PARSE_NODE_IS_LEAF(pn)) {
2299 int arg = PY_PARSE_NODE_LEAF_ARG(pn);
2300 switch (PY_PARSE_NODE_LEAF_KIND(pn)) {
Damien4b03e772013-10-05 14:17:09 +01002301 case PY_PARSE_NODE_ID: EMIT(load_id, arg); break;
Damien429d7192013-10-04 19:53:11 +01002302 case PY_PARSE_NODE_SMALL_INT: EMIT(load_const_small_int, arg); break;
2303 case PY_PARSE_NODE_INTEGER: EMIT(load_const_int, arg); break;
2304 case PY_PARSE_NODE_DECIMAL: EMIT(load_const_dec, arg); break;
2305 case PY_PARSE_NODE_STRING: EMIT(load_const_str, arg, false); break;
2306 case PY_PARSE_NODE_BYTES: EMIT(load_const_str, arg, true); break;
Damien91d387d2013-10-09 15:09:52 +01002307 case PY_PARSE_NODE_TOKEN:
2308 if (arg == PY_TOKEN_NEWLINE) {
2309 // this can occur when file_input lets through a NEWLINE (eg if file starts with a newline)
Damien5ac1b2e2013-10-18 19:58:12 +01002310 // or when single_input lets through a NEWLINE (user enters a blank line)
Damien91d387d2013-10-09 15:09:52 +01002311 // do nothing
2312 } else {
2313 EMIT(load_const_tok, arg);
2314 }
2315 break;
Damien429d7192013-10-04 19:53:11 +01002316 default: assert(0);
2317 }
2318 } else {
2319 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2320 compile_function_t f = compile_function[PY_PARSE_NODE_STRUCT_KIND(pns)];
2321 if (f == NULL) {
2322 printf("node %u cannot be compiled\n", (uint)PY_PARSE_NODE_STRUCT_KIND(pns));
Damien5ac1b2e2013-10-18 19:58:12 +01002323 py_parse_node_show(pn, 0);
Damien429d7192013-10-04 19:53:11 +01002324 assert(0);
2325 } else {
2326 f(comp, pns);
2327 }
2328 }
2329}
2330
2331void 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) {
2332 // TODO verify that *k and **k are last etc
Damien429d7192013-10-04 19:53:11 +01002333 qstr param_name = 0;
2334 py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
Damienb14de212013-10-06 00:28:28 +01002335 if (PY_PARSE_NODE_IS_ID(pn)) {
2336 param_name = PY_PARSE_NODE_LEAF_ARG(pn);
Damien429d7192013-10-04 19:53:11 +01002337 if (comp->have_bare_star) {
2338 // comes after a bare star, so doesn't count as a parameter
2339 } else {
2340 comp->scope_cur->num_params += 1;
2341 }
Damienb14de212013-10-06 00:28:28 +01002342 } else {
2343 assert(PY_PARSE_NODE_IS_STRUCT(pn));
2344 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2345 if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
Damien429d7192013-10-04 19:53:11 +01002346 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002347 //int node_index = 1; unused
2348 if (allow_annotations) {
2349 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2350 // this parameter has an annotation
2351 pn_annotation = pns->nodes[1];
2352 }
2353 //node_index = 2; unused
2354 }
2355 /* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2356 if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2357 // this parameter has a default value
2358 if (comp->have_bare_star) {
2359 comp->scope_cur->num_dict_params += 1;
2360 } else {
2361 comp->scope_cur->num_default_params += 1;
2362 }
2363 }
2364 */
2365 if (comp->have_bare_star) {
2366 // comes after a bare star, so doesn't count as a parameter
2367 } else {
2368 comp->scope_cur->num_params += 1;
2369 }
2370 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2371 if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2372 // bare star
2373 // TODO see http://www.python.org/dev/peps/pep-3102/
2374 comp->have_bare_star = true;
2375 //assert(comp->scope_cur->num_dict_params == 0);
2376 } else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2377 // named star
2378 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2379 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2380 } else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2381 // named star with annotation
2382 comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2383 pns = (py_parse_node_struct_t*)pns->nodes[0];
2384 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2385 pn_annotation = pns->nodes[1];
2386 } else {
2387 // shouldn't happen
2388 assert(0);
2389 }
2390 } else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
Damien429d7192013-10-04 19:53:11 +01002391 param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
Damienb14de212013-10-06 00:28:28 +01002392 if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2393 // this parameter has an annotation
2394 pn_annotation = pns->nodes[1];
2395 }
2396 comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
Damien429d7192013-10-04 19:53:11 +01002397 } else {
Damienb14de212013-10-06 00:28:28 +01002398 // TODO anything to implement?
Damien429d7192013-10-04 19:53:11 +01002399 assert(0);
2400 }
Damien429d7192013-10-04 19:53:11 +01002401 }
2402
2403 if (param_name != 0) {
2404 if (!PY_PARSE_NODE_IS_NULL(pn_annotation)) {
2405 // TODO this parameter has an annotation
2406 }
2407 bool added;
2408 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
2409 if (!added) {
2410 printf("SyntaxError?: same name used for parameter; %s\n", qstr_str(param_name));
2411 return;
2412 }
2413 id_info->param = true;
2414 id_info->kind = ID_INFO_KIND_LOCAL;
2415 }
2416}
2417
2418void compile_scope_func_param(compiler_t *comp, py_parse_node_t pn) {
2419 compile_scope_func_lambda_param(comp, pn, PN_typedargslist_name, PN_typedargslist_star, PN_typedargslist_dbl_star, true);
2420}
2421
2422void compile_scope_lambda_param(compiler_t *comp, py_parse_node_t pn) {
2423 compile_scope_func_lambda_param(comp, pn, PN_varargslist_name, PN_varargslist_star, PN_varargslist_dbl_star, false);
2424}
2425
2426void 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) {
2427 tail_recursion:
2428 if (PY_PARSE_NODE_IS_NULL(pn_iter)) {
2429 // no more nested if/for; compile inner expression
2430 compile_node(comp, pn_inner_expr);
2431 if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
2432 EMIT(list_append, for_depth + 2);
2433 } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
2434 EMIT(map_add, for_depth + 2);
2435 } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
2436 EMIT(set_add, for_depth + 2);
2437 } else {
2438 EMIT(yield_value);
2439 EMIT(pop_top);
2440 }
2441 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
2442 // if condition
2443 py_parse_node_struct_t *pns_comp_if = (py_parse_node_struct_t*)pn_iter;
2444 c_if_cond(comp, pns_comp_if->nodes[0], false, l_top);
2445 pn_iter = pns_comp_if->nodes[1];
2446 goto tail_recursion;
2447 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_for)) {
2448 // for loop
2449 py_parse_node_struct_t *pns_comp_for2 = (py_parse_node_struct_t*)pn_iter;
2450 compile_node(comp, pns_comp_for2->nodes[1]);
Damienb05d7072013-10-05 13:37:10 +01002451 int l_end2 = comp_next_label(comp);
2452 int l_top2 = comp_next_label(comp);
Damien429d7192013-10-04 19:53:11 +01002453 EMIT(get_iter);
2454 EMIT(label_assign, l_top2);
2455 EMIT(for_iter, l_end2);
2456 c_assign(comp, pns_comp_for2->nodes[0], ASSIGN_STORE);
2457 compile_scope_comp_iter(comp, pns_comp_for2->nodes[2], pn_inner_expr, l_top2, for_depth + 1);
2458 EMIT(jump, l_top2);
2459 EMIT(label_assign, l_end2);
2460 EMIT(for_iter_end);
2461 } else {
2462 // shouldn't happen
2463 assert(0);
2464 }
2465}
2466
2467void check_for_doc_string(compiler_t *comp, py_parse_node_t pn) {
2468 // see http://www.python.org/dev/peps/pep-0257/
2469
2470 // look for the first statement
2471 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2472 // fall through
2473 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_file_input_2)) {
2474 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2475 } else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_suite_block_stmts)) {
2476 pn = ((py_parse_node_struct_t*)pn)->nodes[0];
2477 } else {
2478 return;
2479 }
2480
2481 // check the first statement for a doc string
2482 if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_expr_stmt)) {
2483 py_parse_node_struct_t* pns = (py_parse_node_struct_t*)pn;
2484 if (PY_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
2485 int kind = PY_PARSE_NODE_LEAF_KIND(pns->nodes[0]);
2486 if (kind == PY_PARSE_NODE_STRING) {
2487 compile_node(comp, pns->nodes[0]); // a doc string
2488 // store doc string
Damien4b03e772013-10-05 14:17:09 +01002489 EMIT(store_id, comp->qstr___doc__);
Damien429d7192013-10-04 19:53:11 +01002490 }
2491 }
2492 }
2493}
2494
2495void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2496 comp->pass = pass;
2497 comp->scope_cur = scope;
Damienb05d7072013-10-05 13:37:10 +01002498 comp->next_label = 1;
Damien415eb6f2013-10-05 12:19:06 +01002499 EMIT(start_pass, pass, scope);
Damien429d7192013-10-04 19:53:11 +01002500
2501 if (comp->pass == PASS_1) {
2502 scope->stack_size = 0;
2503 }
2504
Damien5ac1b2e2013-10-18 19:58:12 +01002505#if MICROPY_EMIT_CPYTHON
Damien429d7192013-10-04 19:53:11 +01002506 if (comp->pass == PASS_3) {
Damien429d7192013-10-04 19:53:11 +01002507 scope_print_info(scope);
2508 }
Damien5ac1b2e2013-10-18 19:58:12 +01002509#endif
Damien429d7192013-10-04 19:53:11 +01002510
2511 // compile
2512 if (scope->kind == SCOPE_MODULE) {
Damien5ac1b2e2013-10-18 19:58:12 +01002513 if (!comp->is_repl) {
2514 check_for_doc_string(comp, scope->pn);
2515 }
Damien429d7192013-10-04 19:53:11 +01002516 compile_node(comp, scope->pn);
2517 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2518 EMIT(return_value);
2519 } else if (scope->kind == SCOPE_FUNCTION) {
2520 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2521 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2522 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2523
2524 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002525 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002526 if (comp->pass == PASS_1) {
2527 comp->have_bare_star = false;
2528 apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
2529 }
2530
Damien826005c2013-10-05 23:17:28 +01002531 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // 2 is something...
Damien429d7192013-10-04 19:53:11 +01002532
2533 compile_node(comp, pns->nodes[3]); // 3 is function body
2534 // emit return if it wasn't the last opcode
Damien415eb6f2013-10-05 12:19:06 +01002535 if (!EMIT(last_emit_was_return_value)) {
Damien429d7192013-10-04 19:53:11 +01002536 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2537 EMIT(return_value);
2538 }
2539 } else if (scope->kind == SCOPE_LAMBDA) {
2540 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2541 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2542 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 3);
2543
2544 // work out number of parameters, keywords and default parameters, and add them to the id_info array
Damien6cdd3af2013-10-05 18:08:26 +01002545 // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
Damien429d7192013-10-04 19:53:11 +01002546 if (comp->pass == PASS_1) {
2547 comp->have_bare_star = false;
2548 apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
2549 }
2550
2551 compile_node(comp, pns->nodes[1]); // 1 is lambda body
2552 EMIT(return_value);
2553 } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) {
2554 // a bit of a hack at the moment
2555
2556 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2557 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2558 assert(PY_PARSE_NODE_STRUCT_NUM_NODES(pns) == 2);
2559 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
2560 py_parse_node_struct_t *pns_comp_for = (py_parse_node_struct_t*)pns->nodes[1];
2561
Damien6cdd3af2013-10-05 18:08:26 +01002562 qstr qstr_arg = qstr_from_str_static(".0");
Damien429d7192013-10-04 19:53:11 +01002563 if (comp->pass == PASS_1) {
2564 bool added;
2565 id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
2566 assert(added);
2567 id_info->kind = ID_INFO_KIND_LOCAL;
2568 scope->num_params = 1;
2569 }
2570
2571 if (scope->kind == SCOPE_LIST_COMP) {
2572 EMIT(build_list, 0);
2573 } else if (scope->kind == SCOPE_DICT_COMP) {
2574 EMIT(build_map, 0);
2575 } else if (scope->kind == SCOPE_SET_COMP) {
2576 EMIT(build_set, 0);
2577 }
2578
Damienb05d7072013-10-05 13:37:10 +01002579 int l_end = comp_next_label(comp);
2580 int l_top = comp_next_label(comp);
Damien4b03e772013-10-05 14:17:09 +01002581 EMIT(load_id, qstr_arg);
Damien429d7192013-10-04 19:53:11 +01002582 EMIT(label_assign, l_top);
2583 EMIT(for_iter, l_end);
2584 c_assign(comp, pns_comp_for->nodes[0], ASSIGN_STORE);
2585 compile_scope_comp_iter(comp, pns_comp_for->nodes[2], pns->nodes[0], l_top, 0);
2586 EMIT(jump, l_top);
2587 EMIT(label_assign, l_end);
2588 EMIT(for_iter_end);
2589
2590 if (scope->kind == SCOPE_GEN_EXPR) {
2591 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2592 }
2593 EMIT(return_value);
2594 } else {
2595 assert(scope->kind == SCOPE_CLASS);
2596 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2597 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2598 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
2599
2600 if (comp->pass == PASS_1) {
2601 bool added;
2602 id_info_t *id_info = scope_find_or_add_id(scope, comp->qstr___class__, &added);
2603 assert(added);
2604 id_info->kind = ID_INFO_KIND_LOCAL;
2605 id_info = scope_find_or_add_id(scope, comp->qstr___locals__, &added);
2606 assert(added);
2607 id_info->kind = ID_INFO_KIND_LOCAL;
2608 id_info->param = true;
2609 scope->num_params = 1; // __locals__ is the parameter
2610 }
2611
Damien4b03e772013-10-05 14:17:09 +01002612 EMIT(load_id, comp->qstr___locals__);
Damien429d7192013-10-04 19:53:11 +01002613 EMIT(store_locals);
Damien4b03e772013-10-05 14:17:09 +01002614 EMIT(load_id, comp->qstr___name__);
2615 EMIT(store_id, comp->qstr___module__);
Damien429d7192013-10-04 19:53:11 +01002616 EMIT(load_const_id, PY_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // 0 is class name
Damien4b03e772013-10-05 14:17:09 +01002617 EMIT(store_id, comp->qstr___qualname__);
Damien429d7192013-10-04 19:53:11 +01002618
2619 check_for_doc_string(comp, pns->nodes[2]);
2620 compile_node(comp, pns->nodes[2]); // 2 is class body
2621
2622 id_info_t *id = scope_find(scope, comp->qstr___class__);
2623 assert(id != NULL);
2624 if (id->kind == ID_INFO_KIND_LOCAL) {
2625 EMIT(load_const_tok, PY_TOKEN_KW_NONE);
2626 } else {
2627 EMIT(load_closure, comp->qstr___class__);
2628 }
2629 EMIT(return_value);
2630 }
2631
Damien415eb6f2013-10-05 12:19:06 +01002632 EMIT(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002633
Damien826005c2013-10-05 23:17:28 +01002634}
2635
2636void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
2637 comp->pass = pass;
2638 comp->scope_cur = scope;
2639 comp->next_label = 1;
2640
2641 if (scope->kind != SCOPE_FUNCTION) {
2642 printf("Error: inline assembler must be a function\n");
2643 return;
2644 }
2645
Damiena2f2f7d2013-10-06 00:14:13 +01002646 if (comp->pass > PASS_1) {
2647 EMIT_INLINE_ASM(start_pass, comp->pass, comp->scope_cur);
2648 }
2649
Damien826005c2013-10-05 23:17:28 +01002650 // get the function definition parse node
2651 assert(PY_PARSE_NODE_IS_STRUCT(scope->pn));
2652 py_parse_node_struct_t *pns = (py_parse_node_struct_t*)scope->pn;
2653 assert(PY_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2654
Damiena2f2f7d2013-10-06 00:14:13 +01002655 //qstr f_id = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
Damien826005c2013-10-05 23:17:28 +01002656
Damiena2f2f7d2013-10-06 00:14:13 +01002657 // parameters are in pns->nodes[1]
2658 if (comp->pass == PASS_2) {
2659 py_parse_node_t *pn_params;
2660 int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
2661 scope->num_params = EMIT_INLINE_ASM(count_params, n_params, pn_params);
2662 }
2663
Damien826005c2013-10-05 23:17:28 +01002664 assert(PY_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2665
2666 py_parse_node_t pn_body = pns->nodes[3]; // body
2667 py_parse_node_t *nodes;
2668 int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
2669
Damien826005c2013-10-05 23:17:28 +01002670 if (comp->pass == PASS_3) {
2671 //printf("----\n");
2672 scope_print_info(scope);
2673 }
2674
2675 for (int i = 0; i < num; i++) {
2676 assert(PY_PARSE_NODE_IS_STRUCT(nodes[i]));
2677 py_parse_node_struct_t *pns2 = (py_parse_node_struct_t*)nodes[i];
2678 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_expr_stmt);
2679 assert(PY_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2680 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[1]));
2681 pns2 = (py_parse_node_struct_t*)pns2->nodes[0];
2682 assert(PY_PARSE_NODE_STRUCT_KIND(pns2) == PN_power);
2683 assert(PY_PARSE_NODE_IS_ID(pns2->nodes[0]));
2684 assert(PY_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren));
2685 assert(PY_PARSE_NODE_IS_NULL(pns2->nodes[2]));
2686 qstr op = PY_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2687 pns2 = (py_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
2688 py_parse_node_t *pn_arg;
2689 int n_args = list_get(&pns2->nodes[0], PN_arglist, &pn_arg);
2690
2691 // emit instructions
2692 if (strcmp(qstr_str(op), "label") == 0) {
2693 if (!(n_args == 1 && PY_PARSE_NODE_IS_ID(pn_arg[0]))) {
2694 printf("SyntaxError: inline assembler 'label' requires 1 argument\n");
2695 return;
2696 }
2697 int lab = comp_next_label(comp);
2698 if (pass > PASS_1) {
2699 EMIT_INLINE_ASM(label, lab, PY_PARSE_NODE_LEAF_ARG(pn_arg[0]));
2700 }
2701 } else {
2702 if (pass > PASS_1) {
2703 EMIT_INLINE_ASM(op, op, n_args, pn_arg);
2704 }
2705 }
2706 }
2707
2708 if (comp->pass > PASS_1) {
2709 EMIT_INLINE_ASM(end_pass);
Damienb05d7072013-10-05 13:37:10 +01002710 }
Damien429d7192013-10-04 19:53:11 +01002711}
2712
2713void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
2714 // in functions, turn implicit globals into explicit globals
2715 // compute num_locals, and the index of each local
2716 scope->num_locals = 0;
2717 for (int i = 0; i < scope->id_info_len; i++) {
2718 id_info_t *id = &scope->id_info[i];
2719 if (scope->kind == SCOPE_CLASS && id->qstr == comp->qstr___class__) {
2720 // __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
2721 continue;
2722 }
2723 if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
2724 id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
2725 }
2726 if (id->param || id->kind == ID_INFO_KIND_LOCAL) {
2727 id->local_num = scope->num_locals;
2728 scope->num_locals += 1;
2729 }
2730 }
2731
2732 // compute flags
2733 //scope->flags = 0; since we set some things in parameters
2734 if (scope->kind != SCOPE_MODULE) {
2735 scope->flags |= SCOPE_FLAG_NEWLOCALS;
2736 }
2737 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) {
2738 assert(scope->parent != NULL);
2739 scope->flags |= SCOPE_FLAG_OPTIMISED;
2740
2741 // TODO possibly other ways it can be nested
2742 if (scope->parent->kind == SCOPE_FUNCTION || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) {
2743 scope->flags |= SCOPE_FLAG_NESTED;
2744 }
2745 }
2746 int num_free = 0;
2747 for (int i = 0; i < scope->id_info_len; i++) {
2748 id_info_t *id = &scope->id_info[i];
2749 if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
2750 num_free += 1;
2751 }
2752 }
2753 if (num_free == 0) {
2754 scope->flags |= SCOPE_FLAG_NOFREE;
2755 }
2756}
2757
Damien5ac1b2e2013-10-18 19:58:12 +01002758bool py_compile(py_parse_node_t pn, bool is_repl) {
Damien429d7192013-10-04 19:53:11 +01002759 compiler_t *comp = m_new(compiler_t, 1);
2760
Damien6cdd3af2013-10-05 18:08:26 +01002761 comp->qstr___class__ = qstr_from_str_static("__class__");
2762 comp->qstr___locals__ = qstr_from_str_static("__locals__");
2763 comp->qstr___name__ = qstr_from_str_static("__name__");
2764 comp->qstr___module__ = qstr_from_str_static("__module__");
2765 comp->qstr___qualname__ = qstr_from_str_static("__qualname__");
2766 comp->qstr___doc__ = qstr_from_str_static("__doc__");
2767 comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
2768 comp->qstr_micropython = qstr_from_str_static("micropython");
Damien5ac1b2e2013-10-18 19:58:12 +01002769 comp->qstr_byte_code = qstr_from_str_static("byte_code");
Damien6cdd3af2013-10-05 18:08:26 +01002770 comp->qstr_native = qstr_from_str_static("native");
Damien7af3d192013-10-07 00:02:49 +01002771 comp->qstr_viper = qstr_from_str_static("viper");
Damien5bfb7592013-10-05 18:41:24 +01002772 comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
Damien429d7192013-10-04 19:53:11 +01002773
Damien5ac1b2e2013-10-18 19:58:12 +01002774 comp->is_repl = is_repl;
2775 comp->had_error = false;
2776
Damien429d7192013-10-04 19:53:11 +01002777 comp->break_label = 0;
2778 comp->continue_label = 0;
2779 comp->except_nest_level = 0;
2780 comp->scope_head = NULL;
2781 comp->scope_cur = NULL;
2782
Damien826005c2013-10-05 23:17:28 +01002783 // optimise constants
Damien429d7192013-10-04 19:53:11 +01002784 pn = fold_constants(pn);
Damien826005c2013-10-05 23:17:28 +01002785
2786 // set the outer scope
Damien6cdd3af2013-10-05 18:08:26 +01002787 scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
Damien429d7192013-10-04 19:53:11 +01002788
Damien826005c2013-10-05 23:17:28 +01002789 // compile pass 1
2790 comp->emit = emit_pass1_new(comp->qstr___class__);
2791 comp->emit_method_table = &emit_pass1_method_table;
2792 comp->emit_inline_asm = NULL;
2793 comp->emit_inline_asm_method_table = NULL;
2794 uint max_num_labels = 0;
Damien5ac1b2e2013-10-18 19:58:12 +01002795 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002796 if (false) {
Damien3ef4abb2013-10-12 16:53:13 +01002797#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002798 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
Damien826005c2013-10-05 23:17:28 +01002799 compile_scope_inline_asm(comp, s, PASS_1);
Damienc025ebb2013-10-12 14:30:21 +01002800#endif
Damien826005c2013-10-05 23:17:28 +01002801 } else {
2802 compile_scope(comp, s, PASS_1);
2803 }
2804
2805 // update maximim number of labels needed
2806 if (comp->next_label > max_num_labels) {
2807 max_num_labels = comp->next_label;
2808 }
Damien429d7192013-10-04 19:53:11 +01002809 }
2810
Damien826005c2013-10-05 23:17:28 +01002811 // compute some things related to scope and identifiers
Damien5ac1b2e2013-10-18 19:58:12 +01002812 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damien429d7192013-10-04 19:53:11 +01002813 compile_scope_compute_things(comp, s);
2814 }
2815
Damien826005c2013-10-05 23:17:28 +01002816 // finish with pass 1
Damien6cdd3af2013-10-05 18:08:26 +01002817 emit_pass1_free(comp->emit);
2818
Damien826005c2013-10-05 23:17:28 +01002819 // compile pass 2 and 3
Damien3ef4abb2013-10-12 16:53:13 +01002820#if !MICROPY_EMIT_CPYTHON
Damien6cdd3af2013-10-05 18:08:26 +01002821 emit_t *emit_bc = NULL;
Damiendc833822013-10-06 01:01:01 +01002822 emit_t *emit_native = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002823#endif
Damien3ef4abb2013-10-12 16:53:13 +01002824#if MICROPY_EMIT_INLINE_THUMB
Damien826005c2013-10-05 23:17:28 +01002825 emit_inline_asm_t *emit_inline_thumb = NULL;
Damienc025ebb2013-10-12 14:30:21 +01002826#endif
Damien5ac1b2e2013-10-18 19:58:12 +01002827 for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
Damienc025ebb2013-10-12 14:30:21 +01002828 if (false) {
2829 // dummy
2830
Damien3ef4abb2013-10-12 16:53:13 +01002831#if MICROPY_EMIT_INLINE_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002832 } else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
2833 // inline assembly for thumb
Damien826005c2013-10-05 23:17:28 +01002834 if (emit_inline_thumb == NULL) {
2835 emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
2836 }
2837 comp->emit = NULL;
2838 comp->emit_method_table = NULL;
2839 comp->emit_inline_asm = emit_inline_thumb;
2840 comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
2841 compile_scope_inline_asm(comp, s, PASS_2);
2842 compile_scope_inline_asm(comp, s, PASS_3);
Damienc025ebb2013-10-12 14:30:21 +01002843#endif
2844
Damien826005c2013-10-05 23:17:28 +01002845 } else {
Damienc025ebb2013-10-12 14:30:21 +01002846
2847 // choose the emit type
2848
Damien3ef4abb2013-10-12 16:53:13 +01002849#if MICROPY_EMIT_CPYTHON
Damienc025ebb2013-10-12 14:30:21 +01002850 comp->emit = emit_cpython_new(max_num_labels);
2851 comp->emit_method_table = &emit_cpython_method_table;
2852#else
Damien826005c2013-10-05 23:17:28 +01002853 switch (s->emit_options) {
2854 case EMIT_OPT_NATIVE_PYTHON:
Damien3410be82013-10-07 23:09:10 +01002855 case EMIT_OPT_VIPER:
Damien3ef4abb2013-10-12 16:53:13 +01002856#if MICROPY_EMIT_X64
Damiendc833822013-10-06 01:01:01 +01002857 if (emit_native == NULL) {
Damien13ed3a62013-10-08 09:05:10 +01002858 emit_native = emit_native_x64_new(max_num_labels);
Damien826005c2013-10-05 23:17:28 +01002859 }
Damien13ed3a62013-10-08 09:05:10 +01002860 comp->emit_method_table = &emit_native_x64_method_table;
Damien3ef4abb2013-10-12 16:53:13 +01002861#elif MICROPY_EMIT_THUMB
Damienc025ebb2013-10-12 14:30:21 +01002862 if (emit_native == NULL) {
2863 emit_native = emit_native_thumb_new(max_num_labels);
2864 }
2865 comp->emit_method_table = &emit_native_thumb_method_table;
2866#endif
2867 comp->emit = emit_native;
Damien3410be82013-10-07 23:09:10 +01002868 comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
Damien7af3d192013-10-07 00:02:49 +01002869 break;
2870
Damien826005c2013-10-05 23:17:28 +01002871 default:
2872 if (emit_bc == NULL) {
2873 emit_bc = emit_bc_new(max_num_labels);
2874 }
2875 comp->emit = emit_bc;
2876 comp->emit_method_table = &emit_bc_method_table;
2877 break;
2878 }
Damienc025ebb2013-10-12 14:30:21 +01002879#endif
2880
2881 // compile pass 2 and pass 3
Damien826005c2013-10-05 23:17:28 +01002882 compile_scope(comp, s, PASS_2);
2883 compile_scope(comp, s, PASS_3);
Damien6cdd3af2013-10-05 18:08:26 +01002884 }
Damien429d7192013-10-04 19:53:11 +01002885 }
2886
2887 m_free(comp);
Damien5ac1b2e2013-10-18 19:58:12 +01002888
2889 return !comp->had_error;
Damien429d7192013-10-04 19:53:11 +01002890}