blob: 5fa405d3ba5cca094dcfc153e170196a4eb676b8 [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 }
Guido van Rossume3a204f1991-05-05 20:05:35 +0000367 if (*end == 'l' || *end == 'L') {
368 extern object *long_scan();
369 return long_scan(s, 0);
370 }
Guido van Rossum282914b1991-04-04 10:42:56 +0000371 errno = 0;
372 xx = strtod(s, &end);
373 if (*end == '\0') {
374 if (errno != 0) {
375 err_setstr(RuntimeError, "float constant too large");
376 return NULL;
377 }
378 return newfloatobject(xx);
379 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000380 err_setstr(RuntimeError, "bad number syntax");
381 return NULL;
382}
383
384static object *
385parsestr(s)
386 char *s;
387{
388 object *v;
389 int len;
390 char *buf;
391 char *p;
392 int c;
393 if (*s != '\'') {
394 err_badcall();
395 return NULL;
396 }
397 s++;
398 len = strlen(s);
399 if (s[--len] != '\'') {
400 err_badcall();
401 return NULL;
402 }
403 if (strchr(s, '\\') == NULL)
404 return newsizedstringobject(s, len);
405 v = newsizedstringobject((char *)NULL, len);
406 p = buf = getstringvalue(v);
407 while (*s != '\0' && *s != '\'') {
408 if (*s != '\\') {
409 *p++ = *s++;
410 continue;
411 }
412 s++;
413 switch (*s++) {
414 /* XXX This assumes ASCII! */
415 case '\\': *p++ = '\\'; break;
416 case '\'': *p++ = '\''; break;
417 case 'b': *p++ = '\b'; break;
418 case 'f': *p++ = '\014'; break; /* FF */
419 case 't': *p++ = '\t'; break;
420 case 'n': *p++ = '\n'; break;
421 case 'r': *p++ = '\r'; break;
422 case 'v': *p++ = '\013'; break; /* VT */
423 case 'E': *p++ = '\033'; break; /* ESC, not C */
424 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
425 case '0': case '1': case '2': case '3':
426 case '4': case '5': case '6': case '7':
427 c = s[-1] - '0';
428 if ('0' <= *s && *s <= '7') {
429 c = (c<<3) + *s++ - '0';
430 if ('0' <= *s && *s <= '7')
431 c = (c<<3) + *s++ - '0';
432 }
433 *p++ = c;
434 break;
435 case 'x':
436 if (isxdigit(*s)) {
437 sscanf(s, "%x", &c);
438 *p++ = c;
439 do {
440 s++;
441 } while (isxdigit(*s));
442 break;
443 }
444 /* FALLTHROUGH */
445 default: *p++ = '\\'; *p++ = s[-1]; break;
446 }
447 }
448 resizestring(&v, (int)(p - buf));
449 return v;
450}
451
452static void
453com_list_constructor(c, n)
454 struct compiling *c;
455 node *n;
456{
457 int len;
458 int i;
459 object *v, *w;
460 if (TYPE(n) != testlist)
461 REQ(n, exprlist);
462 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
463 len = (NCH(n) + 1) / 2;
464 for (i = 0; i < NCH(n); i += 2)
465 com_node(c, CHILD(n, i));
466 com_addoparg(c, BUILD_LIST, len);
467}
468
469static void
470com_atom(c, n)
471 struct compiling *c;
472 node *n;
473{
474 node *ch;
475 object *v;
476 int i;
477 REQ(n, atom);
478 ch = CHILD(n, 0);
479 switch (TYPE(ch)) {
480 case LPAR:
481 if (TYPE(CHILD(n, 1)) == RPAR)
482 com_addoparg(c, BUILD_TUPLE, 0);
483 else
484 com_node(c, CHILD(n, 1));
485 break;
486 case LSQB:
487 if (TYPE(CHILD(n, 1)) == RSQB)
488 com_addoparg(c, BUILD_LIST, 0);
489 else
490 com_list_constructor(c, CHILD(n, 1));
491 break;
492 case LBRACE:
493 com_addoparg(c, BUILD_MAP, 0);
494 break;
495 case BACKQUOTE:
496 com_node(c, CHILD(n, 1));
497 com_addbyte(c, UNARY_CONVERT);
498 break;
499 case NUMBER:
500 if ((v = parsenumber(STR(ch))) == NULL) {
501 c->c_errors++;
502 i = 255;
503 }
504 else {
505 i = com_addconst(c, v);
506 DECREF(v);
507 }
508 com_addoparg(c, LOAD_CONST, i);
509 break;
510 case STRING:
511 if ((v = parsestr(STR(ch))) == NULL) {
512 c->c_errors++;
513 i = 255;
514 }
515 else {
516 i = com_addconst(c, v);
517 DECREF(v);
518 }
519 com_addoparg(c, LOAD_CONST, i);
520 break;
521 case NAME:
522 com_addopname(c, LOAD_NAME, ch);
523 break;
524 default:
525 fprintf(stderr, "node type %d\n", TYPE(ch));
526 err_setstr(SystemError, "com_atom: unexpected node type");
527 c->c_errors++;
528 }
529}
530
531static void
532com_slice(c, n, op)
533 struct compiling *c;
534 node *n;
535 int op;
536{
537 if (NCH(n) == 1) {
538 com_addbyte(c, op);
539 }
540 else if (NCH(n) == 2) {
541 if (TYPE(CHILD(n, 0)) != COLON) {
542 com_node(c, CHILD(n, 0));
543 com_addbyte(c, op+1);
544 }
545 else {
546 com_node(c, CHILD(n, 1));
547 com_addbyte(c, op+2);
548 }
549 }
550 else {
551 com_node(c, CHILD(n, 0));
552 com_node(c, CHILD(n, 2));
553 com_addbyte(c, op+3);
554 }
555}
556
557static void
558com_apply_subscript(c, n)
559 struct compiling *c;
560 node *n;
561{
562 REQ(n, subscript);
563 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
564 /* It's a single subscript */
565 com_node(c, CHILD(n, 0));
566 com_addbyte(c, BINARY_SUBSCR);
567 }
568 else {
569 /* It's a slice: [expr] ':' [expr] */
570 com_slice(c, n, SLICE);
571 }
572}
573
574static void
575com_call_function(c, n)
576 struct compiling *c;
577 node *n; /* EITHER testlist OR ')' */
578{
579 if (TYPE(n) == RPAR) {
580 com_addbyte(c, UNARY_CALL);
581 }
582 else {
583 com_node(c, n);
584 com_addbyte(c, BINARY_CALL);
585 }
586}
587
588static void
589com_select_member(c, n)
590 struct compiling *c;
591 node *n;
592{
593 com_addopname(c, LOAD_ATTR, n);
594}
595
596static void
597com_apply_trailer(c, n)
598 struct compiling *c;
599 node *n;
600{
601 REQ(n, trailer);
602 switch (TYPE(CHILD(n, 0))) {
603 case LPAR:
604 com_call_function(c, CHILD(n, 1));
605 break;
606 case DOT:
607 com_select_member(c, CHILD(n, 1));
608 break;
609 case LSQB:
610 com_apply_subscript(c, CHILD(n, 1));
611 break;
612 default:
613 err_setstr(SystemError,
614 "com_apply_trailer: unknown trailer type");
615 c->c_errors++;
616 }
617}
618
619static void
620com_factor(c, n)
621 struct compiling *c;
622 node *n;
623{
624 int i;
625 REQ(n, factor);
626 if (TYPE(CHILD(n, 0)) == PLUS) {
627 com_factor(c, CHILD(n, 1));
628 com_addbyte(c, UNARY_POSITIVE);
629 }
630 else if (TYPE(CHILD(n, 0)) == MINUS) {
631 com_factor(c, CHILD(n, 1));
632 com_addbyte(c, UNARY_NEGATIVE);
633 }
634 else {
635 com_atom(c, CHILD(n, 0));
636 for (i = 1; i < NCH(n); i++)
637 com_apply_trailer(c, CHILD(n, i));
638 }
639}
640
641static void
642com_term(c, n)
643 struct compiling *c;
644 node *n;
645{
646 int i;
647 int op;
648 REQ(n, term);
649 com_factor(c, CHILD(n, 0));
650 for (i = 2; i < NCH(n); i += 2) {
651 com_factor(c, CHILD(n, i));
652 switch (TYPE(CHILD(n, i-1))) {
653 case STAR:
654 op = BINARY_MULTIPLY;
655 break;
656 case SLASH:
657 op = BINARY_DIVIDE;
658 break;
659 case PERCENT:
660 op = BINARY_MODULO;
661 break;
662 default:
663 err_setstr(SystemError,
664 "com_term: term operator not *, / or %");
665 c->c_errors++;
666 op = 255;
667 }
668 com_addbyte(c, op);
669 }
670}
671
672static void
673com_expr(c, n)
674 struct compiling *c;
675 node *n;
676{
677 int i;
678 int op;
679 REQ(n, expr);
680 com_term(c, CHILD(n, 0));
681 for (i = 2; i < NCH(n); i += 2) {
682 com_term(c, CHILD(n, i));
683 switch (TYPE(CHILD(n, i-1))) {
684 case PLUS:
685 op = BINARY_ADD;
686 break;
687 case MINUS:
688 op = BINARY_SUBTRACT;
689 break;
690 default:
691 err_setstr(SystemError,
692 "com_expr: expr operator not + or -");
693 c->c_errors++;
694 op = 255;
695 }
696 com_addbyte(c, op);
697 }
698}
699
700static enum cmp_op
701cmp_type(n)
702 node *n;
703{
704 REQ(n, comp_op);
705 /* comp_op: '<' | '>' | '=' | '>' '=' | '<' '=' | '<' '>'
706 | 'in' | 'not' 'in' | 'is' | 'is' not' */
707 if (NCH(n) == 1) {
708 n = CHILD(n, 0);
709 switch (TYPE(n)) {
710 case LESS: return LT;
711 case GREATER: return GT;
712 case EQUAL: return EQ;
713 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
714 if (strcmp(STR(n), "is") == 0) return IS;
715 }
716 }
717 else if (NCH(n) == 2) {
718 int t2 = TYPE(CHILD(n, 1));
719 switch (TYPE(CHILD(n, 0))) {
720 case LESS: if (t2 == EQUAL) return LE;
721 if (t2 == GREATER) return NE;
722 break;
723 case GREATER: if (t2 == EQUAL) return GE;
724 break;
725 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
726 return NOT_IN;
727 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
728 return IS_NOT;
729 }
730 }
731 return BAD;
732}
733
734static void
735com_comparison(c, n)
736 struct compiling *c;
737 node *n;
738{
739 int i;
740 enum cmp_op op;
741 int anchor;
742 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
743 com_expr(c, CHILD(n, 0));
744 if (NCH(n) == 1)
745 return;
746
747 /****************************************************************
748 The following code is generated for all but the last
749 comparison in a chain:
750
751 label: on stack: opcode: jump to:
752
753 a <code to load b>
754 a, b DUP_TOP
755 a, b, b ROT_THREE
756 b, a, b COMPARE_OP
757 b, 0-or-1 JUMP_IF_FALSE L1
758 b, 1 POP_TOP
759 b
760
761 We are now ready to repeat this sequence for the next
762 comparison in the chain.
763
764 For the last we generate:
765
766 b <code to load c>
767 b, c COMPARE_OP
768 0-or-1
769
770 If there were any jumps to L1 (i.e., there was more than one
771 comparison), we generate:
772
773 0-or-1 JUMP_FORWARD L2
774 L1: b, 0 ROT_TWO
775 0, b POP_TOP
776 0
777 L2:
778 ****************************************************************/
779
780 anchor = 0;
781
782 for (i = 2; i < NCH(n); i += 2) {
783 com_expr(c, CHILD(n, i));
784 if (i+2 < NCH(n)) {
785 com_addbyte(c, DUP_TOP);
786 com_addbyte(c, ROT_THREE);
787 }
788 op = cmp_type(CHILD(n, i-1));
789 if (op == BAD) {
790 err_setstr(SystemError,
791 "com_comparison: unknown comparison op");
792 c->c_errors++;
793 }
794 com_addoparg(c, COMPARE_OP, op);
795 if (i+2 < NCH(n)) {
796 com_addfwref(c, JUMP_IF_FALSE, &anchor);
797 com_addbyte(c, POP_TOP);
798 }
799 }
800
801 if (anchor) {
802 int anchor2 = 0;
803 com_addfwref(c, JUMP_FORWARD, &anchor2);
804 com_backpatch(c, anchor);
805 com_addbyte(c, ROT_TWO);
806 com_addbyte(c, POP_TOP);
807 com_backpatch(c, anchor2);
808 }
809}
810
811static void
812com_not_test(c, n)
813 struct compiling *c;
814 node *n;
815{
816 REQ(n, not_test); /* 'not' not_test | comparison */
817 if (NCH(n) == 1) {
818 com_comparison(c, CHILD(n, 0));
819 }
820 else {
821 com_not_test(c, CHILD(n, 1));
822 com_addbyte(c, UNARY_NOT);
823 }
824}
825
826static void
827com_and_test(c, n)
828 struct compiling *c;
829 node *n;
830{
831 int i;
832 int anchor;
833 REQ(n, and_test); /* not_test ('and' not_test)* */
834 anchor = 0;
835 i = 0;
836 for (;;) {
837 com_not_test(c, CHILD(n, i));
838 if ((i += 2) >= NCH(n))
839 break;
840 com_addfwref(c, JUMP_IF_FALSE, &anchor);
841 com_addbyte(c, POP_TOP);
842 }
843 if (anchor)
844 com_backpatch(c, anchor);
845}
846
847static void
848com_test(c, n)
849 struct compiling *c;
850 node *n;
851{
852 int i;
853 int anchor;
854 REQ(n, test); /* and_test ('and' and_test)* */
855 anchor = 0;
856 i = 0;
857 for (;;) {
858 com_and_test(c, CHILD(n, i));
859 if ((i += 2) >= NCH(n))
860 break;
861 com_addfwref(c, JUMP_IF_TRUE, &anchor);
862 com_addbyte(c, POP_TOP);
863 }
864 if (anchor)
865 com_backpatch(c, anchor);
866}
867
868static void
869com_list(c, n)
870 struct compiling *c;
871 node *n;
872{
873 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
874 if (NCH(n) == 1) {
875 com_node(c, CHILD(n, 0));
876 }
877 else {
878 int i;
879 int len;
880 len = (NCH(n) + 1) / 2;
881 for (i = 0; i < NCH(n); i += 2)
882 com_node(c, CHILD(n, i));
883 com_addoparg(c, BUILD_TUPLE, len);
884 }
885}
886
887
888/* Begin of assignment compilation */
889
890static void com_assign_name PROTO((struct compiling *, node *, int));
891static void com_assign PROTO((struct compiling *, node *, int));
892
893static void
894com_assign_attr(c, n, assigning)
895 struct compiling *c;
896 node *n;
897 int assigning;
898{
899 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
900}
901
902static void
903com_assign_slice(c, n, assigning)
904 struct compiling *c;
905 node *n;
906 int assigning;
907{
908 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
909}
910
911static void
912com_assign_subscript(c, n, assigning)
913 struct compiling *c;
914 node *n;
915 int assigning;
916{
917 com_node(c, n);
918 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
919}
920
921static void
922com_assign_trailer(c, n, assigning)
923 struct compiling *c;
924 node *n;
925 int assigning;
926{
927 char *name;
928 REQ(n, trailer);
929 switch (TYPE(CHILD(n, 0))) {
930 case LPAR: /* '(' [exprlist] ')' */
931 err_setstr(TypeError, "can't assign to function call");
932 c->c_errors++;
933 break;
934 case DOT: /* '.' NAME */
935 com_assign_attr(c, CHILD(n, 1), assigning);
936 break;
937 case LSQB: /* '[' subscript ']' */
938 n = CHILD(n, 1);
939 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
940 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
941 com_assign_slice(c, n, assigning);
942 else
943 com_assign_subscript(c, CHILD(n, 0), assigning);
944 break;
945 default:
946 err_setstr(TypeError, "unknown trailer type");
947 c->c_errors++;
948 }
949}
950
951static void
952com_assign_tuple(c, n, assigning)
953 struct compiling *c;
954 node *n;
955 int assigning;
956{
957 int i;
958 if (TYPE(n) != testlist)
959 REQ(n, exprlist);
960 if (assigning)
961 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
962 for (i = 0; i < NCH(n); i += 2)
963 com_assign(c, CHILD(n, i), assigning);
964}
965
966static void
967com_assign_list(c, n, assigning)
968 struct compiling *c;
969 node *n;
970 int assigning;
971{
972 int i;
973 if (assigning)
974 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
975 for (i = 0; i < NCH(n); i += 2)
976 com_assign(c, CHILD(n, i), assigning);
977}
978
979static void
980com_assign_name(c, n, assigning)
981 struct compiling *c;
982 node *n;
983 int assigning;
984{
985 REQ(n, NAME);
986 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
987}
988
989static void
990com_assign(c, n, assigning)
991 struct compiling *c;
992 node *n;
993 int assigning;
994{
995 /* Loop to avoid trivial recursion */
996 for (;;) {
997 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000998
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000999 case exprlist:
1000 case testlist:
1001 if (NCH(n) > 1) {
1002 com_assign_tuple(c, n, assigning);
1003 return;
1004 }
1005 n = CHILD(n, 0);
1006 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001007
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001008 case test:
1009 case and_test:
1010 case not_test:
1011 if (NCH(n) > 1) {
1012 err_setstr(TypeError,
1013 "can't assign to operator");
1014 c->c_errors++;
1015 return;
1016 }
1017 n = CHILD(n, 0);
1018 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001019
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001020 case comparison:
1021 if (NCH(n) > 1) {
1022 err_setstr(TypeError,
1023 "can't assign to operator");
1024 c->c_errors++;
1025 return;
1026 }
1027 n = CHILD(n, 0);
1028 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001029
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001030 case expr:
1031 if (NCH(n) > 1) {
1032 err_setstr(TypeError,
1033 "can't assign to operator");
1034 c->c_errors++;
1035 return;
1036 }
1037 n = CHILD(n, 0);
1038 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001039
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001040 case term:
1041 if (NCH(n) > 1) {
1042 err_setstr(TypeError,
1043 "can't assign to operator");
1044 c->c_errors++;
1045 return;
1046 }
1047 n = CHILD(n, 0);
1048 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001049
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001050 case factor: /* ('+'|'-') factor | atom trailer* */
1051 if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
1052 err_setstr(TypeError,
1053 "can't assign to operator");
1054 c->c_errors++;
1055 return;
1056 }
1057 if (NCH(n) > 1) { /* trailer present */
1058 int i;
1059 com_node(c, CHILD(n, 0));
1060 for (i = 1; i+1 < NCH(n); i++) {
1061 com_apply_trailer(c, CHILD(n, i));
1062 } /* NB i is still alive */
1063 com_assign_trailer(c,
1064 CHILD(n, i), assigning);
1065 return;
1066 }
1067 n = CHILD(n, 0);
1068 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001069
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001070 case atom:
1071 switch (TYPE(CHILD(n, 0))) {
1072 case LPAR:
1073 n = CHILD(n, 1);
1074 if (TYPE(n) == RPAR) {
1075 /* XXX Should allow () = () ??? */
1076 err_setstr(TypeError,
1077 "can't assign to ()");
1078 c->c_errors++;
1079 return;
1080 }
1081 break;
1082 case LSQB:
1083 n = CHILD(n, 1);
1084 if (TYPE(n) == RSQB) {
1085 err_setstr(TypeError,
1086 "can't assign to []");
1087 c->c_errors++;
1088 return;
1089 }
1090 com_assign_list(c, n, assigning);
1091 return;
1092 case NAME:
1093 com_assign_name(c, CHILD(n, 0), assigning);
1094 return;
1095 default:
1096 err_setstr(TypeError,
1097 "can't assign to constant");
1098 c->c_errors++;
1099 return;
1100 }
1101 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001102
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001103 default:
1104 fprintf(stderr, "node type %d\n", TYPE(n));
1105 err_setstr(SystemError, "com_assign: bad node");
1106 c->c_errors++;
1107 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001108
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001109 }
1110 }
1111}
1112
1113static void
1114com_expr_stmt(c, n)
1115 struct compiling *c;
1116 node *n;
1117{
1118 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* NEWLINE */
1119 com_node(c, CHILD(n, NCH(n)-2));
1120 if (NCH(n) == 2) {
1121 com_addbyte(c, PRINT_EXPR);
1122 }
1123 else {
1124 int i;
1125 for (i = 0; i < NCH(n)-3; i+=2) {
1126 if (i+2 < NCH(n)-3)
1127 com_addbyte(c, DUP_TOP);
1128 com_assign(c, CHILD(n, i), 1/*assign*/);
1129 }
1130 }
1131}
1132
1133static void
1134com_print_stmt(c, n)
1135 struct compiling *c;
1136 node *n;
1137{
1138 int i;
1139 REQ(n, print_stmt); /* 'print' (test ',')* [test] NEWLINE */
1140 for (i = 1; i+1 < NCH(n); i += 2) {
1141 com_node(c, CHILD(n, i));
1142 com_addbyte(c, PRINT_ITEM);
1143 }
1144 if (TYPE(CHILD(n, NCH(n)-2)) != COMMA)
1145 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001146 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001147}
1148
1149static void
1150com_return_stmt(c, n)
1151 struct compiling *c;
1152 node *n;
1153{
1154 REQ(n, return_stmt); /* 'return' [testlist] NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001155 if (!c->c_infunction) {
1156 err_setstr(TypeError, "'return' outside function");
1157 c->c_errors++;
1158 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001159 if (NCH(n) == 2)
1160 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1161 else
1162 com_node(c, CHILD(n, 1));
1163 com_addbyte(c, RETURN_VALUE);
1164}
1165
1166static void
1167com_raise_stmt(c, n)
1168 struct compiling *c;
1169 node *n;
1170{
1171 REQ(n, raise_stmt); /* 'raise' expr [',' expr] NEWLINE */
1172 com_node(c, CHILD(n, 1));
1173 if (NCH(n) > 3)
1174 com_node(c, CHILD(n, 3));
1175 else
1176 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1177 com_addbyte(c, RAISE_EXCEPTION);
1178}
1179
1180static void
1181com_import_stmt(c, n)
1182 struct compiling *c;
1183 node *n;
1184{
1185 int i;
1186 REQ(n, import_stmt);
1187 /* 'import' NAME (',' NAME)* NEWLINE |
1188 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE */
1189 if (STR(CHILD(n, 0))[0] == 'f') {
1190 /* 'from' NAME 'import' ... */
1191 REQ(CHILD(n, 1), NAME);
1192 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1193 for (i = 3; i < NCH(n); i += 2)
1194 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1195 com_addbyte(c, POP_TOP);
1196 }
1197 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001198 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001199 for (i = 1; i < NCH(n); i += 2) {
1200 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1201 com_addopname(c, STORE_NAME, CHILD(n, i));
1202 }
1203 }
1204}
1205
1206static void
1207com_if_stmt(c, n)
1208 struct compiling *c;
1209 node *n;
1210{
1211 int i;
1212 int anchor = 0;
1213 REQ(n, if_stmt);
1214 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1215 for (i = 0; i+3 < NCH(n); i+=4) {
1216 int a = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001217 node *ch = CHILD(n, i+1);
1218 if (i > 0)
1219 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001220 com_node(c, CHILD(n, i+1));
1221 com_addfwref(c, JUMP_IF_FALSE, &a);
1222 com_addbyte(c, POP_TOP);
1223 com_node(c, CHILD(n, i+3));
1224 com_addfwref(c, JUMP_FORWARD, &anchor);
1225 com_backpatch(c, a);
1226 com_addbyte(c, POP_TOP);
1227 }
1228 if (i+2 < NCH(n))
1229 com_node(c, CHILD(n, i+2));
1230 com_backpatch(c, anchor);
1231}
1232
1233static void
1234com_while_stmt(c, n)
1235 struct compiling *c;
1236 node *n;
1237{
1238 int break_anchor = 0;
1239 int anchor = 0;
1240 int begin;
1241 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1242 com_addfwref(c, SETUP_LOOP, &break_anchor);
1243 begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001244 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001245 com_node(c, CHILD(n, 1));
1246 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1247 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001248 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001249 com_node(c, CHILD(n, 3));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001250 c->c_loops--;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001251 com_addoparg(c, JUMP_ABSOLUTE, begin);
1252 com_backpatch(c, anchor);
1253 com_addbyte(c, POP_TOP);
1254 com_addbyte(c, POP_BLOCK);
1255 if (NCH(n) > 4)
1256 com_node(c, CHILD(n, 6));
1257 com_backpatch(c, break_anchor);
1258}
1259
1260static void
1261com_for_stmt(c, n)
1262 struct compiling *c;
1263 node *n;
1264{
1265 object *v;
1266 int break_anchor = 0;
1267 int anchor = 0;
1268 int begin;
1269 REQ(n, for_stmt);
1270 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1271 com_addfwref(c, SETUP_LOOP, &break_anchor);
1272 com_node(c, CHILD(n, 3));
1273 v = newintobject(0L);
1274 if (v == NULL)
1275 c->c_errors++;
1276 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1277 XDECREF(v);
1278 begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001279 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001280 com_addfwref(c, FOR_LOOP, &anchor);
1281 com_assign(c, CHILD(n, 1), 1/*assigning*/);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001282 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001283 com_node(c, CHILD(n, 5));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001284 c->c_loops--;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001285 com_addoparg(c, JUMP_ABSOLUTE, begin);
1286 com_backpatch(c, anchor);
1287 com_addbyte(c, POP_BLOCK);
1288 if (NCH(n) > 8)
1289 com_node(c, CHILD(n, 8));
1290 com_backpatch(c, break_anchor);
1291}
1292
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001293/* Although 'execpt' and 'finally' clauses can be combined
1294 syntactically, they are compiled separately. In fact,
1295 try: S
1296 except E1: S1
1297 except E2: S2
1298 ...
1299 finally: Sf
1300 is equivalent to
1301 try:
1302 try: S
1303 except E1: S1
1304 except E2: S2
1305 ...
1306 finally: Sf
1307 meaning that the 'finally' clause is entered even if things
1308 go wrong again in an exception handler. Note that this is
1309 not the case for exception handlers: at most one is entered.
1310
1311 Code generated for "try: S finally: Sf" is as follows:
1312
1313 SETUP_FINALLY L
1314 <code for S>
1315 POP_BLOCK
1316 LOAD_CONST <nil>
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001317 L: <code for Sf>
1318 END_FINALLY
1319
1320 The special instructions use the block stack. Each block
1321 stack entry contains the instruction that created it (here
1322 SETUP_FINALLY), the level of the value stack at the time the
1323 block stack entry was created, and a label (here L).
1324
1325 SETUP_FINALLY:
1326 Pushes the current value stack level and the label
1327 onto the block stack.
1328 POP_BLOCK:
1329 Pops en entry from the block stack, and pops the value
1330 stack until its level is the same as indicated on the
1331 block stack. (The label is ignored.)
1332 END_FINALLY:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001333 Pops a variable number of entries from the *value* stack
1334 and re-raises the exception they specify. The number of
1335 entries popped depends on the (pseudo) exception type.
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001336
1337 The block stack is unwound when an exception is raised:
1338 when a SETUP_FINALLY entry is found, the exception is pushed
1339 onto the value stack (and the exception condition is cleared),
1340 and the interpreter jumps to the label gotten from the block
1341 stack.
1342
1343 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
Guido van Rossum3f5da241990-12-20 15:06:42 +00001344 (The contents of the value stack is shown in [], with the top
1345 at the right; 'tb' is trace-back info, 'val' the exception's
1346 associated value, and 'exc' the exception.)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001347
1348 Value stack Label Instruction Argument
1349 [] SETUP_EXCEPT L1
1350 [] <code for S>
1351 [] POP_BLOCK
1352 [] JUMP_FORWARD L0
1353
Guido van Rossum3f5da241990-12-20 15:06:42 +00001354 [tb, val, exc] L1: DUP )
1355 [tb, val, exc, exc] <evaluate E1> )
1356 [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
1357 [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
1358 [tb, val, exc, 1] POP )
1359 [tb, val, exc] POP
1360 [tb, val] <assign to V1> (or POP if no V1)
1361 [tb] POP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001362 [] <code for S1>
1363 JUMP_FORWARD L0
1364
Guido van Rossum3f5da241990-12-20 15:06:42 +00001365 [tb, val, exc, 0] L2: POP
1366 [tb, val, exc] DUP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001367 .............................etc.......................
1368
Guido van Rossum3f5da241990-12-20 15:06:42 +00001369 [tb, val, exc, 0] Ln+1: POP
1370 [tb, val, exc] END_FINALLY # re-raise exception
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001371
1372 [] L0: <next statement>
1373
1374 Of course, parts are not generated if Vi or Ei is not present.
1375*/
1376
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001377static void
1378com_try_stmt(c, n)
1379 struct compiling *c;
1380 node *n;
1381{
1382 int finally_anchor = 0;
1383 int except_anchor = 0;
1384 REQ(n, try_stmt);
1385 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001386
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001387 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1388 /* Have a 'finally' clause */
1389 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
1390 }
1391 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1392 /* Have an 'except' clause */
1393 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
1394 }
1395 com_node(c, CHILD(n, 2));
1396 if (except_anchor) {
1397 int end_anchor = 0;
1398 int i;
1399 node *ch;
1400 com_addbyte(c, POP_BLOCK);
1401 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1402 com_backpatch(c, except_anchor);
1403 for (i = 3;
1404 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1405 i += 3) {
1406 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001407 if (except_anchor == 0) {
1408 err_setstr(TypeError,
1409 "default 'except:' must be last");
1410 c->c_errors++;
1411 break;
1412 }
1413 except_anchor = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001414 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001415 if (NCH(ch) > 1) {
1416 com_addbyte(c, DUP_TOP);
1417 com_node(c, CHILD(ch, 1));
1418 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001419 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001420 com_addbyte(c, POP_TOP);
1421 }
1422 com_addbyte(c, POP_TOP);
1423 if (NCH(ch) > 3)
1424 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1425 else
1426 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001427 com_addbyte(c, POP_TOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001428 com_node(c, CHILD(n, i+2));
1429 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001430 if (except_anchor) {
1431 com_backpatch(c, except_anchor);
1432 com_addbyte(c, POP_TOP);
1433 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001434 }
1435 com_addbyte(c, END_FINALLY);
1436 com_backpatch(c, end_anchor);
1437 }
1438 if (finally_anchor) {
Guido van Rossum3f5da241990-12-20 15:06:42 +00001439 node *ch;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001440 com_addbyte(c, POP_BLOCK);
1441 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001442 com_backpatch(c, finally_anchor);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001443 ch = CHILD(n, NCH(n)-1);
1444 com_addoparg(c, SET_LINENO, ch->n_lineno);
1445 com_node(c, ch);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001446 com_addbyte(c, END_FINALLY);
1447 }
1448}
1449
1450static void
1451com_suite(c, n)
1452 struct compiling *c;
1453 node *n;
1454{
1455 REQ(n, suite);
1456 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1457 if (NCH(n) == 1) {
1458 com_node(c, CHILD(n, 0));
1459 }
1460 else {
1461 int i;
1462 for (i = 0; i < NCH(n); i++) {
1463 node *ch = CHILD(n, i);
1464 if (TYPE(ch) == stmt)
1465 com_node(c, ch);
1466 }
1467 }
1468}
1469
1470static void
1471com_funcdef(c, n)
1472 struct compiling *c;
1473 node *n;
1474{
1475 object *v;
1476 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001477 v = (object *)compile(n, c->c_filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +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_addopname(c, STORE_NAME, CHILD(n, 1));
1485 DECREF(v);
1486 }
1487}
1488
1489static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001490com_bases(c, n)
1491 struct compiling *c;
1492 node *n;
1493{
1494 int i, nbases;
1495 REQ(n, baselist);
1496 /*
1497 baselist: atom arguments (',' atom arguments)*
1498 arguments: '(' [testlist] ')'
1499 */
1500 for (i = 0; i < NCH(n); i += 3)
1501 com_node(c, CHILD(n, i));
1502 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1503}
1504
1505static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001506com_classdef(c, n)
1507 struct compiling *c;
1508 node *n;
1509{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001510 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001511 REQ(n, classdef);
1512 /*
1513 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1514 baselist: atom arguments (',' atom arguments)*
1515 arguments: '(' [testlist] ')'
1516 */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001517 if (NCH(n) == 7)
1518 com_bases(c, CHILD(n, 4));
1519 else
1520 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001521 v = (object *)compile(n, c->c_filename);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001522 if (v == NULL)
1523 c->c_errors++;
1524 else {
1525 int i = com_addconst(c, v);
1526 com_addoparg(c, LOAD_CONST, i);
1527 com_addbyte(c, BUILD_FUNCTION);
1528 com_addbyte(c, UNARY_CALL);
1529 com_addbyte(c, BUILD_CLASS);
1530 com_addopname(c, STORE_NAME, CHILD(n, 1));
1531 DECREF(v);
1532 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001533}
1534
1535static void
1536com_node(c, n)
1537 struct compiling *c;
1538 node *n;
1539{
1540 switch (TYPE(n)) {
1541
1542 /* Definition nodes */
1543
1544 case funcdef:
1545 com_funcdef(c, n);
1546 break;
1547 case classdef:
1548 com_classdef(c, n);
1549 break;
1550
1551 /* Trivial parse tree nodes */
1552
1553 case stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001554 case flow_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001555 com_node(c, CHILD(n, 0));
1556 break;
1557
1558 case simple_stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001559 case compound_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001560 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001561 com_node(c, CHILD(n, 0));
1562 break;
1563
1564 /* Statement nodes */
1565
1566 case expr_stmt:
1567 com_expr_stmt(c, n);
1568 break;
1569 case print_stmt:
1570 com_print_stmt(c, n);
1571 break;
1572 case del_stmt: /* 'del' exprlist NEWLINE */
1573 com_assign(c, CHILD(n, 1), 0/*delete*/);
1574 break;
1575 case pass_stmt:
1576 break;
1577 case break_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001578 if (c->c_loops == 0) {
1579 err_setstr(TypeError, "'break' outside loop");
1580 c->c_errors++;
1581 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001582 com_addbyte(c, BREAK_LOOP);
1583 break;
1584 case return_stmt:
1585 com_return_stmt(c, n);
1586 break;
1587 case raise_stmt:
1588 com_raise_stmt(c, n);
1589 break;
1590 case import_stmt:
1591 com_import_stmt(c, n);
1592 break;
1593 case if_stmt:
1594 com_if_stmt(c, n);
1595 break;
1596 case while_stmt:
1597 com_while_stmt(c, n);
1598 break;
1599 case for_stmt:
1600 com_for_stmt(c, n);
1601 break;
1602 case try_stmt:
1603 com_try_stmt(c, n);
1604 break;
1605 case suite:
1606 com_suite(c, n);
1607 break;
1608
1609 /* Expression nodes */
1610
1611 case testlist:
1612 com_list(c, n);
1613 break;
1614 case test:
1615 com_test(c, n);
1616 break;
1617 case and_test:
1618 com_and_test(c, n);
1619 break;
1620 case not_test:
1621 com_not_test(c, n);
1622 break;
1623 case comparison:
1624 com_comparison(c, n);
1625 break;
1626 case exprlist:
1627 com_list(c, n);
1628 break;
1629 case expr:
1630 com_expr(c, n);
1631 break;
1632 case term:
1633 com_term(c, n);
1634 break;
1635 case factor:
1636 com_factor(c, n);
1637 break;
1638 case atom:
1639 com_atom(c, n);
1640 break;
1641
1642 default:
1643 fprintf(stderr, "node type %d\n", TYPE(n));
1644 err_setstr(SystemError, "com_node: unexpected node type");
1645 c->c_errors++;
1646 }
1647}
1648
1649static void com_fplist PROTO((struct compiling *, node *));
1650
1651static void
1652com_fpdef(c, n)
1653 struct compiling *c;
1654 node *n;
1655{
1656 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1657 if (TYPE(CHILD(n, 0)) == LPAR)
1658 com_fplist(c, CHILD(n, 1));
1659 else
1660 com_addopname(c, STORE_NAME, CHILD(n, 0));
1661}
1662
1663static void
1664com_fplist(c, n)
1665 struct compiling *c;
1666 node *n;
1667{
1668 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1669 if (NCH(n) == 1) {
1670 com_fpdef(c, CHILD(n, 0));
1671 }
1672 else {
1673 int i;
1674 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1675 for (i = 0; i < NCH(n); i += 2)
1676 com_fpdef(c, CHILD(n, i));
1677 }
1678}
1679
1680static void
1681com_file_input(c, n)
1682 struct compiling *c;
1683 node *n;
1684{
1685 int i;
1686 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1687 for (i = 0; i < NCH(n); i++) {
1688 node *ch = CHILD(n, i);
1689 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1690 com_node(c, ch);
1691 }
1692}
1693
1694/* Top-level compile-node interface */
1695
1696static void
1697compile_funcdef(c, n)
1698 struct compiling *c;
1699 node *n;
1700{
1701 node *ch;
1702 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1703 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1704 ch = CHILD(ch, 1); /* ')' | fplist */
1705 if (TYPE(ch) == RPAR)
1706 com_addbyte(c, REFUSE_ARGS);
1707 else {
1708 com_addbyte(c, REQUIRE_ARGS);
1709 com_fplist(c, ch);
1710 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001711 c->c_infunction = 1;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001712 com_node(c, CHILD(n, 4));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001713 c->c_infunction = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001714 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1715 com_addbyte(c, RETURN_VALUE);
1716}
1717
1718static void
1719compile_node(c, n)
1720 struct compiling *c;
1721 node *n;
1722{
Guido van Rossum3f5da241990-12-20 15:06:42 +00001723 com_addoparg(c, SET_LINENO, n->n_lineno);
1724
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001725 switch (TYPE(n)) {
1726
Guido van Rossum4c417781991-01-21 16:09:22 +00001727 case single_input: /* One interactive command */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001728 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001729 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001730 n = CHILD(n, 0);
1731 if (TYPE(n) != NEWLINE)
1732 com_node(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001733 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1734 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001735 break;
1736
Guido van Rossum4c417781991-01-21 16:09:22 +00001737 case file_input: /* A whole file, or built-in function exec() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001738 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001739 com_file_input(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001740 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1741 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001742 break;
1743
Guido van Rossum4c417781991-01-21 16:09:22 +00001744 case expr_input: /* Built-in function eval() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001745 com_addbyte(c, REFUSE_ARGS);
1746 com_node(c, CHILD(n, 0));
1747 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001748 break;
1749
Guido van Rossum4c417781991-01-21 16:09:22 +00001750 case eval_input: /* Built-in function input() */
1751 com_addbyte(c, REFUSE_ARGS);
1752 com_node(c, CHILD(n, 0));
1753 com_addbyte(c, RETURN_VALUE);
1754 break;
1755
1756 case funcdef: /* A function definition */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001757 compile_funcdef(c, n);
1758 break;
1759
Guido van Rossum4c417781991-01-21 16:09:22 +00001760 case classdef: /* A class definition */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001761 /* 'class' NAME parameters ['=' baselist] ':' suite */
1762 com_addbyte(c, REFUSE_ARGS);
1763 com_node(c, CHILD(n, NCH(n)-1));
1764 com_addbyte(c, LOAD_LOCALS);
1765 com_addbyte(c, RETURN_VALUE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001766 break;
1767
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001768 default:
1769 fprintf(stderr, "node type %d\n", TYPE(n));
1770 err_setstr(SystemError, "compile_node: unexpected node type");
1771 c->c_errors++;
1772 }
1773}
1774
Guido van Rossum282914b1991-04-04 10:42:56 +00001775/* Optimization for local and global variables.
1776
1777 Attempt to replace all LOAD_NAME instructions that refer to a local
1778 variable with LOAD_LOCAL instructions, and all that refer to a global
1779 variable with LOAD_GLOBAL instructions.
1780
1781 To find all local variables, we check all STORE_NAME and IMPORT_FROM
1782 instructions. This yields all local variables, including arguments,
1783 function definitions, class definitions and import statements.
1784
1785 There is one leak: 'from foo import *' introduces local variables
1786 that we can't know while compiling. If this is the case, LOAD_GLOBAL
1787 instructions are not generated -- LOAD_NAME is left in place for
1788 globals, since it first checks for globals (LOAD_LOCAL is still used
1789 for recognized locals, since it doesn't hurt).
1790
1791 This optimization means that using the same name as a global and
1792 as a local variable within the same scope is now illegal, which
1793 is a change to the language! Also using eval() to introduce new
1794 local variables won't work. But both were bad practice at best.
1795
1796 The optimization doesn't save much: basically, it saves one
1797 unsuccessful dictionary lookup per global (or built-in) variable
1798 reference. On the (slow!) Mac Plus, with 4 local variables,
1799 this saving was measured to be about 0.18 ms. We might save more
1800 by using a different data structure to hold local variables, like
1801 an array indexed by variable number.
1802
1803 NB: this modifies the string object co->co_code!
1804*/
1805
1806static void
1807optimizer(co)
1808 codeobject *co;
1809{
Guido van Rossum0a697f61991-04-16 08:39:12 +00001810 unsigned char *next_instr, *cur_instr;
Guido van Rossum282914b1991-04-04 10:42:56 +00001811 object *locals;
1812 int opcode;
1813 int oparg;
1814 object *name;
1815 int star_used;
Guido van Rossum0a697f61991-04-16 08:39:12 +00001816
Guido van Rossum282914b1991-04-04 10:42:56 +00001817#define NEXTOP() (*next_instr++)
1818#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
1819#define GETITEM(v, i) (getlistitem((v), (i)))
1820#define GETNAMEOBJ(i) (GETITEM(co->co_names, (i)))
1821
1822 locals = newdictobject();
1823 if (locals == NULL) {
1824 err_clear();
1825 return; /* For now, this is OK */
1826 }
1827
Guido van Rossum0a697f61991-04-16 08:39:12 +00001828 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00001829 for (;;) {
1830 opcode = NEXTOP();
1831 if (opcode == STOP_CODE)
1832 break;
1833 if (HAS_ARG(opcode))
1834 oparg = NEXTARG();
1835 if (opcode == STORE_NAME || opcode == IMPORT_FROM) {
1836 name = GETNAMEOBJ(oparg);
1837 if (dict2insert(locals, name, None) != 0) {
1838 DECREF(locals);
1839 return; /* Sorry */
1840 }
1841 }
1842 }
1843
1844 star_used = (dictlookup(locals, "*") != NULL);
Guido van Rossum0a697f61991-04-16 08:39:12 +00001845 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00001846 for (;;) {
1847 cur_instr = next_instr;
1848 opcode = NEXTOP();
1849 if (opcode == STOP_CODE)
1850 break;
1851 if (HAS_ARG(opcode))
1852 oparg = NEXTARG();
1853 if (opcode == LOAD_NAME) {
1854 name = GETNAMEOBJ(oparg);
1855 if (dictlookup(locals, getstringvalue(name)) != NULL)
1856 *cur_instr = LOAD_LOCAL;
1857 else if (!star_used)
1858 *cur_instr = LOAD_GLOBAL;
1859 }
1860 }
1861
1862 DECREF(locals);
1863}
1864
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001865codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001866compile(n, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001867 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001868 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001869{
1870 struct compiling sc;
1871 codeobject *co;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001872 if (!com_init(&sc, filename))
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001873 return NULL;
1874 compile_node(&sc, n);
1875 com_done(&sc);
1876 if (sc.c_errors == 0)
Guido van Rossum3f5da241990-12-20 15:06:42 +00001877 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names, filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001878 else
1879 co = NULL;
1880 com_free(&sc);
Guido van Rossumfb8edfc1991-05-14 11:56:03 +00001881 if (co != NULL && filename[0] != '<')
Guido van Rossum282914b1991-04-04 10:42:56 +00001882 optimizer(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001883 return co;
1884}