blob: 59391968e6bda7b3a42dc13e7661e8b9e3ff8a31 [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 Rossuma082ce41991-06-04 19:41:56 +000092codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +000093newcodeobject(code, consts, names, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +000094 object *code;
95 object *consts;
96 object *names;
Guido van Rossuma082ce41991-06-04 19:41:56 +000097 object *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +000098{
99 codeobject *co;
100 int i;
101 /* Check argument types */
102 if (code == NULL || !is_stringobject(code) ||
103 consts == NULL || !is_listobject(consts) ||
104 names == NULL || !is_listobject(names)) {
105 err_badcall();
106 return NULL;
107 }
108 /* Make sure the list of names contains only strings */
109 for (i = getlistsize(names); --i >= 0; ) {
110 object *v = getlistitem(names, i);
111 if (v == NULL || !is_stringobject(v)) {
112 err_badcall();
113 return NULL;
114 }
115 }
116 co = NEWOBJ(codeobject, &Codetype);
117 if (co != NULL) {
118 INCREF(code);
119 co->co_code = (stringobject *)code;
120 INCREF(consts);
121 co->co_consts = consts;
122 INCREF(names);
123 co->co_names = names;
Guido van Rossuma082ce41991-06-04 19:41:56 +0000124 INCREF(filename);
125 co->co_filename = filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000126 }
127 return co;
128}
129
130
131/* Data structure used internally */
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000132
133#define MAXBLOCKS 20 /* Max static block nesting within a function */
134
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000135struct compiling {
136 object *c_code; /* string */
137 object *c_consts; /* list of objects */
138 object *c_names; /* list of strings (names) */
139 int c_nexti; /* index into c_code */
140 int c_errors; /* counts errors occurred */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000141 int c_infunction; /* set when compiling a function */
142 int c_loops; /* counts nested loops */
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000143 int c_begin; /* begin of current loop, for 'continue' */
144 int c_block[MAXBLOCKS]; /* stack of block types */
145 int c_nblocks; /* current block stack level */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000146 char *c_filename; /* filename of current node */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000147};
148
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000149
150/* Interface to the block stack */
151
152static void
153block_push(c, type)
154 struct compiling *c;
155 int type;
156{
157 if (c->c_nblocks >= MAXBLOCKS) {
158 err_setstr(TypeError, "too many statically nested blocks");
159 c->c_errors++;
160 }
161 else {
162 c->c_block[c->c_nblocks++] = type;
163 }
164}
165
166static void
167block_pop(c, type)
168 struct compiling *c;
169 int type;
170{
171 if (c->c_nblocks > 0)
172 c->c_nblocks--;
173 if (c->c_block[c->c_nblocks] != type && c->c_errors == 0) {
174 err_setstr(SystemError, "bad block pop");
175 c->c_errors++;
176 }
177}
178
179
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000180/* Prototypes */
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000181
Guido van Rossum3f5da241990-12-20 15:06:42 +0000182static int com_init PROTO((struct compiling *, char *));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000183static void com_free PROTO((struct compiling *));
184static void com_done PROTO((struct compiling *));
185static void com_node PROTO((struct compiling *, struct _node *));
186static void com_addbyte PROTO((struct compiling *, int));
187static void com_addint PROTO((struct compiling *, int));
188static void com_addoparg PROTO((struct compiling *, int, int));
189static void com_addfwref PROTO((struct compiling *, int, int *));
190static void com_backpatch PROTO((struct compiling *, int));
191static int com_add PROTO((struct compiling *, object *, object *));
192static int com_addconst PROTO((struct compiling *, object *));
193static int com_addname PROTO((struct compiling *, object *));
194static void com_addopname PROTO((struct compiling *, int, node *));
195
196static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000197com_init(c, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000198 struct compiling *c;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000199 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000200{
Guido van Rossum62d46241991-04-03 19:00:23 +0000201 if ((c->c_code = newsizedstringobject((char *)NULL, 1000)) == NULL)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000202 goto fail_3;
203 if ((c->c_consts = newlistobject(0)) == NULL)
204 goto fail_2;
205 if ((c->c_names = newlistobject(0)) == NULL)
206 goto fail_1;
207 c->c_nexti = 0;
208 c->c_errors = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000209 c->c_infunction = 0;
210 c->c_loops = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000211 c->c_begin = 0;
212 c->c_nblocks = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000213 c->c_filename = filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000214 return 1;
215
216 fail_1:
217 DECREF(c->c_consts);
218 fail_2:
219 DECREF(c->c_code);
220 fail_3:
221 return 0;
222}
223
224static void
225com_free(c)
226 struct compiling *c;
227{
228 XDECREF(c->c_code);
229 XDECREF(c->c_consts);
230 XDECREF(c->c_names);
231}
232
233static void
234com_done(c)
235 struct compiling *c;
236{
237 if (c->c_code != NULL)
238 resizestring(&c->c_code, c->c_nexti);
239}
240
241static void
242com_addbyte(c, byte)
243 struct compiling *c;
244 int byte;
245{
246 int len;
247 if (byte < 0 || byte > 255) {
Guido van Rossum01cfd441991-10-20 20:12:38 +0000248 /*
Guido van Rossum3f5da241990-12-20 15:06:42 +0000249 fprintf(stderr, "XXX compiling bad byte: %d\n", byte);
250 abort();
Guido van Rossum01cfd441991-10-20 20:12:38 +0000251 */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000252 err_setstr(SystemError, "com_addbyte: byte out of range");
253 c->c_errors++;
254 }
255 if (c->c_code == NULL)
256 return;
257 len = getstringsize(c->c_code);
258 if (c->c_nexti >= len) {
259 if (resizestring(&c->c_code, len+1000) != 0) {
260 c->c_errors++;
261 return;
262 }
263 }
264 getstringvalue(c->c_code)[c->c_nexti++] = byte;
265}
266
267static void
268com_addint(c, x)
269 struct compiling *c;
270 int x;
271{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000272 com_addbyte(c, x & 0xff);
273 com_addbyte(c, x >> 8); /* XXX x should be positive */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000274}
275
276static void
277com_addoparg(c, op, arg)
278 struct compiling *c;
279 int op;
280 int arg;
281{
282 com_addbyte(c, op);
283 com_addint(c, arg);
284}
285
286static void
287com_addfwref(c, op, p_anchor)
288 struct compiling *c;
289 int op;
290 int *p_anchor;
291{
292 /* Compile a forward reference for backpatching */
293 int here;
294 int anchor;
295 com_addbyte(c, op);
296 here = c->c_nexti;
297 anchor = *p_anchor;
298 *p_anchor = here;
299 com_addint(c, anchor == 0 ? 0 : here - anchor);
300}
301
302static void
303com_backpatch(c, anchor)
304 struct compiling *c;
305 int anchor; /* Must be nonzero */
306{
307 unsigned char *code = (unsigned char *) getstringvalue(c->c_code);
308 int target = c->c_nexti;
309 int lastanchor = 0;
310 int dist;
311 int prev;
312 for (;;) {
313 /* Make the JUMP instruction at anchor point to target */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000314 prev = code[anchor] + (code[anchor+1] << 8);
315 dist = target - (anchor+2);
316 code[anchor] = dist & 0xff;
317 code[anchor+1] = dist >> 8;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000318 if (!prev)
319 break;
320 lastanchor = anchor;
321 anchor -= prev;
322 }
323}
324
325/* Handle constants and names uniformly */
326
327static int
328com_add(c, list, v)
329 struct compiling *c;
330 object *list;
331 object *v;
332{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000333 int n = getlistsize(list);
334 int i;
335 for (i = n; --i >= 0; ) {
336 object *w = getlistitem(list, i);
Guido van Rossumefc0bd01991-07-01 18:44:20 +0000337 if (v->ob_type == w->ob_type && cmpobject(v, w) == 0)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000338 return i;
339 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000340 if (addlistitem(list, v) != 0)
341 c->c_errors++;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000342 return n;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000343}
344
345static int
346com_addconst(c, v)
347 struct compiling *c;
348 object *v;
349{
350 return com_add(c, c->c_consts, v);
351}
352
353static int
354com_addname(c, v)
355 struct compiling *c;
356 object *v;
357{
358 return com_add(c, c->c_names, v);
359}
360
361static void
362com_addopname(c, op, n)
363 struct compiling *c;
364 int op;
365 node *n;
366{
367 object *v;
368 int i;
369 char *name;
370 if (TYPE(n) == STAR)
371 name = "*";
372 else {
373 REQ(n, NAME);
374 name = STR(n);
375 }
376 if ((v = newstringobject(name)) == NULL) {
377 c->c_errors++;
378 i = 255;
379 }
380 else {
381 i = com_addname(c, v);
382 DECREF(v);
383 }
384 com_addoparg(c, op, i);
385}
386
387static object *
388parsenumber(s)
389 char *s;
390{
391 extern long strtol();
Guido van Rossum282914b1991-04-04 10:42:56 +0000392 extern double strtod();
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000393 char *end = s;
394 long x;
Guido van Rossum282914b1991-04-04 10:42:56 +0000395 double xx;
396 errno = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000397 x = strtol(s, &end, 0);
Guido van Rossum282914b1991-04-04 10:42:56 +0000398 if (*end == '\0') {
399 if (errno != 0) {
400 err_setstr(RuntimeError, "integer constant too large");
401 return NULL;
402 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000403 return newintobject(x);
Guido van Rossum282914b1991-04-04 10:42:56 +0000404 }
Guido van Rossume3a204f1991-05-05 20:05:35 +0000405 if (*end == 'l' || *end == 'L') {
406 extern object *long_scan();
407 return long_scan(s, 0);
408 }
Guido van Rossum282914b1991-04-04 10:42:56 +0000409 errno = 0;
410 xx = strtod(s, &end);
411 if (*end == '\0') {
412 if (errno != 0) {
413 err_setstr(RuntimeError, "float constant too large");
414 return NULL;
415 }
416 return newfloatobject(xx);
417 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000418 err_setstr(RuntimeError, "bad number syntax");
419 return NULL;
420}
421
422static object *
423parsestr(s)
424 char *s;
425{
426 object *v;
427 int len;
428 char *buf;
429 char *p;
430 int c;
431 if (*s != '\'') {
432 err_badcall();
433 return NULL;
434 }
435 s++;
436 len = strlen(s);
437 if (s[--len] != '\'') {
438 err_badcall();
439 return NULL;
440 }
441 if (strchr(s, '\\') == NULL)
442 return newsizedstringobject(s, len);
443 v = newsizedstringobject((char *)NULL, len);
444 p = buf = getstringvalue(v);
445 while (*s != '\0' && *s != '\'') {
446 if (*s != '\\') {
447 *p++ = *s++;
448 continue;
449 }
450 s++;
451 switch (*s++) {
452 /* XXX This assumes ASCII! */
453 case '\\': *p++ = '\\'; break;
454 case '\'': *p++ = '\''; break;
455 case 'b': *p++ = '\b'; break;
456 case 'f': *p++ = '\014'; break; /* FF */
457 case 't': *p++ = '\t'; break;
458 case 'n': *p++ = '\n'; break;
459 case 'r': *p++ = '\r'; break;
460 case 'v': *p++ = '\013'; break; /* VT */
461 case 'E': *p++ = '\033'; break; /* ESC, not C */
462 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
463 case '0': case '1': case '2': case '3':
464 case '4': case '5': case '6': case '7':
465 c = s[-1] - '0';
466 if ('0' <= *s && *s <= '7') {
467 c = (c<<3) + *s++ - '0';
468 if ('0' <= *s && *s <= '7')
469 c = (c<<3) + *s++ - '0';
470 }
471 *p++ = c;
472 break;
473 case 'x':
474 if (isxdigit(*s)) {
475 sscanf(s, "%x", &c);
476 *p++ = c;
477 do {
478 s++;
479 } while (isxdigit(*s));
480 break;
481 }
482 /* FALLTHROUGH */
483 default: *p++ = '\\'; *p++ = s[-1]; break;
484 }
485 }
486 resizestring(&v, (int)(p - buf));
487 return v;
488}
489
490static void
491com_list_constructor(c, n)
492 struct compiling *c;
493 node *n;
494{
495 int len;
496 int i;
497 object *v, *w;
498 if (TYPE(n) != testlist)
499 REQ(n, exprlist);
500 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
501 len = (NCH(n) + 1) / 2;
502 for (i = 0; i < NCH(n); i += 2)
503 com_node(c, CHILD(n, i));
504 com_addoparg(c, BUILD_LIST, len);
505}
506
507static void
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000508com_dictmaker(c, n)
509 struct compiling *c;
510 node *n;
511{
512 int i;
513 /* dictmaker: test ':' test (',' test ':' value)* [','] */
514 for (i = 0; i+2 < NCH(n); i += 4) {
515 /* We must arrange things just right for STORE_SUBSCR.
516 It wants the stack to look like (value) (dict) (key) */
517 com_addbyte(c, DUP_TOP);
518 com_node(c, CHILD(n, i+2)); /* value */
519 com_addbyte(c, ROT_TWO);
520 com_node(c, CHILD(n, i)); /* key */
521 com_addbyte(c, STORE_SUBSCR);
522 }
523}
524
525static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000526com_atom(c, n)
527 struct compiling *c;
528 node *n;
529{
530 node *ch;
531 object *v;
532 int i;
533 REQ(n, atom);
534 ch = CHILD(n, 0);
535 switch (TYPE(ch)) {
536 case LPAR:
537 if (TYPE(CHILD(n, 1)) == RPAR)
538 com_addoparg(c, BUILD_TUPLE, 0);
539 else
540 com_node(c, CHILD(n, 1));
541 break;
542 case LSQB:
543 if (TYPE(CHILD(n, 1)) == RSQB)
544 com_addoparg(c, BUILD_LIST, 0);
545 else
546 com_list_constructor(c, CHILD(n, 1));
547 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000548 case LBRACE: /* '{' [dictmaker] '}' */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000549 com_addoparg(c, BUILD_MAP, 0);
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000550 if (TYPE(CHILD(n, 1)) != RBRACE)
551 com_dictmaker(c, CHILD(n, 1));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000552 break;
553 case BACKQUOTE:
554 com_node(c, CHILD(n, 1));
555 com_addbyte(c, UNARY_CONVERT);
556 break;
557 case NUMBER:
558 if ((v = parsenumber(STR(ch))) == NULL) {
559 c->c_errors++;
560 i = 255;
561 }
562 else {
563 i = com_addconst(c, v);
564 DECREF(v);
565 }
566 com_addoparg(c, LOAD_CONST, i);
567 break;
568 case STRING:
569 if ((v = parsestr(STR(ch))) == NULL) {
570 c->c_errors++;
571 i = 255;
572 }
573 else {
574 i = com_addconst(c, v);
575 DECREF(v);
576 }
577 com_addoparg(c, LOAD_CONST, i);
578 break;
579 case NAME:
580 com_addopname(c, LOAD_NAME, ch);
581 break;
582 default:
583 fprintf(stderr, "node type %d\n", TYPE(ch));
584 err_setstr(SystemError, "com_atom: unexpected node type");
585 c->c_errors++;
586 }
587}
588
589static void
590com_slice(c, n, op)
591 struct compiling *c;
592 node *n;
593 int op;
594{
595 if (NCH(n) == 1) {
596 com_addbyte(c, op);
597 }
598 else if (NCH(n) == 2) {
599 if (TYPE(CHILD(n, 0)) != COLON) {
600 com_node(c, CHILD(n, 0));
601 com_addbyte(c, op+1);
602 }
603 else {
604 com_node(c, CHILD(n, 1));
605 com_addbyte(c, op+2);
606 }
607 }
608 else {
609 com_node(c, CHILD(n, 0));
610 com_node(c, CHILD(n, 2));
611 com_addbyte(c, op+3);
612 }
613}
614
615static void
616com_apply_subscript(c, n)
617 struct compiling *c;
618 node *n;
619{
620 REQ(n, subscript);
621 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
622 /* It's a single subscript */
623 com_node(c, CHILD(n, 0));
624 com_addbyte(c, BINARY_SUBSCR);
625 }
626 else {
627 /* It's a slice: [expr] ':' [expr] */
628 com_slice(c, n, SLICE);
629 }
630}
631
632static void
633com_call_function(c, n)
634 struct compiling *c;
635 node *n; /* EITHER testlist OR ')' */
636{
637 if (TYPE(n) == RPAR) {
638 com_addbyte(c, UNARY_CALL);
639 }
640 else {
641 com_node(c, n);
642 com_addbyte(c, BINARY_CALL);
643 }
644}
645
646static void
647com_select_member(c, n)
648 struct compiling *c;
649 node *n;
650{
651 com_addopname(c, LOAD_ATTR, n);
652}
653
654static void
655com_apply_trailer(c, n)
656 struct compiling *c;
657 node *n;
658{
659 REQ(n, trailer);
660 switch (TYPE(CHILD(n, 0))) {
661 case LPAR:
662 com_call_function(c, CHILD(n, 1));
663 break;
664 case DOT:
665 com_select_member(c, CHILD(n, 1));
666 break;
667 case LSQB:
668 com_apply_subscript(c, CHILD(n, 1));
669 break;
670 default:
671 err_setstr(SystemError,
672 "com_apply_trailer: unknown trailer type");
673 c->c_errors++;
674 }
675}
676
677static void
678com_factor(c, n)
679 struct compiling *c;
680 node *n;
681{
682 int i;
683 REQ(n, factor);
684 if (TYPE(CHILD(n, 0)) == PLUS) {
685 com_factor(c, CHILD(n, 1));
686 com_addbyte(c, UNARY_POSITIVE);
687 }
688 else if (TYPE(CHILD(n, 0)) == MINUS) {
689 com_factor(c, CHILD(n, 1));
690 com_addbyte(c, UNARY_NEGATIVE);
691 }
692 else {
693 com_atom(c, CHILD(n, 0));
694 for (i = 1; i < NCH(n); i++)
695 com_apply_trailer(c, CHILD(n, i));
696 }
697}
698
699static void
700com_term(c, n)
701 struct compiling *c;
702 node *n;
703{
704 int i;
705 int op;
706 REQ(n, term);
707 com_factor(c, CHILD(n, 0));
708 for (i = 2; i < NCH(n); i += 2) {
709 com_factor(c, CHILD(n, i));
710 switch (TYPE(CHILD(n, i-1))) {
711 case STAR:
712 op = BINARY_MULTIPLY;
713 break;
714 case SLASH:
715 op = BINARY_DIVIDE;
716 break;
717 case PERCENT:
718 op = BINARY_MODULO;
719 break;
720 default:
721 err_setstr(SystemError,
722 "com_term: term operator not *, / or %");
723 c->c_errors++;
724 op = 255;
725 }
726 com_addbyte(c, op);
727 }
728}
729
730static void
731com_expr(c, n)
732 struct compiling *c;
733 node *n;
734{
735 int i;
736 int op;
737 REQ(n, expr);
738 com_term(c, CHILD(n, 0));
739 for (i = 2; i < NCH(n); i += 2) {
740 com_term(c, CHILD(n, i));
741 switch (TYPE(CHILD(n, i-1))) {
742 case PLUS:
743 op = BINARY_ADD;
744 break;
745 case MINUS:
746 op = BINARY_SUBTRACT;
747 break;
748 default:
749 err_setstr(SystemError,
750 "com_expr: expr operator not + or -");
751 c->c_errors++;
752 op = 255;
753 }
754 com_addbyte(c, op);
755 }
756}
757
758static enum cmp_op
759cmp_type(n)
760 node *n;
761{
762 REQ(n, comp_op);
Guido van Rossum01cfd441991-10-20 20:12:38 +0000763 /* comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000764 | 'in' | 'not' 'in' | 'is' | 'is' not' */
765 if (NCH(n) == 1) {
766 n = CHILD(n, 0);
767 switch (TYPE(n)) {
768 case LESS: return LT;
769 case GREATER: return GT;
Guido van Rossum01cfd441991-10-20 20:12:38 +0000770 case EQEQUAL: /* == */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000771 case EQUAL: return EQ;
Guido van Rossum01cfd441991-10-20 20:12:38 +0000772 case LESSEQUAL: return LE;
773 case GREATEREQUAL: return GE;
774 case NOTEQUAL: return NE; /* <> or != */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000775 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
776 if (strcmp(STR(n), "is") == 0) return IS;
777 }
778 }
779 else if (NCH(n) == 2) {
780 int t2 = TYPE(CHILD(n, 1));
781 switch (TYPE(CHILD(n, 0))) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000782 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
783 return NOT_IN;
784 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
785 return IS_NOT;
786 }
787 }
788 return BAD;
789}
790
791static void
792com_comparison(c, n)
793 struct compiling *c;
794 node *n;
795{
796 int i;
797 enum cmp_op op;
798 int anchor;
799 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
800 com_expr(c, CHILD(n, 0));
801 if (NCH(n) == 1)
802 return;
803
804 /****************************************************************
805 The following code is generated for all but the last
806 comparison in a chain:
807
808 label: on stack: opcode: jump to:
809
810 a <code to load b>
811 a, b DUP_TOP
812 a, b, b ROT_THREE
813 b, a, b COMPARE_OP
814 b, 0-or-1 JUMP_IF_FALSE L1
815 b, 1 POP_TOP
816 b
817
818 We are now ready to repeat this sequence for the next
819 comparison in the chain.
820
821 For the last we generate:
822
823 b <code to load c>
824 b, c COMPARE_OP
825 0-or-1
826
827 If there were any jumps to L1 (i.e., there was more than one
828 comparison), we generate:
829
830 0-or-1 JUMP_FORWARD L2
831 L1: b, 0 ROT_TWO
832 0, b POP_TOP
833 0
834 L2:
835 ****************************************************************/
836
837 anchor = 0;
838
839 for (i = 2; i < NCH(n); i += 2) {
840 com_expr(c, CHILD(n, i));
841 if (i+2 < NCH(n)) {
842 com_addbyte(c, DUP_TOP);
843 com_addbyte(c, ROT_THREE);
844 }
845 op = cmp_type(CHILD(n, i-1));
846 if (op == BAD) {
847 err_setstr(SystemError,
848 "com_comparison: unknown comparison op");
849 c->c_errors++;
850 }
851 com_addoparg(c, COMPARE_OP, op);
852 if (i+2 < NCH(n)) {
853 com_addfwref(c, JUMP_IF_FALSE, &anchor);
854 com_addbyte(c, POP_TOP);
855 }
856 }
857
858 if (anchor) {
859 int anchor2 = 0;
860 com_addfwref(c, JUMP_FORWARD, &anchor2);
861 com_backpatch(c, anchor);
862 com_addbyte(c, ROT_TWO);
863 com_addbyte(c, POP_TOP);
864 com_backpatch(c, anchor2);
865 }
866}
867
868static void
869com_not_test(c, n)
870 struct compiling *c;
871 node *n;
872{
873 REQ(n, not_test); /* 'not' not_test | comparison */
874 if (NCH(n) == 1) {
875 com_comparison(c, CHILD(n, 0));
876 }
877 else {
878 com_not_test(c, CHILD(n, 1));
879 com_addbyte(c, UNARY_NOT);
880 }
881}
882
883static void
884com_and_test(c, n)
885 struct compiling *c;
886 node *n;
887{
888 int i;
889 int anchor;
890 REQ(n, and_test); /* not_test ('and' not_test)* */
891 anchor = 0;
892 i = 0;
893 for (;;) {
894 com_not_test(c, CHILD(n, i));
895 if ((i += 2) >= NCH(n))
896 break;
897 com_addfwref(c, JUMP_IF_FALSE, &anchor);
898 com_addbyte(c, POP_TOP);
899 }
900 if (anchor)
901 com_backpatch(c, anchor);
902}
903
904static void
905com_test(c, n)
906 struct compiling *c;
907 node *n;
908{
909 int i;
910 int anchor;
911 REQ(n, test); /* and_test ('and' and_test)* */
912 anchor = 0;
913 i = 0;
914 for (;;) {
915 com_and_test(c, CHILD(n, i));
916 if ((i += 2) >= NCH(n))
917 break;
918 com_addfwref(c, JUMP_IF_TRUE, &anchor);
919 com_addbyte(c, POP_TOP);
920 }
921 if (anchor)
922 com_backpatch(c, anchor);
923}
924
925static void
926com_list(c, n)
927 struct compiling *c;
928 node *n;
929{
930 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
931 if (NCH(n) == 1) {
932 com_node(c, CHILD(n, 0));
933 }
934 else {
935 int i;
936 int len;
937 len = (NCH(n) + 1) / 2;
938 for (i = 0; i < NCH(n); i += 2)
939 com_node(c, CHILD(n, i));
940 com_addoparg(c, BUILD_TUPLE, len);
941 }
942}
943
944
945/* Begin of assignment compilation */
946
947static void com_assign_name PROTO((struct compiling *, node *, int));
948static void com_assign PROTO((struct compiling *, node *, int));
949
950static void
951com_assign_attr(c, n, assigning)
952 struct compiling *c;
953 node *n;
954 int assigning;
955{
956 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
957}
958
959static void
960com_assign_slice(c, n, assigning)
961 struct compiling *c;
962 node *n;
963 int assigning;
964{
965 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
966}
967
968static void
969com_assign_subscript(c, n, assigning)
970 struct compiling *c;
971 node *n;
972 int assigning;
973{
974 com_node(c, n);
975 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
976}
977
978static void
979com_assign_trailer(c, n, assigning)
980 struct compiling *c;
981 node *n;
982 int assigning;
983{
984 char *name;
985 REQ(n, trailer);
986 switch (TYPE(CHILD(n, 0))) {
987 case LPAR: /* '(' [exprlist] ')' */
988 err_setstr(TypeError, "can't assign to function call");
989 c->c_errors++;
990 break;
991 case DOT: /* '.' NAME */
992 com_assign_attr(c, CHILD(n, 1), assigning);
993 break;
994 case LSQB: /* '[' subscript ']' */
995 n = CHILD(n, 1);
996 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
997 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
998 com_assign_slice(c, n, assigning);
999 else
1000 com_assign_subscript(c, CHILD(n, 0), assigning);
1001 break;
1002 default:
1003 err_setstr(TypeError, "unknown trailer type");
1004 c->c_errors++;
1005 }
1006}
1007
1008static void
1009com_assign_tuple(c, n, assigning)
1010 struct compiling *c;
1011 node *n;
1012 int assigning;
1013{
1014 int i;
1015 if (TYPE(n) != testlist)
1016 REQ(n, exprlist);
1017 if (assigning)
1018 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1019 for (i = 0; i < NCH(n); i += 2)
1020 com_assign(c, CHILD(n, i), assigning);
1021}
1022
1023static void
1024com_assign_list(c, n, assigning)
1025 struct compiling *c;
1026 node *n;
1027 int assigning;
1028{
1029 int i;
1030 if (assigning)
1031 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
1032 for (i = 0; i < NCH(n); i += 2)
1033 com_assign(c, CHILD(n, i), assigning);
1034}
1035
1036static void
1037com_assign_name(c, n, assigning)
1038 struct compiling *c;
1039 node *n;
1040 int assigning;
1041{
1042 REQ(n, NAME);
1043 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
1044}
1045
1046static void
1047com_assign(c, n, assigning)
1048 struct compiling *c;
1049 node *n;
1050 int assigning;
1051{
1052 /* Loop to avoid trivial recursion */
1053 for (;;) {
1054 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001055
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001056 case exprlist:
1057 case testlist:
1058 if (NCH(n) > 1) {
1059 com_assign_tuple(c, n, assigning);
1060 return;
1061 }
1062 n = CHILD(n, 0);
1063 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001064
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001065 case test:
1066 case and_test:
1067 case not_test:
1068 if (NCH(n) > 1) {
1069 err_setstr(TypeError,
1070 "can't assign to operator");
1071 c->c_errors++;
1072 return;
1073 }
1074 n = CHILD(n, 0);
1075 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001076
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001077 case comparison:
1078 if (NCH(n) > 1) {
1079 err_setstr(TypeError,
1080 "can't assign to operator");
1081 c->c_errors++;
1082 return;
1083 }
1084 n = CHILD(n, 0);
1085 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001086
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001087 case expr:
1088 if (NCH(n) > 1) {
1089 err_setstr(TypeError,
1090 "can't assign to operator");
1091 c->c_errors++;
1092 return;
1093 }
1094 n = CHILD(n, 0);
1095 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001096
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001097 case term:
1098 if (NCH(n) > 1) {
1099 err_setstr(TypeError,
1100 "can't assign to operator");
1101 c->c_errors++;
1102 return;
1103 }
1104 n = CHILD(n, 0);
1105 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001106
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001107 case factor: /* ('+'|'-') factor | atom trailer* */
1108 if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
1109 err_setstr(TypeError,
1110 "can't assign to operator");
1111 c->c_errors++;
1112 return;
1113 }
1114 if (NCH(n) > 1) { /* trailer present */
1115 int i;
1116 com_node(c, CHILD(n, 0));
1117 for (i = 1; i+1 < NCH(n); i++) {
1118 com_apply_trailer(c, CHILD(n, i));
1119 } /* NB i is still alive */
1120 com_assign_trailer(c,
1121 CHILD(n, i), assigning);
1122 return;
1123 }
1124 n = CHILD(n, 0);
1125 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001126
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001127 case atom:
1128 switch (TYPE(CHILD(n, 0))) {
1129 case LPAR:
1130 n = CHILD(n, 1);
1131 if (TYPE(n) == RPAR) {
1132 /* XXX Should allow () = () ??? */
1133 err_setstr(TypeError,
1134 "can't assign to ()");
1135 c->c_errors++;
1136 return;
1137 }
1138 break;
1139 case LSQB:
1140 n = CHILD(n, 1);
1141 if (TYPE(n) == RSQB) {
1142 err_setstr(TypeError,
1143 "can't assign to []");
1144 c->c_errors++;
1145 return;
1146 }
1147 com_assign_list(c, n, assigning);
1148 return;
1149 case NAME:
1150 com_assign_name(c, CHILD(n, 0), assigning);
1151 return;
1152 default:
1153 err_setstr(TypeError,
1154 "can't assign to constant");
1155 c->c_errors++;
1156 return;
1157 }
1158 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001159
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001160 default:
1161 fprintf(stderr, "node type %d\n", TYPE(n));
1162 err_setstr(SystemError, "com_assign: bad node");
1163 c->c_errors++;
1164 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001165
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001166 }
1167 }
1168}
1169
1170static void
1171com_expr_stmt(c, n)
1172 struct compiling *c;
1173 node *n;
1174{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001175 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* */
1176 com_node(c, CHILD(n, NCH(n)-1));
1177 if (NCH(n) == 1) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001178 com_addbyte(c, PRINT_EXPR);
1179 }
1180 else {
1181 int i;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001182 for (i = 0; i < NCH(n)-2; i+=2) {
1183 if (i+2 < NCH(n)-2)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001184 com_addbyte(c, DUP_TOP);
1185 com_assign(c, CHILD(n, i), 1/*assign*/);
1186 }
1187 }
1188}
1189
1190static void
1191com_print_stmt(c, n)
1192 struct compiling *c;
1193 node *n;
1194{
1195 int i;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001196 REQ(n, print_stmt); /* 'print' (test ',')* [test] */
1197 for (i = 1; i < NCH(n); i += 2) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001198 com_node(c, CHILD(n, i));
1199 com_addbyte(c, PRINT_ITEM);
1200 }
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001201 if (TYPE(CHILD(n, NCH(n)-1)) != COMMA)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001202 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001203 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001204}
1205
1206static void
1207com_return_stmt(c, n)
1208 struct compiling *c;
1209 node *n;
1210{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001211 REQ(n, return_stmt); /* 'return' [testlist] */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001212 if (!c->c_infunction) {
1213 err_setstr(TypeError, "'return' outside function");
1214 c->c_errors++;
1215 }
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001216 if (NCH(n) < 2)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001217 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1218 else
1219 com_node(c, CHILD(n, 1));
1220 com_addbyte(c, RETURN_VALUE);
1221}
1222
1223static void
1224com_raise_stmt(c, n)
1225 struct compiling *c;
1226 node *n;
1227{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001228 REQ(n, raise_stmt); /* 'raise' test [',' test] */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001229 com_node(c, CHILD(n, 1));
1230 if (NCH(n) > 3)
1231 com_node(c, CHILD(n, 3));
1232 else
1233 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1234 com_addbyte(c, RAISE_EXCEPTION);
1235}
1236
1237static void
1238com_import_stmt(c, n)
1239 struct compiling *c;
1240 node *n;
1241{
1242 int i;
1243 REQ(n, import_stmt);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001244 /* 'import' NAME (',' NAME)* |
1245 'from' NAME 'import' ('*' | NAME (',' NAME)*) */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001246 if (STR(CHILD(n, 0))[0] == 'f') {
1247 /* 'from' NAME 'import' ... */
1248 REQ(CHILD(n, 1), NAME);
1249 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1250 for (i = 3; i < NCH(n); i += 2)
1251 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1252 com_addbyte(c, POP_TOP);
1253 }
1254 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001255 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001256 for (i = 1; i < NCH(n); i += 2) {
1257 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1258 com_addopname(c, STORE_NAME, CHILD(n, i));
1259 }
1260 }
1261}
1262
1263static void
1264com_if_stmt(c, n)
1265 struct compiling *c;
1266 node *n;
1267{
1268 int i;
1269 int anchor = 0;
1270 REQ(n, if_stmt);
1271 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1272 for (i = 0; i+3 < NCH(n); i+=4) {
1273 int a = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001274 node *ch = CHILD(n, i+1);
1275 if (i > 0)
1276 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001277 com_node(c, CHILD(n, i+1));
1278 com_addfwref(c, JUMP_IF_FALSE, &a);
1279 com_addbyte(c, POP_TOP);
1280 com_node(c, CHILD(n, i+3));
1281 com_addfwref(c, JUMP_FORWARD, &anchor);
1282 com_backpatch(c, a);
1283 com_addbyte(c, POP_TOP);
1284 }
1285 if (i+2 < NCH(n))
1286 com_node(c, CHILD(n, i+2));
1287 com_backpatch(c, anchor);
1288}
1289
1290static void
1291com_while_stmt(c, n)
1292 struct compiling *c;
1293 node *n;
1294{
1295 int break_anchor = 0;
1296 int anchor = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001297 int save_begin = c->c_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001298 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1299 com_addfwref(c, SETUP_LOOP, &break_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001300 block_push(c, SETUP_LOOP);
1301 c->c_begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001302 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001303 com_node(c, CHILD(n, 1));
1304 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1305 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001306 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001307 com_node(c, CHILD(n, 3));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001308 c->c_loops--;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001309 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1310 c->c_begin = save_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001311 com_backpatch(c, anchor);
1312 com_addbyte(c, POP_TOP);
1313 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001314 block_pop(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001315 if (NCH(n) > 4)
1316 com_node(c, CHILD(n, 6));
1317 com_backpatch(c, break_anchor);
1318}
1319
1320static void
1321com_for_stmt(c, n)
1322 struct compiling *c;
1323 node *n;
1324{
1325 object *v;
1326 int break_anchor = 0;
1327 int anchor = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001328 int save_begin = c->c_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001329 REQ(n, for_stmt);
1330 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1331 com_addfwref(c, SETUP_LOOP, &break_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001332 block_push(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001333 com_node(c, CHILD(n, 3));
1334 v = newintobject(0L);
1335 if (v == NULL)
1336 c->c_errors++;
1337 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1338 XDECREF(v);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001339 c->c_begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001340 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001341 com_addfwref(c, FOR_LOOP, &anchor);
1342 com_assign(c, CHILD(n, 1), 1/*assigning*/);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001343 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001344 com_node(c, CHILD(n, 5));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001345 c->c_loops--;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001346 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1347 c->c_begin = save_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001348 com_backpatch(c, anchor);
1349 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001350 block_pop(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001351 if (NCH(n) > 8)
1352 com_node(c, CHILD(n, 8));
1353 com_backpatch(c, break_anchor);
1354}
1355
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001356/* Although 'execpt' and 'finally' clauses can be combined
1357 syntactically, they are compiled separately. In fact,
1358 try: S
1359 except E1: S1
1360 except E2: S2
1361 ...
1362 finally: Sf
1363 is equivalent to
1364 try:
1365 try: S
1366 except E1: S1
1367 except E2: S2
1368 ...
1369 finally: Sf
1370 meaning that the 'finally' clause is entered even if things
1371 go wrong again in an exception handler. Note that this is
1372 not the case for exception handlers: at most one is entered.
1373
1374 Code generated for "try: S finally: Sf" is as follows:
1375
1376 SETUP_FINALLY L
1377 <code for S>
1378 POP_BLOCK
1379 LOAD_CONST <nil>
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001380 L: <code for Sf>
1381 END_FINALLY
1382
1383 The special instructions use the block stack. Each block
1384 stack entry contains the instruction that created it (here
1385 SETUP_FINALLY), the level of the value stack at the time the
1386 block stack entry was created, and a label (here L).
1387
1388 SETUP_FINALLY:
1389 Pushes the current value stack level and the label
1390 onto the block stack.
1391 POP_BLOCK:
1392 Pops en entry from the block stack, and pops the value
1393 stack until its level is the same as indicated on the
1394 block stack. (The label is ignored.)
1395 END_FINALLY:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001396 Pops a variable number of entries from the *value* stack
1397 and re-raises the exception they specify. The number of
1398 entries popped depends on the (pseudo) exception type.
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001399
1400 The block stack is unwound when an exception is raised:
1401 when a SETUP_FINALLY entry is found, the exception is pushed
1402 onto the value stack (and the exception condition is cleared),
1403 and the interpreter jumps to the label gotten from the block
1404 stack.
1405
1406 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
Guido van Rossum3f5da241990-12-20 15:06:42 +00001407 (The contents of the value stack is shown in [], with the top
1408 at the right; 'tb' is trace-back info, 'val' the exception's
1409 associated value, and 'exc' the exception.)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001410
1411 Value stack Label Instruction Argument
1412 [] SETUP_EXCEPT L1
1413 [] <code for S>
1414 [] POP_BLOCK
1415 [] JUMP_FORWARD L0
1416
Guido van Rossum3f5da241990-12-20 15:06:42 +00001417 [tb, val, exc] L1: DUP )
1418 [tb, val, exc, exc] <evaluate E1> )
1419 [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
1420 [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
1421 [tb, val, exc, 1] POP )
1422 [tb, val, exc] POP
1423 [tb, val] <assign to V1> (or POP if no V1)
1424 [tb] POP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001425 [] <code for S1>
1426 JUMP_FORWARD L0
1427
Guido van Rossum3f5da241990-12-20 15:06:42 +00001428 [tb, val, exc, 0] L2: POP
1429 [tb, val, exc] DUP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001430 .............................etc.......................
1431
Guido van Rossum3f5da241990-12-20 15:06:42 +00001432 [tb, val, exc, 0] Ln+1: POP
1433 [tb, val, exc] END_FINALLY # re-raise exception
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001434
1435 [] L0: <next statement>
1436
1437 Of course, parts are not generated if Vi or Ei is not present.
1438*/
1439
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001440static void
1441com_try_stmt(c, n)
1442 struct compiling *c;
1443 node *n;
1444{
1445 int finally_anchor = 0;
1446 int except_anchor = 0;
1447 REQ(n, try_stmt);
1448 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001449
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001450 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1451 /* Have a 'finally' clause */
1452 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001453 block_push(c, SETUP_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001454 }
1455 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1456 /* Have an 'except' clause */
1457 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001458 block_push(c, SETUP_EXCEPT);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001459 }
1460 com_node(c, CHILD(n, 2));
1461 if (except_anchor) {
1462 int end_anchor = 0;
1463 int i;
1464 node *ch;
1465 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001466 block_pop(c, SETUP_EXCEPT);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001467 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1468 com_backpatch(c, except_anchor);
1469 for (i = 3;
1470 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1471 i += 3) {
1472 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001473 if (except_anchor == 0) {
1474 err_setstr(TypeError,
1475 "default 'except:' must be last");
1476 c->c_errors++;
1477 break;
1478 }
1479 except_anchor = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001480 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001481 if (NCH(ch) > 1) {
1482 com_addbyte(c, DUP_TOP);
1483 com_node(c, CHILD(ch, 1));
1484 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001485 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001486 com_addbyte(c, POP_TOP);
1487 }
1488 com_addbyte(c, POP_TOP);
1489 if (NCH(ch) > 3)
1490 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1491 else
1492 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001493 com_addbyte(c, POP_TOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001494 com_node(c, CHILD(n, i+2));
1495 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001496 if (except_anchor) {
1497 com_backpatch(c, except_anchor);
1498 com_addbyte(c, POP_TOP);
1499 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001500 }
1501 com_addbyte(c, END_FINALLY);
1502 com_backpatch(c, end_anchor);
1503 }
1504 if (finally_anchor) {
Guido van Rossum3f5da241990-12-20 15:06:42 +00001505 node *ch;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001506 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001507 block_pop(c, SETUP_FINALLY);
1508 block_push(c, END_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001509 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001510 com_backpatch(c, finally_anchor);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001511 ch = CHILD(n, NCH(n)-1);
1512 com_addoparg(c, SET_LINENO, ch->n_lineno);
1513 com_node(c, ch);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001514 com_addbyte(c, END_FINALLY);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001515 block_pop(c, END_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001516 }
1517}
1518
1519static void
1520com_suite(c, n)
1521 struct compiling *c;
1522 node *n;
1523{
1524 REQ(n, suite);
1525 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1526 if (NCH(n) == 1) {
1527 com_node(c, CHILD(n, 0));
1528 }
1529 else {
1530 int i;
1531 for (i = 0; i < NCH(n); i++) {
1532 node *ch = CHILD(n, i);
1533 if (TYPE(ch) == stmt)
1534 com_node(c, ch);
1535 }
1536 }
1537}
1538
1539static void
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001540com_continue_stmt(c, n)
1541 struct compiling *c;
1542 node *n;
1543{
1544 int i = c->c_nblocks;
1545 if (i-- > 0 && c->c_block[i] == SETUP_LOOP) {
1546 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1547 }
1548 else {
1549 err_setstr(TypeError, "'continue' not properly in loop");
1550 c->c_errors++;
1551 }
1552 /* XXX Could allow it inside a 'finally' clause
1553 XXX if we could pop the exception still on the stack */
1554}
1555
1556static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001557com_funcdef(c, n)
1558 struct compiling *c;
1559 node *n;
1560{
1561 object *v;
1562 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001563 v = (object *)compile(n, c->c_filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001564 if (v == NULL)
1565 c->c_errors++;
1566 else {
1567 int i = com_addconst(c, v);
1568 com_addoparg(c, LOAD_CONST, i);
1569 com_addbyte(c, BUILD_FUNCTION);
1570 com_addopname(c, STORE_NAME, CHILD(n, 1));
1571 DECREF(v);
1572 }
1573}
1574
1575static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001576com_bases(c, n)
1577 struct compiling *c;
1578 node *n;
1579{
1580 int i, nbases;
1581 REQ(n, baselist);
1582 /*
1583 baselist: atom arguments (',' atom arguments)*
1584 arguments: '(' [testlist] ')'
1585 */
1586 for (i = 0; i < NCH(n); i += 3)
1587 com_node(c, CHILD(n, i));
1588 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1589}
1590
1591static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001592com_classdef(c, n)
1593 struct compiling *c;
1594 node *n;
1595{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001596 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001597 REQ(n, classdef);
1598 /*
1599 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1600 baselist: atom arguments (',' atom arguments)*
1601 arguments: '(' [testlist] ')'
1602 */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001603 if (NCH(n) == 7)
1604 com_bases(c, CHILD(n, 4));
1605 else
1606 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001607 v = (object *)compile(n, c->c_filename);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001608 if (v == NULL)
1609 c->c_errors++;
1610 else {
1611 int i = com_addconst(c, v);
1612 com_addoparg(c, LOAD_CONST, i);
1613 com_addbyte(c, BUILD_FUNCTION);
1614 com_addbyte(c, UNARY_CALL);
1615 com_addbyte(c, BUILD_CLASS);
1616 com_addopname(c, STORE_NAME, CHILD(n, 1));
1617 DECREF(v);
1618 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001619}
1620
1621static void
1622com_node(c, n)
1623 struct compiling *c;
1624 node *n;
1625{
1626 switch (TYPE(n)) {
1627
1628 /* Definition nodes */
1629
1630 case funcdef:
1631 com_funcdef(c, n);
1632 break;
1633 case classdef:
1634 com_classdef(c, n);
1635 break;
1636
1637 /* Trivial parse tree nodes */
1638
1639 case stmt:
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001640 case small_stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001641 case flow_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001642 com_node(c, CHILD(n, 0));
1643 break;
1644
1645 case simple_stmt:
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001646 /* small_stmt (';' small_stmt)* [';'] NEWLINE */
1647 com_addoparg(c, SET_LINENO, n->n_lineno);
1648 {
1649 int i;
1650 for (i = 0; i < NCH(n)-1; i += 2)
1651 com_node(c, CHILD(n, i));
1652 }
1653 break;
1654
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001655 case compound_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001656 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001657 com_node(c, CHILD(n, 0));
1658 break;
1659
1660 /* Statement nodes */
1661
1662 case expr_stmt:
1663 com_expr_stmt(c, n);
1664 break;
1665 case print_stmt:
1666 com_print_stmt(c, n);
1667 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001668 case del_stmt: /* 'del' exprlist */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001669 com_assign(c, CHILD(n, 1), 0/*delete*/);
1670 break;
1671 case pass_stmt:
1672 break;
1673 case break_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001674 if (c->c_loops == 0) {
1675 err_setstr(TypeError, "'break' outside loop");
1676 c->c_errors++;
1677 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001678 com_addbyte(c, BREAK_LOOP);
1679 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001680 case continue_stmt:
1681 com_continue_stmt(c, n);
1682 break;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001683 case return_stmt:
1684 com_return_stmt(c, n);
1685 break;
1686 case raise_stmt:
1687 com_raise_stmt(c, n);
1688 break;
1689 case import_stmt:
1690 com_import_stmt(c, n);
1691 break;
1692 case if_stmt:
1693 com_if_stmt(c, n);
1694 break;
1695 case while_stmt:
1696 com_while_stmt(c, n);
1697 break;
1698 case for_stmt:
1699 com_for_stmt(c, n);
1700 break;
1701 case try_stmt:
1702 com_try_stmt(c, n);
1703 break;
1704 case suite:
1705 com_suite(c, n);
1706 break;
1707
1708 /* Expression nodes */
1709
1710 case testlist:
1711 com_list(c, n);
1712 break;
1713 case test:
1714 com_test(c, n);
1715 break;
1716 case and_test:
1717 com_and_test(c, n);
1718 break;
1719 case not_test:
1720 com_not_test(c, n);
1721 break;
1722 case comparison:
1723 com_comparison(c, n);
1724 break;
1725 case exprlist:
1726 com_list(c, n);
1727 break;
1728 case expr:
1729 com_expr(c, n);
1730 break;
1731 case term:
1732 com_term(c, n);
1733 break;
1734 case factor:
1735 com_factor(c, n);
1736 break;
1737 case atom:
1738 com_atom(c, n);
1739 break;
1740
1741 default:
1742 fprintf(stderr, "node type %d\n", TYPE(n));
1743 err_setstr(SystemError, "com_node: unexpected node type");
1744 c->c_errors++;
1745 }
1746}
1747
1748static void com_fplist PROTO((struct compiling *, node *));
1749
1750static void
1751com_fpdef(c, n)
1752 struct compiling *c;
1753 node *n;
1754{
1755 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1756 if (TYPE(CHILD(n, 0)) == LPAR)
1757 com_fplist(c, CHILD(n, 1));
1758 else
1759 com_addopname(c, STORE_NAME, CHILD(n, 0));
1760}
1761
1762static void
1763com_fplist(c, n)
1764 struct compiling *c;
1765 node *n;
1766{
1767 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1768 if (NCH(n) == 1) {
1769 com_fpdef(c, CHILD(n, 0));
1770 }
1771 else {
1772 int i;
1773 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1774 for (i = 0; i < NCH(n); i += 2)
1775 com_fpdef(c, CHILD(n, i));
1776 }
1777}
1778
1779static void
1780com_file_input(c, n)
1781 struct compiling *c;
1782 node *n;
1783{
1784 int i;
1785 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1786 for (i = 0; i < NCH(n); i++) {
1787 node *ch = CHILD(n, i);
1788 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1789 com_node(c, ch);
1790 }
1791}
1792
1793/* Top-level compile-node interface */
1794
1795static void
1796compile_funcdef(c, n)
1797 struct compiling *c;
1798 node *n;
1799{
1800 node *ch;
1801 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1802 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1803 ch = CHILD(ch, 1); /* ')' | fplist */
1804 if (TYPE(ch) == RPAR)
1805 com_addbyte(c, REFUSE_ARGS);
1806 else {
1807 com_addbyte(c, REQUIRE_ARGS);
1808 com_fplist(c, ch);
1809 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001810 c->c_infunction = 1;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001811 com_node(c, CHILD(n, 4));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001812 c->c_infunction = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001813 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1814 com_addbyte(c, RETURN_VALUE);
1815}
1816
1817static void
1818compile_node(c, n)
1819 struct compiling *c;
1820 node *n;
1821{
Guido van Rossum3f5da241990-12-20 15:06:42 +00001822 com_addoparg(c, SET_LINENO, n->n_lineno);
1823
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001824 switch (TYPE(n)) {
1825
Guido van Rossum4c417781991-01-21 16:09:22 +00001826 case single_input: /* One interactive command */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001827 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001828 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001829 n = CHILD(n, 0);
1830 if (TYPE(n) != NEWLINE)
1831 com_node(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001832 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1833 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001834 break;
1835
Guido van Rossum4c417781991-01-21 16:09:22 +00001836 case file_input: /* A whole file, or built-in function exec() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001837 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001838 com_file_input(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001839 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1840 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001841 break;
1842
Guido van Rossum4c417781991-01-21 16:09:22 +00001843 case expr_input: /* Built-in function eval() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001844 com_addbyte(c, REFUSE_ARGS);
1845 com_node(c, CHILD(n, 0));
1846 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001847 break;
1848
Guido van Rossum4c417781991-01-21 16:09:22 +00001849 case eval_input: /* Built-in function input() */
1850 com_addbyte(c, REFUSE_ARGS);
1851 com_node(c, CHILD(n, 0));
1852 com_addbyte(c, RETURN_VALUE);
1853 break;
1854
1855 case funcdef: /* A function definition */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001856 compile_funcdef(c, n);
1857 break;
1858
Guido van Rossum4c417781991-01-21 16:09:22 +00001859 case classdef: /* A class definition */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001860 /* 'class' NAME parameters ['=' baselist] ':' suite */
1861 com_addbyte(c, REFUSE_ARGS);
1862 com_node(c, CHILD(n, NCH(n)-1));
1863 com_addbyte(c, LOAD_LOCALS);
1864 com_addbyte(c, RETURN_VALUE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001865 break;
1866
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001867 default:
1868 fprintf(stderr, "node type %d\n", TYPE(n));
1869 err_setstr(SystemError, "compile_node: unexpected node type");
1870 c->c_errors++;
1871 }
1872}
1873
Guido van Rossum282914b1991-04-04 10:42:56 +00001874/* Optimization for local and global variables.
1875
1876 Attempt to replace all LOAD_NAME instructions that refer to a local
1877 variable with LOAD_LOCAL instructions, and all that refer to a global
1878 variable with LOAD_GLOBAL instructions.
1879
1880 To find all local variables, we check all STORE_NAME and IMPORT_FROM
1881 instructions. This yields all local variables, including arguments,
1882 function definitions, class definitions and import statements.
1883
1884 There is one leak: 'from foo import *' introduces local variables
1885 that we can't know while compiling. If this is the case, LOAD_GLOBAL
1886 instructions are not generated -- LOAD_NAME is left in place for
1887 globals, since it first checks for globals (LOAD_LOCAL is still used
1888 for recognized locals, since it doesn't hurt).
1889
1890 This optimization means that using the same name as a global and
1891 as a local variable within the same scope is now illegal, which
1892 is a change to the language! Also using eval() to introduce new
1893 local variables won't work. But both were bad practice at best.
1894
1895 The optimization doesn't save much: basically, it saves one
1896 unsuccessful dictionary lookup per global (or built-in) variable
1897 reference. On the (slow!) Mac Plus, with 4 local variables,
1898 this saving was measured to be about 0.18 ms. We might save more
1899 by using a different data structure to hold local variables, like
1900 an array indexed by variable number.
1901
1902 NB: this modifies the string object co->co_code!
1903*/
1904
1905static void
1906optimizer(co)
1907 codeobject *co;
1908{
Guido van Rossum0a697f61991-04-16 08:39:12 +00001909 unsigned char *next_instr, *cur_instr;
Guido van Rossum282914b1991-04-04 10:42:56 +00001910 object *locals;
1911 int opcode;
1912 int oparg;
1913 object *name;
1914 int star_used;
Guido van Rossum0a697f61991-04-16 08:39:12 +00001915
Guido van Rossum282914b1991-04-04 10:42:56 +00001916#define NEXTOP() (*next_instr++)
1917#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
1918#define GETITEM(v, i) (getlistitem((v), (i)))
1919#define GETNAMEOBJ(i) (GETITEM(co->co_names, (i)))
1920
1921 locals = newdictobject();
1922 if (locals == NULL) {
1923 err_clear();
1924 return; /* For now, this is OK */
1925 }
1926
Guido van Rossum0a697f61991-04-16 08:39:12 +00001927 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00001928 for (;;) {
1929 opcode = NEXTOP();
1930 if (opcode == STOP_CODE)
1931 break;
1932 if (HAS_ARG(opcode))
1933 oparg = NEXTARG();
1934 if (opcode == STORE_NAME || opcode == IMPORT_FROM) {
1935 name = GETNAMEOBJ(oparg);
1936 if (dict2insert(locals, name, None) != 0) {
1937 DECREF(locals);
1938 return; /* Sorry */
1939 }
1940 }
1941 }
1942
1943 star_used = (dictlookup(locals, "*") != NULL);
Guido van Rossum0a697f61991-04-16 08:39:12 +00001944 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00001945 for (;;) {
1946 cur_instr = next_instr;
1947 opcode = NEXTOP();
1948 if (opcode == STOP_CODE)
1949 break;
1950 if (HAS_ARG(opcode))
1951 oparg = NEXTARG();
1952 if (opcode == LOAD_NAME) {
1953 name = GETNAMEOBJ(oparg);
Guido van Rossum83163251991-08-16 08:58:43 +00001954 if (dict2lookup(locals, name) != NULL)
Guido van Rossum282914b1991-04-04 10:42:56 +00001955 *cur_instr = LOAD_LOCAL;
Guido van Rossum83163251991-08-16 08:58:43 +00001956 else {
1957 err_clear();
1958 if (!star_used)
1959 *cur_instr = LOAD_GLOBAL;
1960 }
Guido van Rossum282914b1991-04-04 10:42:56 +00001961 }
1962 }
1963
1964 DECREF(locals);
1965}
1966
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001967codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001968compile(n, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001969 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001970 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001971{
1972 struct compiling sc;
1973 codeobject *co;
Guido van Rossuma082ce41991-06-04 19:41:56 +00001974 object *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001975 if (!com_init(&sc, filename))
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001976 return NULL;
1977 compile_node(&sc, n);
1978 com_done(&sc);
Guido van Rossuma082ce41991-06-04 19:41:56 +00001979 if (sc.c_errors == 0 && (v = newstringobject(filename)) != NULL) {
1980 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names, v);
1981 DECREF(v);
1982 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001983 else
1984 co = NULL;
1985 com_free(&sc);
Guido van Rossumfb8edfc1991-05-14 11:56:03 +00001986 if (co != NULL && filename[0] != '<')
Guido van Rossum282914b1991-04-04 10:42:56 +00001987 optimizer(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001988 return co;
1989}