@@ -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+
132135struct 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+
144182static int com_init PROTO ((struct compiling * , char * ) );
145183static void com_free PROTO ((struct compiling * ) );
146184static 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+
465523static void
466524com_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+
14661555static void
14671556com_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