@@ -294,6 +294,7 @@ struct compiling {
294294#ifdef PRIVATE_NAME_MANGLING
295295 char * c_private ; /* for private name mangling */
296296#endif
297+ int c_tmpname ; /* temporary local name counter */
297298};
298299
299300
@@ -368,8 +369,10 @@ static int com_addconst(struct compiling *, PyObject *);
368369static int com_addname (struct compiling * , PyObject * );
369370static void com_addopname (struct compiling * , int , node * );
370371static void com_list (struct compiling * , node * , int );
372+ static void com_list_iter (struct compiling * , node * , node * , char * );
371373static int com_argdefs (struct compiling * , node * );
372374static int com_newlocal (struct compiling * , char * );
375+ static void com_assign (struct compiling * , node * , int );
373376static PyCodeObject * icompile (struct _node * , struct compiling * );
374377static PyCodeObject * jcompile (struct _node * , char * ,
375378 struct compiling * );
@@ -419,6 +422,7 @@ com_init(struct compiling *c, char *filename)
419422 c -> c_last_addr = 0 ;
420423 c -> c_last_line = 0 ;
421424 c -> c_lnotab_next = 0 ;
425+ c -> c_tmpname = 0 ;
422426 return 1 ;
423427
424428 fail :
@@ -941,18 +945,116 @@ parsestrplus(node *n)
941945}
942946
943947static void
944- com_list_constructor (struct compiling * c , node * n )
948+ com_list_for (struct compiling * c , node * n , node * e , char * t )
945949{
946- int len ;
947- int i ;
948- if (TYPE (n ) != testlist )
949- REQ (n , exprlist );
950- /* exprlist: expr (',' expr)* [',']; likewise for testlist */
951- len = (NCH (n ) + 1 ) / 2 ;
952- for (i = 0 ; i < NCH (n ); i += 2 )
953- com_node (c , CHILD (n , i ));
954- com_addoparg (c , BUILD_LIST , len );
955- com_pop (c , len - 1 );
950+ PyObject * v ;
951+ int anchor = 0 ;
952+ int save_begin = c -> c_begin ;
953+
954+ /* list_iter: for v in expr [list_iter] */
955+ com_node (c , CHILD (n , 3 )); /* expr */
956+ v = PyInt_FromLong (0L );
957+ if (v == NULL )
958+ c -> c_errors ++ ;
959+ com_addoparg (c , LOAD_CONST , com_addconst (c , v ));
960+ com_push (c , 1 );
961+ Py_XDECREF (v );
962+ c -> c_begin = c -> c_nexti ;
963+ com_addoparg (c , SET_LINENO , n -> n_lineno );
964+ com_addfwref (c , FOR_LOOP , & anchor );
965+ com_push (c , 1 );
966+ com_assign (c , CHILD (n , 1 ), OP_ASSIGN );
967+ c -> c_loops ++ ;
968+ com_list_iter (c , n , e , t );
969+ c -> c_loops -- ;
970+ com_addoparg (c , JUMP_ABSOLUTE , c -> c_begin );
971+ c -> c_begin = save_begin ;
972+ com_backpatch (c , anchor );
973+ com_pop (c , 2 ); /* FOR_LOOP has popped these */
974+ }
975+
976+ static void
977+ com_list_if (struct compiling * c , node * n , node * e , char * t )
978+ {
979+ int anchor = 0 ;
980+ int a = 0 ;
981+ /* list_iter: 'if' test [list_iter] */
982+ com_addoparg (c , SET_LINENO , n -> n_lineno );
983+ com_node (c , CHILD (n , 1 ));
984+ com_addfwref (c , JUMP_IF_FALSE , & a );
985+ com_addbyte (c , POP_TOP );
986+ com_pop (c , 1 );
987+ com_list_iter (c , n , e , t );
988+ com_addfwref (c , JUMP_FORWARD , & anchor );
989+ com_backpatch (c , a );
990+ /* We jump here with an extra entry which we now pop */
991+ com_addbyte (c , POP_TOP );
992+ com_backpatch (c , anchor );
993+ }
994+
995+ static void
996+ com_list_iter (struct compiling * c ,
997+ node * p , /* parent of list_iter node */
998+ node * e , /* element expression node */
999+ char * t /* name of result list temp local */ )
1000+ {
1001+ /* list_iter is the last child in a listmaker, list_for, or list_if */
1002+ node * n = CHILD (p , NCH (p )- 1 );
1003+ if (TYPE (n ) == list_iter ) {
1004+ n = CHILD (n , 0 );
1005+ switch (TYPE (n )) {
1006+ case list_for :
1007+ com_list_for (c , n , e , t );
1008+ break ;
1009+ case list_if :
1010+ com_list_if (c , n , e , t );
1011+ break ;
1012+ default :
1013+ com_error (c , PyExc_SystemError ,
1014+ "invalid list_iter node type" );
1015+ }
1016+ }
1017+ else {
1018+ com_addopnamestr (c , LOAD_NAME , t );
1019+ com_push (c , 1 );
1020+ com_node (c , e );
1021+ com_addoparg (c , CALL_FUNCTION , 1 );
1022+ com_addbyte (c , POP_TOP );
1023+ com_pop (c , 2 );
1024+ }
1025+ }
1026+
1027+ static void
1028+ com_list_comprehension (struct compiling * c , node * n )
1029+ {
1030+ /* listmaker: test list_iter */
1031+ char tmpname [12 ];
1032+ sprintf (tmpname , "__%d__" , ++ c -> c_tmpname );
1033+ com_addoparg (c , BUILD_LIST , 0 );
1034+ com_addbyte (c , DUP_TOP ); /* leave the result on the stack */
1035+ com_push (c , 2 );
1036+ com_addopnamestr (c , LOAD_ATTR , "append" );
1037+ com_addopnamestr (c , STORE_NAME , tmpname );
1038+ com_pop (c , 1 );
1039+ com_list_iter (c , n , CHILD (n , 0 ), tmpname );
1040+ com_addopnamestr (c , DELETE_NAME , tmpname );
1041+ -- c -> c_tmpname ;
1042+ }
1043+
1044+ static void
1045+ com_listmaker (struct compiling * c , node * n )
1046+ {
1047+ /* listmaker: test ( list_iter | (',' test)* [','] ) */
1048+ if (TYPE (CHILD (n , 1 )) == list_iter )
1049+ com_list_comprehension (c , n );
1050+ else {
1051+ int len = 0 ;
1052+ int i ;
1053+ for (i = 0 ; i < NCH (n ); i += 2 , len ++ )
1054+ com_node (c , CHILD (n , i ));
1055+ com_addoparg (c , BUILD_LIST , len );
1056+ com_pop (c , len - 1 );
1057+ }
9561058}
9571059
9581060static void
@@ -990,18 +1092,18 @@ com_atom(struct compiling *c, node *n)
9901092 else
9911093 com_node (c , CHILD (n , 1 ));
9921094 break ;
993- case LSQB :
1095+ case LSQB : /* '[' [listmaker] ']' */
9941096 if (TYPE (CHILD (n , 1 )) == RSQB ) {
9951097 com_addoparg (c , BUILD_LIST , 0 );
9961098 com_push (c , 1 );
9971099 }
9981100 else
999- com_list_constructor (c , CHILD (n , 1 ));
1101+ com_listmaker (c , CHILD (n , 1 ));
10001102 break ;
10011103 case LBRACE : /* '{' [dictmaker] '}' */
10021104 com_addoparg (c , BUILD_MAP , 0 );
10031105 com_push (c , 1 );
1004- if (TYPE (CHILD (n , 1 )) != RBRACE )
1106+ if (TYPE (CHILD (n , 1 )) == dictmaker )
10051107 com_dictmaker (c , CHILD (n , 1 ));
10061108 break ;
10071109 case BACKQUOTE :
@@ -1743,6 +1845,19 @@ com_assign_sequence(struct compiling *c, node *n, int assigning)
17431845 com_assign (c , CHILD (n , i ), assigning );
17441846}
17451847
1848+ static void
1849+ com_assign_list (struct compiling * c , node * n , int assigning )
1850+ {
1851+ int i ;
1852+ if (assigning ) {
1853+ i = (NCH (n )+ 1 )/2 ;
1854+ com_addoparg (c , UNPACK_SEQUENCE , i );
1855+ com_push (c , i - 1 );
1856+ }
1857+ for (i = 0 ; i < NCH (n ); i += 2 )
1858+ com_assign (c , CHILD (n , i ), assigning );
1859+ }
1860+
17461861static void
17471862com_assign_name (struct compiling * c , node * n , int assigning )
17481863{
0 commit comments