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