blob: 1c3f2facb2fceafcc30468ee359d9dc843bcff97 [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
44#define OFF(x) offsetof(codeobject, x)
45
46static struct memberlist code_memberlist[] = {
47 {"co_code", T_OBJECT, OFF(co_code)},
48 {"co_consts", T_OBJECT, OFF(co_consts)},
49 {"co_names", T_OBJECT, OFF(co_names)},
50 {"co_filename", T_OBJECT, OFF(co_filename)},
51 {NULL} /* Sentinel */
52};
53
54static object *
55code_getattr(co, name)
56 codeobject *co;
57 char *name;
58{
59 return getmember((char *)co, code_memberlist, name);
60}
Guido van Rossum10dc2e81990-11-18 17:27:39 +000061
62static void
Guido van Rossum3f5da241990-12-20 15:06:42 +000063code_dealloc(co)
64 codeobject *co;
Guido van Rossum10dc2e81990-11-18 17:27:39 +000065{
Guido van Rossum3f5da241990-12-20 15:06:42 +000066 XDECREF(co->co_code);
67 XDECREF(co->co_consts);
68 XDECREF(co->co_names);
69 XDECREF(co->co_filename);
70 DEL(co);
Guido van Rossum10dc2e81990-11-18 17:27:39 +000071}
72
73typeobject Codetype = {
74 OB_HEAD_INIT(&Typetype)
75 0,
76 "code",
77 sizeof(codeobject),
78 0,
79 code_dealloc, /*tp_dealloc*/
80 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +000081 code_getattr, /*tp_getattr*/
Guido van Rossum10dc2e81990-11-18 17:27:39 +000082 0, /*tp_setattr*/
83 0, /*tp_compare*/
84 0, /*tp_repr*/
85 0, /*tp_as_number*/
86 0, /*tp_as_sequence*/
87 0, /*tp_as_mapping*/
88};
89
Guido van Rossum3f5da241990-12-20 15:06:42 +000090static codeobject *newcodeobject PROTO((object *, object *, object *, char *));
Guido van Rossum10dc2e81990-11-18 17:27:39 +000091
92static codeobject *
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 Rossum3f5da241990-12-20 15:06:42 +000097 char *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 Rossum3f5da241990-12-20 15:06:42 +0000124 if ((co->co_filename = newstringobject(filename)) == NULL) {
125 DECREF(co);
126 co = NULL;
127 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000128 }
129 return co;
130}
131
132
133/* Data structure used internally */
134struct compiling {
135 object *c_code; /* string */
136 object *c_consts; /* list of objects */
137 object *c_names; /* list of strings (names) */
138 int c_nexti; /* index into c_code */
139 int c_errors; /* counts errors occurred */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000140 int c_infunction; /* set when compiling a function */
141 int c_loops; /* counts nested loops */
142 char *c_filename; /* filename of current node */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000143};
144
145/* Prototypes */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000146static int com_init PROTO((struct compiling *, char *));
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000147static void com_free PROTO((struct compiling *));
148static void com_done PROTO((struct compiling *));
149static void com_node PROTO((struct compiling *, struct _node *));
150static void com_addbyte PROTO((struct compiling *, int));
151static void com_addint PROTO((struct compiling *, int));
152static void com_addoparg PROTO((struct compiling *, int, int));
153static void com_addfwref PROTO((struct compiling *, int, int *));
154static void com_backpatch PROTO((struct compiling *, int));
155static int com_add PROTO((struct compiling *, object *, object *));
156static int com_addconst PROTO((struct compiling *, object *));
157static int com_addname PROTO((struct compiling *, object *));
158static void com_addopname PROTO((struct compiling *, int, node *));
159
160static int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000161com_init(c, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000162 struct compiling *c;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000163 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000164{
165 if ((c->c_code = newsizedstringobject((char *)NULL, 0)) == NULL)
166 goto fail_3;
167 if ((c->c_consts = newlistobject(0)) == NULL)
168 goto fail_2;
169 if ((c->c_names = newlistobject(0)) == NULL)
170 goto fail_1;
171 c->c_nexti = 0;
172 c->c_errors = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000173 c->c_infunction = 0;
174 c->c_loops = 0;
175 c->c_filename = filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000176 return 1;
177
178 fail_1:
179 DECREF(c->c_consts);
180 fail_2:
181 DECREF(c->c_code);
182 fail_3:
183 return 0;
184}
185
186static void
187com_free(c)
188 struct compiling *c;
189{
190 XDECREF(c->c_code);
191 XDECREF(c->c_consts);
192 XDECREF(c->c_names);
193}
194
195static void
196com_done(c)
197 struct compiling *c;
198{
199 if (c->c_code != NULL)
200 resizestring(&c->c_code, c->c_nexti);
201}
202
203static void
204com_addbyte(c, byte)
205 struct compiling *c;
206 int byte;
207{
208 int len;
209 if (byte < 0 || byte > 255) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000210 fprintf(stderr, "XXX compiling bad byte: %d\n", byte);
211 abort();
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000212 err_setstr(SystemError, "com_addbyte: byte out of range");
213 c->c_errors++;
214 }
215 if (c->c_code == NULL)
216 return;
217 len = getstringsize(c->c_code);
218 if (c->c_nexti >= len) {
219 if (resizestring(&c->c_code, len+1000) != 0) {
220 c->c_errors++;
221 return;
222 }
223 }
224 getstringvalue(c->c_code)[c->c_nexti++] = byte;
225}
226
227static void
228com_addint(c, x)
229 struct compiling *c;
230 int x;
231{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000232 com_addbyte(c, x & 0xff);
233 com_addbyte(c, x >> 8); /* XXX x should be positive */
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000234}
235
236static void
237com_addoparg(c, op, arg)
238 struct compiling *c;
239 int op;
240 int arg;
241{
242 com_addbyte(c, op);
243 com_addint(c, arg);
244}
245
246static void
247com_addfwref(c, op, p_anchor)
248 struct compiling *c;
249 int op;
250 int *p_anchor;
251{
252 /* Compile a forward reference for backpatching */
253 int here;
254 int anchor;
255 com_addbyte(c, op);
256 here = c->c_nexti;
257 anchor = *p_anchor;
258 *p_anchor = here;
259 com_addint(c, anchor == 0 ? 0 : here - anchor);
260}
261
262static void
263com_backpatch(c, anchor)
264 struct compiling *c;
265 int anchor; /* Must be nonzero */
266{
267 unsigned char *code = (unsigned char *) getstringvalue(c->c_code);
268 int target = c->c_nexti;
269 int lastanchor = 0;
270 int dist;
271 int prev;
272 for (;;) {
273 /* Make the JUMP instruction at anchor point to target */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000274 prev = code[anchor] + (code[anchor+1] << 8);
275 dist = target - (anchor+2);
276 code[anchor] = dist & 0xff;
277 code[anchor+1] = dist >> 8;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000278 if (!prev)
279 break;
280 lastanchor = anchor;
281 anchor -= prev;
282 }
283}
284
285/* Handle constants and names uniformly */
286
287static int
288com_add(c, list, v)
289 struct compiling *c;
290 object *list;
291 object *v;
292{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000293 int n = getlistsize(list);
294 int i;
295 for (i = n; --i >= 0; ) {
296 object *w = getlistitem(list, i);
297 if (cmpobject(v, w) == 0)
298 return i;
299 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000300 if (addlistitem(list, v) != 0)
301 c->c_errors++;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000302 return n;
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000303}
304
305static int
306com_addconst(c, v)
307 struct compiling *c;
308 object *v;
309{
310 return com_add(c, c->c_consts, v);
311}
312
313static int
314com_addname(c, v)
315 struct compiling *c;
316 object *v;
317{
318 return com_add(c, c->c_names, v);
319}
320
321static void
322com_addopname(c, op, n)
323 struct compiling *c;
324 int op;
325 node *n;
326{
327 object *v;
328 int i;
329 char *name;
330 if (TYPE(n) == STAR)
331 name = "*";
332 else {
333 REQ(n, NAME);
334 name = STR(n);
335 }
336 if ((v = newstringobject(name)) == NULL) {
337 c->c_errors++;
338 i = 255;
339 }
340 else {
341 i = com_addname(c, v);
342 DECREF(v);
343 }
344 com_addoparg(c, op, i);
345}
346
347static object *
348parsenumber(s)
349 char *s;
350{
351 extern long strtol();
352 extern double atof();
353 char *end = s;
354 long x;
355 x = strtol(s, &end, 0);
356 if (*end == '\0')
357 return newintobject(x);
358 if (*end == '.' || *end == 'e' || *end == 'E')
359 return newfloatobject(atof(s));
360 err_setstr(RuntimeError, "bad number syntax");
361 return NULL;
362}
363
364static object *
365parsestr(s)
366 char *s;
367{
368 object *v;
369 int len;
370 char *buf;
371 char *p;
372 int c;
373 if (*s != '\'') {
374 err_badcall();
375 return NULL;
376 }
377 s++;
378 len = strlen(s);
379 if (s[--len] != '\'') {
380 err_badcall();
381 return NULL;
382 }
383 if (strchr(s, '\\') == NULL)
384 return newsizedstringobject(s, len);
385 v = newsizedstringobject((char *)NULL, len);
386 p = buf = getstringvalue(v);
387 while (*s != '\0' && *s != '\'') {
388 if (*s != '\\') {
389 *p++ = *s++;
390 continue;
391 }
392 s++;
393 switch (*s++) {
394 /* XXX This assumes ASCII! */
395 case '\\': *p++ = '\\'; break;
396 case '\'': *p++ = '\''; break;
397 case 'b': *p++ = '\b'; break;
398 case 'f': *p++ = '\014'; break; /* FF */
399 case 't': *p++ = '\t'; break;
400 case 'n': *p++ = '\n'; break;
401 case 'r': *p++ = '\r'; break;
402 case 'v': *p++ = '\013'; break; /* VT */
403 case 'E': *p++ = '\033'; break; /* ESC, not C */
404 case 'a': *p++ = '\007'; break; /* BEL, not classic C */
405 case '0': case '1': case '2': case '3':
406 case '4': case '5': case '6': case '7':
407 c = s[-1] - '0';
408 if ('0' <= *s && *s <= '7') {
409 c = (c<<3) + *s++ - '0';
410 if ('0' <= *s && *s <= '7')
411 c = (c<<3) + *s++ - '0';
412 }
413 *p++ = c;
414 break;
415 case 'x':
416 if (isxdigit(*s)) {
417 sscanf(s, "%x", &c);
418 *p++ = c;
419 do {
420 s++;
421 } while (isxdigit(*s));
422 break;
423 }
424 /* FALLTHROUGH */
425 default: *p++ = '\\'; *p++ = s[-1]; break;
426 }
427 }
428 resizestring(&v, (int)(p - buf));
429 return v;
430}
431
432static void
433com_list_constructor(c, n)
434 struct compiling *c;
435 node *n;
436{
437 int len;
438 int i;
439 object *v, *w;
440 if (TYPE(n) != testlist)
441 REQ(n, exprlist);
442 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
443 len = (NCH(n) + 1) / 2;
444 for (i = 0; i < NCH(n); i += 2)
445 com_node(c, CHILD(n, i));
446 com_addoparg(c, BUILD_LIST, len);
447}
448
449static void
450com_atom(c, n)
451 struct compiling *c;
452 node *n;
453{
454 node *ch;
455 object *v;
456 int i;
457 REQ(n, atom);
458 ch = CHILD(n, 0);
459 switch (TYPE(ch)) {
460 case LPAR:
461 if (TYPE(CHILD(n, 1)) == RPAR)
462 com_addoparg(c, BUILD_TUPLE, 0);
463 else
464 com_node(c, CHILD(n, 1));
465 break;
466 case LSQB:
467 if (TYPE(CHILD(n, 1)) == RSQB)
468 com_addoparg(c, BUILD_LIST, 0);
469 else
470 com_list_constructor(c, CHILD(n, 1));
471 break;
472 case LBRACE:
473 com_addoparg(c, BUILD_MAP, 0);
474 break;
475 case BACKQUOTE:
476 com_node(c, CHILD(n, 1));
477 com_addbyte(c, UNARY_CONVERT);
478 break;
479 case NUMBER:
480 if ((v = parsenumber(STR(ch))) == NULL) {
481 c->c_errors++;
482 i = 255;
483 }
484 else {
485 i = com_addconst(c, v);
486 DECREF(v);
487 }
488 com_addoparg(c, LOAD_CONST, i);
489 break;
490 case STRING:
491 if ((v = parsestr(STR(ch))) == NULL) {
492 c->c_errors++;
493 i = 255;
494 }
495 else {
496 i = com_addconst(c, v);
497 DECREF(v);
498 }
499 com_addoparg(c, LOAD_CONST, i);
500 break;
501 case NAME:
502 com_addopname(c, LOAD_NAME, ch);
503 break;
504 default:
505 fprintf(stderr, "node type %d\n", TYPE(ch));
506 err_setstr(SystemError, "com_atom: unexpected node type");
507 c->c_errors++;
508 }
509}
510
511static void
512com_slice(c, n, op)
513 struct compiling *c;
514 node *n;
515 int op;
516{
517 if (NCH(n) == 1) {
518 com_addbyte(c, op);
519 }
520 else if (NCH(n) == 2) {
521 if (TYPE(CHILD(n, 0)) != COLON) {
522 com_node(c, CHILD(n, 0));
523 com_addbyte(c, op+1);
524 }
525 else {
526 com_node(c, CHILD(n, 1));
527 com_addbyte(c, op+2);
528 }
529 }
530 else {
531 com_node(c, CHILD(n, 0));
532 com_node(c, CHILD(n, 2));
533 com_addbyte(c, op+3);
534 }
535}
536
537static void
538com_apply_subscript(c, n)
539 struct compiling *c;
540 node *n;
541{
542 REQ(n, subscript);
543 if (NCH(n) == 1 && TYPE(CHILD(n, 0)) != COLON) {
544 /* It's a single subscript */
545 com_node(c, CHILD(n, 0));
546 com_addbyte(c, BINARY_SUBSCR);
547 }
548 else {
549 /* It's a slice: [expr] ':' [expr] */
550 com_slice(c, n, SLICE);
551 }
552}
553
554static void
555com_call_function(c, n)
556 struct compiling *c;
557 node *n; /* EITHER testlist OR ')' */
558{
559 if (TYPE(n) == RPAR) {
560 com_addbyte(c, UNARY_CALL);
561 }
562 else {
563 com_node(c, n);
564 com_addbyte(c, BINARY_CALL);
565 }
566}
567
568static void
569com_select_member(c, n)
570 struct compiling *c;
571 node *n;
572{
573 com_addopname(c, LOAD_ATTR, n);
574}
575
576static void
577com_apply_trailer(c, n)
578 struct compiling *c;
579 node *n;
580{
581 REQ(n, trailer);
582 switch (TYPE(CHILD(n, 0))) {
583 case LPAR:
584 com_call_function(c, CHILD(n, 1));
585 break;
586 case DOT:
587 com_select_member(c, CHILD(n, 1));
588 break;
589 case LSQB:
590 com_apply_subscript(c, CHILD(n, 1));
591 break;
592 default:
593 err_setstr(SystemError,
594 "com_apply_trailer: unknown trailer type");
595 c->c_errors++;
596 }
597}
598
599static void
600com_factor(c, n)
601 struct compiling *c;
602 node *n;
603{
604 int i;
605 REQ(n, factor);
606 if (TYPE(CHILD(n, 0)) == PLUS) {
607 com_factor(c, CHILD(n, 1));
608 com_addbyte(c, UNARY_POSITIVE);
609 }
610 else if (TYPE(CHILD(n, 0)) == MINUS) {
611 com_factor(c, CHILD(n, 1));
612 com_addbyte(c, UNARY_NEGATIVE);
613 }
614 else {
615 com_atom(c, CHILD(n, 0));
616 for (i = 1; i < NCH(n); i++)
617 com_apply_trailer(c, CHILD(n, i));
618 }
619}
620
621static void
622com_term(c, n)
623 struct compiling *c;
624 node *n;
625{
626 int i;
627 int op;
628 REQ(n, term);
629 com_factor(c, CHILD(n, 0));
630 for (i = 2; i < NCH(n); i += 2) {
631 com_factor(c, CHILD(n, i));
632 switch (TYPE(CHILD(n, i-1))) {
633 case STAR:
634 op = BINARY_MULTIPLY;
635 break;
636 case SLASH:
637 op = BINARY_DIVIDE;
638 break;
639 case PERCENT:
640 op = BINARY_MODULO;
641 break;
642 default:
643 err_setstr(SystemError,
644 "com_term: term operator not *, / or %");
645 c->c_errors++;
646 op = 255;
647 }
648 com_addbyte(c, op);
649 }
650}
651
652static void
653com_expr(c, n)
654 struct compiling *c;
655 node *n;
656{
657 int i;
658 int op;
659 REQ(n, expr);
660 com_term(c, CHILD(n, 0));
661 for (i = 2; i < NCH(n); i += 2) {
662 com_term(c, CHILD(n, i));
663 switch (TYPE(CHILD(n, i-1))) {
664 case PLUS:
665 op = BINARY_ADD;
666 break;
667 case MINUS:
668 op = BINARY_SUBTRACT;
669 break;
670 default:
671 err_setstr(SystemError,
672 "com_expr: expr operator not + or -");
673 c->c_errors++;
674 op = 255;
675 }
676 com_addbyte(c, op);
677 }
678}
679
680static enum cmp_op
681cmp_type(n)
682 node *n;
683{
684 REQ(n, comp_op);
685 /* comp_op: '<' | '>' | '=' | '>' '=' | '<' '=' | '<' '>'
686 | 'in' | 'not' 'in' | 'is' | 'is' not' */
687 if (NCH(n) == 1) {
688 n = CHILD(n, 0);
689 switch (TYPE(n)) {
690 case LESS: return LT;
691 case GREATER: return GT;
692 case EQUAL: return EQ;
693 case NAME: if (strcmp(STR(n), "in") == 0) return IN;
694 if (strcmp(STR(n), "is") == 0) return IS;
695 }
696 }
697 else if (NCH(n) == 2) {
698 int t2 = TYPE(CHILD(n, 1));
699 switch (TYPE(CHILD(n, 0))) {
700 case LESS: if (t2 == EQUAL) return LE;
701 if (t2 == GREATER) return NE;
702 break;
703 case GREATER: if (t2 == EQUAL) return GE;
704 break;
705 case NAME: if (strcmp(STR(CHILD(n, 1)), "in") == 0)
706 return NOT_IN;
707 if (strcmp(STR(CHILD(n, 0)), "is") == 0)
708 return IS_NOT;
709 }
710 }
711 return BAD;
712}
713
714static void
715com_comparison(c, n)
716 struct compiling *c;
717 node *n;
718{
719 int i;
720 enum cmp_op op;
721 int anchor;
722 REQ(n, comparison); /* comparison: expr (comp_op expr)* */
723 com_expr(c, CHILD(n, 0));
724 if (NCH(n) == 1)
725 return;
726
727 /****************************************************************
728 The following code is generated for all but the last
729 comparison in a chain:
730
731 label: on stack: opcode: jump to:
732
733 a <code to load b>
734 a, b DUP_TOP
735 a, b, b ROT_THREE
736 b, a, b COMPARE_OP
737 b, 0-or-1 JUMP_IF_FALSE L1
738 b, 1 POP_TOP
739 b
740
741 We are now ready to repeat this sequence for the next
742 comparison in the chain.
743
744 For the last we generate:
745
746 b <code to load c>
747 b, c COMPARE_OP
748 0-or-1
749
750 If there were any jumps to L1 (i.e., there was more than one
751 comparison), we generate:
752
753 0-or-1 JUMP_FORWARD L2
754 L1: b, 0 ROT_TWO
755 0, b POP_TOP
756 0
757 L2:
758 ****************************************************************/
759
760 anchor = 0;
761
762 for (i = 2; i < NCH(n); i += 2) {
763 com_expr(c, CHILD(n, i));
764 if (i+2 < NCH(n)) {
765 com_addbyte(c, DUP_TOP);
766 com_addbyte(c, ROT_THREE);
767 }
768 op = cmp_type(CHILD(n, i-1));
769 if (op == BAD) {
770 err_setstr(SystemError,
771 "com_comparison: unknown comparison op");
772 c->c_errors++;
773 }
774 com_addoparg(c, COMPARE_OP, op);
775 if (i+2 < NCH(n)) {
776 com_addfwref(c, JUMP_IF_FALSE, &anchor);
777 com_addbyte(c, POP_TOP);
778 }
779 }
780
781 if (anchor) {
782 int anchor2 = 0;
783 com_addfwref(c, JUMP_FORWARD, &anchor2);
784 com_backpatch(c, anchor);
785 com_addbyte(c, ROT_TWO);
786 com_addbyte(c, POP_TOP);
787 com_backpatch(c, anchor2);
788 }
789}
790
791static void
792com_not_test(c, n)
793 struct compiling *c;
794 node *n;
795{
796 REQ(n, not_test); /* 'not' not_test | comparison */
797 if (NCH(n) == 1) {
798 com_comparison(c, CHILD(n, 0));
799 }
800 else {
801 com_not_test(c, CHILD(n, 1));
802 com_addbyte(c, UNARY_NOT);
803 }
804}
805
806static void
807com_and_test(c, n)
808 struct compiling *c;
809 node *n;
810{
811 int i;
812 int anchor;
813 REQ(n, and_test); /* not_test ('and' not_test)* */
814 anchor = 0;
815 i = 0;
816 for (;;) {
817 com_not_test(c, CHILD(n, i));
818 if ((i += 2) >= NCH(n))
819 break;
820 com_addfwref(c, JUMP_IF_FALSE, &anchor);
821 com_addbyte(c, POP_TOP);
822 }
823 if (anchor)
824 com_backpatch(c, anchor);
825}
826
827static void
828com_test(c, n)
829 struct compiling *c;
830 node *n;
831{
832 int i;
833 int anchor;
834 REQ(n, test); /* and_test ('and' and_test)* */
835 anchor = 0;
836 i = 0;
837 for (;;) {
838 com_and_test(c, CHILD(n, i));
839 if ((i += 2) >= NCH(n))
840 break;
841 com_addfwref(c, JUMP_IF_TRUE, &anchor);
842 com_addbyte(c, POP_TOP);
843 }
844 if (anchor)
845 com_backpatch(c, anchor);
846}
847
848static void
849com_list(c, n)
850 struct compiling *c;
851 node *n;
852{
853 /* exprlist: expr (',' expr)* [',']; likewise for testlist */
854 if (NCH(n) == 1) {
855 com_node(c, CHILD(n, 0));
856 }
857 else {
858 int i;
859 int len;
860 len = (NCH(n) + 1) / 2;
861 for (i = 0; i < NCH(n); i += 2)
862 com_node(c, CHILD(n, i));
863 com_addoparg(c, BUILD_TUPLE, len);
864 }
865}
866
867
868/* Begin of assignment compilation */
869
870static void com_assign_name PROTO((struct compiling *, node *, int));
871static void com_assign PROTO((struct compiling *, node *, int));
872
873static void
874com_assign_attr(c, n, assigning)
875 struct compiling *c;
876 node *n;
877 int assigning;
878{
879 com_addopname(c, assigning ? STORE_ATTR : DELETE_ATTR, n);
880}
881
882static void
883com_assign_slice(c, n, assigning)
884 struct compiling *c;
885 node *n;
886 int assigning;
887{
888 com_slice(c, n, assigning ? STORE_SLICE : DELETE_SLICE);
889}
890
891static void
892com_assign_subscript(c, n, assigning)
893 struct compiling *c;
894 node *n;
895 int assigning;
896{
897 com_node(c, n);
898 com_addbyte(c, assigning ? STORE_SUBSCR : DELETE_SUBSCR);
899}
900
901static void
902com_assign_trailer(c, n, assigning)
903 struct compiling *c;
904 node *n;
905 int assigning;
906{
907 char *name;
908 REQ(n, trailer);
909 switch (TYPE(CHILD(n, 0))) {
910 case LPAR: /* '(' [exprlist] ')' */
911 err_setstr(TypeError, "can't assign to function call");
912 c->c_errors++;
913 break;
914 case DOT: /* '.' NAME */
915 com_assign_attr(c, CHILD(n, 1), assigning);
916 break;
917 case LSQB: /* '[' subscript ']' */
918 n = CHILD(n, 1);
919 REQ(n, subscript); /* subscript: expr | [expr] ':' [expr] */
920 if (NCH(n) > 1 || TYPE(CHILD(n, 0)) == COLON)
921 com_assign_slice(c, n, assigning);
922 else
923 com_assign_subscript(c, CHILD(n, 0), assigning);
924 break;
925 default:
926 err_setstr(TypeError, "unknown trailer type");
927 c->c_errors++;
928 }
929}
930
931static void
932com_assign_tuple(c, n, assigning)
933 struct compiling *c;
934 node *n;
935 int assigning;
936{
937 int i;
938 if (TYPE(n) != testlist)
939 REQ(n, exprlist);
940 if (assigning)
941 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
942 for (i = 0; i < NCH(n); i += 2)
943 com_assign(c, CHILD(n, i), assigning);
944}
945
946static void
947com_assign_list(c, n, assigning)
948 struct compiling *c;
949 node *n;
950 int assigning;
951{
952 int i;
953 if (assigning)
954 com_addoparg(c, UNPACK_LIST, (NCH(n)+1)/2);
955 for (i = 0; i < NCH(n); i += 2)
956 com_assign(c, CHILD(n, i), assigning);
957}
958
959static void
960com_assign_name(c, n, assigning)
961 struct compiling *c;
962 node *n;
963 int assigning;
964{
965 REQ(n, NAME);
966 com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
967}
968
969static void
970com_assign(c, n, assigning)
971 struct compiling *c;
972 node *n;
973 int assigning;
974{
975 /* Loop to avoid trivial recursion */
976 for (;;) {
977 switch (TYPE(n)) {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000978
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000979 case exprlist:
980 case testlist:
981 if (NCH(n) > 1) {
982 com_assign_tuple(c, n, assigning);
983 return;
984 }
985 n = CHILD(n, 0);
986 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000987
Guido van Rossum10dc2e81990-11-18 17:27:39 +0000988 case test:
989 case and_test:
990 case not_test:
991 if (NCH(n) > 1) {
992 err_setstr(TypeError,
993 "can't assign to operator");
994 c->c_errors++;
995 return;
996 }
997 n = CHILD(n, 0);
998 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +0000999
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001000 case comparison:
1001 if (NCH(n) > 1) {
1002 err_setstr(TypeError,
1003 "can't assign to operator");
1004 c->c_errors++;
1005 return;
1006 }
1007 n = CHILD(n, 0);
1008 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001009
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001010 case expr:
1011 if (NCH(n) > 1) {
1012 err_setstr(TypeError,
1013 "can't assign to operator");
1014 c->c_errors++;
1015 return;
1016 }
1017 n = CHILD(n, 0);
1018 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001019
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001020 case term:
1021 if (NCH(n) > 1) {
1022 err_setstr(TypeError,
1023 "can't assign to operator");
1024 c->c_errors++;
1025 return;
1026 }
1027 n = CHILD(n, 0);
1028 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001029
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001030 case factor: /* ('+'|'-') factor | atom trailer* */
1031 if (TYPE(CHILD(n, 0)) != atom) { /* '+' | '-' */
1032 err_setstr(TypeError,
1033 "can't assign to operator");
1034 c->c_errors++;
1035 return;
1036 }
1037 if (NCH(n) > 1) { /* trailer present */
1038 int i;
1039 com_node(c, CHILD(n, 0));
1040 for (i = 1; i+1 < NCH(n); i++) {
1041 com_apply_trailer(c, CHILD(n, i));
1042 } /* NB i is still alive */
1043 com_assign_trailer(c,
1044 CHILD(n, i), assigning);
1045 return;
1046 }
1047 n = CHILD(n, 0);
1048 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001049
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001050 case atom:
1051 switch (TYPE(CHILD(n, 0))) {
1052 case LPAR:
1053 n = CHILD(n, 1);
1054 if (TYPE(n) == RPAR) {
1055 /* XXX Should allow () = () ??? */
1056 err_setstr(TypeError,
1057 "can't assign to ()");
1058 c->c_errors++;
1059 return;
1060 }
1061 break;
1062 case LSQB:
1063 n = CHILD(n, 1);
1064 if (TYPE(n) == RSQB) {
1065 err_setstr(TypeError,
1066 "can't assign to []");
1067 c->c_errors++;
1068 return;
1069 }
1070 com_assign_list(c, n, assigning);
1071 return;
1072 case NAME:
1073 com_assign_name(c, CHILD(n, 0), assigning);
1074 return;
1075 default:
1076 err_setstr(TypeError,
1077 "can't assign to constant");
1078 c->c_errors++;
1079 return;
1080 }
1081 break;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001082
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001083 default:
1084 fprintf(stderr, "node type %d\n", TYPE(n));
1085 err_setstr(SystemError, "com_assign: bad node");
1086 c->c_errors++;
1087 return;
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001088
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001089 }
1090 }
1091}
1092
1093static void
1094com_expr_stmt(c, n)
1095 struct compiling *c;
1096 node *n;
1097{
1098 REQ(n, expr_stmt); /* exprlist ('=' exprlist)* NEWLINE */
1099 com_node(c, CHILD(n, NCH(n)-2));
1100 if (NCH(n) == 2) {
1101 com_addbyte(c, PRINT_EXPR);
1102 }
1103 else {
1104 int i;
1105 for (i = 0; i < NCH(n)-3; i+=2) {
1106 if (i+2 < NCH(n)-3)
1107 com_addbyte(c, DUP_TOP);
1108 com_assign(c, CHILD(n, i), 1/*assign*/);
1109 }
1110 }
1111}
1112
1113static void
1114com_print_stmt(c, n)
1115 struct compiling *c;
1116 node *n;
1117{
1118 int i;
1119 REQ(n, print_stmt); /* 'print' (test ',')* [test] NEWLINE */
1120 for (i = 1; i+1 < NCH(n); i += 2) {
1121 com_node(c, CHILD(n, i));
1122 com_addbyte(c, PRINT_ITEM);
1123 }
1124 if (TYPE(CHILD(n, NCH(n)-2)) != COMMA)
1125 com_addbyte(c, PRINT_NEWLINE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001126 /* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001127}
1128
1129static void
1130com_return_stmt(c, n)
1131 struct compiling *c;
1132 node *n;
1133{
1134 REQ(n, return_stmt); /* 'return' [testlist] NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001135 if (!c->c_infunction) {
1136 err_setstr(TypeError, "'return' outside function");
1137 c->c_errors++;
1138 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001139 if (NCH(n) == 2)
1140 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1141 else
1142 com_node(c, CHILD(n, 1));
1143 com_addbyte(c, RETURN_VALUE);
1144}
1145
1146static void
1147com_raise_stmt(c, n)
1148 struct compiling *c;
1149 node *n;
1150{
1151 REQ(n, raise_stmt); /* 'raise' expr [',' expr] NEWLINE */
1152 com_node(c, CHILD(n, 1));
1153 if (NCH(n) > 3)
1154 com_node(c, CHILD(n, 3));
1155 else
1156 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1157 com_addbyte(c, RAISE_EXCEPTION);
1158}
1159
1160static void
1161com_import_stmt(c, n)
1162 struct compiling *c;
1163 node *n;
1164{
1165 int i;
1166 REQ(n, import_stmt);
1167 /* 'import' NAME (',' NAME)* NEWLINE |
1168 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE */
1169 if (STR(CHILD(n, 0))[0] == 'f') {
1170 /* 'from' NAME 'import' ... */
1171 REQ(CHILD(n, 1), NAME);
1172 com_addopname(c, IMPORT_NAME, CHILD(n, 1));
1173 for (i = 3; i < NCH(n); i += 2)
1174 com_addopname(c, IMPORT_FROM, CHILD(n, i));
1175 com_addbyte(c, POP_TOP);
1176 }
1177 else {
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001178 /* 'import' ... */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001179 for (i = 1; i < NCH(n); i += 2) {
1180 com_addopname(c, IMPORT_NAME, CHILD(n, i));
1181 com_addopname(c, STORE_NAME, CHILD(n, i));
1182 }
1183 }
1184}
1185
1186static void
1187com_if_stmt(c, n)
1188 struct compiling *c;
1189 node *n;
1190{
1191 int i;
1192 int anchor = 0;
1193 REQ(n, if_stmt);
1194 /*'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] */
1195 for (i = 0; i+3 < NCH(n); i+=4) {
1196 int a = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001197 node *ch = CHILD(n, i+1);
1198 if (i > 0)
1199 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001200 com_node(c, CHILD(n, i+1));
1201 com_addfwref(c, JUMP_IF_FALSE, &a);
1202 com_addbyte(c, POP_TOP);
1203 com_node(c, CHILD(n, i+3));
1204 com_addfwref(c, JUMP_FORWARD, &anchor);
1205 com_backpatch(c, a);
1206 com_addbyte(c, POP_TOP);
1207 }
1208 if (i+2 < NCH(n))
1209 com_node(c, CHILD(n, i+2));
1210 com_backpatch(c, anchor);
1211}
1212
1213static void
1214com_while_stmt(c, n)
1215 struct compiling *c;
1216 node *n;
1217{
1218 int break_anchor = 0;
1219 int anchor = 0;
1220 int begin;
1221 REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
1222 com_addfwref(c, SETUP_LOOP, &break_anchor);
1223 begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001224 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001225 com_node(c, CHILD(n, 1));
1226 com_addfwref(c, JUMP_IF_FALSE, &anchor);
1227 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001228 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001229 com_node(c, CHILD(n, 3));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001230 c->c_loops--;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001231 com_addoparg(c, JUMP_ABSOLUTE, begin);
1232 com_backpatch(c, anchor);
1233 com_addbyte(c, POP_TOP);
1234 com_addbyte(c, POP_BLOCK);
1235 if (NCH(n) > 4)
1236 com_node(c, CHILD(n, 6));
1237 com_backpatch(c, break_anchor);
1238}
1239
1240static void
1241com_for_stmt(c, n)
1242 struct compiling *c;
1243 node *n;
1244{
1245 object *v;
1246 int break_anchor = 0;
1247 int anchor = 0;
1248 int begin;
1249 REQ(n, for_stmt);
1250 /* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
1251 com_addfwref(c, SETUP_LOOP, &break_anchor);
1252 com_node(c, CHILD(n, 3));
1253 v = newintobject(0L);
1254 if (v == NULL)
1255 c->c_errors++;
1256 com_addoparg(c, LOAD_CONST, com_addconst(c, v));
1257 XDECREF(v);
1258 begin = c->c_nexti;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001259 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001260 com_addfwref(c, FOR_LOOP, &anchor);
1261 com_assign(c, CHILD(n, 1), 1/*assigning*/);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001262 c->c_loops++;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001263 com_node(c, CHILD(n, 5));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001264 c->c_loops--;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001265 com_addoparg(c, JUMP_ABSOLUTE, begin);
1266 com_backpatch(c, anchor);
1267 com_addbyte(c, POP_BLOCK);
1268 if (NCH(n) > 8)
1269 com_node(c, CHILD(n, 8));
1270 com_backpatch(c, break_anchor);
1271}
1272
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001273/* Although 'execpt' and 'finally' clauses can be combined
1274 syntactically, they are compiled separately. In fact,
1275 try: S
1276 except E1: S1
1277 except E2: S2
1278 ...
1279 finally: Sf
1280 is equivalent to
1281 try:
1282 try: S
1283 except E1: S1
1284 except E2: S2
1285 ...
1286 finally: Sf
1287 meaning that the 'finally' clause is entered even if things
1288 go wrong again in an exception handler. Note that this is
1289 not the case for exception handlers: at most one is entered.
1290
1291 Code generated for "try: S finally: Sf" is as follows:
1292
1293 SETUP_FINALLY L
1294 <code for S>
1295 POP_BLOCK
1296 LOAD_CONST <nil>
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001297 L: <code for Sf>
1298 END_FINALLY
1299
1300 The special instructions use the block stack. Each block
1301 stack entry contains the instruction that created it (here
1302 SETUP_FINALLY), the level of the value stack at the time the
1303 block stack entry was created, and a label (here L).
1304
1305 SETUP_FINALLY:
1306 Pushes the current value stack level and the label
1307 onto the block stack.
1308 POP_BLOCK:
1309 Pops en entry from the block stack, and pops the value
1310 stack until its level is the same as indicated on the
1311 block stack. (The label is ignored.)
1312 END_FINALLY:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001313 Pops a variable number of entries from the *value* stack
1314 and re-raises the exception they specify. The number of
1315 entries popped depends on the (pseudo) exception type.
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001316
1317 The block stack is unwound when an exception is raised:
1318 when a SETUP_FINALLY entry is found, the exception is pushed
1319 onto the value stack (and the exception condition is cleared),
1320 and the interpreter jumps to the label gotten from the block
1321 stack.
1322
1323 Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
Guido van Rossum3f5da241990-12-20 15:06:42 +00001324 (The contents of the value stack is shown in [], with the top
1325 at the right; 'tb' is trace-back info, 'val' the exception's
1326 associated value, and 'exc' the exception.)
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001327
1328 Value stack Label Instruction Argument
1329 [] SETUP_EXCEPT L1
1330 [] <code for S>
1331 [] POP_BLOCK
1332 [] JUMP_FORWARD L0
1333
Guido van Rossum3f5da241990-12-20 15:06:42 +00001334 [tb, val, exc] L1: DUP )
1335 [tb, val, exc, exc] <evaluate E1> )
1336 [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
1337 [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
1338 [tb, val, exc, 1] POP )
1339 [tb, val, exc] POP
1340 [tb, val] <assign to V1> (or POP if no V1)
1341 [tb] POP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001342 [] <code for S1>
1343 JUMP_FORWARD L0
1344
Guido van Rossum3f5da241990-12-20 15:06:42 +00001345 [tb, val, exc, 0] L2: POP
1346 [tb, val, exc] DUP
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001347 .............................etc.......................
1348
Guido van Rossum3f5da241990-12-20 15:06:42 +00001349 [tb, val, exc, 0] Ln+1: POP
1350 [tb, val, exc] END_FINALLY # re-raise exception
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001351
1352 [] L0: <next statement>
1353
1354 Of course, parts are not generated if Vi or Ei is not present.
1355*/
1356
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001357static void
1358com_try_stmt(c, n)
1359 struct compiling *c;
1360 node *n;
1361{
1362 int finally_anchor = 0;
1363 int except_anchor = 0;
1364 REQ(n, try_stmt);
1365 /* 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001366
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001367 if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
1368 /* Have a 'finally' clause */
1369 com_addfwref(c, SETUP_FINALLY, &finally_anchor);
1370 }
1371 if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
1372 /* Have an 'except' clause */
1373 com_addfwref(c, SETUP_EXCEPT, &except_anchor);
1374 }
1375 com_node(c, CHILD(n, 2));
1376 if (except_anchor) {
1377 int end_anchor = 0;
1378 int i;
1379 node *ch;
1380 com_addbyte(c, POP_BLOCK);
1381 com_addfwref(c, JUMP_FORWARD, &end_anchor);
1382 com_backpatch(c, except_anchor);
1383 for (i = 3;
1384 i < NCH(n) && TYPE(ch = CHILD(n, i)) == except_clause;
1385 i += 3) {
1386 /* except_clause: 'except' [expr [',' expr]] */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001387 if (except_anchor == 0) {
1388 err_setstr(TypeError,
1389 "default 'except:' must be last");
1390 c->c_errors++;
1391 break;
1392 }
1393 except_anchor = 0;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001394 com_addoparg(c, SET_LINENO, ch->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001395 if (NCH(ch) > 1) {
1396 com_addbyte(c, DUP_TOP);
1397 com_node(c, CHILD(ch, 1));
1398 com_addoparg(c, COMPARE_OP, EXC_MATCH);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001399 com_addfwref(c, JUMP_IF_FALSE, &except_anchor);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001400 com_addbyte(c, POP_TOP);
1401 }
1402 com_addbyte(c, POP_TOP);
1403 if (NCH(ch) > 3)
1404 com_assign(c, CHILD(ch, 3), 1/*assigning*/);
1405 else
1406 com_addbyte(c, POP_TOP);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001407 com_addbyte(c, POP_TOP);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001408 com_node(c, CHILD(n, i+2));
1409 com_addfwref(c, JUMP_FORWARD, &end_anchor);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001410 if (except_anchor) {
1411 com_backpatch(c, except_anchor);
1412 com_addbyte(c, POP_TOP);
1413 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001414 }
1415 com_addbyte(c, END_FINALLY);
1416 com_backpatch(c, end_anchor);
1417 }
1418 if (finally_anchor) {
Guido van Rossum3f5da241990-12-20 15:06:42 +00001419 node *ch;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001420 com_addbyte(c, POP_BLOCK);
1421 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001422 com_backpatch(c, finally_anchor);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001423 ch = CHILD(n, NCH(n)-1);
1424 com_addoparg(c, SET_LINENO, ch->n_lineno);
1425 com_node(c, ch);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001426 com_addbyte(c, END_FINALLY);
1427 }
1428}
1429
1430static void
1431com_suite(c, n)
1432 struct compiling *c;
1433 node *n;
1434{
1435 REQ(n, suite);
1436 /* simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT */
1437 if (NCH(n) == 1) {
1438 com_node(c, CHILD(n, 0));
1439 }
1440 else {
1441 int i;
1442 for (i = 0; i < NCH(n); i++) {
1443 node *ch = CHILD(n, i);
1444 if (TYPE(ch) == stmt)
1445 com_node(c, ch);
1446 }
1447 }
1448}
1449
1450static void
1451com_funcdef(c, n)
1452 struct compiling *c;
1453 node *n;
1454{
1455 object *v;
1456 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001457 v = (object *)compile(n, c->c_filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001458 if (v == NULL)
1459 c->c_errors++;
1460 else {
1461 int i = com_addconst(c, v);
1462 com_addoparg(c, LOAD_CONST, i);
1463 com_addbyte(c, BUILD_FUNCTION);
1464 com_addopname(c, STORE_NAME, CHILD(n, 1));
1465 DECREF(v);
1466 }
1467}
1468
1469static void
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001470com_bases(c, n)
1471 struct compiling *c;
1472 node *n;
1473{
1474 int i, nbases;
1475 REQ(n, baselist);
1476 /*
1477 baselist: atom arguments (',' atom arguments)*
1478 arguments: '(' [testlist] ')'
1479 */
1480 for (i = 0; i < NCH(n); i += 3)
1481 com_node(c, CHILD(n, i));
1482 com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
1483}
1484
1485static void
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001486com_classdef(c, n)
1487 struct compiling *c;
1488 node *n;
1489{
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001490 object *v;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001491 REQ(n, classdef);
1492 /*
1493 classdef: 'class' NAME parameters ['=' baselist] ':' suite
1494 baselist: atom arguments (',' atom arguments)*
1495 arguments: '(' [testlist] ')'
1496 */
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001497 if (NCH(n) == 7)
1498 com_bases(c, CHILD(n, 4));
1499 else
1500 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001501 v = (object *)compile(n, c->c_filename);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001502 if (v == NULL)
1503 c->c_errors++;
1504 else {
1505 int i = com_addconst(c, v);
1506 com_addoparg(c, LOAD_CONST, i);
1507 com_addbyte(c, BUILD_FUNCTION);
1508 com_addbyte(c, UNARY_CALL);
1509 com_addbyte(c, BUILD_CLASS);
1510 com_addopname(c, STORE_NAME, CHILD(n, 1));
1511 DECREF(v);
1512 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001513}
1514
1515static void
1516com_node(c, n)
1517 struct compiling *c;
1518 node *n;
1519{
1520 switch (TYPE(n)) {
1521
1522 /* Definition nodes */
1523
1524 case funcdef:
1525 com_funcdef(c, n);
1526 break;
1527 case classdef:
1528 com_classdef(c, n);
1529 break;
1530
1531 /* Trivial parse tree nodes */
1532
1533 case stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001534 case flow_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001535 com_node(c, CHILD(n, 0));
1536 break;
1537
1538 case simple_stmt:
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001539 case compound_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001540 com_addoparg(c, SET_LINENO, n->n_lineno);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001541 com_node(c, CHILD(n, 0));
1542 break;
1543
1544 /* Statement nodes */
1545
1546 case expr_stmt:
1547 com_expr_stmt(c, n);
1548 break;
1549 case print_stmt:
1550 com_print_stmt(c, n);
1551 break;
1552 case del_stmt: /* 'del' exprlist NEWLINE */
1553 com_assign(c, CHILD(n, 1), 0/*delete*/);
1554 break;
1555 case pass_stmt:
1556 break;
1557 case break_stmt:
Guido van Rossum3f5da241990-12-20 15:06:42 +00001558 if (c->c_loops == 0) {
1559 err_setstr(TypeError, "'break' outside loop");
1560 c->c_errors++;
1561 }
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001562 com_addbyte(c, BREAK_LOOP);
1563 break;
1564 case return_stmt:
1565 com_return_stmt(c, n);
1566 break;
1567 case raise_stmt:
1568 com_raise_stmt(c, n);
1569 break;
1570 case import_stmt:
1571 com_import_stmt(c, n);
1572 break;
1573 case if_stmt:
1574 com_if_stmt(c, n);
1575 break;
1576 case while_stmt:
1577 com_while_stmt(c, n);
1578 break;
1579 case for_stmt:
1580 com_for_stmt(c, n);
1581 break;
1582 case try_stmt:
1583 com_try_stmt(c, n);
1584 break;
1585 case suite:
1586 com_suite(c, n);
1587 break;
1588
1589 /* Expression nodes */
1590
1591 case testlist:
1592 com_list(c, n);
1593 break;
1594 case test:
1595 com_test(c, n);
1596 break;
1597 case and_test:
1598 com_and_test(c, n);
1599 break;
1600 case not_test:
1601 com_not_test(c, n);
1602 break;
1603 case comparison:
1604 com_comparison(c, n);
1605 break;
1606 case exprlist:
1607 com_list(c, n);
1608 break;
1609 case expr:
1610 com_expr(c, n);
1611 break;
1612 case term:
1613 com_term(c, n);
1614 break;
1615 case factor:
1616 com_factor(c, n);
1617 break;
1618 case atom:
1619 com_atom(c, n);
1620 break;
1621
1622 default:
1623 fprintf(stderr, "node type %d\n", TYPE(n));
1624 err_setstr(SystemError, "com_node: unexpected node type");
1625 c->c_errors++;
1626 }
1627}
1628
1629static void com_fplist PROTO((struct compiling *, node *));
1630
1631static void
1632com_fpdef(c, n)
1633 struct compiling *c;
1634 node *n;
1635{
1636 REQ(n, fpdef); /* fpdef: NAME | '(' fplist ')' */
1637 if (TYPE(CHILD(n, 0)) == LPAR)
1638 com_fplist(c, CHILD(n, 1));
1639 else
1640 com_addopname(c, STORE_NAME, CHILD(n, 0));
1641}
1642
1643static void
1644com_fplist(c, n)
1645 struct compiling *c;
1646 node *n;
1647{
1648 REQ(n, fplist); /* fplist: fpdef (',' fpdef)* */
1649 if (NCH(n) == 1) {
1650 com_fpdef(c, CHILD(n, 0));
1651 }
1652 else {
1653 int i;
1654 com_addoparg(c, UNPACK_TUPLE, (NCH(n)+1)/2);
1655 for (i = 0; i < NCH(n); i += 2)
1656 com_fpdef(c, CHILD(n, i));
1657 }
1658}
1659
1660static void
1661com_file_input(c, n)
1662 struct compiling *c;
1663 node *n;
1664{
1665 int i;
1666 REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
1667 for (i = 0; i < NCH(n); i++) {
1668 node *ch = CHILD(n, i);
1669 if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
1670 com_node(c, ch);
1671 }
1672}
1673
1674/* Top-level compile-node interface */
1675
1676static void
1677compile_funcdef(c, n)
1678 struct compiling *c;
1679 node *n;
1680{
1681 node *ch;
1682 REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
1683 ch = CHILD(n, 2); /* parameters: '(' [fplist] ')' */
1684 ch = CHILD(ch, 1); /* ')' | fplist */
1685 if (TYPE(ch) == RPAR)
1686 com_addbyte(c, REFUSE_ARGS);
1687 else {
1688 com_addbyte(c, REQUIRE_ARGS);
1689 com_fplist(c, ch);
1690 }
Guido van Rossum3f5da241990-12-20 15:06:42 +00001691 c->c_infunction = 1;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001692 com_node(c, CHILD(n, 4));
Guido van Rossum3f5da241990-12-20 15:06:42 +00001693 c->c_infunction = 0;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001694 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1695 com_addbyte(c, RETURN_VALUE);
1696}
1697
1698static void
1699compile_node(c, n)
1700 struct compiling *c;
1701 node *n;
1702{
Guido van Rossum3f5da241990-12-20 15:06:42 +00001703 com_addoparg(c, SET_LINENO, n->n_lineno);
1704
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001705 switch (TYPE(n)) {
1706
Guido van Rossum4c417781991-01-21 16:09:22 +00001707 case single_input: /* One interactive command */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001708 /* NEWLINE | simple_stmt | compound_stmt NEWLINE */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001709 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001710 n = CHILD(n, 0);
1711 if (TYPE(n) != NEWLINE)
1712 com_node(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001713 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1714 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001715 break;
1716
Guido van Rossum4c417781991-01-21 16:09:22 +00001717 case file_input: /* A whole file, or built-in function exec() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001718 com_addbyte(c, REFUSE_ARGS);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001719 com_file_input(c, n);
Guido van Rossum3f5da241990-12-20 15:06:42 +00001720 com_addoparg(c, LOAD_CONST, com_addconst(c, None));
1721 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001722 break;
1723
Guido van Rossum4c417781991-01-21 16:09:22 +00001724 case expr_input: /* Built-in function eval() */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001725 com_addbyte(c, REFUSE_ARGS);
1726 com_node(c, CHILD(n, 0));
1727 com_addbyte(c, RETURN_VALUE);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001728 break;
1729
Guido van Rossum4c417781991-01-21 16:09:22 +00001730 case eval_input: /* Built-in function input() */
1731 com_addbyte(c, REFUSE_ARGS);
1732 com_node(c, CHILD(n, 0));
1733 com_addbyte(c, RETURN_VALUE);
1734 break;
1735
1736 case funcdef: /* A function definition */
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001737 compile_funcdef(c, n);
1738 break;
1739
Guido van Rossum4c417781991-01-21 16:09:22 +00001740 case classdef: /* A class definition */
Guido van Rossum3f5da241990-12-20 15:06:42 +00001741 /* 'class' NAME parameters ['=' baselist] ':' suite */
1742 com_addbyte(c, REFUSE_ARGS);
1743 com_node(c, CHILD(n, NCH(n)-1));
1744 com_addbyte(c, LOAD_LOCALS);
1745 com_addbyte(c, RETURN_VALUE);
Guido van Rossumd6f3bc21990-11-18 17:35:03 +00001746 break;
1747
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001748 default:
1749 fprintf(stderr, "node type %d\n", TYPE(n));
1750 err_setstr(SystemError, "compile_node: unexpected node type");
1751 c->c_errors++;
1752 }
1753}
1754
1755codeobject *
Guido van Rossum3f5da241990-12-20 15:06:42 +00001756compile(n, filename)
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001757 node *n;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001758 char *filename;
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001759{
1760 struct compiling sc;
1761 codeobject *co;
Guido van Rossum3f5da241990-12-20 15:06:42 +00001762 if (!com_init(&sc, filename))
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001763 return NULL;
1764 compile_node(&sc, n);
1765 com_done(&sc);
1766 if (sc.c_errors == 0)
Guido van Rossum3f5da241990-12-20 15:06:42 +00001767 co = newcodeobject(sc.c_code, sc.c_consts, sc.c_names, filename);
Guido van Rossum10dc2e81990-11-18 17:27:39 +00001768 else
1769 co = NULL;
1770 com_free(&sc);
1771 return co;
1772}