blob: 956719052c78c1911fd9c1896c1a894c7392cd70 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum10dc2e81990-11-18 17:27:39 +000025/* Compile an expression node to intermediate code */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027/* XXX TO DO:
28 XXX Compute maximum needed stack sizes while compiling
29 XXX Generate simple jump for break/return outside 'try...finally'
30 XXX Include function name in code (and module names?)
31*/
Guido van Rossum10dc2e81990-11-18 17:27:39 +000032
Guido van Rossum3f5da241990-12-20 15:06:42 +000033#include "allobjects.h"
34
Guido van Rossum10dc2e81990-11-18 17:27:39 +000035#include "node.h"
36#include "token.h"
37#include "graminit.h"
Guido van Rossum10dc2e81990-11-18 17:27:39 +000038#include "compile.h"
39#include "opcode.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000040#include "structmember.h"
41
42#include <ctype.h>
43
Guido van Rossum282914b1991-04-04 10:42:56 +000044extern int errno;
45
Guido van Rossum3f5da241990-12-20 15:06:42 +000046#define OFF(x) offsetof(codeobject, x)
47
48static struct memberlist code_memberlist[] = {
49 {"co_code", T_OBJECT, OFF(co_code)},
50 {"co_consts", T_OBJECT, OFF(co_consts)},
51 {"co_names", T_OBJECT, OFF(co_names)},
52 {"co_filename", T_OBJECT, OFF(co_filename)},
53 {NULL} /* Sentinel */
54};
55
56static object *
57code_getattr(co, name)
58 codeobject *co;
59 char *name;
60{
61 return getmember((char *)co, code_memberlist, name);
62}
Guido van Rossum10dc2e81990-11-18 17:27:39 +000063
64static void
Guido van Rossum3f5da241990-12-20 15:06:42 +000065code_dealloc(co)
66 codeobject *co;
Guido van Rossum10dc2e81990-11-18 17:27:39 +000067{
Guido van Rossum3f5da241990-12-20 15:06:42 +000068 XDECREF(co->co_code);
69 XDECREF(co->co_consts);
70 XDECREF(co->co_names);
71 XDECREF(co->co_filename);
72 DEL(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +000073}
74
75typeobject Codetype = {
76 OB_HEAD_INIT(&Typetype)
77 0,
78 "code",
79 sizeof(codeobject),
80 0,
81 code_dealloc, /*tp_dealloc*/
82 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +000083 code_getattr, /*tp_getattr*/
Guido van Rossum10dc2e81990-11-18 17:27:39 +000084 0, /*tp_setattr*/
85 0, /*tp_compare*/
86 0, /*tp_repr*/
87 0, /*tp_as_number*/
88 0, /*tp_as_sequence*/
89 0, /*tp_as_mapping*/
90};
91
Guido van Rossum3f5da241990-12-20 15:06:42 +000092static codeobject *newcodeobject PROTO((object *, object *, object *, char *));
Guido van Rossum10dc2e81990-11-18 17:27:39 +000093
94static codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +000095newcodeobject(code, consts, names, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +000096 object *code;
97 object *consts;
98 object *names;
Guido van Rossum3f5da241990-12-20 15:06:42 +000099 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000100{
101 codeobject *co;
102 int i;
103 /* Check argument types */
104 if (code == NULL || !is_stringobject(code) ||
105 consts == NULL || !is_listobject(consts) ||
106 names == NULL || !is_listobject(names)) {
107 err_badcall();
108 return NULL;
109 }
110 /* Make sure the list of names contains only strings */
111 for (i = getlistsize(names); --i >= 0; ) {
112 object *v = getlistitem(names, i);
113 if (v == NULL || !is_stringobject(v)) {
114 err_badcall();
115 return NULL;
116 }
117 }
118 co = NEWOBJ(codeobject, &Codetype);
119 if (co != NULL) {
120 INCREF(code);
121 co->co_code = (stringobject *)code;
122 INCREF(consts);
123 co->co_consts = consts;
124 INCREF(names);
125 co->co_names = names;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000126 if ((co->co_filename = newstringobject(filename)) == NULL) {
127 DECREF(co);
128 co = NULL;
129 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000130 }
131 return co;
132}
133
134
135/* Data structure used internally */
136struct compiling {
137 object *c_code; /* string */
138 object *c_consts; /* list of objects */
139 object *c_names; /* list of strings (names) */
140 int c_nexti; /* index into c_code */
141 int c_errors; /* counts errors occurred */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142 int c_infunction; /* set when compiling a function */
143 int c_loops; /* counts nested loops */
144 char *c_filename; /* filename of current node */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000145};
146
147/* Prototypes */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148static int com_init PROTO((struct compiling *, char *));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000149static void com_free PROTO((struct compiling *));
150static void com_done PROTO((struct compiling *));
151static void com_node PROTO((struct compiling *, struct _node *));
152static void com_addbyte PROTO((struct compiling *, int));
153static void com_addint PROTO((struct compiling *, int));
154static void com_addoparg PROTO((struct compiling *, int, int));
155static void com_addfwref PROTO((struct compiling *, int, int *));
156static void com_backpatch PROTO((struct compiling *, int));
157static int com_add PROTO((struct compiling *, object *, object *));
158static int com_addconst PROTO((struct compiling *, object *));
159static int com_addname PROTO((struct compiling *, object *));
160static void com_addopname PROTO((struct compiling *, int, node *));
161
162static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000163com_init(c, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000164 struct compiling *c;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000165 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000166{
Guido van Rossum62d46241991-04-03 19:00:23 +0000167 if ((c->c_code = newsizedstringobject((char *)NULL, 1000)) == NULL)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000168 goto fail_3;
169 if ((c->c_consts = newlistobject(0)) == NULL)
170 goto fail_2;
171 if ((c->c_names = newlistobject(0)) == NULL)
172 goto fail_1;
173 c->c_nexti = 0;
174 c->c_errors = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000175 c->c_infunction = 0;
176 c->c_loops = 0;
177 c->c_filename = filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000178 return 1;
179
180 fail_1:
181 DECREF(c->c_consts);
182 fail_2:
183 DECREF(c->c_code);
184 fail_3:
185 return 0;
186}
187
188static void
189com_free(c)
190 struct compiling *c;
191{
192 XDECREF(c->c_code);
193 XDECREF(c->c_consts);
194 XDECREF(c->c_names);
195}
196
197static void
198com_done(c)
199 struct compiling *c;
200{
201 if (c->c_code != NULL)
202 resizestring(&c->c_code, c->c_nexti);
203}
204
205static void
206com_addbyte(c, byte)
207 struct compiling *c;
208 int byte;
209{
210 int len;
211 if (byte < 0 || byte > 255) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000212 fprintf(stderr, "XXX compiling bad byte: %d\n", byte);
213 abort();
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000214 err_setstr(SystemError, "com_addbyte: byte out of range");
215 c->c_errors++;
216 }
217 if (c->c_code == NULL)
218 return;
219 len = getstringsize(c->c_code);
220 if (c->c_nexti >= len) {
221 if (resizestring(&c->c_code, len+1000) != 0) {
222 c->c_errors++;
223 return;
224 }
225 }
226 getstringvalue(c->c_code)[c->c_nexti++] = byte;
227}
228
229static void
230com_addint(c, x)
231 struct compiling *c;
232 int x;
233{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000234 com_addbyte(c, x & 0xff);
235 com_addbyte(c, x >> 8); /* XXX x should be positive */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000236}
237
238static void
239com_addoparg(c, op, arg)
240 struct compiling *c;
241 int op;
242 int arg;
243{
244 com_addbyte(c, op);
245 com_addint(c, arg);
246}
247
248static void
249com_addfwref(c, op, p_anchor)
250 struct compiling *c;
251 int op;
252 int *p_anchor;
253{
254 /* Compile a forward reference for backpatching */
255 int here;
256 int anchor;
257 com_addbyte(c, op);
258 here = c->c_nexti;
259 anchor = *p_anchor;
260 *p_anchor = here;
261 com_addint(c, anchor == 0 ? 0 : here - anchor);
262}
263
264static void
265com_backpatch(c, anchor)
266 struct compiling *c;
267 int anchor; /* Must be nonzero */
268{
269 unsigned char *code = (unsigned char *) getstringvalue(c->c_code);
270 int target = c->c_nexti;
271 int lastanchor = 0;
272 int dist;
273 int prev;
274 for (;;) {
275 /* Make the JUMP instruction at anchor point to target */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000276 prev = code[anchor] + (code[anchor+1] << 8);
277 dist = target - (anchor+2);
278 code[anchor] = dist & 0xff;
279 code[anchor+1] = dist >> 8;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000280 if (!prev)
281 break;
282 lastanchor = anchor;
283 anchor -= prev;
284 }
285}
286
287/* Handle constants and names uniformly */
288
289static int
290com_add(c, list, v)
291 struct compiling *c;
292 object *list;
293 object *v;
294{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000295 int n = getlistsize(list);
296 int i;
297 for (i = n; --i >= 0; ) {
298 object *w = getlistitem(list, i);
299 if (cmpobject(v, w) == 0)
300 return i;
301 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000302 if (addlistitem(list, v) != 0)
303 c->c_errors++;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000304 return n;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000305}
306
307static int
308com_addconst(c, v)
309 struct compiling *c;
310 object *v;
311{
312 return com_add(c, c->c_consts, v);
313}
314
315static int
316com_addname(c, v)
317 struct compiling *c;
318 object *v;
319{
320 return com_add(c, c->c_names, v);
321}
322
323static void
324com_addopname(c, op, n)
325 struct compiling *c;
326 int op;
327 node *n;
328{
329 object *v;
330 int i;
331 char *name;
332 if (TYPE(n) == STAR)
333 name = "*";
334 else {
335 REQ(n, NAME);
336 name = STR(n);
337 }
338 if ((v = newstringobject(name)) == NULL) {
339 c->c_errors++;
340 i = 255;
341 }
342 else {
343 i = com_addname(c, v);
344 DECREF(v);
345 }
346 com_addoparg(c, op, i);
347}
348
349static object *
350parsenumber(s)
351 char *s;
352{
353 extern long strtol();
Guido van Rossum282914b1991-04-04 10:42:56 +0000354 extern double strtod();
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000355 char *end = s;
356 long x;
Guido van Rossum282914b1991-04-04 10:42:56 +0000357 double xx;
358 errno = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000359 x = strtol(s, &end, 0);
Guido van Rossum282914b1991-04-04 10:42:56 +0000360 if (*end == '\0') {
361 if (errno != 0) {
362 err_setstr(RuntimeError, "integer constant too large");
363 return NULL;
364 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000365 return newintobject(x);
Guido van Rossum282914b1991-04-04 10:42:56 +0000366 }
367 errno = 0;
368 xx = strtod(s, &end);
369 if (*end == '\0') {
370 if (errno != 0) {
371 err_setstr(RuntimeError, "float constant too large");
372 return NULL;
373 }
374 return newfloatobject(xx);
375 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000376 err_setstr(RuntimeError, "bad number syntax");
377 return NULL;
378}
379
380static object *
381parsestr(s)
382 char *s;
383{
384 object *v;
385 int len;
386 char *buf;
387 char *p;
388 int c;
389 if (*s != '\'') {
390 err_badcall();
391 return NULL;
392 }
393 s++;
394 len = strlen(s);
395 if (s[--len] != '\'') {
396 err_badcall();
397 return NULL;
398 }
399 if (strchr(s, '\\') == NULL)
400 return newsizedstringobject(s, len);
401 v = newsizedstringobject((char *)NULL, len);
402 p = buf = getstringvalue(v);
403 while (*s != '\0' && *s != '\'') {
404 if (*s != '\\') {
405 *p++ = *s++;
406 continue;
407 }
408 s++;
409 switch (*s++) {
410 /* XXX This assumes ASCII! */
411 case '\\': *p++ = '\\'; break;
412 case '\'': *p++ = '\''; break;
413 case 'b': *p++ = '\b'; break;
414 case 'f': *p++ = '\014'; break; /* FF */
415 case 't': *p++ = '\t'; break;
416 case 'n': *p++ = '\n'; break;
417 case 'r': *p++ = '\r'; break;
418 case 'v': *p++ = '\013'; break; /* VT */
419 case 'E': *p++ = '\033'; break; /* ESC, not C */
420 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
421 case '0': case '1': case '2': case '3':
422 case '4': case '5': case '6': case '7':
423 c = s[-1] - '0';
424 if ('0' <= *s && *s <= '7') {
425 c = (c<<3) + *s++ - '0';
426 if ('0' <= *s && *s <= '7')
427 c = (c<<3) + *s++ - '0';
428 }
429 *p++ = c;
430 break;
431 case 'x':
432 if (isxdigit(*s)) {
433 sscanf(s, "%x", &c);
434 *p++ = c;
435 do {
436 s++;
437 } while (isxdigit(*s));
438 break;
439 }
440 /* FALLTHROUGH */
441 default: *p++ = '\\'; *p++ = s[-1]; break;
442 }
443 }
444 resizestring(&v, (int)(p - buf));
445 return v;
446}
447
448static void
449com_list_constructor(c, n)
450 struct compiling *c;
451 node *n;
452{
453 int len;
454 int i;
455 object *v, *w;
456 if (TYPE(n) != testlist)
457 REQ(n, exprlist);
458 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
459 len = (NCH(n) + 1) / 2;
460 for (i = 0; i < NCH(n); i += 2)
461 com_node(c, CHILD(n, i));
462 com_addoparg(c, BUILD_LIST, len);
463}
464
465static void
466com_atom(c, n)
467 struct compiling *c;
468 node *n;
469{
470 node *ch;
471 object *v;
472 int i;
473 REQ(n, atom);
474 ch = CHILD(n, 0);
475 switch (TYPE(ch)) {
476 case LPAR:
477 if (TYPE(CHILD(n, 1)) == RPAR)
478 com_addoparg(c, BUILD_TUPLE, 0);
479 else
480 com_node(c, CHILD(n, 1));
481 break;
482 case LSQB:
483 if (TYPE(CHILD(n, 1)) == RSQB)
484 com_addoparg(c, BUILD_LIST, 0);
485 else
486 com_list_constructor(c, CHILD(n, 1));
487 break;
488 case LBRACE:
489 com_addoparg(c, BUILD_MAP, 0);
490 break;
491 case BACKQUOTE:
492 com_node(c, CHILD(n, 1));
493 com_addbyte(c, UNARY_CONVERT);
494 break;
495 case NUMBER:
496 if ((v = parsenumber(STR(ch))) == NULL) {
497 c->c_errors++;
498 i = 255;
499 }
500 else {
501 i = com_addconst(c, v);
502 DECREF(v);
503 }
504 com_addoparg(c, LOAD_CONST, i);
505 break;
506 case STRING:
507 if ((v = parsestr(STR(ch))) == NULL) {
508 c->c_errors++;
509 i = 255;
510 }
511 else {
512 i = com_addconst(c, v);
513 DECREF(v);
514 }
515 com_addoparg(c, LOAD_CONST, i);
516 break;
517 case NAME:
518 com_addopname(c, LOAD_NAME, ch);
519 break;
520 default:
521 fprintf(stderr, "node type %d\n", TYPE(ch));
522 err_setstr(SystemError, "com_atom: unexpected node type");
523 c->c_errors++;
524 }
525}
526
527static void
528com_slice(c, n, op)
529 struct compiling *c;
530 node *n;
531 int op;
532{
533 if (NCH(n) == 1) {
534 com_addbyte(c, op);
535 }
536 else if (NCH(n) == 2) {
537 if (TYPE(CHILD(n, 0)) != COLON) {
538 com_node(c, CHILD(n, 0));
539 com_addbyte(c, op+1);
540 }
541 else {
542 com_node(c, CHILD(n, 1));
543 com_addbyte(c, op+2);
544 }
545 }
546 else {
547 com_node(c, CHILD(n, 0));
548 com_node(c, CHILD(n, 2));
549 com_addbyte(c, op+3);
550 }
551}
552
553static void
554com_apply_subscript(c, n)
555 struct compiling *c;
556 node *n;
557{
558 REQ(n, subscript);
559 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
560 /* It's a single subscript */
561 com_node(c, CHILD(n, 0));
562 com_addbyte(c, BINARY_SUBSCR);
563 }
564 else {
565 /* It's a slice: [expr] ':' [expr] */
566 com_slice(c, n, SLICE);
567 }
568}
569
570static void
571com_call_function(c, n)
572 struct compiling *c;
573 node *n; /* EITHER testlist OR ')' */
574{
575 if (TYPE(n) == RPAR) {
576 com_addbyte(c, UNARY_CALL);
577 }
578 else {
579 com_node(c, n);
580 com_addbyte(c, BINARY_CALL);
581 }
582}
583
584static void
585com_select_member(c, n)
586 struct compiling *c;
587 node *n;
588{
589 com_addopname(c, LOAD_ATTR, n);
590}
591
592static void
593com_apply_trailer(c, n)
594 struct compiling *c;
595 node *n;
596{
597 REQ(n, trailer);
598 switch (TYPE(CHILD(n, 0))) {
599 case LPAR:
600 com_call_function(c, CHILD(n, 1));
601 break;
602 case DOT:
603 com_select_member(c, CHILD(n, 1));
604 break;
605 case LSQB:
606 com_apply_subscript(c, CHILD(n, 1));
607 break;
608 default:
609 err_setstr(SystemError,
610 "com_apply_trailer: unknown trailer type");
611 c->c_errors++;
612 }
613}
614
615static void
616com_factor(c, n)
617 struct compiling *c;
618 node *n;
619{
620 int i;
621 REQ(n, factor);
622 if (TYPE(CHILD(n, 0)) == PLUS) {
623 com_factor(c, CHILD(n, 1));
624 com_addbyte(c, UNARY_POSITIVE);
625 }
626 else if (TYPE(CHILD(n, 0)) == MINUS) {
627 com_factor(c, CHILD(n, 1));
628 com_addbyte(c, UNARY_NEGATIVE);
629 }
630 else {
631 com_atom(c, CHILD(n, 0));
632 for (i = 1; i < NCH(n); i++)
633 com_apply_trailer(c, CHILD(n, i));
634 }
635}
636
637static void
638com_term(c, n)
639 struct compiling *c;
640 node *n;
641{
642 int i;
643 int op;
644 REQ(n, term);
645 com_factor(c, CHILD(n, 0));
646 for (i = 2; i < NCH(n); i += 2) {
647 com_factor(c, CHILD(n, i));
648 switch (TYPE(CHILD(n, i-1))) {
649 case STAR:
650 op = BINARY_MULTIPLY;
651 break;
652 case SLASH:
653 op = BINARY_DIVIDE;
654 break;
655 case PERCENT:
656 op = BINARY_MODULO;
657 break;
658 default:
659 err_setstr(SystemError,
660 "com_term: term operator not *, / or %");
661 c->c_errors++;
662 op = 255;
663 }
664 com_addbyte(c, op);
665 }
666}
667
668static void
669com_expr(c, n)
670 struct compiling *c;
671 node *n;
672{
673 int i;
674 int op;
675 REQ(n, expr);
676 com_term(c, CHILD(n, 0));
677 for (i = 2; i < NCH(n); i += 2) {
678 com_term(c, CHILD(n, i));
679 switch (TYPE(CHILD(n, i-1))) {
680 case PLUS:
681 op = BINARY_ADD;
682 break;
683 case MINUS:
684 op = BINARY_SUBTRACT;
685 break;
686 default:
687 err_setstr(SystemError,
688 "com_expr: expr operator not + or -");
689 c->c_errors++;
690 op = 255;
691 }
692 com_addbyte(c, op);
693 }
694}
695
696static enum cmp_op
697cmp_type(n)
698 node *n;
699{
700 REQ(n, comp_op);
701 /* comp_op: '<' | '>' | '=' | '>' '=' | '<' '=' | '<' '>'
702 | 'in' | 'not' 'in' | 'is' | 'is' not' */
703 if (NCH(n) == 1) {
704 n = CHILD(n, 0);
705 switch (TYPE(n)) {
706 case LESS: return LT;
707 case GREATER: return GT;
708 case EQUAL: return EQ;
709 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
710 if (strcmp(STR(n), "is") == 0) return IS;
711 }
712 }
713 else if (NCH(n) == 2) {
714 int t2 = TYPE(CHILD(n, 1));
715 switch (TYPE(CHILD(n, 0))) {
716 case LESS: if (t2 == EQUAL) return LE;
717 if (t2 == GREATER) return NE;
718 break;
719 case GREATER: if (t2 == EQUAL) return GE;
720 break;
721 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
722 return NOT_IN;
723 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
724 return IS_NOT;
725 }
726 }
727 return BAD;
728}
729
730static void
731com_comparison(c, n)
732 struct compiling *c;
733 node *n;
734{
735 int i;
736 enum cmp_op op;
737 int anchor;
738 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
739 com_expr(c, CHILD(n, 0));
740 if (NCH(n) == 1)
741 return;
742
743 /****************************************************************
744 The following code is generated for all but the last
745 comparison in a chain:
746
747 label: on stack: opcode: jump to:
748
749 a <code to load b>
750 a, b DUP_TOP
751 a, b, b ROT_THREE
752 b, a, b COMPARE_OP
753 b, 0-or-1 JUMP_IF_FALSE L1
754 b, 1 POP_TOP
755 b
756
757 We are now ready to repeat this sequence for the next
758 comparison in the chain.
759
760 For the last we generate:
761
762 b <code to load c>
763 b, c COMPARE_OP
764 0-or-1
765
766 If there were any jumps to L1 (i.e., there was more than one
767 comparison), we generate:
768
769 0-or-1 JUMP_FORWARD L2
770 L1: b, 0 ROT_TWO
771 0, b POP_TOP
772 0
773 L2:
774 ****************************************************************/
775
776 anchor = 0;
777
778 for (i = 2; i < NCH(n); i += 2) {
779 com_expr(c, CHILD(n, i));
780 if (i+2 < NCH(n)) {
781 com_addbyte(c, DUP_TOP);
782 com_addbyte(c, ROT_THREE);
783 }
784 op = cmp_type(CHILD(n, i-1));
785 if (op == BAD) {
786 err_setstr(SystemError,
787 "com_comparison: unknown comparison op");
788 c->c_errors++;
789 }
790 com_addoparg(c, COMPARE_OP, op);
791 if (i+2 < NCH(n)) {
792 com_addfwref(c, JUMP_IF_FALSE, &anchor);
793 com_addbyte(c, POP_TOP);
794 }
795 }
796
797 if (anchor) {
798 int anchor2 = 0;
799 com_addfwref(c, JUMP_FORWARD, &anchor2);
800 com_backpatch(c, anchor);
801 com_addbyte(c, ROT_TWO);
802 com_addbyte(c, POP_TOP);
803 com_backpatch(c, anchor2);
804 }
805}
806
807static void
808com_not_test(c, n)
809 struct compiling *c;
810 node *n;
811{
812 REQ(n, not_test); /* 'not' not_test | comparison */
813 if (NCH(n) == 1) {
814 com_comparison(c, CHILD(n, 0));
815 }
816 else {
817 com_not_test(c, CHILD(n, 1));
818 com_addbyte(c, UNARY_NOT);
819 }
820}
821
822static void
823com_and_test(c, n)
824 struct compiling *c;
825 node *n;
826{
827 int i;
828 int anchor;
829 REQ(n, and_test); /* not_test ('and' not_test)* */
830 anchor = 0;
831 i = 0;
832 for (;;) {
833 com_not_test(c, CHILD(n, i));
834 if ((i += 2) >= NCH(n))
835 break;
836 com_addfwref(c, JUMP_IF_FALSE, &anchor);
837 com_addbyte(c, POP_TOP);
838 }
839 if (anchor)
840 com_backpatch(c, anchor);
841}
842
843static void
844com_test(c, n)
845 struct compiling *c;
846 node *n;
847{
848 int i;
849 int anchor;
850 REQ(n, test); /* and_test ('and' and_test)* */
851 anchor = 0;
852 i = 0;
853 for (;;) {
854 com_and_test(c, CHILD(n, i));
855 if ((i += 2) >= NCH(n))
856 break;
857 com_addfwref(c, JUMP_IF_TRUE, &anchor);
858 com_addbyte(c, POP_TOP);
859 }
860 if (anchor)
861 com_backpatch(c, anchor);
862}
863
864static void
865com_list(c, n)
866 struct compiling *c;
867 node *n;
868{
869 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
870 if (NCH(n) == 1) {
871 com_node(c, CHILD(n, 0));
872 }
873 else {
874 int i;
875 int len;
876 len = (NCH(n) + 1) / 2;
877 for (i = 0; i < NCH(n); i += 2)
878 com_node(c, CHILD(n, i));
879 com_addoparg(c, BUILD_TUPLE, len);
880 }
881}
882
883
884/* Begin of assignment compilation */
885
886static void com_assign_name PROTO((struct compiling *, node *, int));
887static void com_assign PROTO((struct compiling *, node *, int));
888
889static void
890com_assign_attr(c, n, assigning)
891 struct compiling *c;
892 node *n;
893 int assigning;
894{
895 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
896}
897
898static void
899com_assign_slice(c, n, assigning)
900 struct compiling *c;
901 node *n;
902 int assigning;
903{
904 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
905}
906
907static void
908com_assign_subscript(c, n, assigning)
909 struct compiling *c;
910 node *n;
911 int assigning;
912{
913 com_node(c, n);
914 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
915}
916
917static void
918com_assign_trailer(c, n, assigning)
919 struct compiling *c;
920 node *n;
921 int assigning;
922{
923 char *name;
924 REQ(n, trailer);
925 switch (TYPE(CHILD(n, 0))) {
926 case LPAR: /* '(' [exprlist] ')' */
927 err_setstr(TypeError, "can't assign to function call");
928 c->c_errors++;
929 break;
930 case DOT: /* '.' NAME */
931 com_assign_attr(c, CHILD(n, 1), assigning);
932 break;
933 case LSQB: /* '[' subscript ']' */
934 n = CHILD(n, 1);
935 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
936 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
937 com_assign_slice(c, n, assigning);
938 else
939 com_assign_subscript(c, CHILD(n, 0), assigning);
940 break;
941 default:
942 err_setstr(TypeError, "unknown trailer type");
943 c->c_errors++;
944 }
945}
946
947static void
948com_assign_tuple(c, n, assigning)
949 struct compiling *c;
950 node *n;
951 int assigning;
952{
953 int i;
954 if (TYPE(n) != testlist)
955 REQ(n, exprlist);
956 if (assigning)
957 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
958 for (i = 0; i < NCH(n); i += 2)
959 com_assign(c, CHILD(n, i), assigning);
960}
961
962static void
963com_assign_list(c, n, assigning)
964 struct compiling *c;
965 node *n;
966 int assigning;
967{
968 int i;
969 if (assigning)
970 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
971 for (i = 0; i < NCH(n); i += 2)
972 com_assign(c, CHILD(n, i), assigning);
973}
974
975static void
976com_assign_name(c, n, assigning)
977 struct compiling *c;
978 node *n;
979 int assigning;
980{
981 REQ(n, NAME);
982 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
983}
984
985static void
986com_assign(c, n, assigning)
987 struct compiling *c;
988 node *n;
989 int assigning;
990{
991 /* Loop to avoid trivial recursion */
992 for (;;) {
993 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000994
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000995 case exprlist:
996 case testlist:
997 if (NCH(n) > 1) {
998 com_assign_tuple(c, n, assigning);
999 return;
1000 }
1001 n = CHILD(n, 0);
1002 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001003
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001004 case test:
1005 case and_test:
1006 case not_test:
1007 if (NCH(n) > 1) {
1008 err_setstr(TypeError,
1009 "can't assign to operator");
1010 c->c_errors++;
1011 return;
1012 }
1013 n = CHILD(n, 0);
1014 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001015
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001016 case comparison:
1017 if (NCH(n) > 1) {
1018 err_setstr(TypeError,
1019 "can't assign to operator");
1020 c->c_errors++;
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 expr:
1027 if (NCH(n) > 1) {
1028 err_setstr(TypeError,
1029 "can't assign to operator");
1030 c->c_errors++;
1031 return;
1032 }
1033 n = CHILD(n, 0);
1034 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001035
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001036 case term:
1037 if (NCH(n) > 1) {
1038 err_setstr(TypeError,
1039 "can't assign to operator");
1040 c->c_errors++;
1041 return;
1042 }
1043 n = CHILD(n, 0);
1044 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001045
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001046 case factor: /* ('+'|'-') factor | atom trailer* */
1047 if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
1048 err_setstr(TypeError,
1049 "can't assign to operator");
1050 c->c_errors++;
1051 return;
1052 }
1053 if (NCH(n) > 1) { /* trailer present */
1054 int i;
1055 com_node(c, CHILD(n, 0));
1056 for (i = 1; i+1 < NCH(n); i++) {
1057 com_apply_trailer(c, CHILD(n, i));
1058 } /* NB i is still alive */
1059 com_assign_trailer(c,
1060 CHILD(n, i), assigning);
1061 return;
1062 }
1063 n = CHILD(n, 0);
1064 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001065
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001066 case atom:
1067 switch (TYPE(CHILD(n, 0))) {
1068 case LPAR:
1069 n = CHILD(n, 1);
1070 if (TYPE(n) == RPAR) {
1071 /* XXX Should allow () = () ??? */
1072 err_setstr(TypeError,
1073 "can't assign to ()");
1074 c->c_errors++;
1075 return;
1076 }
1077 break;
1078 case LSQB:
1079 n = CHILD(n, 1);
1080 if (TYPE(n) == RSQB) {
1081 err_setstr(TypeError,
1082 "can't assign to []");
1083 c->c_errors++;
1084 return;
1085 }
1086 com_assign_list(c, n, assigning);
1087 return;
1088 case NAME:
1089 com_assign_name(c, CHILD(n, 0), assigning);
1090 return;
1091 default:
1092 err_setstr(TypeError,
1093 "can't assign to constant");
1094 c->c_errors++;
1095 return;
1096 }
1097 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001098
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001099 default:
1100 fprintf(stderr, "node type %d\n", TYPE(n));
1101 err_setstr(SystemError, "com_assign: bad node");
1102 c->c_errors++;
1103 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001104
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001105 }
1106 }
1107}
1108
1109static void
1110com_expr_stmt(c, n)
1111 struct compiling *c;
1112 node *n;
1113{
1114 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* NEWLINE */
1115 com_node(c, CHILD(n, NCH(n)-2));
1116 if (NCH(n) == 2) {
1117 com_addbyte(c, PRINT_EXPR);
1118 }
1119 else {
1120 int i;
1121 for (i = 0; i < NCH(n)-3; i+=2) {
1122 if (i+2 < NCH(n)-3)
1123 com_addbyte(c, DUP_TOP);
1124 com_assign(c, CHILD(n, i), 1/*assign*/);
1125 }
1126 }
1127}
1128
1129static void
1130com_print_stmt(c, n)
1131 struct compiling *c;
1132 node *n;
1133{
1134 int i;
1135 REQ(n, print_stmt); /* 'print' (test ',')* [test] NEWLINE */
1136 for (i = 1; i+1 < NCH(n); i += 2) {
1137 com_node(c, CHILD(n, i));
1138 com_addbyte(c, PRINT_ITEM);
1139 }
1140 if (TYPE(CHILD(n, NCH(n)-2)) != COMMA)
1141 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001142 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001143}
1144
1145static void
1146com_return_stmt(c, n)
1147 struct compiling *c;
1148 node *n;
1149{
1150 REQ(n, return_stmt); /* 'return' [testlist] NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001151 if (!c->c_infunction) {
1152 err_setstr(TypeError, "'return' outside function");
1153 c->c_errors++;
1154 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001155 if (NCH(n) == 2)
1156 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1157 else
1158 com_node(c, CHILD(n, 1));
1159 com_addbyte(c, RETURN_VALUE);
1160}
1161
1162static void
1163com_raise_stmt(c, n)
1164 struct compiling *c;
1165 node *n;
1166{
1167 REQ(n, raise_stmt); /* 'raise' expr [',' expr] NEWLINE */
1168 com_node(c, CHILD(n, 1));
1169 if (NCH(n) > 3)
1170 com_node(c, CHILD(n, 3));
1171 else
1172 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1173 com_addbyte(c, RAISE_EXCEPTION);
1174}
1175
1176static void
1177com_import_stmt(c, n)
1178 struct compiling *c;
1179 node *n;
1180{
1181 int i;
1182 REQ(n, import_stmt);
1183 /* 'import' NAME (',' NAME)* NEWLINE |
1184 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE */
1185 if (STR(CHILD(n, 0))[0] == 'f') {
1186 /* 'from' NAME 'import' ... */
1187 REQ(CHILD(n, 1), NAME);
1188 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1189 for (i = 3; i < NCH(n); i += 2)
1190 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1191 com_addbyte(c, POP_TOP);
1192 }
1193 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001194 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001195 for (i = 1; i < NCH(n); i += 2) {
1196 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1197 com_addopname(c, STORE_NAME, CHILD(n, i));
1198 }
1199 }
1200}
1201
1202static void
1203com_if_stmt(c, n)
1204 struct compiling *c;
1205 node *n;
1206{
1207 int i;
1208 int anchor = 0;
1209 REQ(n, if_stmt);
1210 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1211 for (i = 0; i+3 < NCH(n); i+=4) {
1212 int a = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001213 node *ch = CHILD(n, i+1);
1214 if (i > 0)
1215 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001216 com_node(c, CHILD(n, i+1));
1217 com_addfwref(c, JUMP_IF_FALSE, &a);
1218 com_addbyte(c, POP_TOP);
1219 com_node(c, CHILD(n, i+3));
1220 com_addfwref(c, JUMP_FORWARD, &anchor);
1221 com_backpatch(c, a);
1222 com_addbyte(c, POP_TOP);
1223 }
1224 if (i+2 < NCH(n))
1225 com_node(c, CHILD(n, i+2));
1226 com_backpatch(c, anchor);
1227}
1228
1229static void
1230com_while_stmt(c, n)
1231 struct compiling *c;
1232 node *n;
1233{
1234 int break_anchor = 0;
1235 int anchor = 0;
1236 int begin;
1237 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1238 com_addfwref(c, SETUP_LOOP, &break_anchor);
1239 begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001240 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001241 com_node(c, CHILD(n, 1));
1242 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1243 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001244 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001245 com_node(c, CHILD(n, 3));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001246 c->c_loops--;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001247 com_addoparg(c, JUMP_ABSOLUTE, begin);
1248 com_backpatch(c, anchor);
1249 com_addbyte(c, POP_TOP);
1250 com_addbyte(c, POP_BLOCK);
1251 if (NCH(n) > 4)
1252 com_node(c, CHILD(n, 6));
1253 com_backpatch(c, break_anchor);
1254}
1255
1256static void
1257com_for_stmt(c, n)
1258 struct compiling *c;
1259 node *n;
1260{
1261 object *v;
1262 int break_anchor = 0;
1263 int anchor = 0;
1264 int begin;
1265 REQ(n, for_stmt);
1266 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1267 com_addfwref(c, SETUP_LOOP, &break_anchor);
1268 com_node(c, CHILD(n, 3));
1269 v = newintobject(0L);
1270 if (v == NULL)
1271 c->c_errors++;
1272 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1273 XDECREF(v);
1274 begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001275 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001276 com_addfwref(c, FOR_LOOP, &anchor);
1277 com_assign(c, CHILD(n, 1), 1/*assigning*/);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001278 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001279 com_node(c, CHILD(n, 5));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001280 c->c_loops--;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001281 com_addoparg(c, JUMP_ABSOLUTE, begin);
1282 com_backpatch(c, anchor);
1283 com_addbyte(c, POP_BLOCK);
1284 if (NCH(n) > 8)
1285 com_node(c, CHILD(n, 8));
1286 com_backpatch(c, break_anchor);
1287}
1288
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001289/* Although 'execpt' and 'finally' clauses can be combined
1290 syntactically, they are compiled separately. In fact,
1291 try: S
1292 except E1: S1
1293 except E2: S2
1294 ...
1295 finally: Sf
1296 is equivalent to
1297 try:
1298 try: S
1299 except E1: S1
1300 except E2: S2
1301 ...
1302 finally: Sf
1303 meaning that the 'finally' clause is entered even if things
1304 go wrong again in an exception handler. Note that this is
1305 not the case for exception handlers: at most one is entered.
1306
1307 Code generated for "try: S finally: Sf" is as follows:
1308
1309 SETUP_FINALLY L
1310 <code for S>
1311 POP_BLOCK
1312 LOAD_CONST <nil>
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001313 L: <code for Sf>
1314 END_FINALLY
1315
1316 The special instructions use the block stack. Each block
1317 stack entry contains the instruction that created it (here
1318 SETUP_FINALLY), the level of the value stack at the time the
1319 block stack entry was created, and a label (here L).
1320
1321 SETUP_FINALLY:
1322 Pushes the current value stack level and the label
1323 onto the block stack.
1324 POP_BLOCK:
1325 Pops en entry from the block stack, and pops the value
1326 stack until its level is the same as indicated on the
1327 block stack. (The label is ignored.)
1328 END_FINALLY:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001329 Pops a variable number of entries from the *value* stack
1330 and re-raises the exception they specify. The number of
1331 entries popped depends on the (pseudo) exception type.
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001332
1333 The block stack is unwound when an exception is raised:
1334 when a SETUP_FINALLY entry is found, the exception is pushed
1335 onto the value stack (and the exception condition is cleared),
1336 and the interpreter jumps to the label gotten from the block
1337 stack.
1338
1339 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
Guido van Rossum3f5da241990-12-20 15:06:42 +00001340 (The contents of the value stack is shown in [], with the top
1341 at the right; 'tb' is trace-back info, 'val' the exception's
1342 associated value, and 'exc' the exception.)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001343
1344 Value stack Label Instruction Argument
1345 [] SETUP_EXCEPT L1
1346 [] <code for S>
1347 [] POP_BLOCK
1348 [] JUMP_FORWARD L0
1349
Guido van Rossum3f5da241990-12-20 15:06:42 +00001350 [tb, val, exc] L1: DUP )
1351 [tb, val, exc, exc] <evaluate E1> )
1352 [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
1353 [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
1354 [tb, val, exc, 1] POP )
1355 [tb, val, exc] POP
1356 [tb, val] <assign to V1> (or POP if no V1)
1357 [tb] POP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001358 [] <code for S1>
1359 JUMP_FORWARD L0
1360
Guido van Rossum3f5da241990-12-20 15:06:42 +00001361 [tb, val, exc, 0] L2: POP
1362 [tb, val, exc] DUP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001363 .............................etc.......................
1364
Guido van Rossum3f5da241990-12-20 15:06:42 +00001365 [tb, val, exc, 0] Ln+1: POP
1366 [tb, val, exc] END_FINALLY # re-raise exception
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001367
1368 [] L0: <next statement>
1369
1370 Of course, parts are not generated if Vi or Ei is not present.
1371*/
1372
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001373static void
1374com_try_stmt(c, n)
1375 struct compiling *c;
1376 node *n;
1377{
1378 int finally_anchor = 0;
1379 int except_anchor = 0;
1380 REQ(n, try_stmt);
1381 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001382
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001383 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1384 /* Have a 'finally' clause */
1385 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
1386 }
1387 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1388 /* Have an 'except' clause */
1389 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
1390 }
1391 com_node(c, CHILD(n, 2));
1392 if (except_anchor) {
1393 int end_anchor = 0;
1394 int i;
1395 node *ch;
1396 com_addbyte(c, POP_BLOCK);
1397 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1398 com_backpatch(c, except_anchor);
1399 for (i = 3;
1400 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1401 i += 3) {
1402 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001403 if (except_anchor == 0) {
1404 err_setstr(TypeError,
1405 "default 'except:' must be last");
1406 c->c_errors++;
1407 break;
1408 }
1409 except_anchor = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001410 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001411 if (NCH(ch) > 1) {
1412 com_addbyte(c, DUP_TOP);
1413 com_node(c, CHILD(ch, 1));
1414 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001415 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001416 com_addbyte(c, POP_TOP);
1417 }
1418 com_addbyte(c, POP_TOP);
1419 if (NCH(ch) > 3)
1420 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1421 else
1422 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001423 com_addbyte(c, POP_TOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001424 com_node(c, CHILD(n, i+2));
1425 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001426 if (except_anchor) {
1427 com_backpatch(c, except_anchor);
1428 com_addbyte(c, POP_TOP);
1429 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001430 }
1431 com_addbyte(c, END_FINALLY);
1432 com_backpatch(c, end_anchor);
1433 }
1434 if (finally_anchor) {
Guido van Rossum3f5da241990-12-20 15:06:42 +00001435 node *ch;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001436 com_addbyte(c, POP_BLOCK);
1437 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001438 com_backpatch(c, finally_anchor);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001439 ch = CHILD(n, NCH(n)-1);
1440 com_addoparg(c, SET_LINENO, ch->n_lineno);
1441 com_node(c, ch);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001442 com_addbyte(c, END_FINALLY);
1443 }
1444}
1445
1446static void
1447com_suite(c, n)
1448 struct compiling *c;
1449 node *n;
1450{
1451 REQ(n, suite);
1452 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1453 if (NCH(n) == 1) {
1454 com_node(c, CHILD(n, 0));
1455 }
1456 else {
1457 int i;
1458 for (i = 0; i < NCH(n); i++) {
1459 node *ch = CHILD(n, i);
1460 if (TYPE(ch) == stmt)
1461 com_node(c, ch);
1462 }
1463 }
1464}
1465
1466static void
1467com_funcdef(c, n)
1468 struct compiling *c;
1469 node *n;
1470{
1471 object *v;
1472 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001473 v = (object *)compile(n, c->c_filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001474 if (v == NULL)
1475 c->c_errors++;
1476 else {
1477 int i = com_addconst(c, v);
1478 com_addoparg(c, LOAD_CONST, i);
1479 com_addbyte(c, BUILD_FUNCTION);
1480 com_addopname(c, STORE_NAME, CHILD(n, 1));
1481 DECREF(v);
1482 }
1483}
1484
1485static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001486com_bases(c, n)
1487 struct compiling *c;
1488 node *n;
1489{
1490 int i, nbases;
1491 REQ(n, baselist);
1492 /*
1493 baselist: atom arguments (',' atom arguments)*
1494 arguments: '(' [testlist] ')'
1495 */
1496 for (i = 0; i < NCH(n); i += 3)
1497 com_node(c, CHILD(n, i));
1498 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1499}
1500
1501static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001502com_classdef(c, n)
1503 struct compiling *c;
1504 node *n;
1505{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001506 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001507 REQ(n, classdef);
1508 /*
1509 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1510 baselist: atom arguments (',' atom arguments)*
1511 arguments: '(' [testlist] ')'
1512 */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001513 if (NCH(n) == 7)
1514 com_bases(c, CHILD(n, 4));
1515 else
1516 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001517 v = (object *)compile(n, c->c_filename);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001518 if (v == NULL)
1519 c->c_errors++;
1520 else {
1521 int i = com_addconst(c, v);
1522 com_addoparg(c, LOAD_CONST, i);
1523 com_addbyte(c, BUILD_FUNCTION);
1524 com_addbyte(c, UNARY_CALL);
1525 com_addbyte(c, BUILD_CLASS);
1526 com_addopname(c, STORE_NAME, CHILD(n, 1));
1527 DECREF(v);
1528 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001529}
1530
1531static void
1532com_node(c, n)
1533 struct compiling *c;
1534 node *n;
1535{
1536 switch (TYPE(n)) {
1537
1538 /* Definition nodes */
1539
1540 case funcdef:
1541 com_funcdef(c, n);
1542 break;
1543 case classdef:
1544 com_classdef(c, n);
1545 break;
1546
1547 /* Trivial parse tree nodes */
1548
1549 case stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001550 case flow_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001551 com_node(c, CHILD(n, 0));
1552 break;
1553
1554 case simple_stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001555 case compound_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001556 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001557 com_node(c, CHILD(n, 0));
1558 break;
1559
1560 /* Statement nodes */
1561
1562 case expr_stmt:
1563 com_expr_stmt(c, n);
1564 break;
1565 case print_stmt:
1566 com_print_stmt(c, n);
1567 break;
1568 case del_stmt: /* 'del' exprlist NEWLINE */
1569 com_assign(c, CHILD(n, 1), 0/*delete*/);
1570 break;
1571 case pass_stmt:
1572 break;
1573 case break_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001574 if (c->c_loops == 0) {
1575 err_setstr(TypeError, "'break' outside loop");
1576 c->c_errors++;
1577 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001578 com_addbyte(c, BREAK_LOOP);
1579 break;
1580 case return_stmt:
1581 com_return_stmt(c, n);
1582 break;
1583 case raise_stmt:
1584 com_raise_stmt(c, n);
1585 break;
1586 case import_stmt:
1587 com_import_stmt(c, n);
1588 break;
1589 case if_stmt:
1590 com_if_stmt(c, n);
1591 break;
1592 case while_stmt:
1593 com_while_stmt(c, n);
1594 break;
1595 case for_stmt:
1596 com_for_stmt(c, n);
1597 break;
1598 case try_stmt:
1599 com_try_stmt(c, n);
1600 break;
1601 case suite:
1602 com_suite(c, n);
1603 break;
1604
1605 /* Expression nodes */
1606
1607 case testlist:
1608 com_list(c, n);
1609 break;
1610 case test:
1611 com_test(c, n);
1612 break;
1613 case and_test:
1614 com_and_test(c, n);
1615 break;
1616 case not_test:
1617 com_not_test(c, n);
1618 break;
1619 case comparison:
1620 com_comparison(c, n);
1621 break;
1622 case exprlist:
1623 com_list(c, n);
1624 break;
1625 case expr:
1626 com_expr(c, n);
1627 break;
1628 case term:
1629 com_term(c, n);
1630 break;
1631 case factor:
1632 com_factor(c, n);
1633 break;
1634 case atom:
1635 com_atom(c, n);
1636 break;
1637
1638 default:
1639 fprintf(stderr, "node type %d\n", TYPE(n));
1640 err_setstr(SystemError, "com_node: unexpected node type");
1641 c->c_errors++;
1642 }
1643}
1644
1645static void com_fplist PROTO((struct compiling *, node *));
1646
1647static void
1648com_fpdef(c, n)
1649 struct compiling *c;
1650 node *n;
1651{
1652 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1653 if (TYPE(CHILD(n, 0)) == LPAR)
1654 com_fplist(c, CHILD(n, 1));
1655 else
1656 com_addopname(c, STORE_NAME, CHILD(n, 0));
1657}
1658
1659static void
1660com_fplist(c, n)
1661 struct compiling *c;
1662 node *n;
1663{
1664 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1665 if (NCH(n) == 1) {
1666 com_fpdef(c, CHILD(n, 0));
1667 }
1668 else {
1669 int i;
1670 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1671 for (i = 0; i < NCH(n); i += 2)
1672 com_fpdef(c, CHILD(n, i));
1673 }
1674}
1675
1676static void
1677com_file_input(c, n)
1678 struct compiling *c;
1679 node *n;
1680{
1681 int i;
1682 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1683 for (i = 0; i < NCH(n); i++) {
1684 node *ch = CHILD(n, i);
1685 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1686 com_node(c, ch);
1687 }
1688}
1689
1690/* Top-level compile-node interface */
1691
1692static void
1693compile_funcdef(c, n)
1694 struct compiling *c;
1695 node *n;
1696{
1697 node *ch;
1698 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1699 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1700 ch = CHILD(ch, 1); /* ')' | fplist */
1701 if (TYPE(ch) == RPAR)
1702 com_addbyte(c, REFUSE_ARGS);
1703 else {
1704 com_addbyte(c, REQUIRE_ARGS);
1705 com_fplist(c, ch);
1706 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001707 c->c_infunction = 1;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001708 com_node(c, CHILD(n, 4));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001709 c->c_infunction = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001710 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1711 com_addbyte(c, RETURN_VALUE);
1712}
1713
1714static void
1715compile_node(c, n)
1716 struct compiling *c;
1717 node *n;
1718{
Guido van Rossum3f5da241990-12-20 15:06:42 +00001719 com_addoparg(c, SET_LINENO, n->n_lineno);
1720
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001721 switch (TYPE(n)) {
1722
Guido van Rossum4c417781991-01-21 16:09:22 +00001723 case single_input: /* One interactive command */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001724 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001725 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001726 n = CHILD(n, 0);
1727 if (TYPE(n) != NEWLINE)
1728 com_node(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001729 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1730 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001731 break;
1732
Guido van Rossum4c417781991-01-21 16:09:22 +00001733 case file_input: /* A whole file, or built-in function exec() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001734 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001735 com_file_input(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001736 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1737 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001738 break;
1739
Guido van Rossum4c417781991-01-21 16:09:22 +00001740 case expr_input: /* Built-in function eval() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001741 com_addbyte(c, REFUSE_ARGS);
1742 com_node(c, CHILD(n, 0));
1743 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001744 break;
1745
Guido van Rossum4c417781991-01-21 16:09:22 +00001746 case eval_input: /* Built-in function input() */
1747 com_addbyte(c, REFUSE_ARGS);
1748 com_node(c, CHILD(n, 0));
1749 com_addbyte(c, RETURN_VALUE);
1750 break;
1751
1752 case funcdef: /* A function definition */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001753 compile_funcdef(c, n);
1754 break;
1755
Guido van Rossum4c417781991-01-21 16:09:22 +00001756 case classdef: /* A class definition */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001757 /* 'class' NAME parameters ['=' baselist] ':' suite */
1758 com_addbyte(c, REFUSE_ARGS);
1759 com_node(c, CHILD(n, NCH(n)-1));
1760 com_addbyte(c, LOAD_LOCALS);
1761 com_addbyte(c, RETURN_VALUE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001762 break;
1763
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001764 default:
1765 fprintf(stderr, "node type %d\n", TYPE(n));
1766 err_setstr(SystemError, "compile_node: unexpected node type");
1767 c->c_errors++;
1768 }
1769}
1770
Guido van Rossum282914b1991-04-04 10:42:56 +00001771/* Optimization for local and global variables.
1772
1773 Attempt to replace all LOAD_NAME instructions that refer to a local
1774 variable with LOAD_LOCAL instructions, and all that refer to a global
1775 variable with LOAD_GLOBAL instructions.
1776
1777 To find all local variables, we check all STORE_NAME and IMPORT_FROM
1778 instructions. This yields all local variables, including arguments,
1779 function definitions, class definitions and import statements.
1780
1781 There is one leak: 'from foo import *' introduces local variables
1782 that we can't know while compiling. If this is the case, LOAD_GLOBAL
1783 instructions are not generated -- LOAD_NAME is left in place for
1784 globals, since it first checks for globals (LOAD_LOCAL is still used
1785 for recognized locals, since it doesn't hurt).
1786
1787 This optimization means that using the same name as a global and
1788 as a local variable within the same scope is now illegal, which
1789 is a change to the language! Also using eval() to introduce new
1790 local variables won't work. But both were bad practice at best.
1791
1792 The optimization doesn't save much: basically, it saves one
1793 unsuccessful dictionary lookup per global (or built-in) variable
1794 reference. On the (slow!) Mac Plus, with 4 local variables,
1795 this saving was measured to be about 0.18 ms. We might save more
1796 by using a different data structure to hold local variables, like
1797 an array indexed by variable number.
1798
1799 NB: this modifies the string object co->co_code!
1800*/
1801
1802static void
1803optimizer(co)
1804 codeobject *co;
1805{
1806 char *next_instr, *cur_instr;
1807 object *locals;
1808 int opcode;
1809 int oparg;
1810 object *name;
1811 int star_used;
1812
1813#define NEXTOP() (*next_instr++)
1814#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
1815#define GETITEM(v, i) (getlistitem((v), (i)))
1816#define GETNAMEOBJ(i) (GETITEM(co->co_names, (i)))
1817
1818 locals = newdictobject();
1819 if (locals == NULL) {
1820 err_clear();
1821 return; /* For now, this is OK */
1822 }
1823
1824 next_instr = GETSTRINGVALUE(co->co_code);
1825 for (;;) {
1826 opcode = NEXTOP();
1827 if (opcode == STOP_CODE)
1828 break;
1829 if (HAS_ARG(opcode))
1830 oparg = NEXTARG();
1831 if (opcode == STORE_NAME || opcode == IMPORT_FROM) {
1832 name = GETNAMEOBJ(oparg);
1833 if (dict2insert(locals, name, None) != 0) {
1834 DECREF(locals);
1835 return; /* Sorry */
1836 }
1837 }
1838 }
1839
1840 star_used = (dictlookup(locals, "*") != NULL);
1841 next_instr = GETSTRINGVALUE(co->co_code);
1842 for (;;) {
1843 cur_instr = next_instr;
1844 opcode = NEXTOP();
1845 if (opcode == STOP_CODE)
1846 break;
1847 if (HAS_ARG(opcode))
1848 oparg = NEXTARG();
1849 if (opcode == LOAD_NAME) {
1850 name = GETNAMEOBJ(oparg);
1851 if (dictlookup(locals, getstringvalue(name)) != NULL)
1852 *cur_instr = LOAD_LOCAL;
1853 else if (!star_used)
1854 *cur_instr = LOAD_GLOBAL;
1855 }
1856 }
1857
1858 DECREF(locals);
1859}
1860
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001861codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001862compile(n, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001863 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001864 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001865{
1866 struct compiling sc;
1867 codeobject *co;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001868 if (!com_init(&sc, filename))
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001869 return NULL;
1870 compile_node(&sc, n);
1871 com_done(&sc);
1872 if (sc.c_errors == 0)
Guido van Rossum3f5da241990-12-20 15:06:42 +00001873 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names, filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001874 else
1875 co = NULL;
1876 com_free(&sc);
Guido van Rossum282914b1991-04-04 10:42:56 +00001877 if (co != NULL)
1878 optimizer(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001879 return co;
1880}