blob: 4dc3d9f19a27384fb4cb868bcf2c866f2e366fc7 [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 Rossum3f5da241990-12-20 15:06:42 +0000248 fprintf(stderr, "XXX compiling bad byte: %d\n", byte);
249 abort();
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000250 err_setstr(SystemError, "com_addbyte: byte out of range");
251 c->c_errors++;
252 }
253 if (c->c_code == NULL)
254 return;
255 len = getstringsize(c->c_code);
256 if (c->c_nexti >= len) {
257 if (resizestring(&c->c_code, len+1000) != 0) {
258 c->c_errors++;
259 return;
260 }
261 }
262 getstringvalue(c->c_code)[c->c_nexti++] = byte;
263}
264
265static void
266com_addint(c, x)
267 struct compiling *c;
268 int x;
269{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000270 com_addbyte(c, x & 0xff);
271 com_addbyte(c, x >> 8); /* XXX x should be positive */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000272}
273
274static void
275com_addoparg(c, op, arg)
276 struct compiling *c;
277 int op;
278 int arg;
279{
280 com_addbyte(c, op);
281 com_addint(c, arg);
282}
283
284static void
285com_addfwref(c, op, p_anchor)
286 struct compiling *c;
287 int op;
288 int *p_anchor;
289{
290 /* Compile a forward reference for backpatching */
291 int here;
292 int anchor;
293 com_addbyte(c, op);
294 here = c->c_nexti;
295 anchor = *p_anchor;
296 *p_anchor = here;
297 com_addint(c, anchor == 0 ? 0 : here - anchor);
298}
299
300static void
301com_backpatch(c, anchor)
302 struct compiling *c;
303 int anchor; /* Must be nonzero */
304{
305 unsigned char *code = (unsigned char *) getstringvalue(c->c_code);
306 int target = c->c_nexti;
307 int lastanchor = 0;
308 int dist;
309 int prev;
310 for (;;) {
311 /* Make the JUMP instruction at anchor point to target */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000312 prev = code[anchor] + (code[anchor+1] << 8);
313 dist = target - (anchor+2);
314 code[anchor] = dist & 0xff;
315 code[anchor+1] = dist >> 8;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000316 if (!prev)
317 break;
318 lastanchor = anchor;
319 anchor -= prev;
320 }
321}
322
323/* Handle constants and names uniformly */
324
325static int
326com_add(c, list, v)
327 struct compiling *c;
328 object *list;
329 object *v;
330{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000331 int n = getlistsize(list);
332 int i;
333 for (i = n; --i >= 0; ) {
334 object *w = getlistitem(list, i);
Guido van Rossumefc0bd01991-07-01 18:44:20 +0000335 if (v->ob_type == w->ob_type && cmpobject(v, w) == 0)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000336 return i;
337 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000338 if (addlistitem(list, v) != 0)
339 c->c_errors++;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000340 return n;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000341}
342
343static int
344com_addconst(c, v)
345 struct compiling *c;
346 object *v;
347{
348 return com_add(c, c->c_consts, v);
349}
350
351static int
352com_addname(c, v)
353 struct compiling *c;
354 object *v;
355{
356 return com_add(c, c->c_names, v);
357}
358
359static void
360com_addopname(c, op, n)
361 struct compiling *c;
362 int op;
363 node *n;
364{
365 object *v;
366 int i;
367 char *name;
368 if (TYPE(n) == STAR)
369 name = "*";
370 else {
371 REQ(n, NAME);
372 name = STR(n);
373 }
374 if ((v = newstringobject(name)) == NULL) {
375 c->c_errors++;
376 i = 255;
377 }
378 else {
379 i = com_addname(c, v);
380 DECREF(v);
381 }
382 com_addoparg(c, op, i);
383}
384
385static object *
386parsenumber(s)
387 char *s;
388{
389 extern long strtol();
Guido van Rossum282914b1991-04-04 10:42:56 +0000390 extern double strtod();
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000391 char *end = s;
392 long x;
Guido van Rossum282914b1991-04-04 10:42:56 +0000393 double xx;
394 errno = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000395 x = strtol(s, &end, 0);
Guido van Rossum282914b1991-04-04 10:42:56 +0000396 if (*end == '\0') {
397 if (errno != 0) {
398 err_setstr(RuntimeError, "integer constant too large");
399 return NULL;
400 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000401 return newintobject(x);
Guido van Rossum282914b1991-04-04 10:42:56 +0000402 }
Guido van Rossume3a204f1991-05-05 20:05:35 +0000403 if (*end == 'l' || *end == 'L') {
404 extern object *long_scan();
405 return long_scan(s, 0);
406 }
Guido van Rossum282914b1991-04-04 10:42:56 +0000407 errno = 0;
408 xx = strtod(s, &end);
409 if (*end == '\0') {
410 if (errno != 0) {
411 err_setstr(RuntimeError, "float constant too large");
412 return NULL;
413 }
414 return newfloatobject(xx);
415 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000416 err_setstr(RuntimeError, "bad number syntax");
417 return NULL;
418}
419
420static object *
421parsestr(s)
422 char *s;
423{
424 object *v;
425 int len;
426 char *buf;
427 char *p;
428 int c;
429 if (*s != '\'') {
430 err_badcall();
431 return NULL;
432 }
433 s++;
434 len = strlen(s);
435 if (s[--len] != '\'') {
436 err_badcall();
437 return NULL;
438 }
439 if (strchr(s, '\\') == NULL)
440 return newsizedstringobject(s, len);
441 v = newsizedstringobject((char *)NULL, len);
442 p = buf = getstringvalue(v);
443 while (*s != '\0' && *s != '\'') {
444 if (*s != '\\') {
445 *p++ = *s++;
446 continue;
447 }
448 s++;
449 switch (*s++) {
450 /* XXX This assumes ASCII! */
451 case '\\': *p++ = '\\'; break;
452 case '\'': *p++ = '\''; break;
453 case 'b': *p++ = '\b'; break;
454 case 'f': *p++ = '\014'; break; /* FF */
455 case 't': *p++ = '\t'; break;
456 case 'n': *p++ = '\n'; break;
457 case 'r': *p++ = '\r'; break;
458 case 'v': *p++ = '\013'; break; /* VT */
459 case 'E': *p++ = '\033'; break; /* ESC, not C */
460 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
461 case '0': case '1': case '2': case '3':
462 case '4': case '5': case '6': case '7':
463 c = s[-1] - '0';
464 if ('0' <= *s && *s <= '7') {
465 c = (c<<3) + *s++ - '0';
466 if ('0' <= *s && *s <= '7')
467 c = (c<<3) + *s++ - '0';
468 }
469 *p++ = c;
470 break;
471 case 'x':
472 if (isxdigit(*s)) {
473 sscanf(s, "%x", &c);
474 *p++ = c;
475 do {
476 s++;
477 } while (isxdigit(*s));
478 break;
479 }
480 /* FALLTHROUGH */
481 default: *p++ = '\\'; *p++ = s[-1]; break;
482 }
483 }
484 resizestring(&v, (int)(p - buf));
485 return v;
486}
487
488static void
489com_list_constructor(c, n)
490 struct compiling *c;
491 node *n;
492{
493 int len;
494 int i;
495 object *v, *w;
496 if (TYPE(n) != testlist)
497 REQ(n, exprlist);
498 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
499 len = (NCH(n) + 1) / 2;
500 for (i = 0; i < NCH(n); i += 2)
501 com_node(c, CHILD(n, i));
502 com_addoparg(c, BUILD_LIST, len);
503}
504
505static void
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000506com_dictmaker(c, n)
507 struct compiling *c;
508 node *n;
509{
510 int i;
511 /* dictmaker: test ':' test (',' test ':' value)* [','] */
512 for (i = 0; i+2 < NCH(n); i += 4) {
513 /* We must arrange things just right for STORE_SUBSCR.
514 It wants the stack to look like (value) (dict) (key) */
515 com_addbyte(c, DUP_TOP);
516 com_node(c, CHILD(n, i+2)); /* value */
517 com_addbyte(c, ROT_TWO);
518 com_node(c, CHILD(n, i)); /* key */
519 com_addbyte(c, STORE_SUBSCR);
520 }
521}
522
523static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000524com_atom(c, n)
525 struct compiling *c;
526 node *n;
527{
528 node *ch;
529 object *v;
530 int i;
531 REQ(n, atom);
532 ch = CHILD(n, 0);
533 switch (TYPE(ch)) {
534 case LPAR:
535 if (TYPE(CHILD(n, 1)) == RPAR)
536 com_addoparg(c, BUILD_TUPLE, 0);
537 else
538 com_node(c, CHILD(n, 1));
539 break;
540 case LSQB:
541 if (TYPE(CHILD(n, 1)) == RSQB)
542 com_addoparg(c, BUILD_LIST, 0);
543 else
544 com_list_constructor(c, CHILD(n, 1));
545 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000546 case LBRACE: /* '{' [dictmaker] '}' */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000547 com_addoparg(c, BUILD_MAP, 0);
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000548 if (TYPE(CHILD(n, 1)) != RBRACE)
549 com_dictmaker(c, CHILD(n, 1));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000550 break;
551 case BACKQUOTE:
552 com_node(c, CHILD(n, 1));
553 com_addbyte(c, UNARY_CONVERT);
554 break;
555 case NUMBER:
556 if ((v = parsenumber(STR(ch))) == NULL) {
557 c->c_errors++;
558 i = 255;
559 }
560 else {
561 i = com_addconst(c, v);
562 DECREF(v);
563 }
564 com_addoparg(c, LOAD_CONST, i);
565 break;
566 case STRING:
567 if ((v = parsestr(STR(ch))) == NULL) {
568 c->c_errors++;
569 i = 255;
570 }
571 else {
572 i = com_addconst(c, v);
573 DECREF(v);
574 }
575 com_addoparg(c, LOAD_CONST, i);
576 break;
577 case NAME:
578 com_addopname(c, LOAD_NAME, ch);
579 break;
580 default:
581 fprintf(stderr, "node type %d\n", TYPE(ch));
582 err_setstr(SystemError, "com_atom: unexpected node type");
583 c->c_errors++;
584 }
585}
586
587static void
588com_slice(c, n, op)
589 struct compiling *c;
590 node *n;
591 int op;
592{
593 if (NCH(n) == 1) {
594 com_addbyte(c, op);
595 }
596 else if (NCH(n) == 2) {
597 if (TYPE(CHILD(n, 0)) != COLON) {
598 com_node(c, CHILD(n, 0));
599 com_addbyte(c, op+1);
600 }
601 else {
602 com_node(c, CHILD(n, 1));
603 com_addbyte(c, op+2);
604 }
605 }
606 else {
607 com_node(c, CHILD(n, 0));
608 com_node(c, CHILD(n, 2));
609 com_addbyte(c, op+3);
610 }
611}
612
613static void
614com_apply_subscript(c, n)
615 struct compiling *c;
616 node *n;
617{
618 REQ(n, subscript);
619 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
620 /* It's a single subscript */
621 com_node(c, CHILD(n, 0));
622 com_addbyte(c, BINARY_SUBSCR);
623 }
624 else {
625 /* It's a slice: [expr] ':' [expr] */
626 com_slice(c, n, SLICE);
627 }
628}
629
630static void
631com_call_function(c, n)
632 struct compiling *c;
633 node *n; /* EITHER testlist OR ')' */
634{
635 if (TYPE(n) == RPAR) {
636 com_addbyte(c, UNARY_CALL);
637 }
638 else {
639 com_node(c, n);
640 com_addbyte(c, BINARY_CALL);
641 }
642}
643
644static void
645com_select_member(c, n)
646 struct compiling *c;
647 node *n;
648{
649 com_addopname(c, LOAD_ATTR, n);
650}
651
652static void
653com_apply_trailer(c, n)
654 struct compiling *c;
655 node *n;
656{
657 REQ(n, trailer);
658 switch (TYPE(CHILD(n, 0))) {
659 case LPAR:
660 com_call_function(c, CHILD(n, 1));
661 break;
662 case DOT:
663 com_select_member(c, CHILD(n, 1));
664 break;
665 case LSQB:
666 com_apply_subscript(c, CHILD(n, 1));
667 break;
668 default:
669 err_setstr(SystemError,
670 "com_apply_trailer: unknown trailer type");
671 c->c_errors++;
672 }
673}
674
675static void
676com_factor(c, n)
677 struct compiling *c;
678 node *n;
679{
680 int i;
681 REQ(n, factor);
682 if (TYPE(CHILD(n, 0)) == PLUS) {
683 com_factor(c, CHILD(n, 1));
684 com_addbyte(c, UNARY_POSITIVE);
685 }
686 else if (TYPE(CHILD(n, 0)) == MINUS) {
687 com_factor(c, CHILD(n, 1));
688 com_addbyte(c, UNARY_NEGATIVE);
689 }
690 else {
691 com_atom(c, CHILD(n, 0));
692 for (i = 1; i < NCH(n); i++)
693 com_apply_trailer(c, CHILD(n, i));
694 }
695}
696
697static void
698com_term(c, n)
699 struct compiling *c;
700 node *n;
701{
702 int i;
703 int op;
704 REQ(n, term);
705 com_factor(c, CHILD(n, 0));
706 for (i = 2; i < NCH(n); i += 2) {
707 com_factor(c, CHILD(n, i));
708 switch (TYPE(CHILD(n, i-1))) {
709 case STAR:
710 op = BINARY_MULTIPLY;
711 break;
712 case SLASH:
713 op = BINARY_DIVIDE;
714 break;
715 case PERCENT:
716 op = BINARY_MODULO;
717 break;
718 default:
719 err_setstr(SystemError,
720 "com_term: term operator not *, / or %");
721 c->c_errors++;
722 op = 255;
723 }
724 com_addbyte(c, op);
725 }
726}
727
728static void
729com_expr(c, n)
730 struct compiling *c;
731 node *n;
732{
733 int i;
734 int op;
735 REQ(n, expr);
736 com_term(c, CHILD(n, 0));
737 for (i = 2; i < NCH(n); i += 2) {
738 com_term(c, CHILD(n, i));
739 switch (TYPE(CHILD(n, i-1))) {
740 case PLUS:
741 op = BINARY_ADD;
742 break;
743 case MINUS:
744 op = BINARY_SUBTRACT;
745 break;
746 default:
747 err_setstr(SystemError,
748 "com_expr: expr operator not + or -");
749 c->c_errors++;
750 op = 255;
751 }
752 com_addbyte(c, op);
753 }
754}
755
756static enum cmp_op
757cmp_type(n)
758 node *n;
759{
760 REQ(n, comp_op);
761 /* comp_op: '<' | '>' | '=' | '>' '=' | '<' '=' | '<' '>'
762 | 'in' | 'not' 'in' | 'is' | 'is' not' */
763 if (NCH(n) == 1) {
764 n = CHILD(n, 0);
765 switch (TYPE(n)) {
766 case LESS: return LT;
767 case GREATER: return GT;
768 case EQUAL: return EQ;
769 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
770 if (strcmp(STR(n), "is") == 0) return IS;
771 }
772 }
773 else if (NCH(n) == 2) {
774 int t2 = TYPE(CHILD(n, 1));
775 switch (TYPE(CHILD(n, 0))) {
776 case LESS: if (t2 == EQUAL) return LE;
777 if (t2 == GREATER) return NE;
778 break;
779 case GREATER: if (t2 == EQUAL) return GE;
780 break;
781 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
782 return NOT_IN;
783 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
784 return IS_NOT;
785 }
786 }
787 return BAD;
788}
789
790static void
791com_comparison(c, n)
792 struct compiling *c;
793 node *n;
794{
795 int i;
796 enum cmp_op op;
797 int anchor;
798 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
799 com_expr(c, CHILD(n, 0));
800 if (NCH(n) == 1)
801 return;
802
803 /****************************************************************
804 The following code is generated for all but the last
805 comparison in a chain:
806
807 label: on stack: opcode: jump to:
808
809 a <code to load b>
810 a, b DUP_TOP
811 a, b, b ROT_THREE
812 b, a, b COMPARE_OP
813 b, 0-or-1 JUMP_IF_FALSE L1
814 b, 1 POP_TOP
815 b
816
817 We are now ready to repeat this sequence for the next
818 comparison in the chain.
819
820 For the last we generate:
821
822 b <code to load c>
823 b, c COMPARE_OP
824 0-or-1
825
826 If there were any jumps to L1 (i.e., there was more than one
827 comparison), we generate:
828
829 0-or-1 JUMP_FORWARD L2
830 L1: b, 0 ROT_TWO
831 0, b POP_TOP
832 0
833 L2:
834 ****************************************************************/
835
836 anchor = 0;
837
838 for (i = 2; i < NCH(n); i += 2) {
839 com_expr(c, CHILD(n, i));
840 if (i+2 < NCH(n)) {
841 com_addbyte(c, DUP_TOP);
842 com_addbyte(c, ROT_THREE);
843 }
844 op = cmp_type(CHILD(n, i-1));
845 if (op == BAD) {
846 err_setstr(SystemError,
847 "com_comparison: unknown comparison op");
848 c->c_errors++;
849 }
850 com_addoparg(c, COMPARE_OP, op);
851 if (i+2 < NCH(n)) {
852 com_addfwref(c, JUMP_IF_FALSE, &anchor);
853 com_addbyte(c, POP_TOP);
854 }
855 }
856
857 if (anchor) {
858 int anchor2 = 0;
859 com_addfwref(c, JUMP_FORWARD, &anchor2);
860 com_backpatch(c, anchor);
861 com_addbyte(c, ROT_TWO);
862 com_addbyte(c, POP_TOP);
863 com_backpatch(c, anchor2);
864 }
865}
866
867static void
868com_not_test(c, n)
869 struct compiling *c;
870 node *n;
871{
872 REQ(n, not_test); /* 'not' not_test | comparison */
873 if (NCH(n) == 1) {
874 com_comparison(c, CHILD(n, 0));
875 }
876 else {
877 com_not_test(c, CHILD(n, 1));
878 com_addbyte(c, UNARY_NOT);
879 }
880}
881
882static void
883com_and_test(c, n)
884 struct compiling *c;
885 node *n;
886{
887 int i;
888 int anchor;
889 REQ(n, and_test); /* not_test ('and' not_test)* */
890 anchor = 0;
891 i = 0;
892 for (;;) {
893 com_not_test(c, CHILD(n, i));
894 if ((i += 2) >= NCH(n))
895 break;
896 com_addfwref(c, JUMP_IF_FALSE, &anchor);
897 com_addbyte(c, POP_TOP);
898 }
899 if (anchor)
900 com_backpatch(c, anchor);
901}
902
903static void
904com_test(c, n)
905 struct compiling *c;
906 node *n;
907{
908 int i;
909 int anchor;
910 REQ(n, test); /* and_test ('and' and_test)* */
911 anchor = 0;
912 i = 0;
913 for (;;) {
914 com_and_test(c, CHILD(n, i));
915 if ((i += 2) >= NCH(n))
916 break;
917 com_addfwref(c, JUMP_IF_TRUE, &anchor);
918 com_addbyte(c, POP_TOP);
919 }
920 if (anchor)
921 com_backpatch(c, anchor);
922}
923
924static void
925com_list(c, n)
926 struct compiling *c;
927 node *n;
928{
929 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
930 if (NCH(n) == 1) {
931 com_node(c, CHILD(n, 0));
932 }
933 else {
934 int i;
935 int len;
936 len = (NCH(n) + 1) / 2;
937 for (i = 0; i < NCH(n); i += 2)
938 com_node(c, CHILD(n, i));
939 com_addoparg(c, BUILD_TUPLE, len);
940 }
941}
942
943
944/* Begin of assignment compilation */
945
946static void com_assign_name PROTO((struct compiling *, node *, int));
947static void com_assign PROTO((struct compiling *, node *, int));
948
949static void
950com_assign_attr(c, n, assigning)
951 struct compiling *c;
952 node *n;
953 int assigning;
954{
955 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
956}
957
958static void
959com_assign_slice(c, n, assigning)
960 struct compiling *c;
961 node *n;
962 int assigning;
963{
964 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
965}
966
967static void
968com_assign_subscript(c, n, assigning)
969 struct compiling *c;
970 node *n;
971 int assigning;
972{
973 com_node(c, n);
974 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
975}
976
977static void
978com_assign_trailer(c, n, assigning)
979 struct compiling *c;
980 node *n;
981 int assigning;
982{
983 char *name;
984 REQ(n, trailer);
985 switch (TYPE(CHILD(n, 0))) {
986 case LPAR: /* '(' [exprlist] ')' */
987 err_setstr(TypeError, "can't assign to function call");
988 c->c_errors++;
989 break;
990 case DOT: /* '.' NAME */
991 com_assign_attr(c, CHILD(n, 1), assigning);
992 break;
993 case LSQB: /* '[' subscript ']' */
994 n = CHILD(n, 1);
995 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
996 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
997 com_assign_slice(c, n, assigning);
998 else
999 com_assign_subscript(c, CHILD(n, 0), assigning);
1000 break;
1001 default:
1002 err_setstr(TypeError, "unknown trailer type");
1003 c->c_errors++;
1004 }
1005}
1006
1007static void
1008com_assign_tuple(c, n, assigning)
1009 struct compiling *c;
1010 node *n;
1011 int assigning;
1012{
1013 int i;
1014 if (TYPE(n) != testlist)
1015 REQ(n, exprlist);
1016 if (assigning)
1017 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1018 for (i = 0; i < NCH(n); i += 2)
1019 com_assign(c, CHILD(n, i), assigning);
1020}
1021
1022static void
1023com_assign_list(c, n, assigning)
1024 struct compiling *c;
1025 node *n;
1026 int assigning;
1027{
1028 int i;
1029 if (assigning)
1030 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
1031 for (i = 0; i < NCH(n); i += 2)
1032 com_assign(c, CHILD(n, i), assigning);
1033}
1034
1035static void
1036com_assign_name(c, n, assigning)
1037 struct compiling *c;
1038 node *n;
1039 int assigning;
1040{
1041 REQ(n, NAME);
1042 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
1043}
1044
1045static void
1046com_assign(c, n, assigning)
1047 struct compiling *c;
1048 node *n;
1049 int assigning;
1050{
1051 /* Loop to avoid trivial recursion */
1052 for (;;) {
1053 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001054
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001055 case exprlist:
1056 case testlist:
1057 if (NCH(n) > 1) {
1058 com_assign_tuple(c, n, assigning);
1059 return;
1060 }
1061 n = CHILD(n, 0);
1062 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001063
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001064 case test:
1065 case and_test:
1066 case not_test:
1067 if (NCH(n) > 1) {
1068 err_setstr(TypeError,
1069 "can't assign to operator");
1070 c->c_errors++;
1071 return;
1072 }
1073 n = CHILD(n, 0);
1074 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001075
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001076 case comparison:
1077 if (NCH(n) > 1) {
1078 err_setstr(TypeError,
1079 "can't assign to operator");
1080 c->c_errors++;
1081 return;
1082 }
1083 n = CHILD(n, 0);
1084 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001085
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001086 case expr:
1087 if (NCH(n) > 1) {
1088 err_setstr(TypeError,
1089 "can't assign to operator");
1090 c->c_errors++;
1091 return;
1092 }
1093 n = CHILD(n, 0);
1094 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001095
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001096 case term:
1097 if (NCH(n) > 1) {
1098 err_setstr(TypeError,
1099 "can't assign to operator");
1100 c->c_errors++;
1101 return;
1102 }
1103 n = CHILD(n, 0);
1104 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001105
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001106 case factor: /* ('+'|'-') factor | atom trailer* */
1107 if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
1108 err_setstr(TypeError,
1109 "can't assign to operator");
1110 c->c_errors++;
1111 return;
1112 }
1113 if (NCH(n) > 1) { /* trailer present */
1114 int i;
1115 com_node(c, CHILD(n, 0));
1116 for (i = 1; i+1 < NCH(n); i++) {
1117 com_apply_trailer(c, CHILD(n, i));
1118 } /* NB i is still alive */
1119 com_assign_trailer(c,
1120 CHILD(n, i), assigning);
1121 return;
1122 }
1123 n = CHILD(n, 0);
1124 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001125
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001126 case atom:
1127 switch (TYPE(CHILD(n, 0))) {
1128 case LPAR:
1129 n = CHILD(n, 1);
1130 if (TYPE(n) == RPAR) {
1131 /* XXX Should allow () = () ??? */
1132 err_setstr(TypeError,
1133 "can't assign to ()");
1134 c->c_errors++;
1135 return;
1136 }
1137 break;
1138 case LSQB:
1139 n = CHILD(n, 1);
1140 if (TYPE(n) == RSQB) {
1141 err_setstr(TypeError,
1142 "can't assign to []");
1143 c->c_errors++;
1144 return;
1145 }
1146 com_assign_list(c, n, assigning);
1147 return;
1148 case NAME:
1149 com_assign_name(c, CHILD(n, 0), assigning);
1150 return;
1151 default:
1152 err_setstr(TypeError,
1153 "can't assign to constant");
1154 c->c_errors++;
1155 return;
1156 }
1157 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001158
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001159 default:
1160 fprintf(stderr, "node type %d\n", TYPE(n));
1161 err_setstr(SystemError, "com_assign: bad node");
1162 c->c_errors++;
1163 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001164
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001165 }
1166 }
1167}
1168
1169static void
1170com_expr_stmt(c, n)
1171 struct compiling *c;
1172 node *n;
1173{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001174 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* */
1175 com_node(c, CHILD(n, NCH(n)-1));
1176 if (NCH(n) == 1) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001177 com_addbyte(c, PRINT_EXPR);
1178 }
1179 else {
1180 int i;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001181 for (i = 0; i < NCH(n)-2; i+=2) {
1182 if (i+2 < NCH(n)-2)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001183 com_addbyte(c, DUP_TOP);
1184 com_assign(c, CHILD(n, i), 1/*assign*/);
1185 }
1186 }
1187}
1188
1189static void
1190com_print_stmt(c, n)
1191 struct compiling *c;
1192 node *n;
1193{
1194 int i;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001195 REQ(n, print_stmt); /* 'print' (test ',')* [test] */
1196 for (i = 1; i < NCH(n); i += 2) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001197 com_node(c, CHILD(n, i));
1198 com_addbyte(c, PRINT_ITEM);
1199 }
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001200 if (TYPE(CHILD(n, NCH(n)-1)) != COMMA)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001201 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001202 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001203}
1204
1205static void
1206com_return_stmt(c, n)
1207 struct compiling *c;
1208 node *n;
1209{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001210 REQ(n, return_stmt); /* 'return' [testlist] */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001211 if (!c->c_infunction) {
1212 err_setstr(TypeError, "'return' outside function");
1213 c->c_errors++;
1214 }
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001215 if (NCH(n) < 2)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001216 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1217 else
1218 com_node(c, CHILD(n, 1));
1219 com_addbyte(c, RETURN_VALUE);
1220}
1221
1222static void
1223com_raise_stmt(c, n)
1224 struct compiling *c;
1225 node *n;
1226{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001227 REQ(n, raise_stmt); /* 'raise' test [',' test] */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001228 com_node(c, CHILD(n, 1));
1229 if (NCH(n) > 3)
1230 com_node(c, CHILD(n, 3));
1231 else
1232 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1233 com_addbyte(c, RAISE_EXCEPTION);
1234}
1235
1236static void
1237com_import_stmt(c, n)
1238 struct compiling *c;
1239 node *n;
1240{
1241 int i;
1242 REQ(n, import_stmt);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001243 /* 'import' NAME (',' NAME)* |
1244 'from' NAME 'import' ('*' | NAME (',' NAME)*) */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001245 if (STR(CHILD(n, 0))[0] == 'f') {
1246 /* 'from' NAME 'import' ... */
1247 REQ(CHILD(n, 1), NAME);
1248 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1249 for (i = 3; i < NCH(n); i += 2)
1250 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1251 com_addbyte(c, POP_TOP);
1252 }
1253 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001254 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001255 for (i = 1; i < NCH(n); i += 2) {
1256 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1257 com_addopname(c, STORE_NAME, CHILD(n, i));
1258 }
1259 }
1260}
1261
1262static void
1263com_if_stmt(c, n)
1264 struct compiling *c;
1265 node *n;
1266{
1267 int i;
1268 int anchor = 0;
1269 REQ(n, if_stmt);
1270 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1271 for (i = 0; i+3 < NCH(n); i+=4) {
1272 int a = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001273 node *ch = CHILD(n, i+1);
1274 if (i > 0)
1275 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001276 com_node(c, CHILD(n, i+1));
1277 com_addfwref(c, JUMP_IF_FALSE, &a);
1278 com_addbyte(c, POP_TOP);
1279 com_node(c, CHILD(n, i+3));
1280 com_addfwref(c, JUMP_FORWARD, &anchor);
1281 com_backpatch(c, a);
1282 com_addbyte(c, POP_TOP);
1283 }
1284 if (i+2 < NCH(n))
1285 com_node(c, CHILD(n, i+2));
1286 com_backpatch(c, anchor);
1287}
1288
1289static void
1290com_while_stmt(c, n)
1291 struct compiling *c;
1292 node *n;
1293{
1294 int break_anchor = 0;
1295 int anchor = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001296 int save_begin = c->c_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001297 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1298 com_addfwref(c, SETUP_LOOP, &break_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001299 block_push(c, SETUP_LOOP);
1300 c->c_begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001301 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001302 com_node(c, CHILD(n, 1));
1303 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1304 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001305 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001306 com_node(c, CHILD(n, 3));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001307 c->c_loops--;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001308 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1309 c->c_begin = save_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001310 com_backpatch(c, anchor);
1311 com_addbyte(c, POP_TOP);
1312 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001313 block_pop(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001314 if (NCH(n) > 4)
1315 com_node(c, CHILD(n, 6));
1316 com_backpatch(c, break_anchor);
1317}
1318
1319static void
1320com_for_stmt(c, n)
1321 struct compiling *c;
1322 node *n;
1323{
1324 object *v;
1325 int break_anchor = 0;
1326 int anchor = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001327 int save_begin = c->c_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001328 REQ(n, for_stmt);
1329 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1330 com_addfwref(c, SETUP_LOOP, &break_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001331 block_push(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001332 com_node(c, CHILD(n, 3));
1333 v = newintobject(0L);
1334 if (v == NULL)
1335 c->c_errors++;
1336 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1337 XDECREF(v);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001338 c->c_begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001339 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001340 com_addfwref(c, FOR_LOOP, &anchor);
1341 com_assign(c, CHILD(n, 1), 1/*assigning*/);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001342 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001343 com_node(c, CHILD(n, 5));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001344 c->c_loops--;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001345 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1346 c->c_begin = save_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001347 com_backpatch(c, anchor);
1348 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001349 block_pop(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001350 if (NCH(n) > 8)
1351 com_node(c, CHILD(n, 8));
1352 com_backpatch(c, break_anchor);
1353}
1354
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001355/* Although 'execpt' and 'finally' clauses can be combined
1356 syntactically, they are compiled separately. In fact,
1357 try: S
1358 except E1: S1
1359 except E2: S2
1360 ...
1361 finally: Sf
1362 is equivalent to
1363 try:
1364 try: S
1365 except E1: S1
1366 except E2: S2
1367 ...
1368 finally: Sf
1369 meaning that the 'finally' clause is entered even if things
1370 go wrong again in an exception handler. Note that this is
1371 not the case for exception handlers: at most one is entered.
1372
1373 Code generated for "try: S finally: Sf" is as follows:
1374
1375 SETUP_FINALLY L
1376 <code for S>
1377 POP_BLOCK
1378 LOAD_CONST <nil>
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001379 L: <code for Sf>
1380 END_FINALLY
1381
1382 The special instructions use the block stack. Each block
1383 stack entry contains the instruction that created it (here
1384 SETUP_FINALLY), the level of the value stack at the time the
1385 block stack entry was created, and a label (here L).
1386
1387 SETUP_FINALLY:
1388 Pushes the current value stack level and the label
1389 onto the block stack.
1390 POP_BLOCK:
1391 Pops en entry from the block stack, and pops the value
1392 stack until its level is the same as indicated on the
1393 block stack. (The label is ignored.)
1394 END_FINALLY:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001395 Pops a variable number of entries from the *value* stack
1396 and re-raises the exception they specify. The number of
1397 entries popped depends on the (pseudo) exception type.
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001398
1399 The block stack is unwound when an exception is raised:
1400 when a SETUP_FINALLY entry is found, the exception is pushed
1401 onto the value stack (and the exception condition is cleared),
1402 and the interpreter jumps to the label gotten from the block
1403 stack.
1404
1405 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
Guido van Rossum3f5da241990-12-20 15:06:42 +00001406 (The contents of the value stack is shown in [], with the top
1407 at the right; 'tb' is trace-back info, 'val' the exception's
1408 associated value, and 'exc' the exception.)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001409
1410 Value stack Label Instruction Argument
1411 [] SETUP_EXCEPT L1
1412 [] <code for S>
1413 [] POP_BLOCK
1414 [] JUMP_FORWARD L0
1415
Guido van Rossum3f5da241990-12-20 15:06:42 +00001416 [tb, val, exc] L1: DUP )
1417 [tb, val, exc, exc] <evaluate E1> )
1418 [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
1419 [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
1420 [tb, val, exc, 1] POP )
1421 [tb, val, exc] POP
1422 [tb, val] <assign to V1> (or POP if no V1)
1423 [tb] POP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001424 [] <code for S1>
1425 JUMP_FORWARD L0
1426
Guido van Rossum3f5da241990-12-20 15:06:42 +00001427 [tb, val, exc, 0] L2: POP
1428 [tb, val, exc] DUP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001429 .............................etc.......................
1430
Guido van Rossum3f5da241990-12-20 15:06:42 +00001431 [tb, val, exc, 0] Ln+1: POP
1432 [tb, val, exc] END_FINALLY # re-raise exception
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001433
1434 [] L0: <next statement>
1435
1436 Of course, parts are not generated if Vi or Ei is not present.
1437*/
1438
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001439static void
1440com_try_stmt(c, n)
1441 struct compiling *c;
1442 node *n;
1443{
1444 int finally_anchor = 0;
1445 int except_anchor = 0;
1446 REQ(n, try_stmt);
1447 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001448
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001449 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1450 /* Have a 'finally' clause */
1451 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001452 block_push(c, SETUP_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001453 }
1454 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1455 /* Have an 'except' clause */
1456 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001457 block_push(c, SETUP_EXCEPT);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001458 }
1459 com_node(c, CHILD(n, 2));
1460 if (except_anchor) {
1461 int end_anchor = 0;
1462 int i;
1463 node *ch;
1464 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001465 block_pop(c, SETUP_EXCEPT);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001466 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1467 com_backpatch(c, except_anchor);
1468 for (i = 3;
1469 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1470 i += 3) {
1471 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001472 if (except_anchor == 0) {
1473 err_setstr(TypeError,
1474 "default 'except:' must be last");
1475 c->c_errors++;
1476 break;
1477 }
1478 except_anchor = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001479 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001480 if (NCH(ch) > 1) {
1481 com_addbyte(c, DUP_TOP);
1482 com_node(c, CHILD(ch, 1));
1483 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001484 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001485 com_addbyte(c, POP_TOP);
1486 }
1487 com_addbyte(c, POP_TOP);
1488 if (NCH(ch) > 3)
1489 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1490 else
1491 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001492 com_addbyte(c, POP_TOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001493 com_node(c, CHILD(n, i+2));
1494 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001495 if (except_anchor) {
1496 com_backpatch(c, except_anchor);
1497 com_addbyte(c, POP_TOP);
1498 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001499 }
1500 com_addbyte(c, END_FINALLY);
1501 com_backpatch(c, end_anchor);
1502 }
1503 if (finally_anchor) {
Guido van Rossum3f5da241990-12-20 15:06:42 +00001504 node *ch;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001505 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001506 block_pop(c, SETUP_FINALLY);
1507 block_push(c, END_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001508 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001509 com_backpatch(c, finally_anchor);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001510 ch = CHILD(n, NCH(n)-1);
1511 com_addoparg(c, SET_LINENO, ch->n_lineno);
1512 com_node(c, ch);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001513 com_addbyte(c, END_FINALLY);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001514 block_pop(c, END_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001515 }
1516}
1517
1518static void
1519com_suite(c, n)
1520 struct compiling *c;
1521 node *n;
1522{
1523 REQ(n, suite);
1524 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1525 if (NCH(n) == 1) {
1526 com_node(c, CHILD(n, 0));
1527 }
1528 else {
1529 int i;
1530 for (i = 0; i < NCH(n); i++) {
1531 node *ch = CHILD(n, i);
1532 if (TYPE(ch) == stmt)
1533 com_node(c, ch);
1534 }
1535 }
1536}
1537
1538static void
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001539com_continue_stmt(c, n)
1540 struct compiling *c;
1541 node *n;
1542{
1543 int i = c->c_nblocks;
1544 if (i-- > 0 && c->c_block[i] == SETUP_LOOP) {
1545 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1546 }
1547 else {
1548 err_setstr(TypeError, "'continue' not properly in loop");
1549 c->c_errors++;
1550 }
1551 /* XXX Could allow it inside a 'finally' clause
1552 XXX if we could pop the exception still on the stack */
1553}
1554
1555static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001556com_funcdef(c, n)
1557 struct compiling *c;
1558 node *n;
1559{
1560 object *v;
1561 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001562 v = (object *)compile(n, c->c_filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001563 if (v == NULL)
1564 c->c_errors++;
1565 else {
1566 int i = com_addconst(c, v);
1567 com_addoparg(c, LOAD_CONST, i);
1568 com_addbyte(c, BUILD_FUNCTION);
1569 com_addopname(c, STORE_NAME, CHILD(n, 1));
1570 DECREF(v);
1571 }
1572}
1573
1574static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001575com_bases(c, n)
1576 struct compiling *c;
1577 node *n;
1578{
1579 int i, nbases;
1580 REQ(n, baselist);
1581 /*
1582 baselist: atom arguments (',' atom arguments)*
1583 arguments: '(' [testlist] ')'
1584 */
1585 for (i = 0; i < NCH(n); i += 3)
1586 com_node(c, CHILD(n, i));
1587 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1588}
1589
1590static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001591com_classdef(c, n)
1592 struct compiling *c;
1593 node *n;
1594{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001595 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001596 REQ(n, classdef);
1597 /*
1598 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1599 baselist: atom arguments (',' atom arguments)*
1600 arguments: '(' [testlist] ')'
1601 */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001602 if (NCH(n) == 7)
1603 com_bases(c, CHILD(n, 4));
1604 else
1605 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001606 v = (object *)compile(n, c->c_filename);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001607 if (v == NULL)
1608 c->c_errors++;
1609 else {
1610 int i = com_addconst(c, v);
1611 com_addoparg(c, LOAD_CONST, i);
1612 com_addbyte(c, BUILD_FUNCTION);
1613 com_addbyte(c, UNARY_CALL);
1614 com_addbyte(c, BUILD_CLASS);
1615 com_addopname(c, STORE_NAME, CHILD(n, 1));
1616 DECREF(v);
1617 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001618}
1619
1620static void
1621com_node(c, n)
1622 struct compiling *c;
1623 node *n;
1624{
1625 switch (TYPE(n)) {
1626
1627 /* Definition nodes */
1628
1629 case funcdef:
1630 com_funcdef(c, n);
1631 break;
1632 case classdef:
1633 com_classdef(c, n);
1634 break;
1635
1636 /* Trivial parse tree nodes */
1637
1638 case stmt:
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001639 case small_stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001640 case flow_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001641 com_node(c, CHILD(n, 0));
1642 break;
1643
1644 case simple_stmt:
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001645 /* small_stmt (';' small_stmt)* [';'] NEWLINE */
1646 com_addoparg(c, SET_LINENO, n->n_lineno);
1647 {
1648 int i;
1649 for (i = 0; i < NCH(n)-1; i += 2)
1650 com_node(c, CHILD(n, i));
1651 }
1652 break;
1653
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001654 case compound_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001655 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001656 com_node(c, CHILD(n, 0));
1657 break;
1658
1659 /* Statement nodes */
1660
1661 case expr_stmt:
1662 com_expr_stmt(c, n);
1663 break;
1664 case print_stmt:
1665 com_print_stmt(c, n);
1666 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001667 case del_stmt: /* 'del' exprlist */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001668 com_assign(c, CHILD(n, 1), 0/*delete*/);
1669 break;
1670 case pass_stmt:
1671 break;
1672 case break_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001673 if (c->c_loops == 0) {
1674 err_setstr(TypeError, "'break' outside loop");
1675 c->c_errors++;
1676 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001677 com_addbyte(c, BREAK_LOOP);
1678 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001679 case continue_stmt:
1680 com_continue_stmt(c, n);
1681 break;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001682 case return_stmt:
1683 com_return_stmt(c, n);
1684 break;
1685 case raise_stmt:
1686 com_raise_stmt(c, n);
1687 break;
1688 case import_stmt:
1689 com_import_stmt(c, n);
1690 break;
1691 case if_stmt:
1692 com_if_stmt(c, n);
1693 break;
1694 case while_stmt:
1695 com_while_stmt(c, n);
1696 break;
1697 case for_stmt:
1698 com_for_stmt(c, n);
1699 break;
1700 case try_stmt:
1701 com_try_stmt(c, n);
1702 break;
1703 case suite:
1704 com_suite(c, n);
1705 break;
1706
1707 /* Expression nodes */
1708
1709 case testlist:
1710 com_list(c, n);
1711 break;
1712 case test:
1713 com_test(c, n);
1714 break;
1715 case and_test:
1716 com_and_test(c, n);
1717 break;
1718 case not_test:
1719 com_not_test(c, n);
1720 break;
1721 case comparison:
1722 com_comparison(c, n);
1723 break;
1724 case exprlist:
1725 com_list(c, n);
1726 break;
1727 case expr:
1728 com_expr(c, n);
1729 break;
1730 case term:
1731 com_term(c, n);
1732 break;
1733 case factor:
1734 com_factor(c, n);
1735 break;
1736 case atom:
1737 com_atom(c, n);
1738 break;
1739
1740 default:
1741 fprintf(stderr, "node type %d\n", TYPE(n));
1742 err_setstr(SystemError, "com_node: unexpected node type");
1743 c->c_errors++;
1744 }
1745}
1746
1747static void com_fplist PROTO((struct compiling *, node *));
1748
1749static void
1750com_fpdef(c, n)
1751 struct compiling *c;
1752 node *n;
1753{
1754 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1755 if (TYPE(CHILD(n, 0)) == LPAR)
1756 com_fplist(c, CHILD(n, 1));
1757 else
1758 com_addopname(c, STORE_NAME, CHILD(n, 0));
1759}
1760
1761static void
1762com_fplist(c, n)
1763 struct compiling *c;
1764 node *n;
1765{
1766 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1767 if (NCH(n) == 1) {
1768 com_fpdef(c, CHILD(n, 0));
1769 }
1770 else {
1771 int i;
1772 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1773 for (i = 0; i < NCH(n); i += 2)
1774 com_fpdef(c, CHILD(n, i));
1775 }
1776}
1777
1778static void
1779com_file_input(c, n)
1780 struct compiling *c;
1781 node *n;
1782{
1783 int i;
1784 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1785 for (i = 0; i < NCH(n); i++) {
1786 node *ch = CHILD(n, i);
1787 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1788 com_node(c, ch);
1789 }
1790}
1791
1792/* Top-level compile-node interface */
1793
1794static void
1795compile_funcdef(c, n)
1796 struct compiling *c;
1797 node *n;
1798{
1799 node *ch;
1800 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1801 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1802 ch = CHILD(ch, 1); /* ')' | fplist */
1803 if (TYPE(ch) == RPAR)
1804 com_addbyte(c, REFUSE_ARGS);
1805 else {
1806 com_addbyte(c, REQUIRE_ARGS);
1807 com_fplist(c, ch);
1808 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001809 c->c_infunction = 1;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001810 com_node(c, CHILD(n, 4));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001811 c->c_infunction = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001812 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1813 com_addbyte(c, RETURN_VALUE);
1814}
1815
1816static void
1817compile_node(c, n)
1818 struct compiling *c;
1819 node *n;
1820{
Guido van Rossum3f5da241990-12-20 15:06:42 +00001821 com_addoparg(c, SET_LINENO, n->n_lineno);
1822
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001823 switch (TYPE(n)) {
1824
Guido van Rossum4c417781991-01-21 16:09:22 +00001825 case single_input: /* One interactive command */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001826 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001827 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001828 n = CHILD(n, 0);
1829 if (TYPE(n) != NEWLINE)
1830 com_node(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001831 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1832 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001833 break;
1834
Guido van Rossum4c417781991-01-21 16:09:22 +00001835 case file_input: /* A whole file, or built-in function exec() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001836 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001837 com_file_input(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001838 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1839 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001840 break;
1841
Guido van Rossum4c417781991-01-21 16:09:22 +00001842 case expr_input: /* Built-in function eval() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001843 com_addbyte(c, REFUSE_ARGS);
1844 com_node(c, CHILD(n, 0));
1845 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001846 break;
1847
Guido van Rossum4c417781991-01-21 16:09:22 +00001848 case eval_input: /* Built-in function input() */
1849 com_addbyte(c, REFUSE_ARGS);
1850 com_node(c, CHILD(n, 0));
1851 com_addbyte(c, RETURN_VALUE);
1852 break;
1853
1854 case funcdef: /* A function definition */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001855 compile_funcdef(c, n);
1856 break;
1857
Guido van Rossum4c417781991-01-21 16:09:22 +00001858 case classdef: /* A class definition */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001859 /* 'class' NAME parameters ['=' baselist] ':' suite */
1860 com_addbyte(c, REFUSE_ARGS);
1861 com_node(c, CHILD(n, NCH(n)-1));
1862 com_addbyte(c, LOAD_LOCALS);
1863 com_addbyte(c, RETURN_VALUE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001864 break;
1865
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001866 default:
1867 fprintf(stderr, "node type %d\n", TYPE(n));
1868 err_setstr(SystemError, "compile_node: unexpected node type");
1869 c->c_errors++;
1870 }
1871}
1872
Guido van Rossum282914b1991-04-04 10:42:56 +00001873/* Optimization for local and global variables.
1874
1875 Attempt to replace all LOAD_NAME instructions that refer to a local
1876 variable with LOAD_LOCAL instructions, and all that refer to a global
1877 variable with LOAD_GLOBAL instructions.
1878
1879 To find all local variables, we check all STORE_NAME and IMPORT_FROM
1880 instructions. This yields all local variables, including arguments,
1881 function definitions, class definitions and import statements.
1882
1883 There is one leak: 'from foo import *' introduces local variables
1884 that we can't know while compiling. If this is the case, LOAD_GLOBAL
1885 instructions are not generated -- LOAD_NAME is left in place for
1886 globals, since it first checks for globals (LOAD_LOCAL is still used
1887 for recognized locals, since it doesn't hurt).
1888
1889 This optimization means that using the same name as a global and
1890 as a local variable within the same scope is now illegal, which
1891 is a change to the language! Also using eval() to introduce new
1892 local variables won't work. But both were bad practice at best.
1893
1894 The optimization doesn't save much: basically, it saves one
1895 unsuccessful dictionary lookup per global (or built-in) variable
1896 reference. On the (slow!) Mac Plus, with 4 local variables,
1897 this saving was measured to be about 0.18 ms. We might save more
1898 by using a different data structure to hold local variables, like
1899 an array indexed by variable number.
1900
1901 NB: this modifies the string object co->co_code!
1902*/
1903
1904static void
1905optimizer(co)
1906 codeobject *co;
1907{
Guido van Rossum0a697f61991-04-16 08:39:12 +00001908 unsigned char *next_instr, *cur_instr;
Guido van Rossum282914b1991-04-04 10:42:56 +00001909 object *locals;
1910 int opcode;
1911 int oparg;
1912 object *name;
1913 int star_used;
Guido van Rossum0a697f61991-04-16 08:39:12 +00001914
Guido van Rossum282914b1991-04-04 10:42:56 +00001915#define NEXTOP() (*next_instr++)
1916#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
1917#define GETITEM(v, i) (getlistitem((v), (i)))
1918#define GETNAMEOBJ(i) (GETITEM(co->co_names, (i)))
1919
1920 locals = newdictobject();
1921 if (locals == NULL) {
1922 err_clear();
1923 return; /* For now, this is OK */
1924 }
1925
Guido van Rossum0a697f61991-04-16 08:39:12 +00001926 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00001927 for (;;) {
1928 opcode = NEXTOP();
1929 if (opcode == STOP_CODE)
1930 break;
1931 if (HAS_ARG(opcode))
1932 oparg = NEXTARG();
1933 if (opcode == STORE_NAME || opcode == IMPORT_FROM) {
1934 name = GETNAMEOBJ(oparg);
1935 if (dict2insert(locals, name, None) != 0) {
1936 DECREF(locals);
1937 return; /* Sorry */
1938 }
1939 }
1940 }
1941
1942 star_used = (dictlookup(locals, "*") != NULL);
Guido van Rossum0a697f61991-04-16 08:39:12 +00001943 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00001944 for (;;) {
1945 cur_instr = next_instr;
1946 opcode = NEXTOP();
1947 if (opcode == STOP_CODE)
1948 break;
1949 if (HAS_ARG(opcode))
1950 oparg = NEXTARG();
1951 if (opcode == LOAD_NAME) {
1952 name = GETNAMEOBJ(oparg);
1953 if (dictlookup(locals, getstringvalue(name)) != NULL)
1954 *cur_instr = LOAD_LOCAL;
1955 else if (!star_used)
1956 *cur_instr = LOAD_GLOBAL;
1957 }
1958 }
1959
1960 DECREF(locals);
1961}
1962
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001963codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001964compile(n, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001965 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001966 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001967{
1968 struct compiling sc;
1969 codeobject *co;
Guido van Rossuma082ce41991-06-04 19:41:56 +00001970 object *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001971 if (!com_init(&sc, filename))
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001972 return NULL;
1973 compile_node(&sc, n);
1974 com_done(&sc);
Guido van Rossuma082ce41991-06-04 19:41:56 +00001975 if (sc.c_errors == 0 && (v = newstringobject(filename)) != NULL) {
1976 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names, v);
1977 DECREF(v);
1978 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001979 else
1980 co = NULL;
1981 com_free(&sc);
Guido van Rossumfb8edfc1991-05-14 11:56:03 +00001982 if (co != NULL && filename[0] != '<')
Guido van Rossum282914b1991-04-04 10:42:56 +00001983 optimizer(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001984 return co;
1985}