blob: 08785a7ebb2a68b28f4d1685666de4ed7c4e00cd [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) */
Guido van Rossumc5e96291991-12-10 13:53:51 +0000139 object *c_globals; /* dictionary */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000140 int c_nexti; /* index into c_code */
141 int c_errors; /* counts errors occurred */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000142 int c_infunction; /* set when compiling a function */
143 int c_loops; /* counts nested loops */
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000144 int c_begin; /* begin of current loop, for 'continue' */
145 int c_block[MAXBLOCKS]; /* stack of block types */
146 int c_nblocks; /* current block stack level */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000147 char *c_filename; /* filename of current node */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000148};
149
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000150
151/* Interface to the block stack */
152
153static void
154block_push(c, type)
155 struct compiling *c;
156 int type;
157{
158 if (c->c_nblocks >= MAXBLOCKS) {
159 err_setstr(TypeError, "too many statically nested blocks");
160 c->c_errors++;
161 }
162 else {
163 c->c_block[c->c_nblocks++] = type;
164 }
165}
166
167static void
168block_pop(c, type)
169 struct compiling *c;
170 int type;
171{
172 if (c->c_nblocks > 0)
173 c->c_nblocks--;
174 if (c->c_block[c->c_nblocks] != type && c->c_errors == 0) {
175 err_setstr(SystemError, "bad block pop");
176 c->c_errors++;
177 }
178}
179
180
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000181/* Prototypes */
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000182
Guido van Rossum3f5da241990-12-20 15:06:42 +0000183static int com_init PROTO((struct compiling *, char *));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000184static void com_free PROTO((struct compiling *));
185static void com_done PROTO((struct compiling *));
186static void com_node PROTO((struct compiling *, struct _node *));
187static void com_addbyte PROTO((struct compiling *, int));
188static void com_addint PROTO((struct compiling *, int));
189static void com_addoparg PROTO((struct compiling *, int, int));
190static void com_addfwref PROTO((struct compiling *, int, int *));
191static void com_backpatch PROTO((struct compiling *, int));
192static int com_add PROTO((struct compiling *, object *, object *));
193static int com_addconst PROTO((struct compiling *, object *));
194static int com_addname PROTO((struct compiling *, object *));
195static void com_addopname PROTO((struct compiling *, int, node *));
Guido van Rossum288a60f1991-12-16 13:05:10 +0000196static void com_list PROTO((struct compiling *, node *, int));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000197
198static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000199com_init(c, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000200 struct compiling *c;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000201 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000202{
Guido van Rossum62d46241991-04-03 19:00:23 +0000203 if ((c->c_code = newsizedstringobject((char *)NULL, 1000)) == NULL)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000204 goto fail_3;
205 if ((c->c_consts = newlistobject(0)) == NULL)
206 goto fail_2;
207 if ((c->c_names = newlistobject(0)) == NULL)
208 goto fail_1;
Guido van Rossumc5e96291991-12-10 13:53:51 +0000209 if ((c->c_globals = newdictobject()) == NULL)
210 goto fail_0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000211 c->c_nexti = 0;
212 c->c_errors = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000213 c->c_infunction = 0;
214 c->c_loops = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000215 c->c_begin = 0;
216 c->c_nblocks = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000217 c->c_filename = filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000218 return 1;
219
Guido van Rossumc5e96291991-12-10 13:53:51 +0000220 fail_0:
221 DECREF(c->c_names);
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000222 fail_1:
223 DECREF(c->c_consts);
224 fail_2:
225 DECREF(c->c_code);
226 fail_3:
227 return 0;
228}
229
230static void
231com_free(c)
232 struct compiling *c;
233{
234 XDECREF(c->c_code);
235 XDECREF(c->c_consts);
236 XDECREF(c->c_names);
Guido van Rossumc5e96291991-12-10 13:53:51 +0000237 XDECREF(c->c_globals);
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000238}
239
240static void
241com_done(c)
242 struct compiling *c;
243{
244 if (c->c_code != NULL)
245 resizestring(&c->c_code, c->c_nexti);
246}
247
248static void
249com_addbyte(c, byte)
250 struct compiling *c;
251 int byte;
252{
253 int len;
254 if (byte < 0 || byte > 255) {
Guido van Rossum01cfd441991-10-20 20:12:38 +0000255 /*
Guido van Rossum3f5da241990-12-20 15:06:42 +0000256 fprintf(stderr, "XXX compiling bad byte: %d\n", byte);
257 abort();
Guido van Rossum01cfd441991-10-20 20:12:38 +0000258 */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000259 err_setstr(SystemError, "com_addbyte: byte out of range");
260 c->c_errors++;
261 }
262 if (c->c_code == NULL)
263 return;
264 len = getstringsize(c->c_code);
265 if (c->c_nexti >= len) {
266 if (resizestring(&c->c_code, len+1000) != 0) {
267 c->c_errors++;
268 return;
269 }
270 }
271 getstringvalue(c->c_code)[c->c_nexti++] = byte;
272}
273
274static void
275com_addint(c, x)
276 struct compiling *c;
277 int x;
278{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000279 com_addbyte(c, x & 0xff);
280 com_addbyte(c, x >> 8); /* XXX x should be positive */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000281}
282
283static void
284com_addoparg(c, op, arg)
285 struct compiling *c;
286 int op;
287 int arg;
288{
289 com_addbyte(c, op);
290 com_addint(c, arg);
291}
292
293static void
294com_addfwref(c, op, p_anchor)
295 struct compiling *c;
296 int op;
297 int *p_anchor;
298{
299 /* Compile a forward reference for backpatching */
300 int here;
301 int anchor;
302 com_addbyte(c, op);
303 here = c->c_nexti;
304 anchor = *p_anchor;
305 *p_anchor = here;
306 com_addint(c, anchor == 0 ? 0 : here - anchor);
307}
308
309static void
310com_backpatch(c, anchor)
311 struct compiling *c;
312 int anchor; /* Must be nonzero */
313{
314 unsigned char *code = (unsigned char *) getstringvalue(c->c_code);
315 int target = c->c_nexti;
316 int lastanchor = 0;
317 int dist;
318 int prev;
319 for (;;) {
320 /* Make the JUMP instruction at anchor point to target */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000321 prev = code[anchor] + (code[anchor+1] << 8);
322 dist = target - (anchor+2);
323 code[anchor] = dist & 0xff;
324 code[anchor+1] = dist >> 8;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000325 if (!prev)
326 break;
327 lastanchor = anchor;
328 anchor -= prev;
329 }
330}
331
332/* Handle constants and names uniformly */
333
334static int
335com_add(c, list, v)
336 struct compiling *c;
337 object *list;
338 object *v;
339{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000340 int n = getlistsize(list);
341 int i;
342 for (i = n; --i >= 0; ) {
343 object *w = getlistitem(list, i);
Guido van Rossumefc0bd01991-07-01 18:44:20 +0000344 if (v->ob_type == w->ob_type && cmpobject(v, w) == 0)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000345 return i;
346 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000347 if (addlistitem(list, v) != 0)
348 c->c_errors++;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000349 return n;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000350}
351
352static int
353com_addconst(c, v)
354 struct compiling *c;
355 object *v;
356{
357 return com_add(c, c->c_consts, v);
358}
359
360static int
361com_addname(c, v)
362 struct compiling *c;
363 object *v;
364{
365 return com_add(c, c->c_names, v);
366}
367
368static void
369com_addopname(c, op, n)
370 struct compiling *c;
371 int op;
372 node *n;
373{
374 object *v;
375 int i;
376 char *name;
377 if (TYPE(n) == STAR)
378 name = "*";
379 else {
380 REQ(n, NAME);
381 name = STR(n);
382 }
383 if ((v = newstringobject(name)) == NULL) {
384 c->c_errors++;
385 i = 255;
386 }
387 else {
388 i = com_addname(c, v);
389 DECREF(v);
390 }
Guido van Rossumc5e96291991-12-10 13:53:51 +0000391 /* Hack to replace *_NAME opcodes by *_GLOBAL if necessary */
392 switch (op) {
393 case LOAD_NAME:
394 case STORE_NAME:
395 case DELETE_NAME:
396 if (dictlookup(c->c_globals, name) != NULL) {
397 switch (op) {
398 case LOAD_NAME: op = LOAD_GLOBAL; break;
399 case STORE_NAME: op = STORE_GLOBAL; break;
400 case DELETE_NAME: op = DELETE_GLOBAL; break;
401 }
402 }
403 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000404 com_addoparg(c, op, i);
405}
406
407static object *
408parsenumber(s)
409 char *s;
410{
411 extern long strtol();
Guido van Rossum282914b1991-04-04 10:42:56 +0000412 extern double strtod();
Guido van Rossumc5e96291991-12-10 13:53:51 +0000413 char *end;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000414 long x;
Guido van Rossum282914b1991-04-04 10:42:56 +0000415 double xx;
416 errno = 0;
Guido van Rossumc5e96291991-12-10 13:53:51 +0000417 end = s + strlen(s) - 1;
418 if (*end == 'l' || *end == 'L') {
419 extern object *long_scan();
420 return long_scan(s, 0);
421 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000422 x = strtol(s, &end, 0);
Guido van Rossum282914b1991-04-04 10:42:56 +0000423 if (*end == '\0') {
424 if (errno != 0) {
Guido van Rossumefb087b1991-12-16 15:41:41 +0000425 err_setstr(OverflowError,
426 "integer constant too large");
Guido van Rossum282914b1991-04-04 10:42:56 +0000427 return NULL;
428 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000429 return newintobject(x);
Guido van Rossum282914b1991-04-04 10:42:56 +0000430 }
431 errno = 0;
432 xx = strtod(s, &end);
433 if (*end == '\0') {
434 if (errno != 0) {
Guido van Rossumefb087b1991-12-16 15:41:41 +0000435 err_setstr(OverflowError, "float constant too large");
Guido van Rossum282914b1991-04-04 10:42:56 +0000436 return NULL;
437 }
438 return newfloatobject(xx);
439 }
Guido van Rossumefb087b1991-12-16 15:41:41 +0000440 err_setstr(SystemError, "bad number syntax?!?!");
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000441 return NULL;
442}
443
444static object *
445parsestr(s)
446 char *s;
447{
448 object *v;
449 int len;
450 char *buf;
451 char *p;
452 int c;
453 if (*s != '\'') {
454 err_badcall();
455 return NULL;
456 }
457 s++;
458 len = strlen(s);
459 if (s[--len] != '\'') {
460 err_badcall();
461 return NULL;
462 }
463 if (strchr(s, '\\') == NULL)
464 return newsizedstringobject(s, len);
465 v = newsizedstringobject((char *)NULL, len);
466 p = buf = getstringvalue(v);
467 while (*s != '\0' && *s != '\'') {
468 if (*s != '\\') {
469 *p++ = *s++;
470 continue;
471 }
472 s++;
473 switch (*s++) {
474 /* XXX This assumes ASCII! */
475 case '\\': *p++ = '\\'; break;
476 case '\'': *p++ = '\''; break;
477 case 'b': *p++ = '\b'; break;
478 case 'f': *p++ = '\014'; break; /* FF */
479 case 't': *p++ = '\t'; break;
480 case 'n': *p++ = '\n'; break;
481 case 'r': *p++ = '\r'; break;
482 case 'v': *p++ = '\013'; break; /* VT */
483 case 'E': *p++ = '\033'; break; /* ESC, not C */
484 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
485 case '0': case '1': case '2': case '3':
486 case '4': case '5': case '6': case '7':
487 c = s[-1] - '0';
488 if ('0' <= *s && *s <= '7') {
489 c = (c<<3) + *s++ - '0';
490 if ('0' <= *s && *s <= '7')
491 c = (c<<3) + *s++ - '0';
492 }
493 *p++ = c;
494 break;
495 case 'x':
496 if (isxdigit(*s)) {
497 sscanf(s, "%x", &c);
498 *p++ = c;
499 do {
500 s++;
501 } while (isxdigit(*s));
502 break;
503 }
504 /* FALLTHROUGH */
505 default: *p++ = '\\'; *p++ = s[-1]; break;
506 }
507 }
508 resizestring(&v, (int)(p - buf));
509 return v;
510}
511
512static void
513com_list_constructor(c, n)
514 struct compiling *c;
515 node *n;
516{
517 int len;
518 int i;
519 object *v, *w;
520 if (TYPE(n) != testlist)
521 REQ(n, exprlist);
522 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
523 len = (NCH(n) + 1) / 2;
524 for (i = 0; i < NCH(n); i += 2)
525 com_node(c, CHILD(n, i));
526 com_addoparg(c, BUILD_LIST, len);
527}
528
529static void
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000530com_dictmaker(c, n)
531 struct compiling *c;
532 node *n;
533{
534 int i;
535 /* dictmaker: test ':' test (',' test ':' value)* [','] */
536 for (i = 0; i+2 < NCH(n); i += 4) {
537 /* We must arrange things just right for STORE_SUBSCR.
538 It wants the stack to look like (value) (dict) (key) */
539 com_addbyte(c, DUP_TOP);
540 com_node(c, CHILD(n, i+2)); /* value */
541 com_addbyte(c, ROT_TWO);
542 com_node(c, CHILD(n, i)); /* key */
543 com_addbyte(c, STORE_SUBSCR);
544 }
545}
546
547static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000548com_atom(c, n)
549 struct compiling *c;
550 node *n;
551{
552 node *ch;
553 object *v;
554 int i;
555 REQ(n, atom);
556 ch = CHILD(n, 0);
557 switch (TYPE(ch)) {
558 case LPAR:
559 if (TYPE(CHILD(n, 1)) == RPAR)
560 com_addoparg(c, BUILD_TUPLE, 0);
561 else
562 com_node(c, CHILD(n, 1));
563 break;
564 case LSQB:
565 if (TYPE(CHILD(n, 1)) == RSQB)
566 com_addoparg(c, BUILD_LIST, 0);
567 else
568 com_list_constructor(c, CHILD(n, 1));
569 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000570 case LBRACE: /* '{' [dictmaker] '}' */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000571 com_addoparg(c, BUILD_MAP, 0);
Guido van Rossum4bad92c1991-07-27 21:34:52 +0000572 if (TYPE(CHILD(n, 1)) != RBRACE)
573 com_dictmaker(c, CHILD(n, 1));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000574 break;
575 case BACKQUOTE:
576 com_node(c, CHILD(n, 1));
577 com_addbyte(c, UNARY_CONVERT);
578 break;
579 case NUMBER:
580 if ((v = parsenumber(STR(ch))) == NULL) {
581 c->c_errors++;
582 i = 255;
583 }
584 else {
585 i = com_addconst(c, v);
586 DECREF(v);
587 }
588 com_addoparg(c, LOAD_CONST, i);
589 break;
590 case STRING:
591 if ((v = parsestr(STR(ch))) == NULL) {
592 c->c_errors++;
593 i = 255;
594 }
595 else {
596 i = com_addconst(c, v);
597 DECREF(v);
598 }
599 com_addoparg(c, LOAD_CONST, i);
600 break;
601 case NAME:
602 com_addopname(c, LOAD_NAME, ch);
603 break;
604 default:
605 fprintf(stderr, "node type %d\n", TYPE(ch));
606 err_setstr(SystemError, "com_atom: unexpected node type");
607 c->c_errors++;
608 }
609}
610
611static void
612com_slice(c, n, op)
613 struct compiling *c;
614 node *n;
615 int op;
616{
617 if (NCH(n) == 1) {
618 com_addbyte(c, op);
619 }
620 else if (NCH(n) == 2) {
621 if (TYPE(CHILD(n, 0)) != COLON) {
622 com_node(c, CHILD(n, 0));
623 com_addbyte(c, op+1);
624 }
625 else {
626 com_node(c, CHILD(n, 1));
627 com_addbyte(c, op+2);
628 }
629 }
630 else {
631 com_node(c, CHILD(n, 0));
632 com_node(c, CHILD(n, 2));
633 com_addbyte(c, op+3);
634 }
635}
636
637static void
638com_apply_subscript(c, n)
639 struct compiling *c;
640 node *n;
641{
642 REQ(n, subscript);
643 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
644 /* It's a single subscript */
645 com_node(c, CHILD(n, 0));
646 com_addbyte(c, BINARY_SUBSCR);
647 }
648 else {
649 /* It's a slice: [expr] ':' [expr] */
650 com_slice(c, n, SLICE);
651 }
652}
653
654static void
655com_call_function(c, n)
656 struct compiling *c;
657 node *n; /* EITHER testlist OR ')' */
658{
659 if (TYPE(n) == RPAR) {
Guido van Rossum288a60f1991-12-16 13:05:10 +0000660 com_addoparg(c, BUILD_TUPLE, 0);
661 com_addbyte(c, BINARY_CALL);
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000662 }
663 else {
Guido van Rossum288a60f1991-12-16 13:05:10 +0000664 int i;
665 REQ(n, testlist);
666 com_list(c, n, 1);
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000667 com_addbyte(c, BINARY_CALL);
668 }
669}
670
671static void
672com_select_member(c, n)
673 struct compiling *c;
674 node *n;
675{
676 com_addopname(c, LOAD_ATTR, n);
677}
678
679static void
680com_apply_trailer(c, n)
681 struct compiling *c;
682 node *n;
683{
684 REQ(n, trailer);
685 switch (TYPE(CHILD(n, 0))) {
686 case LPAR:
687 com_call_function(c, CHILD(n, 1));
688 break;
689 case DOT:
690 com_select_member(c, CHILD(n, 1));
691 break;
692 case LSQB:
693 com_apply_subscript(c, CHILD(n, 1));
694 break;
695 default:
696 err_setstr(SystemError,
697 "com_apply_trailer: unknown trailer type");
698 c->c_errors++;
699 }
700}
701
702static void
703com_factor(c, n)
704 struct compiling *c;
705 node *n;
706{
707 int i;
708 REQ(n, factor);
709 if (TYPE(CHILD(n, 0)) == PLUS) {
710 com_factor(c, CHILD(n, 1));
711 com_addbyte(c, UNARY_POSITIVE);
712 }
713 else if (TYPE(CHILD(n, 0)) == MINUS) {
714 com_factor(c, CHILD(n, 1));
715 com_addbyte(c, UNARY_NEGATIVE);
716 }
Guido van Rossum7928cd71991-10-24 14:59:31 +0000717 else if (TYPE(CHILD(n, 0)) == TILDE) {
718 com_factor(c, CHILD(n, 1));
719 com_addbyte(c, UNARY_INVERT);
720 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000721 else {
722 com_atom(c, CHILD(n, 0));
723 for (i = 1; i < NCH(n); i++)
724 com_apply_trailer(c, CHILD(n, i));
725 }
726}
727
728static void
729com_term(c, n)
730 struct compiling *c;
731 node *n;
732{
733 int i;
734 int op;
735 REQ(n, term);
736 com_factor(c, CHILD(n, 0));
737 for (i = 2; i < NCH(n); i += 2) {
738 com_factor(c, CHILD(n, i));
739 switch (TYPE(CHILD(n, i-1))) {
740 case STAR:
741 op = BINARY_MULTIPLY;
742 break;
743 case SLASH:
744 op = BINARY_DIVIDE;
745 break;
746 case PERCENT:
747 op = BINARY_MODULO;
748 break;
749 default:
750 err_setstr(SystemError,
Guido van Rossum7928cd71991-10-24 14:59:31 +0000751 "com_term: operator not *, / or %");
752 c->c_errors++;
753 op = 255;
754 }
755 com_addbyte(c, op);
756 }
757}
758
759static void
760com_arith_expr(c, n)
761 struct compiling *c;
762 node *n;
763{
764 int i;
765 int op;
766 REQ(n, arith_expr);
767 com_term(c, CHILD(n, 0));
768 for (i = 2; i < NCH(n); i += 2) {
769 com_term(c, CHILD(n, i));
770 switch (TYPE(CHILD(n, i-1))) {
771 case PLUS:
772 op = BINARY_ADD;
773 break;
774 case MINUS:
775 op = BINARY_SUBTRACT;
776 break;
777 default:
778 err_setstr(SystemError,
779 "com_arith_expr: operator not + or -");
780 c->c_errors++;
781 op = 255;
782 }
783 com_addbyte(c, op);
784 }
785}
786
787static void
788com_shift_expr(c, n)
789 struct compiling *c;
790 node *n;
791{
792 int i;
793 int op;
794 REQ(n, shift_expr);
795 com_arith_expr(c, CHILD(n, 0));
796 for (i = 2; i < NCH(n); i += 2) {
797 com_arith_expr(c, CHILD(n, i));
798 switch (TYPE(CHILD(n, i-1))) {
799 case LEFTSHIFT:
800 op = BINARY_LSHIFT;
801 break;
802 case RIGHTSHIFT:
803 op = BINARY_RSHIFT;
804 break;
805 default:
806 err_setstr(SystemError,
807 "com_shift_expr: operator not << or >>");
808 c->c_errors++;
809 op = 255;
810 }
811 com_addbyte(c, op);
812 }
813}
814
815static void
816com_and_expr(c, n)
817 struct compiling *c;
818 node *n;
819{
820 int i;
821 int op;
822 REQ(n, and_expr);
823 com_shift_expr(c, CHILD(n, 0));
824 for (i = 2; i < NCH(n); i += 2) {
825 com_shift_expr(c, CHILD(n, i));
826 if (TYPE(CHILD(n, i-1)) == AMPER) {
827 op = BINARY_AND;
828 }
829 else {
830 err_setstr(SystemError,
831 "com_and_expr: operator not &");
832 c->c_errors++;
833 op = 255;
834 }
835 com_addbyte(c, op);
836 }
837}
838
839static void
840com_xor_expr(c, n)
841 struct compiling *c;
842 node *n;
843{
844 int i;
845 int op;
846 REQ(n, xor_expr);
847 com_and_expr(c, CHILD(n, 0));
848 for (i = 2; i < NCH(n); i += 2) {
849 com_and_expr(c, CHILD(n, i));
850 if (TYPE(CHILD(n, i-1)) == CIRCUMFLEX) {
851 op = BINARY_XOR;
852 }
853 else {
854 err_setstr(SystemError,
855 "com_xor_expr: operator not ^");
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000856 c->c_errors++;
857 op = 255;
858 }
859 com_addbyte(c, op);
860 }
861}
862
863static void
864com_expr(c, n)
865 struct compiling *c;
866 node *n;
867{
868 int i;
869 int op;
870 REQ(n, expr);
Guido van Rossum7928cd71991-10-24 14:59:31 +0000871 com_xor_expr(c, CHILD(n, 0));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000872 for (i = 2; i < NCH(n); i += 2) {
Guido van Rossum7928cd71991-10-24 14:59:31 +0000873 com_xor_expr(c, CHILD(n, i));
874 if (TYPE(CHILD(n, i-1)) == VBAR) {
875 op = BINARY_OR;
876 }
877 else {
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000878 err_setstr(SystemError,
Guido van Rossum7928cd71991-10-24 14:59:31 +0000879 "com_expr: expr operator not |");
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000880 c->c_errors++;
881 op = 255;
882 }
883 com_addbyte(c, op);
884 }
885}
886
887static enum cmp_op
888cmp_type(n)
889 node *n;
890{
891 REQ(n, comp_op);
Guido van Rossum01cfd441991-10-20 20:12:38 +0000892 /* comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000893 | 'in' | 'not' 'in' | 'is' | 'is' not' */
894 if (NCH(n) == 1) {
895 n = CHILD(n, 0);
896 switch (TYPE(n)) {
897 case LESS: return LT;
898 case GREATER: return GT;
Guido van Rossum01cfd441991-10-20 20:12:38 +0000899 case EQEQUAL: /* == */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000900 case EQUAL: return EQ;
Guido van Rossum01cfd441991-10-20 20:12:38 +0000901 case LESSEQUAL: return LE;
902 case GREATEREQUAL: return GE;
903 case NOTEQUAL: return NE; /* <> or != */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000904 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
905 if (strcmp(STR(n), "is") == 0) return IS;
906 }
907 }
908 else if (NCH(n) == 2) {
909 int t2 = TYPE(CHILD(n, 1));
910 switch (TYPE(CHILD(n, 0))) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000911 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
912 return NOT_IN;
913 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
914 return IS_NOT;
915 }
916 }
917 return BAD;
918}
919
920static void
921com_comparison(c, n)
922 struct compiling *c;
923 node *n;
924{
925 int i;
926 enum cmp_op op;
927 int anchor;
928 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
929 com_expr(c, CHILD(n, 0));
930 if (NCH(n) == 1)
931 return;
932
933 /****************************************************************
934 The following code is generated for all but the last
935 comparison in a chain:
936
937 label: on stack: opcode: jump to:
938
939 a <code to load b>
940 a, b DUP_TOP
941 a, b, b ROT_THREE
942 b, a, b COMPARE_OP
943 b, 0-or-1 JUMP_IF_FALSE L1
944 b, 1 POP_TOP
945 b
946
947 We are now ready to repeat this sequence for the next
948 comparison in the chain.
949
950 For the last we generate:
951
952 b <code to load c>
953 b, c COMPARE_OP
954 0-or-1
955
956 If there were any jumps to L1 (i.e., there was more than one
957 comparison), we generate:
958
959 0-or-1 JUMP_FORWARD L2
960 L1: b, 0 ROT_TWO
961 0, b POP_TOP
962 0
963 L2:
964 ****************************************************************/
965
966 anchor = 0;
967
968 for (i = 2; i < NCH(n); i += 2) {
969 com_expr(c, CHILD(n, i));
970 if (i+2 < NCH(n)) {
971 com_addbyte(c, DUP_TOP);
972 com_addbyte(c, ROT_THREE);
973 }
974 op = cmp_type(CHILD(n, i-1));
975 if (op == BAD) {
976 err_setstr(SystemError,
977 "com_comparison: unknown comparison op");
978 c->c_errors++;
979 }
980 com_addoparg(c, COMPARE_OP, op);
981 if (i+2 < NCH(n)) {
982 com_addfwref(c, JUMP_IF_FALSE, &anchor);
983 com_addbyte(c, POP_TOP);
984 }
985 }
986
987 if (anchor) {
988 int anchor2 = 0;
989 com_addfwref(c, JUMP_FORWARD, &anchor2);
990 com_backpatch(c, anchor);
991 com_addbyte(c, ROT_TWO);
992 com_addbyte(c, POP_TOP);
993 com_backpatch(c, anchor2);
994 }
995}
996
997static void
998com_not_test(c, n)
999 struct compiling *c;
1000 node *n;
1001{
1002 REQ(n, not_test); /* 'not' not_test | comparison */
1003 if (NCH(n) == 1) {
1004 com_comparison(c, CHILD(n, 0));
1005 }
1006 else {
1007 com_not_test(c, CHILD(n, 1));
1008 com_addbyte(c, UNARY_NOT);
1009 }
1010}
1011
1012static void
1013com_and_test(c, n)
1014 struct compiling *c;
1015 node *n;
1016{
1017 int i;
1018 int anchor;
1019 REQ(n, and_test); /* not_test ('and' not_test)* */
1020 anchor = 0;
1021 i = 0;
1022 for (;;) {
1023 com_not_test(c, CHILD(n, i));
1024 if ((i += 2) >= NCH(n))
1025 break;
1026 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1027 com_addbyte(c, POP_TOP);
1028 }
1029 if (anchor)
1030 com_backpatch(c, anchor);
1031}
1032
1033static void
1034com_test(c, n)
1035 struct compiling *c;
1036 node *n;
1037{
1038 int i;
1039 int anchor;
1040 REQ(n, test); /* and_test ('and' and_test)* */
1041 anchor = 0;
1042 i = 0;
1043 for (;;) {
1044 com_and_test(c, CHILD(n, i));
1045 if ((i += 2) >= NCH(n))
1046 break;
1047 com_addfwref(c, JUMP_IF_TRUE, &anchor);
1048 com_addbyte(c, POP_TOP);
1049 }
1050 if (anchor)
1051 com_backpatch(c, anchor);
1052}
1053
1054static void
Guido van Rossum288a60f1991-12-16 13:05:10 +00001055com_list(c, n, toplevel)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001056 struct compiling *c;
1057 node *n;
Guido van Rossum288a60f1991-12-16 13:05:10 +00001058 int toplevel; /* If nonzero, *always* build a tuple */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001059{
1060 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
Guido van Rossum288a60f1991-12-16 13:05:10 +00001061 if (NCH(n) == 1 && !toplevel) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001062 com_node(c, CHILD(n, 0));
1063 }
1064 else {
1065 int i;
1066 int len;
1067 len = (NCH(n) + 1) / 2;
1068 for (i = 0; i < NCH(n); i += 2)
1069 com_node(c, CHILD(n, i));
1070 com_addoparg(c, BUILD_TUPLE, len);
1071 }
1072}
1073
1074
1075/* Begin of assignment compilation */
1076
1077static void com_assign_name PROTO((struct compiling *, node *, int));
1078static void com_assign PROTO((struct compiling *, node *, int));
1079
1080static void
1081com_assign_attr(c, n, assigning)
1082 struct compiling *c;
1083 node *n;
1084 int assigning;
1085{
1086 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
1087}
1088
1089static void
1090com_assign_slice(c, n, assigning)
1091 struct compiling *c;
1092 node *n;
1093 int assigning;
1094{
1095 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
1096}
1097
1098static void
1099com_assign_subscript(c, n, assigning)
1100 struct compiling *c;
1101 node *n;
1102 int assigning;
1103{
1104 com_node(c, n);
1105 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
1106}
1107
1108static void
1109com_assign_trailer(c, n, assigning)
1110 struct compiling *c;
1111 node *n;
1112 int assigning;
1113{
1114 char *name;
1115 REQ(n, trailer);
1116 switch (TYPE(CHILD(n, 0))) {
1117 case LPAR: /* '(' [exprlist] ')' */
1118 err_setstr(TypeError, "can't assign to function call");
1119 c->c_errors++;
1120 break;
1121 case DOT: /* '.' NAME */
1122 com_assign_attr(c, CHILD(n, 1), assigning);
1123 break;
1124 case LSQB: /* '[' subscript ']' */
1125 n = CHILD(n, 1);
1126 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
1127 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
1128 com_assign_slice(c, n, assigning);
1129 else
1130 com_assign_subscript(c, CHILD(n, 0), assigning);
1131 break;
1132 default:
1133 err_setstr(TypeError, "unknown trailer type");
1134 c->c_errors++;
1135 }
1136}
1137
1138static void
1139com_assign_tuple(c, n, assigning)
1140 struct compiling *c;
1141 node *n;
1142 int assigning;
1143{
1144 int i;
1145 if (TYPE(n) != testlist)
1146 REQ(n, exprlist);
1147 if (assigning)
1148 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1149 for (i = 0; i < NCH(n); i += 2)
1150 com_assign(c, CHILD(n, i), assigning);
1151}
1152
1153static void
1154com_assign_list(c, n, assigning)
1155 struct compiling *c;
1156 node *n;
1157 int assigning;
1158{
1159 int i;
1160 if (assigning)
1161 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
1162 for (i = 0; i < NCH(n); i += 2)
1163 com_assign(c, CHILD(n, i), assigning);
1164}
1165
1166static void
1167com_assign_name(c, n, assigning)
1168 struct compiling *c;
1169 node *n;
1170 int assigning;
1171{
1172 REQ(n, NAME);
1173 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
1174}
1175
1176static void
1177com_assign(c, n, assigning)
1178 struct compiling *c;
1179 node *n;
1180 int assigning;
1181{
1182 /* Loop to avoid trivial recursion */
1183 for (;;) {
1184 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001185
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001186 case exprlist:
1187 case testlist:
1188 if (NCH(n) > 1) {
1189 com_assign_tuple(c, n, assigning);
1190 return;
1191 }
1192 n = CHILD(n, 0);
1193 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001194
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001195 case test:
1196 case and_test:
1197 case not_test:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001198 case comparison:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001199 case expr:
Guido van Rossum7928cd71991-10-24 14:59:31 +00001200 case xor_expr:
1201 case and_expr:
1202 case shift_expr:
1203 case arith_expr:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001204 case term:
1205 if (NCH(n) > 1) {
1206 err_setstr(TypeError,
1207 "can't assign to operator");
1208 c->c_errors++;
1209 return;
1210 }
1211 n = CHILD(n, 0);
1212 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001213
Guido van Rossum7928cd71991-10-24 14:59:31 +00001214 case factor: /* ('+'|'-'|'~') factor | atom trailer* */
1215 if (TYPE(CHILD(n, 0)) != atom) { /* '+'|'-'|'~' */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001216 err_setstr(TypeError,
1217 "can't assign to operator");
1218 c->c_errors++;
1219 return;
1220 }
1221 if (NCH(n) > 1) { /* trailer present */
1222 int i;
1223 com_node(c, CHILD(n, 0));
1224 for (i = 1; i+1 < NCH(n); i++) {
1225 com_apply_trailer(c, CHILD(n, i));
1226 } /* NB i is still alive */
1227 com_assign_trailer(c,
1228 CHILD(n, i), assigning);
1229 return;
1230 }
1231 n = CHILD(n, 0);
1232 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001233
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001234 case atom:
1235 switch (TYPE(CHILD(n, 0))) {
1236 case LPAR:
1237 n = CHILD(n, 1);
1238 if (TYPE(n) == RPAR) {
1239 /* XXX Should allow () = () ??? */
1240 err_setstr(TypeError,
1241 "can't assign to ()");
1242 c->c_errors++;
1243 return;
1244 }
1245 break;
1246 case LSQB:
1247 n = CHILD(n, 1);
1248 if (TYPE(n) == RSQB) {
1249 err_setstr(TypeError,
1250 "can't assign to []");
1251 c->c_errors++;
1252 return;
1253 }
1254 com_assign_list(c, n, assigning);
1255 return;
1256 case NAME:
1257 com_assign_name(c, CHILD(n, 0), assigning);
1258 return;
1259 default:
1260 err_setstr(TypeError,
1261 "can't assign to constant");
1262 c->c_errors++;
1263 return;
1264 }
1265 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001266
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001267 default:
1268 fprintf(stderr, "node type %d\n", TYPE(n));
1269 err_setstr(SystemError, "com_assign: bad node");
1270 c->c_errors++;
1271 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001272
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001273 }
1274 }
1275}
1276
1277static void
1278com_expr_stmt(c, n)
1279 struct compiling *c;
1280 node *n;
1281{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001282 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* */
1283 com_node(c, CHILD(n, NCH(n)-1));
1284 if (NCH(n) == 1) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001285 com_addbyte(c, PRINT_EXPR);
1286 }
1287 else {
1288 int i;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001289 for (i = 0; i < NCH(n)-2; i+=2) {
1290 if (i+2 < NCH(n)-2)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001291 com_addbyte(c, DUP_TOP);
1292 com_assign(c, CHILD(n, i), 1/*assign*/);
1293 }
1294 }
1295}
1296
1297static void
1298com_print_stmt(c, n)
1299 struct compiling *c;
1300 node *n;
1301{
1302 int i;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001303 REQ(n, print_stmt); /* 'print' (test ',')* [test] */
1304 for (i = 1; i < NCH(n); i += 2) {
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001305 com_node(c, CHILD(n, i));
1306 com_addbyte(c, PRINT_ITEM);
1307 }
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001308 if (TYPE(CHILD(n, NCH(n)-1)) != COMMA)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001309 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001310 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001311}
1312
1313static void
1314com_return_stmt(c, n)
1315 struct compiling *c;
1316 node *n;
1317{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001318 REQ(n, return_stmt); /* 'return' [testlist] */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001319 if (!c->c_infunction) {
1320 err_setstr(TypeError, "'return' outside function");
1321 c->c_errors++;
1322 }
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001323 if (NCH(n) < 2)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001324 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1325 else
1326 com_node(c, CHILD(n, 1));
1327 com_addbyte(c, RETURN_VALUE);
1328}
1329
1330static void
1331com_raise_stmt(c, n)
1332 struct compiling *c;
1333 node *n;
1334{
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001335 REQ(n, raise_stmt); /* 'raise' test [',' test] */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001336 com_node(c, CHILD(n, 1));
1337 if (NCH(n) > 3)
1338 com_node(c, CHILD(n, 3));
1339 else
1340 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1341 com_addbyte(c, RAISE_EXCEPTION);
1342}
1343
1344static void
1345com_import_stmt(c, n)
1346 struct compiling *c;
1347 node *n;
1348{
1349 int i;
1350 REQ(n, import_stmt);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001351 /* 'import' NAME (',' NAME)* |
1352 'from' NAME 'import' ('*' | NAME (',' NAME)*) */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001353 if (STR(CHILD(n, 0))[0] == 'f') {
1354 /* 'from' NAME 'import' ... */
1355 REQ(CHILD(n, 1), NAME);
1356 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1357 for (i = 3; i < NCH(n); i += 2)
1358 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1359 com_addbyte(c, POP_TOP);
1360 }
1361 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001362 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001363 for (i = 1; i < NCH(n); i += 2) {
1364 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1365 com_addopname(c, STORE_NAME, CHILD(n, i));
1366 }
1367 }
1368}
1369
1370static void
Guido van Rossumc5e96291991-12-10 13:53:51 +00001371com_global_stmt(c, n)
1372 struct compiling *c;
1373 node *n;
1374{
1375 int i;
1376 object *v;
1377 REQ(n, global_stmt);
1378 /* 'global' NAME (',' NAME)* */
1379 for (i = 1; i < NCH(n); i += 2) {
1380 if (dictinsert(c->c_globals, STR(CHILD(n, i)), None) != 0)
1381 c->c_errors++;
1382 }
1383}
1384
1385static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001386com_if_stmt(c, n)
1387 struct compiling *c;
1388 node *n;
1389{
1390 int i;
1391 int anchor = 0;
1392 REQ(n, if_stmt);
1393 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1394 for (i = 0; i+3 < NCH(n); i+=4) {
1395 int a = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001396 node *ch = CHILD(n, i+1);
1397 if (i > 0)
1398 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001399 com_node(c, CHILD(n, i+1));
1400 com_addfwref(c, JUMP_IF_FALSE, &a);
1401 com_addbyte(c, POP_TOP);
1402 com_node(c, CHILD(n, i+3));
1403 com_addfwref(c, JUMP_FORWARD, &anchor);
1404 com_backpatch(c, a);
1405 com_addbyte(c, POP_TOP);
1406 }
1407 if (i+2 < NCH(n))
1408 com_node(c, CHILD(n, i+2));
1409 com_backpatch(c, anchor);
1410}
1411
1412static void
1413com_while_stmt(c, n)
1414 struct compiling *c;
1415 node *n;
1416{
1417 int break_anchor = 0;
1418 int anchor = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001419 int save_begin = c->c_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001420 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1421 com_addfwref(c, SETUP_LOOP, &break_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001422 block_push(c, SETUP_LOOP);
1423 c->c_begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001424 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001425 com_node(c, CHILD(n, 1));
1426 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1427 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001428 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001429 com_node(c, CHILD(n, 3));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001430 c->c_loops--;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001431 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1432 c->c_begin = save_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001433 com_backpatch(c, anchor);
1434 com_addbyte(c, POP_TOP);
1435 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001436 block_pop(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001437 if (NCH(n) > 4)
1438 com_node(c, CHILD(n, 6));
1439 com_backpatch(c, break_anchor);
1440}
1441
1442static void
1443com_for_stmt(c, n)
1444 struct compiling *c;
1445 node *n;
1446{
1447 object *v;
1448 int break_anchor = 0;
1449 int anchor = 0;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001450 int save_begin = c->c_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001451 REQ(n, for_stmt);
1452 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1453 com_addfwref(c, SETUP_LOOP, &break_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001454 block_push(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001455 com_node(c, CHILD(n, 3));
1456 v = newintobject(0L);
1457 if (v == NULL)
1458 c->c_errors++;
1459 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1460 XDECREF(v);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001461 c->c_begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001462 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001463 com_addfwref(c, FOR_LOOP, &anchor);
1464 com_assign(c, CHILD(n, 1), 1/*assigning*/);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001465 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001466 com_node(c, CHILD(n, 5));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001467 c->c_loops--;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001468 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1469 c->c_begin = save_begin;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001470 com_backpatch(c, anchor);
1471 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001472 block_pop(c, SETUP_LOOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001473 if (NCH(n) > 8)
1474 com_node(c, CHILD(n, 8));
1475 com_backpatch(c, break_anchor);
1476}
1477
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001478/* Although 'execpt' and 'finally' clauses can be combined
1479 syntactically, they are compiled separately. In fact,
1480 try: S
1481 except E1: S1
1482 except E2: S2
1483 ...
1484 finally: Sf
1485 is equivalent to
1486 try:
1487 try: S
1488 except E1: S1
1489 except E2: S2
1490 ...
1491 finally: Sf
1492 meaning that the 'finally' clause is entered even if things
1493 go wrong again in an exception handler. Note that this is
1494 not the case for exception handlers: at most one is entered.
1495
1496 Code generated for "try: S finally: Sf" is as follows:
1497
1498 SETUP_FINALLY L
1499 <code for S>
1500 POP_BLOCK
1501 LOAD_CONST <nil>
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001502 L: <code for Sf>
1503 END_FINALLY
1504
1505 The special instructions use the block stack. Each block
1506 stack entry contains the instruction that created it (here
1507 SETUP_FINALLY), the level of the value stack at the time the
1508 block stack entry was created, and a label (here L).
1509
1510 SETUP_FINALLY:
1511 Pushes the current value stack level and the label
1512 onto the block stack.
1513 POP_BLOCK:
1514 Pops en entry from the block stack, and pops the value
1515 stack until its level is the same as indicated on the
1516 block stack. (The label is ignored.)
1517 END_FINALLY:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001518 Pops a variable number of entries from the *value* stack
1519 and re-raises the exception they specify. The number of
1520 entries popped depends on the (pseudo) exception type.
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001521
1522 The block stack is unwound when an exception is raised:
1523 when a SETUP_FINALLY entry is found, the exception is pushed
1524 onto the value stack (and the exception condition is cleared),
1525 and the interpreter jumps to the label gotten from the block
1526 stack.
1527
1528 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
Guido van Rossum3f5da241990-12-20 15:06:42 +00001529 (The contents of the value stack is shown in [], with the top
1530 at the right; 'tb' is trace-back info, 'val' the exception's
1531 associated value, and 'exc' the exception.)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001532
1533 Value stack Label Instruction Argument
1534 [] SETUP_EXCEPT L1
1535 [] <code for S>
1536 [] POP_BLOCK
1537 [] JUMP_FORWARD L0
1538
Guido van Rossum3f5da241990-12-20 15:06:42 +00001539 [tb, val, exc] L1: DUP )
1540 [tb, val, exc, exc] <evaluate E1> )
1541 [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
1542 [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
1543 [tb, val, exc, 1] POP )
1544 [tb, val, exc] POP
1545 [tb, val] <assign to V1> (or POP if no V1)
1546 [tb] POP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001547 [] <code for S1>
1548 JUMP_FORWARD L0
1549
Guido van Rossum3f5da241990-12-20 15:06:42 +00001550 [tb, val, exc, 0] L2: POP
1551 [tb, val, exc] DUP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001552 .............................etc.......................
1553
Guido van Rossum3f5da241990-12-20 15:06:42 +00001554 [tb, val, exc, 0] Ln+1: POP
1555 [tb, val, exc] END_FINALLY # re-raise exception
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001556
1557 [] L0: <next statement>
1558
1559 Of course, parts are not generated if Vi or Ei is not present.
1560*/
1561
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001562static void
1563com_try_stmt(c, n)
1564 struct compiling *c;
1565 node *n;
1566{
1567 int finally_anchor = 0;
1568 int except_anchor = 0;
1569 REQ(n, try_stmt);
1570 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001571
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001572 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1573 /* Have a 'finally' clause */
1574 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001575 block_push(c, SETUP_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001576 }
1577 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1578 /* Have an 'except' clause */
1579 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001580 block_push(c, SETUP_EXCEPT);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001581 }
1582 com_node(c, CHILD(n, 2));
1583 if (except_anchor) {
1584 int end_anchor = 0;
1585 int i;
1586 node *ch;
1587 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001588 block_pop(c, SETUP_EXCEPT);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001589 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1590 com_backpatch(c, except_anchor);
1591 for (i = 3;
1592 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1593 i += 3) {
1594 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001595 if (except_anchor == 0) {
1596 err_setstr(TypeError,
1597 "default 'except:' must be last");
1598 c->c_errors++;
1599 break;
1600 }
1601 except_anchor = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001602 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001603 if (NCH(ch) > 1) {
1604 com_addbyte(c, DUP_TOP);
1605 com_node(c, CHILD(ch, 1));
1606 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001607 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001608 com_addbyte(c, POP_TOP);
1609 }
1610 com_addbyte(c, POP_TOP);
1611 if (NCH(ch) > 3)
1612 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1613 else
1614 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001615 com_addbyte(c, POP_TOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001616 com_node(c, CHILD(n, i+2));
1617 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001618 if (except_anchor) {
1619 com_backpatch(c, except_anchor);
1620 com_addbyte(c, POP_TOP);
1621 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001622 }
1623 com_addbyte(c, END_FINALLY);
1624 com_backpatch(c, end_anchor);
1625 }
1626 if (finally_anchor) {
Guido van Rossum3f5da241990-12-20 15:06:42 +00001627 node *ch;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001628 com_addbyte(c, POP_BLOCK);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001629 block_pop(c, SETUP_FINALLY);
1630 block_push(c, END_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001631 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001632 com_backpatch(c, finally_anchor);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001633 ch = CHILD(n, NCH(n)-1);
1634 com_addoparg(c, SET_LINENO, ch->n_lineno);
1635 com_node(c, ch);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001636 com_addbyte(c, END_FINALLY);
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001637 block_pop(c, END_FINALLY);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001638 }
1639}
1640
1641static void
1642com_suite(c, n)
1643 struct compiling *c;
1644 node *n;
1645{
1646 REQ(n, suite);
1647 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1648 if (NCH(n) == 1) {
1649 com_node(c, CHILD(n, 0));
1650 }
1651 else {
1652 int i;
1653 for (i = 0; i < NCH(n); i++) {
1654 node *ch = CHILD(n, i);
1655 if (TYPE(ch) == stmt)
1656 com_node(c, ch);
1657 }
1658 }
1659}
1660
1661static void
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001662com_continue_stmt(c, n)
1663 struct compiling *c;
1664 node *n;
1665{
1666 int i = c->c_nblocks;
1667 if (i-- > 0 && c->c_block[i] == SETUP_LOOP) {
1668 com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1669 }
1670 else {
1671 err_setstr(TypeError, "'continue' not properly in loop");
1672 c->c_errors++;
1673 }
1674 /* XXX Could allow it inside a 'finally' clause
1675 XXX if we could pop the exception still on the stack */
1676}
1677
1678static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001679com_funcdef(c, n)
1680 struct compiling *c;
1681 node *n;
1682{
1683 object *v;
1684 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001685 v = (object *)compile(n, c->c_filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001686 if (v == NULL)
1687 c->c_errors++;
1688 else {
1689 int i = com_addconst(c, v);
1690 com_addoparg(c, LOAD_CONST, i);
1691 com_addbyte(c, BUILD_FUNCTION);
1692 com_addopname(c, STORE_NAME, CHILD(n, 1));
1693 DECREF(v);
1694 }
1695}
1696
1697static void
Guido van Rossumc5e96291991-12-10 13:53:51 +00001698com_oldbases(c, n)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001699 struct compiling *c;
1700 node *n;
1701{
1702 int i, nbases;
1703 REQ(n, baselist);
1704 /*
1705 baselist: atom arguments (',' atom arguments)*
Guido van Rossumc5e96291991-12-10 13:53:51 +00001706 arguments: '(' ')'
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001707 */
1708 for (i = 0; i < NCH(n); i += 3)
1709 com_node(c, CHILD(n, i));
1710 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1711}
1712
1713static void
Guido van Rossumc5e96291991-12-10 13:53:51 +00001714com_newbases(c, n)
1715 struct compiling *c;
1716 node *n;
1717{
1718 int i, nbases;
1719 REQ(n, testlist);
1720 /* testlist: test (',' test)* [','] */
1721 for (i = 0; i < NCH(n); i += 2)
1722 com_node(c, CHILD(n, i));
1723 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 2);
1724}
1725
1726static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001727com_classdef(c, n)
1728 struct compiling *c;
1729 node *n;
1730{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001731 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001732 REQ(n, classdef);
1733 /*
Guido van Rossumc5e96291991-12-10 13:53:51 +00001734 classdef: 'class' NAME
1735 ['(' testlist ')' |'(' ')' ['=' baselist]] ':' suite
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001736 baselist: atom arguments (',' atom arguments)*
Guido van Rossumc5e96291991-12-10 13:53:51 +00001737 arguments: '(' ')'
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001738 */
Guido van Rossumc5e96291991-12-10 13:53:51 +00001739 /* This piece of code must push a tuple on the stack (the bases) */
1740 if (TYPE(CHILD(n, 2)) != LPAR) {
1741 /* New syntax without base classes:
1742 class NAME ':' suite
1743 ___________^
1744 */
1745 com_addoparg(c, BUILD_TUPLE, 0);
1746 }
1747 else {
1748 if (TYPE(CHILD(n, 3)) == RPAR) {
1749 /* Old syntax with or without base classes:
1750 class NAME '(' ')' ['=' baselist] ':' suite
1751 _______________^....^...^
1752 */
1753 if (TYPE(CHILD(n, 4)) == EQUAL)
1754 com_oldbases(c, CHILD(n, 5));
1755 else
1756 com_addoparg(c, BUILD_TUPLE, 0);
1757 }
1758 else {
1759 /* New syntax with base classes:
1760 class NAME '(' testlist ')' ':' suite
1761 _______________^
1762 */
1763 com_newbases(c, CHILD(n, 3));
1764 }
1765 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001766 v = (object *)compile(n, c->c_filename);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001767 if (v == NULL)
1768 c->c_errors++;
1769 else {
1770 int i = com_addconst(c, v);
1771 com_addoparg(c, LOAD_CONST, i);
1772 com_addbyte(c, BUILD_FUNCTION);
1773 com_addbyte(c, UNARY_CALL);
1774 com_addbyte(c, BUILD_CLASS);
1775 com_addopname(c, STORE_NAME, CHILD(n, 1));
1776 DECREF(v);
1777 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001778}
1779
1780static void
1781com_node(c, n)
1782 struct compiling *c;
1783 node *n;
1784{
1785 switch (TYPE(n)) {
1786
1787 /* Definition nodes */
1788
1789 case funcdef:
1790 com_funcdef(c, n);
1791 break;
1792 case classdef:
1793 com_classdef(c, n);
1794 break;
1795
1796 /* Trivial parse tree nodes */
1797
1798 case stmt:
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001799 case small_stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001800 case flow_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001801 com_node(c, CHILD(n, 0));
1802 break;
1803
1804 case simple_stmt:
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001805 /* small_stmt (';' small_stmt)* [';'] NEWLINE */
1806 com_addoparg(c, SET_LINENO, n->n_lineno);
1807 {
1808 int i;
1809 for (i = 0; i < NCH(n)-1; i += 2)
1810 com_node(c, CHILD(n, i));
1811 }
1812 break;
1813
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001814 case compound_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001815 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001816 com_node(c, CHILD(n, 0));
1817 break;
1818
1819 /* Statement nodes */
1820
1821 case expr_stmt:
1822 com_expr_stmt(c, n);
1823 break;
1824 case print_stmt:
1825 com_print_stmt(c, n);
1826 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001827 case del_stmt: /* 'del' exprlist */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001828 com_assign(c, CHILD(n, 1), 0/*delete*/);
1829 break;
1830 case pass_stmt:
1831 break;
1832 case break_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001833 if (c->c_loops == 0) {
1834 err_setstr(TypeError, "'break' outside loop");
1835 c->c_errors++;
1836 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001837 com_addbyte(c, BREAK_LOOP);
1838 break;
Guido van Rossum4bad92c1991-07-27 21:34:52 +00001839 case continue_stmt:
1840 com_continue_stmt(c, n);
1841 break;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001842 case return_stmt:
1843 com_return_stmt(c, n);
1844 break;
1845 case raise_stmt:
1846 com_raise_stmt(c, n);
1847 break;
1848 case import_stmt:
1849 com_import_stmt(c, n);
1850 break;
Guido van Rossumc5e96291991-12-10 13:53:51 +00001851 case global_stmt:
1852 com_global_stmt(c, n);
1853 break;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001854 case if_stmt:
1855 com_if_stmt(c, n);
1856 break;
1857 case while_stmt:
1858 com_while_stmt(c, n);
1859 break;
1860 case for_stmt:
1861 com_for_stmt(c, n);
1862 break;
1863 case try_stmt:
1864 com_try_stmt(c, n);
1865 break;
1866 case suite:
1867 com_suite(c, n);
1868 break;
1869
1870 /* Expression nodes */
1871
1872 case testlist:
Guido van Rossum288a60f1991-12-16 13:05:10 +00001873 com_list(c, n, 0);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001874 break;
1875 case test:
1876 com_test(c, n);
1877 break;
1878 case and_test:
1879 com_and_test(c, n);
1880 break;
1881 case not_test:
1882 com_not_test(c, n);
1883 break;
1884 case comparison:
1885 com_comparison(c, n);
1886 break;
1887 case exprlist:
Guido van Rossum288a60f1991-12-16 13:05:10 +00001888 com_list(c, n, 0);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001889 break;
1890 case expr:
1891 com_expr(c, n);
1892 break;
Guido van Rossum7928cd71991-10-24 14:59:31 +00001893 case xor_expr:
1894 com_xor_expr(c, n);
1895 break;
1896 case and_expr:
1897 com_and_expr(c, n);
1898 break;
1899 case shift_expr:
1900 com_shift_expr(c, n);
1901 break;
1902 case arith_expr:
1903 com_arith_expr(c, n);
1904 break;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001905 case term:
1906 com_term(c, n);
1907 break;
1908 case factor:
1909 com_factor(c, n);
1910 break;
1911 case atom:
1912 com_atom(c, n);
1913 break;
1914
1915 default:
1916 fprintf(stderr, "node type %d\n", TYPE(n));
1917 err_setstr(SystemError, "com_node: unexpected node type");
1918 c->c_errors++;
1919 }
1920}
1921
1922static void com_fplist PROTO((struct compiling *, node *));
1923
1924static void
1925com_fpdef(c, n)
1926 struct compiling *c;
1927 node *n;
1928{
1929 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1930 if (TYPE(CHILD(n, 0)) == LPAR)
1931 com_fplist(c, CHILD(n, 1));
1932 else
1933 com_addopname(c, STORE_NAME, CHILD(n, 0));
1934}
1935
1936static void
1937com_fplist(c, n)
1938 struct compiling *c;
1939 node *n;
1940{
1941 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1942 if (NCH(n) == 1) {
1943 com_fpdef(c, CHILD(n, 0));
1944 }
1945 else {
1946 int i;
1947 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1948 for (i = 0; i < NCH(n); i += 2)
1949 com_fpdef(c, CHILD(n, i));
1950 }
1951}
1952
1953static void
1954com_file_input(c, n)
1955 struct compiling *c;
1956 node *n;
1957{
1958 int i;
1959 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1960 for (i = 0; i < NCH(n); i++) {
1961 node *ch = CHILD(n, i);
1962 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1963 com_node(c, ch);
1964 }
1965}
1966
1967/* Top-level compile-node interface */
1968
1969static void
1970compile_funcdef(c, n)
1971 struct compiling *c;
1972 node *n;
1973{
1974 node *ch;
1975 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1976 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1977 ch = CHILD(ch, 1); /* ')' | fplist */
1978 if (TYPE(ch) == RPAR)
Guido van Rossum288a60f1991-12-16 13:05:10 +00001979 com_addoparg(c, UNPACK_ARG, 0);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001980 else {
Guido van Rossum288a60f1991-12-16 13:05:10 +00001981 int i;
1982 REQ(ch, fplist); /* fplist: fpdef (',' fpdef)* */
1983 com_addoparg(c, UNPACK_ARG, (NCH(ch)+1)/2);
1984 for (i = 0; i < NCH(ch); i += 2)
1985 com_fpdef(c, CHILD(ch, i));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001986 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001987 c->c_infunction = 1;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001988 com_node(c, CHILD(n, 4));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001989 c->c_infunction = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001990 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1991 com_addbyte(c, RETURN_VALUE);
1992}
1993
1994static void
1995compile_node(c, n)
1996 struct compiling *c;
1997 node *n;
1998{
Guido van Rossum3f5da241990-12-20 15:06:42 +00001999 com_addoparg(c, SET_LINENO, n->n_lineno);
2000
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002001 switch (TYPE(n)) {
2002
Guido van Rossum4c417781991-01-21 16:09:22 +00002003 case single_input: /* One interactive command */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002004 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
2005 n = CHILD(n, 0);
2006 if (TYPE(n) != NEWLINE)
2007 com_node(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00002008 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
2009 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002010 break;
2011
Guido van Rossum4c417781991-01-21 16:09:22 +00002012 case file_input: /* A whole file, or built-in function exec() */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002013 com_file_input(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00002014 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
2015 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002016 break;
2017
Guido van Rossum4c417781991-01-21 16:09:22 +00002018 case expr_input: /* Built-in function eval() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00002019 com_node(c, CHILD(n, 0));
2020 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002021 break;
2022
Guido van Rossum4c417781991-01-21 16:09:22 +00002023 case eval_input: /* Built-in function input() */
Guido van Rossum4c417781991-01-21 16:09:22 +00002024 com_node(c, CHILD(n, 0));
2025 com_addbyte(c, RETURN_VALUE);
2026 break;
2027
2028 case funcdef: /* A function definition */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002029 compile_funcdef(c, n);
2030 break;
2031
Guido van Rossum4c417781991-01-21 16:09:22 +00002032 case classdef: /* A class definition */
Guido van Rossumc5e96291991-12-10 13:53:51 +00002033 /* classdef: 'class' NAME
2034 ['(' testlist ')' |'(' ')' ['=' baselist]]
2035 ':' suite */
Guido van Rossumc5e96291991-12-10 13:53:51 +00002036 com_node(c, CHILD(n, NCH(n)-1)); /* The suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00002037 com_addbyte(c, LOAD_LOCALS);
2038 com_addbyte(c, RETURN_VALUE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00002039 break;
2040
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002041 default:
2042 fprintf(stderr, "node type %d\n", TYPE(n));
2043 err_setstr(SystemError, "compile_node: unexpected node type");
2044 c->c_errors++;
2045 }
2046}
2047
Guido van Rossum282914b1991-04-04 10:42:56 +00002048/* Optimization for local and global variables.
2049
2050 Attempt to replace all LOAD_NAME instructions that refer to a local
2051 variable with LOAD_LOCAL instructions, and all that refer to a global
2052 variable with LOAD_GLOBAL instructions.
2053
2054 To find all local variables, we check all STORE_NAME and IMPORT_FROM
2055 instructions. This yields all local variables, including arguments,
2056 function definitions, class definitions and import statements.
2057
2058 There is one leak: 'from foo import *' introduces local variables
2059 that we can't know while compiling. If this is the case, LOAD_GLOBAL
2060 instructions are not generated -- LOAD_NAME is left in place for
2061 globals, since it first checks for globals (LOAD_LOCAL is still used
2062 for recognized locals, since it doesn't hurt).
2063
2064 This optimization means that using the same name as a global and
2065 as a local variable within the same scope is now illegal, which
2066 is a change to the language! Also using eval() to introduce new
2067 local variables won't work. But both were bad practice at best.
2068
2069 The optimization doesn't save much: basically, it saves one
2070 unsuccessful dictionary lookup per global (or built-in) variable
2071 reference. On the (slow!) Mac Plus, with 4 local variables,
2072 this saving was measured to be about 0.18 ms. We might save more
2073 by using a different data structure to hold local variables, like
2074 an array indexed by variable number.
2075
2076 NB: this modifies the string object co->co_code!
2077*/
2078
2079static void
2080optimizer(co)
2081 codeobject *co;
2082{
Guido van Rossum0a697f61991-04-16 08:39:12 +00002083 unsigned char *next_instr, *cur_instr;
Guido van Rossum282914b1991-04-04 10:42:56 +00002084 object *locals;
2085 int opcode;
2086 int oparg;
2087 object *name;
2088 int star_used;
Guido van Rossum0a697f61991-04-16 08:39:12 +00002089
Guido van Rossum282914b1991-04-04 10:42:56 +00002090#define NEXTOP() (*next_instr++)
2091#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
2092#define GETITEM(v, i) (getlistitem((v), (i)))
2093#define GETNAMEOBJ(i) (GETITEM(co->co_names, (i)))
2094
2095 locals = newdictobject();
2096 if (locals == NULL) {
2097 err_clear();
2098 return; /* For now, this is OK */
2099 }
2100
Guido van Rossum0a697f61991-04-16 08:39:12 +00002101 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00002102 for (;;) {
2103 opcode = NEXTOP();
2104 if (opcode == STOP_CODE)
2105 break;
2106 if (HAS_ARG(opcode))
2107 oparg = NEXTARG();
2108 if (opcode == STORE_NAME || opcode == IMPORT_FROM) {
2109 name = GETNAMEOBJ(oparg);
2110 if (dict2insert(locals, name, None) != 0) {
2111 DECREF(locals);
2112 return; /* Sorry */
2113 }
2114 }
2115 }
2116
2117 star_used = (dictlookup(locals, "*") != NULL);
Guido van Rossum0a697f61991-04-16 08:39:12 +00002118 next_instr = (unsigned char *) GETSTRINGVALUE(co->co_code);
Guido van Rossum282914b1991-04-04 10:42:56 +00002119 for (;;) {
2120 cur_instr = next_instr;
2121 opcode = NEXTOP();
2122 if (opcode == STOP_CODE)
2123 break;
2124 if (HAS_ARG(opcode))
2125 oparg = NEXTARG();
2126 if (opcode == LOAD_NAME) {
2127 name = GETNAMEOBJ(oparg);
Guido van Rossum83163251991-08-16 08:58:43 +00002128 if (dict2lookup(locals, name) != NULL)
Guido van Rossum282914b1991-04-04 10:42:56 +00002129 *cur_instr = LOAD_LOCAL;
Guido van Rossum83163251991-08-16 08:58:43 +00002130 else {
2131 err_clear();
2132 if (!star_used)
2133 *cur_instr = LOAD_GLOBAL;
2134 }
Guido van Rossum282914b1991-04-04 10:42:56 +00002135 }
2136 }
2137
2138 DECREF(locals);
2139}
2140
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002141codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00002142compile(n, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002143 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +00002144 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002145{
2146 struct compiling sc;
2147 codeobject *co;
Guido van Rossuma082ce41991-06-04 19:41:56 +00002148 object *v;
Guido van Rossum3f5da241990-12-20 15:06:42 +00002149 if (!com_init(&sc, filename))
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002150 return NULL;
2151 compile_node(&sc, n);
2152 com_done(&sc);
Guido van Rossuma082ce41991-06-04 19:41:56 +00002153 if (sc.c_errors == 0 && (v = newstringobject(filename)) != NULL) {
2154 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names, v);
2155 DECREF(v);
2156 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002157 else
2158 co = NULL;
2159 com_free(&sc);
Guido van Rossumfb8edfc1991-05-14 11:56:03 +00002160 if (co != NULL && filename[0] != '<')
Guido van Rossum282914b1991-04-04 10:42:56 +00002161 optimizer(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00002162 return co;
2163}