blob: 2f5fd69a6c8cd4a6f7bb3e1969498c21d2498f93 [file] [log] [blame]
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001/* Compile an expression node to intermediate code */
2
3#include <stdio.h>
4#include <ctype.h>
5#include "string.h"
6
7#include "PROTO.h"
8#include "object.h"
9#include "objimpl.h"
10#include "intobject.h"
11#include "floatobject.h"
12#include "stringobject.h"
13#include "listobject.h"
14#include "node.h"
15#include "token.h"
16#include "graminit.h"
17#include "errors.h"
18#include "compile.h"
19#include "opcode.h"
20
21static void
22code_dealloc(c)
23 codeobject *c;
24{
25 XDECREF(c->co_code);
26 XDECREF(c->co_consts);
27 XDECREF(c->co_names);
28 DEL(c);
29}
30
31typeobject Codetype = {
32 OB_HEAD_INIT(&Typetype)
33 0,
34 "code",
35 sizeof(codeobject),
36 0,
37 code_dealloc, /*tp_dealloc*/
38 0, /*tp_print*/
39 0, /*tp_getattr*/
40 0, /*tp_setattr*/
41 0, /*tp_compare*/
42 0, /*tp_repr*/
43 0, /*tp_as_number*/
44 0, /*tp_as_sequence*/
45 0, /*tp_as_mapping*/
46};
47
48static codeobject *newcodeobject PROTO((object *, object *, object *));
49
50static codeobject *
51newcodeobject(code, consts, names)
52 object *code;
53 object *consts;
54 object *names;
55{
56 codeobject *co;
57 int i;
58 /* Check argument types */
59 if (code == NULL || !is_stringobject(code) ||
60 consts == NULL || !is_listobject(consts) ||
61 names == NULL || !is_listobject(names)) {
62 err_badcall();
63 return NULL;
64 }
65 /* Make sure the list of names contains only strings */
66 for (i = getlistsize(names); --i >= 0; ) {
67 object *v = getlistitem(names, i);
68 if (v == NULL || !is_stringobject(v)) {
69 err_badcall();
70 return NULL;
71 }
72 }
73 co = NEWOBJ(codeobject, &Codetype);
74 if (co != NULL) {
75 INCREF(code);
76 co->co_code = (stringobject *)code;
77 INCREF(consts);
78 co->co_consts = consts;
79 INCREF(names);
80 co->co_names = names;
81 }
82 return co;
83}
84
85
86/* Data structure used internally */
87struct compiling {
88 object *c_code; /* string */
89 object *c_consts; /* list of objects */
90 object *c_names; /* list of strings (names) */
91 int c_nexti; /* index into c_code */
92 int c_errors; /* counts errors occurred */
93};
94
95/* Prototypes */
96static int com_init PROTO((struct compiling *));
97static void com_free PROTO((struct compiling *));
98static void com_done PROTO((struct compiling *));
99static void com_node PROTO((struct compiling *, struct _node *));
100static void com_addbyte PROTO((struct compiling *, int));
101static void com_addint PROTO((struct compiling *, int));
102static void com_addoparg PROTO((struct compiling *, int, int));
103static void com_addfwref PROTO((struct compiling *, int, int *));
104static void com_backpatch PROTO((struct compiling *, int));
105static int com_add PROTO((struct compiling *, object *, object *));
106static int com_addconst PROTO((struct compiling *, object *));
107static int com_addname PROTO((struct compiling *, object *));
108static void com_addopname PROTO((struct compiling *, int, node *));
109
110static int
111com_init(c)
112 struct compiling *c;
113{
114 if ((c->c_code = newsizedstringobject((char *)NULL, 0)) == NULL)
115 goto fail_3;
116 if ((c->c_consts = newlistobject(0)) == NULL)
117 goto fail_2;
118 if ((c->c_names = newlistobject(0)) == NULL)
119 goto fail_1;
120 c->c_nexti = 0;
121 c->c_errors = 0;
122 return 1;
123
124 fail_1:
125 DECREF(c->c_consts);
126 fail_2:
127 DECREF(c->c_code);
128 fail_3:
129 return 0;
130}
131
132static void
133com_free(c)
134 struct compiling *c;
135{
136 XDECREF(c->c_code);
137 XDECREF(c->c_consts);
138 XDECREF(c->c_names);
139}
140
141static void
142com_done(c)
143 struct compiling *c;
144{
145 if (c->c_code != NULL)
146 resizestring(&c->c_code, c->c_nexti);
147}
148
149static void
150com_addbyte(c, byte)
151 struct compiling *c;
152 int byte;
153{
154 int len;
155 if (byte < 0 || byte > 255) {
156 err_setstr(SystemError, "com_addbyte: byte out of range");
157 c->c_errors++;
158 }
159 if (c->c_code == NULL)
160 return;
161 len = getstringsize(c->c_code);
162 if (c->c_nexti >= len) {
163 if (resizestring(&c->c_code, len+1000) != 0) {
164 c->c_errors++;
165 return;
166 }
167 }
168 getstringvalue(c->c_code)[c->c_nexti++] = byte;
169}
170
171static void
172com_addint(c, x)
173 struct compiling *c;
174 int x;
175{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000176 com_addbyte(c, x & 0xff);
177 com_addbyte(c, x >> 8); /* XXX x should be positive */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000178}
179
180static void
181com_addoparg(c, op, arg)
182 struct compiling *c;
183 int op;
184 int arg;
185{
186 com_addbyte(c, op);
187 com_addint(c, arg);
188}
189
190static void
191com_addfwref(c, op, p_anchor)
192 struct compiling *c;
193 int op;
194 int *p_anchor;
195{
196 /* Compile a forward reference for backpatching */
197 int here;
198 int anchor;
199 com_addbyte(c, op);
200 here = c->c_nexti;
201 anchor = *p_anchor;
202 *p_anchor = here;
203 com_addint(c, anchor == 0 ? 0 : here - anchor);
204}
205
206static void
207com_backpatch(c, anchor)
208 struct compiling *c;
209 int anchor; /* Must be nonzero */
210{
211 unsigned char *code = (unsigned char *) getstringvalue(c->c_code);
212 int target = c->c_nexti;
213 int lastanchor = 0;
214 int dist;
215 int prev;
216 for (;;) {
217 /* Make the JUMP instruction at anchor point to target */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000218 prev = code[anchor] + (code[anchor+1] << 8);
219 dist = target - (anchor+2);
220 code[anchor] = dist & 0xff;
221 code[anchor+1] = dist >> 8;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000222 if (!prev)
223 break;
224 lastanchor = anchor;
225 anchor -= prev;
226 }
227}
228
229/* Handle constants and names uniformly */
230
231static int
232com_add(c, list, v)
233 struct compiling *c;
234 object *list;
235 object *v;
236{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000237 int n = getlistsize(list);
238 int i;
239 for (i = n; --i >= 0; ) {
240 object *w = getlistitem(list, i);
241 if (cmpobject(v, w) == 0)
242 return i;
243 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000244 if (addlistitem(list, v) != 0)
245 c->c_errors++;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000246 return n;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000247}
248
249static int
250com_addconst(c, v)
251 struct compiling *c;
252 object *v;
253{
254 return com_add(c, c->c_consts, v);
255}
256
257static int
258com_addname(c, v)
259 struct compiling *c;
260 object *v;
261{
262 return com_add(c, c->c_names, v);
263}
264
265static void
266com_addopname(c, op, n)
267 struct compiling *c;
268 int op;
269 node *n;
270{
271 object *v;
272 int i;
273 char *name;
274 if (TYPE(n) == STAR)
275 name = "*";
276 else {
277 REQ(n, NAME);
278 name = STR(n);
279 }
280 if ((v = newstringobject(name)) == NULL) {
281 c->c_errors++;
282 i = 255;
283 }
284 else {
285 i = com_addname(c, v);
286 DECREF(v);
287 }
288 com_addoparg(c, op, i);
289}
290
291static object *
292parsenumber(s)
293 char *s;
294{
295 extern long strtol();
296 extern double atof();
297 char *end = s;
298 long x;
299 x = strtol(s, &end, 0);
300 if (*end == '\0')
301 return newintobject(x);
302 if (*end == '.' || *end == 'e' || *end == 'E')
303 return newfloatobject(atof(s));
304 err_setstr(RuntimeError, "bad number syntax");
305 return NULL;
306}
307
308static object *
309parsestr(s)
310 char *s;
311{
312 object *v;
313 int len;
314 char *buf;
315 char *p;
316 int c;
317 if (*s != '\'') {
318 err_badcall();
319 return NULL;
320 }
321 s++;
322 len = strlen(s);
323 if (s[--len] != '\'') {
324 err_badcall();
325 return NULL;
326 }
327 if (strchr(s, '\\') == NULL)
328 return newsizedstringobject(s, len);
329 v = newsizedstringobject((char *)NULL, len);
330 p = buf = getstringvalue(v);
331 while (*s != '\0' && *s != '\'') {
332 if (*s != '\\') {
333 *p++ = *s++;
334 continue;
335 }
336 s++;
337 switch (*s++) {
338 /* XXX This assumes ASCII! */
339 case '\\': *p++ = '\\'; break;
340 case '\'': *p++ = '\''; break;
341 case 'b': *p++ = '\b'; break;
342 case 'f': *p++ = '\014'; break; /* FF */
343 case 't': *p++ = '\t'; break;
344 case 'n': *p++ = '\n'; break;
345 case 'r': *p++ = '\r'; break;
346 case 'v': *p++ = '\013'; break; /* VT */
347 case 'E': *p++ = '\033'; break; /* ESC, not C */
348 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
349 case '0': case '1': case '2': case '3':
350 case '4': case '5': case '6': case '7':
351 c = s[-1] - '0';
352 if ('0' <= *s && *s <= '7') {
353 c = (c<<3) + *s++ - '0';
354 if ('0' <= *s && *s <= '7')
355 c = (c<<3) + *s++ - '0';
356 }
357 *p++ = c;
358 break;
359 case 'x':
360 if (isxdigit(*s)) {
361 sscanf(s, "%x", &c);
362 *p++ = c;
363 do {
364 s++;
365 } while (isxdigit(*s));
366 break;
367 }
368 /* FALLTHROUGH */
369 default: *p++ = '\\'; *p++ = s[-1]; break;
370 }
371 }
372 resizestring(&v, (int)(p - buf));
373 return v;
374}
375
376static void
377com_list_constructor(c, n)
378 struct compiling *c;
379 node *n;
380{
381 int len;
382 int i;
383 object *v, *w;
384 if (TYPE(n) != testlist)
385 REQ(n, exprlist);
386 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
387 len = (NCH(n) + 1) / 2;
388 for (i = 0; i < NCH(n); i += 2)
389 com_node(c, CHILD(n, i));
390 com_addoparg(c, BUILD_LIST, len);
391}
392
393static void
394com_atom(c, n)
395 struct compiling *c;
396 node *n;
397{
398 node *ch;
399 object *v;
400 int i;
401 REQ(n, atom);
402 ch = CHILD(n, 0);
403 switch (TYPE(ch)) {
404 case LPAR:
405 if (TYPE(CHILD(n, 1)) == RPAR)
406 com_addoparg(c, BUILD_TUPLE, 0);
407 else
408 com_node(c, CHILD(n, 1));
409 break;
410 case LSQB:
411 if (TYPE(CHILD(n, 1)) == RSQB)
412 com_addoparg(c, BUILD_LIST, 0);
413 else
414 com_list_constructor(c, CHILD(n, 1));
415 break;
416 case LBRACE:
417 com_addoparg(c, BUILD_MAP, 0);
418 break;
419 case BACKQUOTE:
420 com_node(c, CHILD(n, 1));
421 com_addbyte(c, UNARY_CONVERT);
422 break;
423 case NUMBER:
424 if ((v = parsenumber(STR(ch))) == NULL) {
425 c->c_errors++;
426 i = 255;
427 }
428 else {
429 i = com_addconst(c, v);
430 DECREF(v);
431 }
432 com_addoparg(c, LOAD_CONST, i);
433 break;
434 case STRING:
435 if ((v = parsestr(STR(ch))) == NULL) {
436 c->c_errors++;
437 i = 255;
438 }
439 else {
440 i = com_addconst(c, v);
441 DECREF(v);
442 }
443 com_addoparg(c, LOAD_CONST, i);
444 break;
445 case NAME:
446 com_addopname(c, LOAD_NAME, ch);
447 break;
448 default:
449 fprintf(stderr, "node type %d\n", TYPE(ch));
450 err_setstr(SystemError, "com_atom: unexpected node type");
451 c->c_errors++;
452 }
453}
454
455static void
456com_slice(c, n, op)
457 struct compiling *c;
458 node *n;
459 int op;
460{
461 if (NCH(n) == 1) {
462 com_addbyte(c, op);
463 }
464 else if (NCH(n) == 2) {
465 if (TYPE(CHILD(n, 0)) != COLON) {
466 com_node(c, CHILD(n, 0));
467 com_addbyte(c, op+1);
468 }
469 else {
470 com_node(c, CHILD(n, 1));
471 com_addbyte(c, op+2);
472 }
473 }
474 else {
475 com_node(c, CHILD(n, 0));
476 com_node(c, CHILD(n, 2));
477 com_addbyte(c, op+3);
478 }
479}
480
481static void
482com_apply_subscript(c, n)
483 struct compiling *c;
484 node *n;
485{
486 REQ(n, subscript);
487 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
488 /* It's a single subscript */
489 com_node(c, CHILD(n, 0));
490 com_addbyte(c, BINARY_SUBSCR);
491 }
492 else {
493 /* It's a slice: [expr] ':' [expr] */
494 com_slice(c, n, SLICE);
495 }
496}
497
498static void
499com_call_function(c, n)
500 struct compiling *c;
501 node *n; /* EITHER testlist OR ')' */
502{
503 if (TYPE(n) == RPAR) {
504 com_addbyte(c, UNARY_CALL);
505 }
506 else {
507 com_node(c, n);
508 com_addbyte(c, BINARY_CALL);
509 }
510}
511
512static void
513com_select_member(c, n)
514 struct compiling *c;
515 node *n;
516{
517 com_addopname(c, LOAD_ATTR, n);
518}
519
520static void
521com_apply_trailer(c, n)
522 struct compiling *c;
523 node *n;
524{
525 REQ(n, trailer);
526 switch (TYPE(CHILD(n, 0))) {
527 case LPAR:
528 com_call_function(c, CHILD(n, 1));
529 break;
530 case DOT:
531 com_select_member(c, CHILD(n, 1));
532 break;
533 case LSQB:
534 com_apply_subscript(c, CHILD(n, 1));
535 break;
536 default:
537 err_setstr(SystemError,
538 "com_apply_trailer: unknown trailer type");
539 c->c_errors++;
540 }
541}
542
543static void
544com_factor(c, n)
545 struct compiling *c;
546 node *n;
547{
548 int i;
549 REQ(n, factor);
550 if (TYPE(CHILD(n, 0)) == PLUS) {
551 com_factor(c, CHILD(n, 1));
552 com_addbyte(c, UNARY_POSITIVE);
553 }
554 else if (TYPE(CHILD(n, 0)) == MINUS) {
555 com_factor(c, CHILD(n, 1));
556 com_addbyte(c, UNARY_NEGATIVE);
557 }
558 else {
559 com_atom(c, CHILD(n, 0));
560 for (i = 1; i < NCH(n); i++)
561 com_apply_trailer(c, CHILD(n, i));
562 }
563}
564
565static void
566com_term(c, n)
567 struct compiling *c;
568 node *n;
569{
570 int i;
571 int op;
572 REQ(n, term);
573 com_factor(c, CHILD(n, 0));
574 for (i = 2; i < NCH(n); i += 2) {
575 com_factor(c, CHILD(n, i));
576 switch (TYPE(CHILD(n, i-1))) {
577 case STAR:
578 op = BINARY_MULTIPLY;
579 break;
580 case SLASH:
581 op = BINARY_DIVIDE;
582 break;
583 case PERCENT:
584 op = BINARY_MODULO;
585 break;
586 default:
587 err_setstr(SystemError,
588 "com_term: term operator not *, / or %");
589 c->c_errors++;
590 op = 255;
591 }
592 com_addbyte(c, op);
593 }
594}
595
596static void
597com_expr(c, n)
598 struct compiling *c;
599 node *n;
600{
601 int i;
602 int op;
603 REQ(n, expr);
604 com_term(c, CHILD(n, 0));
605 for (i = 2; i < NCH(n); i += 2) {
606 com_term(c, CHILD(n, i));
607 switch (TYPE(CHILD(n, i-1))) {
608 case PLUS:
609 op = BINARY_ADD;
610 break;
611 case MINUS:
612 op = BINARY_SUBTRACT;
613 break;
614 default:
615 err_setstr(SystemError,
616 "com_expr: expr operator not + or -");
617 c->c_errors++;
618 op = 255;
619 }
620 com_addbyte(c, op);
621 }
622}
623
624static enum cmp_op
625cmp_type(n)
626 node *n;
627{
628 REQ(n, comp_op);
629 /* comp_op: '<' | '>' | '=' | '>' '=' | '<' '=' | '<' '>'
630 | 'in' | 'not' 'in' | 'is' | 'is' not' */
631 if (NCH(n) == 1) {
632 n = CHILD(n, 0);
633 switch (TYPE(n)) {
634 case LESS: return LT;
635 case GREATER: return GT;
636 case EQUAL: return EQ;
637 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
638 if (strcmp(STR(n), "is") == 0) return IS;
639 }
640 }
641 else if (NCH(n) == 2) {
642 int t2 = TYPE(CHILD(n, 1));
643 switch (TYPE(CHILD(n, 0))) {
644 case LESS: if (t2 == EQUAL) return LE;
645 if (t2 == GREATER) return NE;
646 break;
647 case GREATER: if (t2 == EQUAL) return GE;
648 break;
649 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
650 return NOT_IN;
651 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
652 return IS_NOT;
653 }
654 }
655 return BAD;
656}
657
658static void
659com_comparison(c, n)
660 struct compiling *c;
661 node *n;
662{
663 int i;
664 enum cmp_op op;
665 int anchor;
666 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
667 com_expr(c, CHILD(n, 0));
668 if (NCH(n) == 1)
669 return;
670
671 /****************************************************************
672 The following code is generated for all but the last
673 comparison in a chain:
674
675 label: on stack: opcode: jump to:
676
677 a <code to load b>
678 a, b DUP_TOP
679 a, b, b ROT_THREE
680 b, a, b COMPARE_OP
681 b, 0-or-1 JUMP_IF_FALSE L1
682 b, 1 POP_TOP
683 b
684
685 We are now ready to repeat this sequence for the next
686 comparison in the chain.
687
688 For the last we generate:
689
690 b <code to load c>
691 b, c COMPARE_OP
692 0-or-1
693
694 If there were any jumps to L1 (i.e., there was more than one
695 comparison), we generate:
696
697 0-or-1 JUMP_FORWARD L2
698 L1: b, 0 ROT_TWO
699 0, b POP_TOP
700 0
701 L2:
702 ****************************************************************/
703
704 anchor = 0;
705
706 for (i = 2; i < NCH(n); i += 2) {
707 com_expr(c, CHILD(n, i));
708 if (i+2 < NCH(n)) {
709 com_addbyte(c, DUP_TOP);
710 com_addbyte(c, ROT_THREE);
711 }
712 op = cmp_type(CHILD(n, i-1));
713 if (op == BAD) {
714 err_setstr(SystemError,
715 "com_comparison: unknown comparison op");
716 c->c_errors++;
717 }
718 com_addoparg(c, COMPARE_OP, op);
719 if (i+2 < NCH(n)) {
720 com_addfwref(c, JUMP_IF_FALSE, &anchor);
721 com_addbyte(c, POP_TOP);
722 }
723 }
724
725 if (anchor) {
726 int anchor2 = 0;
727 com_addfwref(c, JUMP_FORWARD, &anchor2);
728 com_backpatch(c, anchor);
729 com_addbyte(c, ROT_TWO);
730 com_addbyte(c, POP_TOP);
731 com_backpatch(c, anchor2);
732 }
733}
734
735static void
736com_not_test(c, n)
737 struct compiling *c;
738 node *n;
739{
740 REQ(n, not_test); /* 'not' not_test | comparison */
741 if (NCH(n) == 1) {
742 com_comparison(c, CHILD(n, 0));
743 }
744 else {
745 com_not_test(c, CHILD(n, 1));
746 com_addbyte(c, UNARY_NOT);
747 }
748}
749
750static void
751com_and_test(c, n)
752 struct compiling *c;
753 node *n;
754{
755 int i;
756 int anchor;
757 REQ(n, and_test); /* not_test ('and' not_test)* */
758 anchor = 0;
759 i = 0;
760 for (;;) {
761 com_not_test(c, CHILD(n, i));
762 if ((i += 2) >= NCH(n))
763 break;
764 com_addfwref(c, JUMP_IF_FALSE, &anchor);
765 com_addbyte(c, POP_TOP);
766 }
767 if (anchor)
768 com_backpatch(c, anchor);
769}
770
771static void
772com_test(c, n)
773 struct compiling *c;
774 node *n;
775{
776 int i;
777 int anchor;
778 REQ(n, test); /* and_test ('and' and_test)* */
779 anchor = 0;
780 i = 0;
781 for (;;) {
782 com_and_test(c, CHILD(n, i));
783 if ((i += 2) >= NCH(n))
784 break;
785 com_addfwref(c, JUMP_IF_TRUE, &anchor);
786 com_addbyte(c, POP_TOP);
787 }
788 if (anchor)
789 com_backpatch(c, anchor);
790}
791
792static void
793com_list(c, n)
794 struct compiling *c;
795 node *n;
796{
797 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
798 if (NCH(n) == 1) {
799 com_node(c, CHILD(n, 0));
800 }
801 else {
802 int i;
803 int len;
804 len = (NCH(n) + 1) / 2;
805 for (i = 0; i < NCH(n); i += 2)
806 com_node(c, CHILD(n, i));
807 com_addoparg(c, BUILD_TUPLE, len);
808 }
809}
810
811
812/* Begin of assignment compilation */
813
814static void com_assign_name PROTO((struct compiling *, node *, int));
815static void com_assign PROTO((struct compiling *, node *, int));
816
817static void
818com_assign_attr(c, n, assigning)
819 struct compiling *c;
820 node *n;
821 int assigning;
822{
823 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
824}
825
826static void
827com_assign_slice(c, n, assigning)
828 struct compiling *c;
829 node *n;
830 int assigning;
831{
832 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
833}
834
835static void
836com_assign_subscript(c, n, assigning)
837 struct compiling *c;
838 node *n;
839 int assigning;
840{
841 com_node(c, n);
842 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
843}
844
845static void
846com_assign_trailer(c, n, assigning)
847 struct compiling *c;
848 node *n;
849 int assigning;
850{
851 char *name;
852 REQ(n, trailer);
853 switch (TYPE(CHILD(n, 0))) {
854 case LPAR: /* '(' [exprlist] ')' */
855 err_setstr(TypeError, "can't assign to function call");
856 c->c_errors++;
857 break;
858 case DOT: /* '.' NAME */
859 com_assign_attr(c, CHILD(n, 1), assigning);
860 break;
861 case LSQB: /* '[' subscript ']' */
862 n = CHILD(n, 1);
863 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
864 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
865 com_assign_slice(c, n, assigning);
866 else
867 com_assign_subscript(c, CHILD(n, 0), assigning);
868 break;
869 default:
870 err_setstr(TypeError, "unknown trailer type");
871 c->c_errors++;
872 }
873}
874
875static void
876com_assign_tuple(c, n, assigning)
877 struct compiling *c;
878 node *n;
879 int assigning;
880{
881 int i;
882 if (TYPE(n) != testlist)
883 REQ(n, exprlist);
884 if (assigning)
885 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
886 for (i = 0; i < NCH(n); i += 2)
887 com_assign(c, CHILD(n, i), assigning);
888}
889
890static void
891com_assign_list(c, n, assigning)
892 struct compiling *c;
893 node *n;
894 int assigning;
895{
896 int i;
897 if (assigning)
898 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
899 for (i = 0; i < NCH(n); i += 2)
900 com_assign(c, CHILD(n, i), assigning);
901}
902
903static void
904com_assign_name(c, n, assigning)
905 struct compiling *c;
906 node *n;
907 int assigning;
908{
909 REQ(n, NAME);
910 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
911}
912
913static void
914com_assign(c, n, assigning)
915 struct compiling *c;
916 node *n;
917 int assigning;
918{
919 /* Loop to avoid trivial recursion */
920 for (;;) {
921 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000922
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000923 case exprlist:
924 case testlist:
925 if (NCH(n) > 1) {
926 com_assign_tuple(c, n, assigning);
927 return;
928 }
929 n = CHILD(n, 0);
930 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000931
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000932 case test:
933 case and_test:
934 case not_test:
935 if (NCH(n) > 1) {
936 err_setstr(TypeError,
937 "can't assign to operator");
938 c->c_errors++;
939 return;
940 }
941 n = CHILD(n, 0);
942 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000943
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000944 case comparison:
945 if (NCH(n) > 1) {
946 err_setstr(TypeError,
947 "can't assign to operator");
948 c->c_errors++;
949 return;
950 }
951 n = CHILD(n, 0);
952 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000953
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000954 case expr:
955 if (NCH(n) > 1) {
956 err_setstr(TypeError,
957 "can't assign to operator");
958 c->c_errors++;
959 return;
960 }
961 n = CHILD(n, 0);
962 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000963
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000964 case term:
965 if (NCH(n) > 1) {
966 err_setstr(TypeError,
967 "can't assign to operator");
968 c->c_errors++;
969 return;
970 }
971 n = CHILD(n, 0);
972 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000973
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000974 case factor: /* ('+'|'-') factor | atom trailer* */
975 if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
976 err_setstr(TypeError,
977 "can't assign to operator");
978 c->c_errors++;
979 return;
980 }
981 if (NCH(n) > 1) { /* trailer present */
982 int i;
983 com_node(c, CHILD(n, 0));
984 for (i = 1; i+1 < NCH(n); i++) {
985 com_apply_trailer(c, CHILD(n, i));
986 } /* NB i is still alive */
987 com_assign_trailer(c,
988 CHILD(n, i), assigning);
989 return;
990 }
991 n = CHILD(n, 0);
992 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000993
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000994 case atom:
995 switch (TYPE(CHILD(n, 0))) {
996 case LPAR:
997 n = CHILD(n, 1);
998 if (TYPE(n) == RPAR) {
999 /* XXX Should allow () = () ??? */
1000 err_setstr(TypeError,
1001 "can't assign to ()");
1002 c->c_errors++;
1003 return;
1004 }
1005 break;
1006 case LSQB:
1007 n = CHILD(n, 1);
1008 if (TYPE(n) == RSQB) {
1009 err_setstr(TypeError,
1010 "can't assign to []");
1011 c->c_errors++;
1012 return;
1013 }
1014 com_assign_list(c, n, assigning);
1015 return;
1016 case NAME:
1017 com_assign_name(c, CHILD(n, 0), assigning);
1018 return;
1019 default:
1020 err_setstr(TypeError,
1021 "can't assign to constant");
1022 c->c_errors++;
1023 return;
1024 }
1025 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001026
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001027 default:
1028 fprintf(stderr, "node type %d\n", TYPE(n));
1029 err_setstr(SystemError, "com_assign: bad node");
1030 c->c_errors++;
1031 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001032
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001033 }
1034 }
1035}
1036
1037static void
1038com_expr_stmt(c, n)
1039 struct compiling *c;
1040 node *n;
1041{
1042 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* NEWLINE */
1043 com_node(c, CHILD(n, NCH(n)-2));
1044 if (NCH(n) == 2) {
1045 com_addbyte(c, PRINT_EXPR);
1046 }
1047 else {
1048 int i;
1049 for (i = 0; i < NCH(n)-3; i+=2) {
1050 if (i+2 < NCH(n)-3)
1051 com_addbyte(c, DUP_TOP);
1052 com_assign(c, CHILD(n, i), 1/*assign*/);
1053 }
1054 }
1055}
1056
1057static void
1058com_print_stmt(c, n)
1059 struct compiling *c;
1060 node *n;
1061{
1062 int i;
1063 REQ(n, print_stmt); /* 'print' (test ',')* [test] NEWLINE */
1064 for (i = 1; i+1 < NCH(n); i += 2) {
1065 com_node(c, CHILD(n, i));
1066 com_addbyte(c, PRINT_ITEM);
1067 }
1068 if (TYPE(CHILD(n, NCH(n)-2)) != COMMA)
1069 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001070 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001071}
1072
1073static void
1074com_return_stmt(c, n)
1075 struct compiling *c;
1076 node *n;
1077{
1078 REQ(n, return_stmt); /* 'return' [testlist] NEWLINE */
1079 if (NCH(n) == 2)
1080 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1081 else
1082 com_node(c, CHILD(n, 1));
1083 com_addbyte(c, RETURN_VALUE);
1084}
1085
1086static void
1087com_raise_stmt(c, n)
1088 struct compiling *c;
1089 node *n;
1090{
1091 REQ(n, raise_stmt); /* 'raise' expr [',' expr] NEWLINE */
1092 com_node(c, CHILD(n, 1));
1093 if (NCH(n) > 3)
1094 com_node(c, CHILD(n, 3));
1095 else
1096 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1097 com_addbyte(c, RAISE_EXCEPTION);
1098}
1099
1100static void
1101com_import_stmt(c, n)
1102 struct compiling *c;
1103 node *n;
1104{
1105 int i;
1106 REQ(n, import_stmt);
1107 /* 'import' NAME (',' NAME)* NEWLINE |
1108 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE */
1109 if (STR(CHILD(n, 0))[0] == 'f') {
1110 /* 'from' NAME 'import' ... */
1111 REQ(CHILD(n, 1), NAME);
1112 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1113 for (i = 3; i < NCH(n); i += 2)
1114 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1115 com_addbyte(c, POP_TOP);
1116 }
1117 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001118 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001119 for (i = 1; i < NCH(n); i += 2) {
1120 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1121 com_addopname(c, STORE_NAME, CHILD(n, i));
1122 }
1123 }
1124}
1125
1126static void
1127com_if_stmt(c, n)
1128 struct compiling *c;
1129 node *n;
1130{
1131 int i;
1132 int anchor = 0;
1133 REQ(n, if_stmt);
1134 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1135 for (i = 0; i+3 < NCH(n); i+=4) {
1136 int a = 0;
1137 com_node(c, CHILD(n, i+1));
1138 com_addfwref(c, JUMP_IF_FALSE, &a);
1139 com_addbyte(c, POP_TOP);
1140 com_node(c, CHILD(n, i+3));
1141 com_addfwref(c, JUMP_FORWARD, &anchor);
1142 com_backpatch(c, a);
1143 com_addbyte(c, POP_TOP);
1144 }
1145 if (i+2 < NCH(n))
1146 com_node(c, CHILD(n, i+2));
1147 com_backpatch(c, anchor);
1148}
1149
1150static void
1151com_while_stmt(c, n)
1152 struct compiling *c;
1153 node *n;
1154{
1155 int break_anchor = 0;
1156 int anchor = 0;
1157 int begin;
1158 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1159 com_addfwref(c, SETUP_LOOP, &break_anchor);
1160 begin = c->c_nexti;
1161 com_node(c, CHILD(n, 1));
1162 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1163 com_addbyte(c, POP_TOP);
1164 com_node(c, CHILD(n, 3));
1165 com_addoparg(c, JUMP_ABSOLUTE, begin);
1166 com_backpatch(c, anchor);
1167 com_addbyte(c, POP_TOP);
1168 com_addbyte(c, POP_BLOCK);
1169 if (NCH(n) > 4)
1170 com_node(c, CHILD(n, 6));
1171 com_backpatch(c, break_anchor);
1172}
1173
1174static void
1175com_for_stmt(c, n)
1176 struct compiling *c;
1177 node *n;
1178{
1179 object *v;
1180 int break_anchor = 0;
1181 int anchor = 0;
1182 int begin;
1183 REQ(n, for_stmt);
1184 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1185 com_addfwref(c, SETUP_LOOP, &break_anchor);
1186 com_node(c, CHILD(n, 3));
1187 v = newintobject(0L);
1188 if (v == NULL)
1189 c->c_errors++;
1190 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1191 XDECREF(v);
1192 begin = c->c_nexti;
1193 com_addfwref(c, FOR_LOOP, &anchor);
1194 com_assign(c, CHILD(n, 1), 1/*assigning*/);
1195 com_node(c, CHILD(n, 5));
1196 com_addoparg(c, JUMP_ABSOLUTE, begin);
1197 com_backpatch(c, anchor);
1198 com_addbyte(c, POP_BLOCK);
1199 if (NCH(n) > 8)
1200 com_node(c, CHILD(n, 8));
1201 com_backpatch(c, break_anchor);
1202}
1203
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001204/* Although 'execpt' and 'finally' clauses can be combined
1205 syntactically, they are compiled separately. In fact,
1206 try: S
1207 except E1: S1
1208 except E2: S2
1209 ...
1210 finally: Sf
1211 is equivalent to
1212 try:
1213 try: S
1214 except E1: S1
1215 except E2: S2
1216 ...
1217 finally: Sf
1218 meaning that the 'finally' clause is entered even if things
1219 go wrong again in an exception handler. Note that this is
1220 not the case for exception handlers: at most one is entered.
1221
1222 Code generated for "try: S finally: Sf" is as follows:
1223
1224 SETUP_FINALLY L
1225 <code for S>
1226 POP_BLOCK
1227 LOAD_CONST <nil>
1228 LOAD_CONST <nil>
1229 L: <code for Sf>
1230 END_FINALLY
1231
1232 The special instructions use the block stack. Each block
1233 stack entry contains the instruction that created it (here
1234 SETUP_FINALLY), the level of the value stack at the time the
1235 block stack entry was created, and a label (here L).
1236
1237 SETUP_FINALLY:
1238 Pushes the current value stack level and the label
1239 onto the block stack.
1240 POP_BLOCK:
1241 Pops en entry from the block stack, and pops the value
1242 stack until its level is the same as indicated on the
1243 block stack. (The label is ignored.)
1244 END_FINALLY:
1245 Pops two entries from the *value* stack and re-raises
1246 the exception they specify. If the top entry is nil,
1247 no exception is raised. If it is a number, a pseudo
1248 exception is raised ('return' or 'break'). Otherwise,
1249 a real exception (specified by a string) is raised.
1250 The second entry popped from the is the value that goes
1251 with the exception (or the return value).
1252
1253 The block stack is unwound when an exception is raised:
1254 when a SETUP_FINALLY entry is found, the exception is pushed
1255 onto the value stack (and the exception condition is cleared),
1256 and the interpreter jumps to the label gotten from the block
1257 stack.
1258
1259 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
1260
1261 Value stack Label Instruction Argument
1262 [] SETUP_EXCEPT L1
1263 [] <code for S>
1264 [] POP_BLOCK
1265 [] JUMP_FORWARD L0
1266
1267 [val, exc] L1: DUP
1268 [val, exc, exc] <evaluate E1>
1269 [val, exc, exc, E1] COMPARE_OP EXC_MATCH
1270 [val, exc, 1-or-0] JUMP_IF_FALSE L2
1271 [val, exc, 1] POP
1272 [val, exc] POP
1273 [val] <assign to V1>
1274 [] <code for S1>
1275 JUMP_FORWARD L0
1276
1277 [val, exc, 0] L2: POP
1278 [val, exc] DUP
1279 .............................etc.......................
1280
1281 [val, exc, 0] Ln+1: POP
1282 [val, exc] END_FINALLY # re-raise exception
1283
1284 [] L0: <next statement>
1285
1286 Of course, parts are not generated if Vi or Ei is not present.
1287*/
1288
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001289static void
1290com_try_stmt(c, n)
1291 struct compiling *c;
1292 node *n;
1293{
1294 int finally_anchor = 0;
1295 int except_anchor = 0;
1296 REQ(n, try_stmt);
1297 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001298
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001299 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1300 /* Have a 'finally' clause */
1301 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
1302 }
1303 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1304 /* Have an 'except' clause */
1305 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
1306 }
1307 com_node(c, CHILD(n, 2));
1308 if (except_anchor) {
1309 int end_anchor = 0;
1310 int i;
1311 node *ch;
1312 com_addbyte(c, POP_BLOCK);
1313 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1314 com_backpatch(c, except_anchor);
1315 for (i = 3;
1316 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1317 i += 3) {
1318 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001319 if (except_anchor == 0) {
1320 err_setstr(TypeError,
1321 "default 'except:' must be last");
1322 c->c_errors++;
1323 break;
1324 }
1325 except_anchor = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001326 if (NCH(ch) > 1) {
1327 com_addbyte(c, DUP_TOP);
1328 com_node(c, CHILD(ch, 1));
1329 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001330 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001331 com_addbyte(c, POP_TOP);
1332 }
1333 com_addbyte(c, POP_TOP);
1334 if (NCH(ch) > 3)
1335 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1336 else
1337 com_addbyte(c, POP_TOP);
1338 com_node(c, CHILD(n, i+2));
1339 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001340 if (except_anchor) {
1341 com_backpatch(c, except_anchor);
1342 com_addbyte(c, POP_TOP);
1343 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001344 }
1345 com_addbyte(c, END_FINALLY);
1346 com_backpatch(c, end_anchor);
1347 }
1348 if (finally_anchor) {
1349 com_addbyte(c, POP_BLOCK);
1350 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1351 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1352 com_backpatch(c, finally_anchor);
1353 com_node(c, CHILD(n, NCH(n)-1));
1354 com_addbyte(c, END_FINALLY);
1355 }
1356}
1357
1358static void
1359com_suite(c, n)
1360 struct compiling *c;
1361 node *n;
1362{
1363 REQ(n, suite);
1364 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1365 if (NCH(n) == 1) {
1366 com_node(c, CHILD(n, 0));
1367 }
1368 else {
1369 int i;
1370 for (i = 0; i < NCH(n); i++) {
1371 node *ch = CHILD(n, i);
1372 if (TYPE(ch) == stmt)
1373 com_node(c, ch);
1374 }
1375 }
1376}
1377
1378static void
1379com_funcdef(c, n)
1380 struct compiling *c;
1381 node *n;
1382{
1383 object *v;
1384 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1385 v = (object *)compile(n);
1386 if (v == NULL)
1387 c->c_errors++;
1388 else {
1389 int i = com_addconst(c, v);
1390 com_addoparg(c, LOAD_CONST, i);
1391 com_addbyte(c, BUILD_FUNCTION);
1392 com_addopname(c, STORE_NAME, CHILD(n, 1));
1393 DECREF(v);
1394 }
1395}
1396
1397static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001398com_bases(c, n)
1399 struct compiling *c;
1400 node *n;
1401{
1402 int i, nbases;
1403 REQ(n, baselist);
1404 /*
1405 baselist: atom arguments (',' atom arguments)*
1406 arguments: '(' [testlist] ')'
1407 */
1408 for (i = 0; i < NCH(n); i += 3)
1409 com_node(c, CHILD(n, i));
1410 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1411}
1412
1413static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001414com_classdef(c, n)
1415 struct compiling *c;
1416 node *n;
1417{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001418 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001419 REQ(n, classdef);
1420 /*
1421 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1422 baselist: atom arguments (',' atom arguments)*
1423 arguments: '(' [testlist] ')'
1424 */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001425 if (NCH(n) == 7)
1426 com_bases(c, CHILD(n, 4));
1427 else
1428 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1429 v = (object *)compile(n);
1430 if (v == NULL)
1431 c->c_errors++;
1432 else {
1433 int i = com_addconst(c, v);
1434 com_addoparg(c, LOAD_CONST, i);
1435 com_addbyte(c, BUILD_FUNCTION);
1436 com_addbyte(c, UNARY_CALL);
1437 com_addbyte(c, BUILD_CLASS);
1438 com_addopname(c, STORE_NAME, CHILD(n, 1));
1439 DECREF(v);
1440 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001441}
1442
1443static void
1444com_node(c, n)
1445 struct compiling *c;
1446 node *n;
1447{
1448 switch (TYPE(n)) {
1449
1450 /* Definition nodes */
1451
1452 case funcdef:
1453 com_funcdef(c, n);
1454 break;
1455 case classdef:
1456 com_classdef(c, n);
1457 break;
1458
1459 /* Trivial parse tree nodes */
1460
1461 case stmt:
1462 case simple_stmt:
1463 case flow_stmt:
1464 case compound_stmt:
1465 com_node(c, CHILD(n, 0));
1466 break;
1467
1468 /* Statement nodes */
1469
1470 case expr_stmt:
1471 com_expr_stmt(c, n);
1472 break;
1473 case print_stmt:
1474 com_print_stmt(c, n);
1475 break;
1476 case del_stmt: /* 'del' exprlist NEWLINE */
1477 com_assign(c, CHILD(n, 1), 0/*delete*/);
1478 break;
1479 case pass_stmt:
1480 break;
1481 case break_stmt:
1482 com_addbyte(c, BREAK_LOOP);
1483 break;
1484 case return_stmt:
1485 com_return_stmt(c, n);
1486 break;
1487 case raise_stmt:
1488 com_raise_stmt(c, n);
1489 break;
1490 case import_stmt:
1491 com_import_stmt(c, n);
1492 break;
1493 case if_stmt:
1494 com_if_stmt(c, n);
1495 break;
1496 case while_stmt:
1497 com_while_stmt(c, n);
1498 break;
1499 case for_stmt:
1500 com_for_stmt(c, n);
1501 break;
1502 case try_stmt:
1503 com_try_stmt(c, n);
1504 break;
1505 case suite:
1506 com_suite(c, n);
1507 break;
1508
1509 /* Expression nodes */
1510
1511 case testlist:
1512 com_list(c, n);
1513 break;
1514 case test:
1515 com_test(c, n);
1516 break;
1517 case and_test:
1518 com_and_test(c, n);
1519 break;
1520 case not_test:
1521 com_not_test(c, n);
1522 break;
1523 case comparison:
1524 com_comparison(c, n);
1525 break;
1526 case exprlist:
1527 com_list(c, n);
1528 break;
1529 case expr:
1530 com_expr(c, n);
1531 break;
1532 case term:
1533 com_term(c, n);
1534 break;
1535 case factor:
1536 com_factor(c, n);
1537 break;
1538 case atom:
1539 com_atom(c, n);
1540 break;
1541
1542 default:
1543 fprintf(stderr, "node type %d\n", TYPE(n));
1544 err_setstr(SystemError, "com_node: unexpected node type");
1545 c->c_errors++;
1546 }
1547}
1548
1549static void com_fplist PROTO((struct compiling *, node *));
1550
1551static void
1552com_fpdef(c, n)
1553 struct compiling *c;
1554 node *n;
1555{
1556 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1557 if (TYPE(CHILD(n, 0)) == LPAR)
1558 com_fplist(c, CHILD(n, 1));
1559 else
1560 com_addopname(c, STORE_NAME, CHILD(n, 0));
1561}
1562
1563static void
1564com_fplist(c, n)
1565 struct compiling *c;
1566 node *n;
1567{
1568 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1569 if (NCH(n) == 1) {
1570 com_fpdef(c, CHILD(n, 0));
1571 }
1572 else {
1573 int i;
1574 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1575 for (i = 0; i < NCH(n); i += 2)
1576 com_fpdef(c, CHILD(n, i));
1577 }
1578}
1579
1580static void
1581com_file_input(c, n)
1582 struct compiling *c;
1583 node *n;
1584{
1585 int i;
1586 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1587 for (i = 0; i < NCH(n); i++) {
1588 node *ch = CHILD(n, i);
1589 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1590 com_node(c, ch);
1591 }
1592}
1593
1594/* Top-level compile-node interface */
1595
1596static void
1597compile_funcdef(c, n)
1598 struct compiling *c;
1599 node *n;
1600{
1601 node *ch;
1602 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1603 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1604 ch = CHILD(ch, 1); /* ')' | fplist */
1605 if (TYPE(ch) == RPAR)
1606 com_addbyte(c, REFUSE_ARGS);
1607 else {
1608 com_addbyte(c, REQUIRE_ARGS);
1609 com_fplist(c, ch);
1610 }
1611 com_node(c, CHILD(n, 4));
1612 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1613 com_addbyte(c, RETURN_VALUE);
1614}
1615
1616static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001617compile_classdef(c, n)
1618 struct compiling *c;
1619 node *n;
1620{
1621 node *ch;
1622 REQ(n, classdef);
1623 /*
1624 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1625 */
1626 com_addbyte(c, REFUSE_ARGS);
1627 com_node(c, CHILD(n, NCH(n)-1));
1628 com_addbyte(c, LOAD_LOCALS);
1629 com_addbyte(c, RETURN_VALUE);
1630}
1631
1632static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001633compile_node(c, n)
1634 struct compiling *c;
1635 node *n;
1636{
1637 switch (TYPE(n)) {
1638
1639 case single_input:
1640 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
1641 n = CHILD(n, 0);
1642 if (TYPE(n) != NEWLINE)
1643 com_node(c, n);
1644 break;
1645
1646 case file_input:
1647 com_file_input(c, n);
1648 break;
1649
1650 case expr_input:
1651 case eval_input:
1652 com_node(c, CHILD(n, 0));
1653 break;
1654
1655 case funcdef:
1656 compile_funcdef(c, n);
1657 break;
1658
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001659 case classdef:
1660 compile_classdef(c, n);
1661 break;
1662
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001663 default:
1664 fprintf(stderr, "node type %d\n", TYPE(n));
1665 err_setstr(SystemError, "compile_node: unexpected node type");
1666 c->c_errors++;
1667 }
1668}
1669
1670codeobject *
1671compile(n)
1672 node *n;
1673{
1674 struct compiling sc;
1675 codeobject *co;
1676 if (!com_init(&sc))
1677 return NULL;
1678 compile_node(&sc, n);
1679 com_done(&sc);
1680 if (sc.c_errors == 0)
1681 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names);
1682 else
1683 co = NULL;
1684 com_free(&sc);
1685 return co;
1686}