Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4bad92c

Browse files
committed
New syntax: semicolons, continue statement.
For the latter we must keep track of the current block's type. (We can't continue through a try statement, sigh.()
1 parent 76a00af commit 4bad92c

1 file changed

Lines changed: 123 additions & 21 deletions

File tree

Python/compile.c

Lines changed: 123 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ newcodeobject(code, consts, names, filename)
129129

130130

131131
/* Data structure used internally */
132+
133+
#define MAXBLOCKS 20 /* Max static block nesting within a function */
134+
132135
struct compiling {
133136
object *c_code; /* string */
134137
object *c_consts; /* list of objects */
@@ -137,10 +140,45 @@ struct compiling {
137140
int c_errors; /* counts errors occurred */
138141
int c_infunction; /* set when compiling a function */
139142
int c_loops; /* counts nested loops */
143+
int c_begin; /* begin of current loop, for 'continue' */
144+
int c_block[MAXBLOCKS]; /* stack of block types */
145+
int c_nblocks; /* current block stack level */
140146
char *c_filename; /* filename of current node */
141147
};
142148

149+
150+
/* Interface to the block stack */
151+
152+
static void
153+
block_push(c, type)
154+
struct compiling *c;
155+
int type;
156+
{
157+
if (c->c_nblocks >= MAXBLOCKS) {
158+
err_setstr(TypeError, "too many statically nested blocks");
159+
c->c_errors++;
160+
}
161+
else {
162+
c->c_block[c->c_nblocks++] = type;
163+
}
164+
}
165+
166+
static void
167+
block_pop(c, type)
168+
struct compiling *c;
169+
int type;
170+
{
171+
if (c->c_nblocks > 0)
172+
c->c_nblocks--;
173+
if (c->c_block[c->c_nblocks] != type && c->c_errors == 0) {
174+
err_setstr(SystemError, "bad block pop");
175+
c->c_errors++;
176+
}
177+
}
178+
179+
143180
/* Prototypes */
181+
144182
static int com_init PROTO((struct compiling *, char *));
145183
static void com_free PROTO((struct compiling *));
146184
static void com_done PROTO((struct compiling *));
@@ -170,6 +208,8 @@ com_init(c, filename)
170208
c->c_errors = 0;
171209
c->c_infunction = 0;
172210
c->c_loops = 0;
211+
c->c_begin = 0;
212+
c->c_nblocks = 0;
173213
c->c_filename = filename;
174214
return 1;
175215

@@ -462,6 +502,24 @@ com_list_constructor(c, n)
462502
com_addoparg(c, BUILD_LIST, len);
463503
}
464504

505+
static void
506+
com_dictmaker(c, n)
507+
struct compiling *c;
508+
node *n;
509+
{
510+
int i;
511+
/* dictmaker: test ':' test (',' test ':' value)* [','] */
512+
for (i = 0; i+2 < NCH(n); i += 4) {
513+
/* We must arrange things just right for STORE_SUBSCR.
514+
It wants the stack to look like (value) (dict) (key) */
515+
com_addbyte(c, DUP_TOP);
516+
com_node(c, CHILD(n, i+2)); /* value */
517+
com_addbyte(c, ROT_TWO);
518+
com_node(c, CHILD(n, i)); /* key */
519+
com_addbyte(c, STORE_SUBSCR);
520+
}
521+
}
522+
465523
static void
466524
com_atom(c, n)
467525
struct compiling *c;
@@ -485,8 +543,10 @@ com_atom(c, n)
485543
else
486544
com_list_constructor(c, CHILD(n, 1));
487545
break;
488-
case LBRACE:
546+
case LBRACE: /* '{' [dictmaker] '}' */
489547
com_addoparg(c, BUILD_MAP, 0);
548+
if (TYPE(CHILD(n, 1)) != RBRACE)
549+
com_dictmaker(c, CHILD(n, 1));
490550
break;
491551
case BACKQUOTE:
492552
com_node(c, CHILD(n, 1));
@@ -1111,15 +1171,15 @@ com_expr_stmt(c, n)
11111171
struct compiling *c;
11121172
node *n;
11131173
{
1114-
REQ(n, expr_stmt); /* exprlist ('=' exprlist)* NEWLINE */
1115-
com_node(c, CHILD(n, NCH(n)-2));
1116-
if (NCH(n) == 2) {
1174+
REQ(n, expr_stmt); /* exprlist ('=' exprlist)* */
1175+
com_node(c, CHILD(n, NCH(n)-1));
1176+
if (NCH(n) == 1) {
11171177
com_addbyte(c, PRINT_EXPR);
11181178
}
11191179
else {
11201180
int i;
1121-
for (i = 0; i < NCH(n)-3; i+=2) {
1122-
if (i+2 < NCH(n)-3)
1181+
for (i = 0; i < NCH(n)-2; i+=2) {
1182+
if (i+2 < NCH(n)-2)
11231183
com_addbyte(c, DUP_TOP);
11241184
com_assign(c, CHILD(n, i), 1/*assign*/);
11251185
}
@@ -1132,12 +1192,12 @@ com_print_stmt(c, n)
11321192
node *n;
11331193
{
11341194
int i;
1135-
REQ(n, print_stmt); /* 'print' (test ',')* [test] NEWLINE */
1136-
for (i = 1; i+1 < NCH(n); i += 2) {
1195+
REQ(n, print_stmt); /* 'print' (test ',')* [test] */
1196+
for (i = 1; i < NCH(n); i += 2) {
11371197
com_node(c, CHILD(n, i));
11381198
com_addbyte(c, PRINT_ITEM);
11391199
}
1140-
if (TYPE(CHILD(n, NCH(n)-2)) != COMMA)
1200+
if (TYPE(CHILD(n, NCH(n)-1)) != COMMA)
11411201
com_addbyte(c, PRINT_NEWLINE);
11421202
/* XXX Alternatively, LOAD_CONST '\n' and then PRINT_ITEM */
11431203
}
@@ -1147,12 +1207,12 @@ com_return_stmt(c, n)
11471207
struct compiling *c;
11481208
node *n;
11491209
{
1150-
REQ(n, return_stmt); /* 'return' [testlist] NEWLINE */
1210+
REQ(n, return_stmt); /* 'return' [testlist] */
11511211
if (!c->c_infunction) {
11521212
err_setstr(TypeError, "'return' outside function");
11531213
c->c_errors++;
11541214
}
1155-
if (NCH(n) == 2)
1215+
if (NCH(n) < 2)
11561216
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
11571217
else
11581218
com_node(c, CHILD(n, 1));
@@ -1164,7 +1224,7 @@ com_raise_stmt(c, n)
11641224
struct compiling *c;
11651225
node *n;
11661226
{
1167-
REQ(n, raise_stmt); /* 'raise' expr [',' expr] NEWLINE */
1227+
REQ(n, raise_stmt); /* 'raise' test [',' test] */
11681228
com_node(c, CHILD(n, 1));
11691229
if (NCH(n) > 3)
11701230
com_node(c, CHILD(n, 3));
@@ -1180,8 +1240,8 @@ com_import_stmt(c, n)
11801240
{
11811241
int i;
11821242
REQ(n, import_stmt);
1183-
/* 'import' NAME (',' NAME)* NEWLINE |
1184-
'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE */
1243+
/* 'import' NAME (',' NAME)* |
1244+
'from' NAME 'import' ('*' | NAME (',' NAME)*) */
11851245
if (STR(CHILD(n, 0))[0] == 'f') {
11861246
/* 'from' NAME 'import' ... */
11871247
REQ(CHILD(n, 1), NAME);
@@ -1233,21 +1293,24 @@ com_while_stmt(c, n)
12331293
{
12341294
int break_anchor = 0;
12351295
int anchor = 0;
1236-
int begin;
1296+
int save_begin = c->c_begin;
12371297
REQ(n, while_stmt); /* 'while' test ':' suite ['else' ':' suite] */
12381298
com_addfwref(c, SETUP_LOOP, &break_anchor);
1239-
begin = c->c_nexti;
1299+
block_push(c, SETUP_LOOP);
1300+
c->c_begin = c->c_nexti;
12401301
com_addoparg(c, SET_LINENO, n->n_lineno);
12411302
com_node(c, CHILD(n, 1));
12421303
com_addfwref(c, JUMP_IF_FALSE, &anchor);
12431304
com_addbyte(c, POP_TOP);
12441305
c->c_loops++;
12451306
com_node(c, CHILD(n, 3));
12461307
c->c_loops--;
1247-
com_addoparg(c, JUMP_ABSOLUTE, begin);
1308+
com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1309+
c->c_begin = save_begin;
12481310
com_backpatch(c, anchor);
12491311
com_addbyte(c, POP_TOP);
12501312
com_addbyte(c, POP_BLOCK);
1313+
block_pop(c, SETUP_LOOP);
12511314
if (NCH(n) > 4)
12521315
com_node(c, CHILD(n, 6));
12531316
com_backpatch(c, break_anchor);
@@ -1261,26 +1324,29 @@ com_for_stmt(c, n)
12611324
object *v;
12621325
int break_anchor = 0;
12631326
int anchor = 0;
1264-
int begin;
1327+
int save_begin = c->c_begin;
12651328
REQ(n, for_stmt);
12661329
/* 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] */
12671330
com_addfwref(c, SETUP_LOOP, &break_anchor);
1331+
block_push(c, SETUP_LOOP);
12681332
com_node(c, CHILD(n, 3));
12691333
v = newintobject(0L);
12701334
if (v == NULL)
12711335
c->c_errors++;
12721336
com_addoparg(c, LOAD_CONST, com_addconst(c, v));
12731337
XDECREF(v);
1274-
begin = c->c_nexti;
1338+
c->c_begin = c->c_nexti;
12751339
com_addoparg(c, SET_LINENO, n->n_lineno);
12761340
com_addfwref(c, FOR_LOOP, &anchor);
12771341
com_assign(c, CHILD(n, 1), 1/*assigning*/);
12781342
c->c_loops++;
12791343
com_node(c, CHILD(n, 5));
12801344
c->c_loops--;
1281-
com_addoparg(c, JUMP_ABSOLUTE, begin);
1345+
com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1346+
c->c_begin = save_begin;
12821347
com_backpatch(c, anchor);
12831348
com_addbyte(c, POP_BLOCK);
1349+
block_pop(c, SETUP_LOOP);
12841350
if (NCH(n) > 8)
12851351
com_node(c, CHILD(n, 8));
12861352
com_backpatch(c, break_anchor);
@@ -1383,17 +1449,20 @@ com_try_stmt(c, n)
13831449
if (NCH(n) > 3 && TYPE(CHILD(n, NCH(n)-3)) != except_clause) {
13841450
/* Have a 'finally' clause */
13851451
com_addfwref(c, SETUP_FINALLY, &finally_anchor);
1452+
block_push(c, SETUP_FINALLY);
13861453
}
13871454
if (NCH(n) > 3 && TYPE(CHILD(n, 3)) == except_clause) {
13881455
/* Have an 'except' clause */
13891456
com_addfwref(c, SETUP_EXCEPT, &except_anchor);
1457+
block_push(c, SETUP_EXCEPT);
13901458
}
13911459
com_node(c, CHILD(n, 2));
13921460
if (except_anchor) {
13931461
int end_anchor = 0;
13941462
int i;
13951463
node *ch;
13961464
com_addbyte(c, POP_BLOCK);
1465+
block_pop(c, SETUP_EXCEPT);
13971466
com_addfwref(c, JUMP_FORWARD, &end_anchor);
13981467
com_backpatch(c, except_anchor);
13991468
for (i = 3;
@@ -1434,12 +1503,15 @@ com_try_stmt(c, n)
14341503
if (finally_anchor) {
14351504
node *ch;
14361505
com_addbyte(c, POP_BLOCK);
1506+
block_pop(c, SETUP_FINALLY);
1507+
block_push(c, END_FINALLY);
14371508
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
14381509
com_backpatch(c, finally_anchor);
14391510
ch = CHILD(n, NCH(n)-1);
14401511
com_addoparg(c, SET_LINENO, ch->n_lineno);
14411512
com_node(c, ch);
14421513
com_addbyte(c, END_FINALLY);
1514+
block_pop(c, END_FINALLY);
14431515
}
14441516
}
14451517

@@ -1463,6 +1535,23 @@ com_suite(c, n)
14631535
}
14641536
}
14651537

1538+
static void
1539+
com_continue_stmt(c, n)
1540+
struct compiling *c;
1541+
node *n;
1542+
{
1543+
int i = c->c_nblocks;
1544+
if (i-- > 0 && c->c_block[i] == SETUP_LOOP) {
1545+
com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
1546+
}
1547+
else {
1548+
err_setstr(TypeError, "'continue' not properly in loop");
1549+
c->c_errors++;
1550+
}
1551+
/* XXX Could allow it inside a 'finally' clause
1552+
XXX if we could pop the exception still on the stack */
1553+
}
1554+
14661555
static void
14671556
com_funcdef(c, n)
14681557
struct compiling *c;
@@ -1547,11 +1636,21 @@ com_node(c, n)
15471636
/* Trivial parse tree nodes */
15481637

15491638
case stmt:
1639+
case small_stmt:
15501640
case flow_stmt:
15511641
com_node(c, CHILD(n, 0));
15521642
break;
15531643

15541644
case simple_stmt:
1645+
/* small_stmt (';' small_stmt)* [';'] NEWLINE */
1646+
com_addoparg(c, SET_LINENO, n->n_lineno);
1647+
{
1648+
int i;
1649+
for (i = 0; i < NCH(n)-1; i += 2)
1650+
com_node(c, CHILD(n, i));
1651+
}
1652+
break;
1653+
15551654
case compound_stmt:
15561655
com_addoparg(c, SET_LINENO, n->n_lineno);
15571656
com_node(c, CHILD(n, 0));
@@ -1565,7 +1664,7 @@ com_node(c, n)
15651664
case print_stmt:
15661665
com_print_stmt(c, n);
15671666
break;
1568-
case del_stmt: /* 'del' exprlist NEWLINE */
1667+
case del_stmt: /* 'del' exprlist */
15691668
com_assign(c, CHILD(n, 1), 0/*delete*/);
15701669
break;
15711670
case pass_stmt:
@@ -1577,6 +1676,9 @@ com_node(c, n)
15771676
}
15781677
com_addbyte(c, BREAK_LOOP);
15791678
break;
1679+
case continue_stmt:
1680+
com_continue_stmt(c, n);
1681+
break;
15801682
case return_stmt:
15811683
com_return_stmt(c, n);
15821684
break;

0 commit comments

Comments
 (0)