blob: 637abd772a40889434e0ee774cb988131a7d3d3a [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"
9#include "lexer.h"
10#include "machine.h"
11#include "parse.h"
12#include "compile.h"
13#include "scope.h"
14#include "runtime.h"
15#include "emit.h"
16
17#ifdef EMIT_DO_CPY
18
19struct _emitter_t {
20 int pass;
21 int next_label;
22 int byte_code_offset;
23 int stack_size;
24 bool last_emit_was_return_value;
25
26 scope_t *scope;
27
28 int max_num_labels;
29 int *label_offsets;
30};
31
32emitter_t *emit_new() {
33 emitter_t *emit = m_new(emitter_t, 1);
34 emit->max_num_labels = 0;
35 emit->label_offsets = NULL;
36 return emit;
37}
38
39void emit_start_pass(emitter_t *emit, pass_kind_t pass, scope_t *scope) {
40 emit->pass = pass;
41 emit->next_label = 1;
42 emit->byte_code_offset = 0;
43 emit->stack_size = 0;
44 emit->last_emit_was_return_value = false;
45 emit->scope = scope;
46 if (pass > PASS_1) {
47 if (emit->label_offsets == NULL) {
48 emit->label_offsets = m_new(int, emit->max_num_labels);
49 }
50 if (pass == PASS_2) {
51 memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(int));
52 }
53 }
54}
55
56void emit_end_pass(emitter_t *emit) {
57 // check stack is back to zero size
58 if (emit->stack_size != 0) {
59 printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
60 }
61
62 // calculate number of labels need
63 if (emit->pass == PASS_1) {
64 if (emit->next_label > emit->max_num_labels) {
65 emit->max_num_labels = emit->next_label;
66 }
67 }
68}
69
70bool emit_last_emit_was_return_value(emitter_t *emit) {
71 return emit->last_emit_was_return_value;
72}
73
74int emit_get_stack_size(emitter_t *emit) {
75 return emit->stack_size;
76}
77
78void emit_set_stack_size(emitter_t *emit, int size) {
79 emit->stack_size = size;
80}
81
82static void emit_pre(emitter_t *emit, int stack_size_delta, int byte_code_size) {
83 emit->stack_size += stack_size_delta;
84 if (emit->pass > PASS_1 && emit->stack_size > emit->scope->stack_size) {
85 emit->scope->stack_size = emit->stack_size;
86 }
87 emit->last_emit_was_return_value = false;
88 if (emit->pass == PASS_3 && byte_code_size > 0) {
89 if (emit->byte_code_offset >= 1000) {
90 printf("%d ", emit->byte_code_offset);
91 } else {
92 printf("% 4d ", emit->byte_code_offset);
93 }
94 }
95 emit->byte_code_offset += byte_code_size;
96}
97
98int emit_label_new(emitter_t *emit) {
99 return emit->next_label++;
100}
101
102void emit_label_assign(emitter_t *emit, int l) {
103 emit_pre(emit, 0, 0);
104 if (emit->pass > PASS_1) {
105 assert(l < emit->max_num_labels);
106 if (emit->pass == PASS_2) {
107 // assign label offset
108 assert(emit->label_offsets[l] == -1);
109 emit->label_offsets[l] = emit->byte_code_offset;
110 } else if (emit->pass == PASS_3) {
111 // ensure label offset has not changed from PASS_2 to PASS_3
112 assert(emit->label_offsets[l] == emit->byte_code_offset);
113 //printf("l%d: (at %d)\n", l, emit->byte_code_offset);
114 }
115 }
116}
117
118void emit_import_name(emitter_t *emit, qstr qstr) {
119 emit_pre(emit, -1, 3);
120 if (emit->pass == PASS_3) {
121 printf("IMPORT_NAME %s\n", qstr_str(qstr));
122 }
123}
124
125void emit_import_from(emitter_t *emit, qstr qstr) {
126 emit_pre(emit, 1, 3);
127 if (emit->pass == PASS_3) {
128 printf("IMPORT_FROM %s\n", qstr_str(qstr));
129 }
130}
131
132void emit_import_star(emitter_t *emit) {
133 emit_pre(emit, -1, 1);
134 if (emit->pass == PASS_3) {
135 printf("IMPORT_STAR\n");
136 }
137}
138
139void emit_load_const_tok(emitter_t *emit, py_token_kind_t tok) {
140 emit_pre(emit, 1, 3);
141 if (emit->pass == PASS_3) {
142 printf("LOAD_CONST ");
143 switch (tok) {
144 case PY_TOKEN_KW_FALSE: printf("False"); break;
145 case PY_TOKEN_KW_NONE: printf("None"); break;
146 case PY_TOKEN_KW_TRUE: printf("True"); break;
147 default: printf("?=%d\n", tok); return; assert(0);
148 }
149 printf("\n");
150 }
151}
152
153void emit_load_const_small_int(emitter_t *emit, int arg) {
154 emit_pre(emit, 1, 3);
155 if (emit->pass == PASS_3) {
156 printf("LOAD_CONST %d\n", arg);
157 }
158}
159
160void emit_load_const_int(emitter_t *emit, qstr qstr) {
161 emit_pre(emit, 1, 3);
162 if (emit->pass == PASS_3) {
163 printf("LOAD_CONST %s\n", qstr_str(qstr));
164 }
165}
166
167void emit_load_const_dec(emitter_t *emit, qstr qstr) {
168 emit_pre(emit, 1, 3);
169 if (emit->pass == PASS_3) {
170 printf("LOAD_CONST %s\n", qstr_str(qstr));
171 }
172}
173
174void emit_load_const_id(emitter_t *emit, qstr qstr) {
175 emit_pre(emit, 1, 3);
176 if (emit->pass == PASS_3) {
177 printf("LOAD_CONST '%s'\n", qstr_str(qstr));
178 }
179}
180
181void emit_load_const_str(emitter_t *emit, qstr qstr, bool bytes) {
182 emit_pre(emit, 1, 3);
183 if (emit->pass == PASS_3) {
184 printf("LOAD_CONST ");
185 emit_load_const_verbatim_quoted_str(emit, qstr, bytes);
186 printf("\n");
187 }
188}
189
190void emit_load_const_verbatim_start(emitter_t *emit) {
191 emit_pre(emit, 1, 3);
192 if (emit->pass == PASS_3) {
193 printf("LOAD_CONST ");
194 }
195}
196
197void emit_load_const_verbatim_int(emitter_t *emit, int val) {
198 if (emit->pass == PASS_3) {
199 printf("%d", val);
200 }
201}
202
203void emit_load_const_verbatim_str(emitter_t *emit, const char *str) {
204 if (emit->pass == PASS_3) {
205 printf("%s", str);
206 }
207}
208
209void emit_load_const_verbatim_strn(emitter_t *emit, const char *str, int len) {
210 if (emit->pass == PASS_3) {
211 printf("%.*s", len, str);
212 }
213}
214
215void emit_load_const_verbatim_quoted_str(emitter_t *emit, qstr qstr, bool bytes) {
216 // TODO strings should be escaped before we get here
217 if (emit->pass == PASS_3) {
218 const char *str = qstr_str(qstr);
219 int len = strlen(str);
220 bool has_single_quote = false;
221 bool has_double_quote = false;
222 for (int i = 0; i < len; i++) {
223 if (str[i] == '\'') {
224 has_single_quote = true;
225 } else if (str[i] == '"') {
226 has_double_quote = true;
227 }
228 }
229 if (bytes) {
230 printf("b");
231 }
232 bool quote_single = false;
233 if (has_single_quote && !has_double_quote) {
234 printf("\"");
235 } else {
236 quote_single = true;
237 printf("'");
238 }
239 for (int i = 0; i < len; i++) {
240 if (str[i] == '\n') {
241 printf("\\n");
242 } else if (str[i] == '\\' && str[i + 1] == '\'') {
243 i += 1;
244 if (quote_single) {
245 printf("\\'");
246 } else {
247 printf("'");
248 }
249 } else if (str[i] == '\'' && quote_single) {
250 printf("\\'");
251 } else {
252 printf("%c", str[i]);
253 }
254 }
255 if (has_single_quote && !has_double_quote) {
256 printf("\"");
257 } else {
258 printf("'");
259 }
260 }
261}
262
263void emit_load_const_verbatim_end(emitter_t *emit) {
264 if (emit->pass == PASS_3) {
265 printf("\n");
266 }
267}
268
269void emit_load_name(emitter_t *emit, qstr qstr) {
270 emit_pre(emit, 1, 3);
271 if (emit->pass == PASS_3) {
272 printf("LOAD_NAME %s\n", qstr_str(qstr));
273 }
274}
275
276void emit_load_global(emitter_t *emit, qstr qstr) {
277 emit_pre(emit, 1, 3);
278 if (emit->pass == PASS_3) {
279 printf("LOAD_GLOBAL %s\n", qstr_str(qstr));
280 }
281}
282
283void emit_load_fast(emitter_t *emit, qstr qstr, int local_num) {
284 emit_pre(emit, 1, 3);
285 if (emit->pass == PASS_3) {
286 printf("LOAD_FAST %s\n", qstr_str(qstr));
287 }
288}
289
290void emit_load_deref(emitter_t *emit, qstr qstr) {
291 emit_pre(emit, 1, 3);
292 if (emit->pass == PASS_3) {
293 printf("LOAD_DEREF %s\n", qstr_str(qstr));
294 }
295}
296
297void emit_load_closure(emitter_t *emit, qstr qstr) {
298 emit_pre(emit, 1, 3);
299 if (emit->pass == PASS_3) {
300 printf("LOAD_CLOSURE %s\n", qstr_str(qstr));
301 }
302}
303
304void emit_load_attr(emitter_t *emit, qstr qstr) {
305 emit_pre(emit, 0, 3);
306 if (emit->pass == PASS_3) {
307 printf("LOAD_ATTR %s\n", qstr_str(qstr));
308 }
309}
310
311void emit_load_method(emitter_t *emit, qstr qstr) {
312 emit_load_attr(emit, qstr);
313}
314
315void emit_load_build_class(emitter_t *emit) {
316 emit_pre(emit, 1, 1);
317 if (emit->pass == PASS_3) {
318 printf("LOAD_BUILD_CLASS\n");
319 }
320}
321
322void emit_store_name(emitter_t *emit, qstr qstr) {
323 emit_pre(emit, -1, 3);
324 if (emit->pass == PASS_3) {
325 printf("STORE_NAME %s\n", qstr_str(qstr));
326 }
327}
328
329void emit_store_global(emitter_t *emit, qstr qstr) {
330 emit_pre(emit, -1, 3);
331 if (emit->pass == PASS_3) {
332 printf("STORE_GLOBAL %s\n", qstr_str(qstr));
333 }
334}
335
336void emit_store_fast(emitter_t *emit, qstr qstr, int local_num) {
337 emit_pre(emit, -1, 3);
338 if (emit->pass == PASS_3) {
339 printf("STORE_FAST %s\n", qstr_str(qstr));
340 }
341}
342
343void emit_store_deref(emitter_t *emit, qstr qstr) {
344 emit_pre(emit, -1, 3);
345 if (emit->pass == PASS_3) {
346 printf("STORE_DEREF %s\n", qstr_str(qstr));
347 }
348}
349
350void emit_store_attr(emitter_t *emit, qstr qstr) {
351 emit_pre(emit, -2, 3);
352 if (emit->pass == PASS_3) {
353 printf("STORE_ATTR %s\n", qstr_str(qstr));
354 }
355}
356
357void emit_store_locals(emitter_t *emit) {
358 emit_pre(emit, -1, 1);
359 if (emit->pass == PASS_3) {
360 printf("STORE_LOCALS\n");
361 }
362}
363
364void emit_store_subscr(emitter_t *emit) {
365 emit_pre(emit, -3, 1);
366 if (emit->pass == PASS_3) {
367 printf("STORE_SUBSCR\n");
368 }
369}
370
371void emit_delete_name(emitter_t *emit, qstr qstr) {
372 emit_pre(emit, 0, 3);
373 if (emit->pass == PASS_3) {
374 printf("DELETE_NAME %s\n", qstr_str(qstr));
375 }
376}
377
378void emit_delete_global(emitter_t *emit, qstr qstr) {
379 emit_pre(emit, 0, 3);
380 if (emit->pass == PASS_3) {
381 printf("DELETE_GLOBAL %s\n", qstr_str(qstr));
382 }
383}
384
385void emit_delete_fast(emitter_t *emit, qstr qstr, int local_num) {
386 emit_pre(emit, 0, 3);
387 if (emit->pass == PASS_3) {
388 printf("DELETE_FAST %s\n", qstr_str(qstr));
389 }
390}
391
392void emit_delete_deref(emitter_t *emit, qstr qstr) {
393 emit_pre(emit, 0, 3);
394 if (emit->pass == PASS_3) {
395 printf("DELETE_DEREF %s\n", qstr_str(qstr));
396 }
397}
398
399void emit_delete_attr(emitter_t *emit, qstr qstr) {
400 emit_pre(emit, -1, 3);
401 if (emit->pass == PASS_3) {
402 printf("DELETE_ATTR %s\n", qstr_str(qstr));
403 }
404}
405
406void emit_delete_subscr(emitter_t *emit) {
407 emit_pre(emit, -2, 1);
408 if (emit->pass == PASS_3) {
409 printf("DELETE_SUBSCR\n");
410 }
411}
412
413void emit_dup_top(emitter_t *emit) {
414 emit_pre(emit, 1, 1);
415 if (emit->pass == PASS_3) {
416 printf("DUP_TOP\n");
417 }
418}
419
420void emit_dup_top_two(emitter_t *emit) {
421 emit_pre(emit, 2, 1);
422 if (emit->pass == PASS_3) {
423 printf("DUP_TOP_TWO\n");
424 }
425}
426
427void emit_pop_top(emitter_t *emit) {
428 emit_pre(emit, -1, 1);
429 if (emit->pass == PASS_3) {
430 printf("POP_TOP\n");
431 }
432}
433
434void emit_rot_two(emitter_t *emit) {
435 emit_pre(emit, 0, 1);
436 if (emit->pass == PASS_3) {
437 printf("ROT_TWO\n");
438 }
439}
440
441void emit_rot_three(emitter_t *emit) {
442 emit_pre(emit, 0, 1);
443 if (emit->pass == PASS_3) {
444 printf("ROT_THREE\n");
445 }
446}
447
448void emit_jump(emitter_t *emit, int label) {
449 emit_pre(emit, 0, 3);
450 if (emit->pass == PASS_3) {
451 int dest = emit->label_offsets[label];
452 if (dest < emit->byte_code_offset) {
453 printf("JUMP_ABSOLUTE %d\n", emit->label_offsets[label]);
454 } else {
455 printf("JUMP_FORWARD %d\n", emit->label_offsets[label]);
456 }
457 }
458}
459
460void emit_pop_jump_if_true(emitter_t *emit, int label) {
461 emit_pre(emit, -1, 3);
462 if (emit->pass == PASS_3) {
463 printf("POP_JUMP_IF_TRUE %d\n", emit->label_offsets[label]);
464 }
465}
466
467void emit_pop_jump_if_false(emitter_t *emit, int label) {
468 emit_pre(emit, -1, 3);
469 if (emit->pass == PASS_3) {
470 printf("POP_JUMP_IF_FALSE %d\n", emit->label_offsets[label]);
471 }
472}
473
474void emit_jump_if_true_or_pop(emitter_t *emit, int label) {
475 emit_pre(emit, -1, 3);
476 if (emit->pass == PASS_3) {
477 printf("JUMP_IF_TRUE_OR_POP %d\n", emit->label_offsets[label]);
478 }
479}
480
481void emit_jump_if_false_or_pop(emitter_t *emit, int label) {
482 emit_pre(emit, -1, 3);
483 if (emit->pass == PASS_3) {
484 printf("JUMP_IF_FALSE_OR_POP %d\n", emit->label_offsets[label]);
485 }
486}
487
488void emit_setup_loop(emitter_t *emit, int label) {
489 emit_pre(emit, 0, 3);
490 if (emit->pass == PASS_3) {
491 printf("SETUP_LOOP %d\n", emit->label_offsets[label]);
492 }
493}
494
495void emit_break_loop(emitter_t *emit, int label) {
496 emit_pre(emit, 0, 1);
497 if (emit->pass == PASS_3) {
498 printf("BREAK_LOOP\n"); // CPython doesn't have label
499 //printf("BREAK_LOOP %d\n", emit->label_offsets[label]);
500 }
501}
502
503void emit_continue_loop(emitter_t *emit, int label) {
504 emit_pre(emit, 0, 3);
505 if (emit->pass == PASS_3) {
506 printf("CONTINUE_LOOP %d\n", emit->label_offsets[label]);
507 }
508}
509
510void emit_setup_with(emitter_t *emit, int label) {
511 emit_pre(emit, 7, 3);
512 if (emit->pass == PASS_3) {
513 printf("SETUP_WITH %d\n", emit->label_offsets[label]);
514 }
515}
516
517void emit_with_cleanup(emitter_t *emit) {
518 emit_pre(emit, -7, 1);
519 if (emit->pass == PASS_3) {
520 printf("WITH_CLEANUP\n");
521 }
522}
523
524void emit_setup_except(emitter_t *emit, int label) {
525 emit_pre(emit, 6, 3);
526 if (emit->pass == PASS_3) {
527 printf("SETUP_EXCEPT %d\n", emit->label_offsets[label]);
528 }
529}
530
531void emit_setup_finally(emitter_t *emit, int label) {
532 emit_pre(emit, 6, 3);
533 if (emit->pass == PASS_3) {
534 printf("SETUP_FINALLY %d\n", emit->label_offsets[label]);
535 }
536}
537
538void emit_end_finally(emitter_t *emit) {
539 emit_pre(emit, -1, 1);
540 if (emit->pass == PASS_3) {
541 printf("END_FINALLY\n");
542 }
543}
544
545void emit_get_iter(emitter_t *emit) {
546 emit_pre(emit, 0, 1);
547 if (emit->pass == PASS_3) {
548 printf("GET_ITER\n");
549 }
550}
551
552void emit_for_iter(emitter_t *emit, int label) {
553 emit_pre(emit, 1, 3);
554 if (emit->pass == PASS_3) {
555 printf("FOR_ITER %d\n", emit->label_offsets[label]);
556 }
557}
558
559void emit_for_iter_end(emitter_t *emit) {
560 emit_pre(emit, -1, 0);
561}
562
563void emit_pop_block(emitter_t *emit) {
564 emit_pre(emit, 0, 1);
565 if (emit->pass == PASS_3) {
566 printf("POP_BLOCK\n");
567 }
568}
569
570void emit_pop_except(emitter_t *emit) {
571 emit_pre(emit, 0, 1);
572 if (emit->pass == PASS_3) {
573 printf("POP_EXCEPT\n");
574 }
575}
576
577void emit_unary_op(emitter_t *emit, rt_unary_op_t op) {
578 emit_pre(emit, 0, 1);
579 if (emit->pass == PASS_3) {
580 switch (op) {
581 case RT_UNARY_OP_NOT: printf("UNARY_NOT\n"); break;
582 case RT_UNARY_OP_POSITIVE: printf("UNARY_POSITIVE\n"); break;
583 case RT_UNARY_OP_NEGATIVE: printf("UNARY_NEGATIVE\n"); break;
584 case RT_UNARY_OP_INVERT: printf("UNARY_INVERT\n"); break;
585 default: assert(0);
586 }
587 }
588}
589
590void emit_binary_op(emitter_t *emit, rt_binary_op_t op) {
591 emit_pre(emit, -1, 1);
592 if (emit->pass == PASS_3) {
593 switch (op) {
594 case RT_BINARY_OP_SUBSCR: printf("BINARY_SUBSCR\n"); break;
595 case RT_BINARY_OP_OR: printf("BINARY_OR\n"); break;
596 case RT_BINARY_OP_XOR: printf("BINARY_XOR\n"); break;
597 case RT_BINARY_OP_AND: printf("BINARY_AND\n"); break;
598 case RT_BINARY_OP_LSHIFT: printf("BINARY_LSHIFT\n"); break;
599 case RT_BINARY_OP_RSHIFT: printf("BINARY_RSHIFT\n"); break;
600 case RT_BINARY_OP_ADD: printf("BINARY_ADD\n"); break;
601 case RT_BINARY_OP_SUBTRACT: printf("BINARY_SUBTRACT\n"); break;
602 case RT_BINARY_OP_MULTIPLY: printf("BINARY_MULTIPLY\n"); break;
603 case RT_BINARY_OP_FLOOR_DIVIDE: printf("BINARY_FLOOR_DIVIDE\n"); break;
604 case RT_BINARY_OP_TRUE_DIVIDE: printf("BINARY_TRUE_DIVIDE\n"); break;
605 case RT_BINARY_OP_MODULO: printf("BINARY_MODULO\n"); break;
606 case RT_BINARY_OP_POWER: printf("BINARY_POWER\n"); break;
607 case RT_BINARY_OP_INPLACE_OR: printf("INPLACE_OR\n"); break;
608 case RT_BINARY_OP_INPLACE_XOR: printf("INPLACE_XOR\n"); break;
609 case RT_BINARY_OP_INPLACE_AND: printf("INPLACE_AND\n"); break;
610 case RT_BINARY_OP_INPLACE_LSHIFT: printf("INPLACE_LSHIFT\n"); break;
611 case RT_BINARY_OP_INPLACE_RSHIFT: printf("INPLACE_RSHIFT\n"); break;
612 case RT_BINARY_OP_INPLACE_ADD: printf("INPLACE_ADD\n"); break;
613 case RT_BINARY_OP_INPLACE_SUBTRACT: printf("INPLACE_SUBTRACT\n"); break;
614 case RT_BINARY_OP_INPLACE_MULTIPLY: printf("INPLACE_MULTIPLY\n"); break;
615 case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: printf("INPLACE_FLOOR_DIVIDE\n"); break;
616 case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: printf("INPLACE_TRUE_DIVIDE\n"); break;
617 case RT_BINARY_OP_INPLACE_MODULO: printf("INPLACE_MODULO\n"); break;
618 case RT_BINARY_OP_INPLACE_POWER: printf("INPLACE_POWER\n"); break;
619 default: assert(0);
620 }
621 }
622}
623
624void emit_compare_op(emitter_t *emit, rt_compare_op_t op) {
625 emit_pre(emit, -1, 3);
626 if (emit->pass == PASS_3) {
627 switch (op) {
628 case RT_COMPARE_OP_LESS: printf("COMPARE_OP <\n"); break;
629 case RT_COMPARE_OP_MORE: printf("COMPARE_OP >\n"); break;
630 case RT_COMPARE_OP_EQUAL: printf("COMPARE_OP ==\n"); break;
631 case RT_COMPARE_OP_LESS_EQUAL: printf("COMPARE_OP <=\n"); break;
632 case RT_COMPARE_OP_MORE_EQUAL: printf("COMPARE_OP >=\n"); break;
633 case RT_COMPARE_OP_NOT_EQUAL: printf("COMPARE_OP !=\n"); break;
634 case RT_COMPARE_OP_IN: printf("COMPARE_OP in\n"); break;
635 case RT_COMPARE_OP_NOT_IN: printf("COMPARE_OP not in\n"); break;
636 case RT_COMPARE_OP_IS: printf("COMPARE_OP is\n"); break;
637 case RT_COMPARE_OP_IS_NOT: printf("COMPARE_OP is not\n"); break;
638 case RT_COMPARE_OP_EXCEPTION_MATCH: printf("COMPARE_OP exception match\n"); break;
639 default: assert(0);
640 }
641 }
642}
643
644void emit_build_tuple(emitter_t *emit, int n_args) {
645 emit_pre(emit, 1 - n_args, 3);
646 if (emit->pass == PASS_3) {
647 printf("BUILD_TUPLE %d\n", n_args);
648 }
649}
650
651void emit_build_list(emitter_t *emit, int n_args) {
652 emit_pre(emit, 1 - n_args, 3);
653 if (emit->pass == PASS_3) {
654 printf("BUILD_LIST %d\n", n_args);
655 }
656}
657
658void emit_list_append(emitter_t *emit, int list_index) {
659 emit_pre(emit, -1, 3);
660 if (emit->pass == PASS_3) {
661 printf("LIST_APPEND %d\n", list_index);
662 }
663}
664
665void emit_build_map(emitter_t *emit, int n_args) {
666 emit_pre(emit, 1, 3);
667 if (emit->pass == PASS_3) {
668 printf("BUILD_MAP %d\n", n_args);
669 }
670}
671
672void emit_store_map(emitter_t *emit) {
673 emit_pre(emit, -2, 1);
674 if (emit->pass == PASS_3) {
675 printf("STORE_MAP\n");
676 }
677}
678
679void emit_map_add(emitter_t *emit, int map_index) {
680 emit_pre(emit, -2, 3);
681 if (emit->pass == PASS_3) {
682 printf("MAP_ADD %d\n", map_index);
683 }
684}
685
686void emit_build_set(emitter_t *emit, int n_args) {
687 emit_pre(emit, 1 - n_args, 3);
688 if (emit->pass == PASS_3) {
689 printf("BUILD_SET %d\n", n_args);
690 }
691}
692
693void emit_set_add(emitter_t *emit, int set_index) {
694 emit_pre(emit, -1, 3);
695 if (emit->pass == PASS_3) {
696 printf("SET_ADD %d\n", set_index);
697 }
698}
699
700void emit_build_slice(emitter_t *emit, int n_args) {
701 emit_pre(emit, 1 - n_args, 3);
702 if (emit->pass == PASS_3) {
703 printf("BUILD_SLICE %d\n", n_args);
704 }
705}
706
707void emit_unpack_sequence(emitter_t *emit, int n_args) {
708 emit_pre(emit, -1 + n_args, 3);
709 if (emit->pass == PASS_3) {
710 printf("UNPACK_SEQUENCE %d\n", n_args);
711 }
712}
713
714void emit_unpack_ex(emitter_t *emit, int n_left, int n_right) {
715 emit_pre(emit, -1 + n_left + n_right + 1, 3);
716 if (emit->pass == PASS_3) {
717 printf("UNPACK_EX %d\n", n_left | (n_right << 8));
718 }
719}
720
721void emit_call_function(emitter_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
722 int s = 0;
723 if (have_star_arg) {
724 s += 1;
725 }
726 if (have_dbl_star_arg) {
727 s += 1;
728 }
729 emit_pre(emit, -n_positional - 2 * n_keyword - s, 3);
730 if (emit->pass == PASS_3) {
731 if (have_star_arg) {
732 if (have_dbl_star_arg) {
733 printf("CALL_FUNCTION_VAR_KW");
734 } else {
735 printf("CALL_FUNCTION_VAR");
736 }
737 } else {
738 if (have_dbl_star_arg) {
739 printf("CALL_FUNCTION_KW");
740 } else {
741 printf("CALL_FUNCTION");
742 }
743 }
744 printf(" %d, %d\n", n_positional, n_keyword);
745 }
746}
747
748void emit_call_method(emitter_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) {
749 emit_call_function(emit, n_positional, n_keyword, have_star_arg, have_dbl_star_arg);
750}
751
752void emit_return_value(emitter_t *emit) {
753 emit_pre(emit, -1, 1);
754 emit->last_emit_was_return_value = true;
755 if (emit->pass == PASS_3) {
756 printf("RETURN_VALUE\n");
757 }
758}
759
760void emit_raise_varargs(emitter_t *emit, int n_args) {
761 emit_pre(emit, -n_args, 3);
762 if (emit->pass == PASS_3) {
763 printf("RAISE_VARARGS %d\n", n_args);
764 }
765}
766
767void load_const_code_and_name(emitter_t *emit, qstr qstr) {
768 emit_pre(emit, 1, 3);
769 if (emit->pass == PASS_3) {
770 printf("LOAD_CONST code %s\n", qstr_str(qstr));
771 }
772 // load qualified name
773 emit_pre(emit, 1, 3);
774 if (emit->pass == PASS_3) {
775 printf("LOAD_CONST '");
776 // code just to work out the qualname (or whatever it is)
777 {
778 int depth = 0;
779 for (scope_t *s = emit->scope; s->parent != NULL; s = s->parent) {
780 depth += 1;
781 }
782 for (int wanted_depth = depth; wanted_depth >= 0; wanted_depth--) {
783 scope_t *s = emit->scope;
784 for (int i = 0; i < wanted_depth; i++) {
785 s = s->parent;
786 }
787 if (s->kind == SCOPE_FUNCTION) {
788 printf("%s.<locals>.", qstr_str(s->simple_name));
789 } else if (s->kind == SCOPE_CLASS) {
790 printf("%s.", qstr_str(s->simple_name));
791 }
792 }
793 }
794 printf("%s'\n", qstr_str(qstr));
795 }
796}
797
798void emit_make_function(emitter_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
799 load_const_code_and_name(emit, scope->simple_name);
800 emit_pre(emit, -1 - n_default_params - 2 * n_dict_params, 3);
801 if (emit->pass == PASS_3) {
802 printf("MAKE_FUNCTION %d\n", (n_dict_params << 8) | n_default_params);
803 }
804}
805
806void emit_make_closure(emitter_t *emit, scope_t *scope, int n_dict_params, int n_default_params) {
807 load_const_code_and_name(emit, scope->simple_name);
808 emit_pre(emit, -2 - n_default_params - 2 * n_dict_params, 3);
809 if (emit->pass == PASS_3) {
810 printf("MAKE_CLOSURE %d\n", (n_dict_params << 8) | n_default_params);
811 }
812}
813
814void emit_yield_value(emitter_t *emit) {
815 emit_pre(emit, 0, 1);
816 if (emit->pass == PASS_2) {
817 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
818 }
819 if (emit->pass == PASS_3) {
820 printf("YIELD_VALUE\n");
821 }
822}
823
824void emit_yield_from(emitter_t *emit) {
825 emit_pre(emit, -1, 1);
826 if (emit->pass == PASS_2) {
827 emit->scope->flags |= SCOPE_FLAG_GENERATOR;
828 }
829 if (emit->pass == PASS_3) {
830 printf("YIELD_FROM\n");
831 }
832}
833
834#endif // EMIT_DO_CPY