[Python-checkins] CVS: python/dist/src/Python compile.c,2.120,2.121 graminit.c,2.23,2.24

Skip Montanaro python-dev@python.org
Sat, 12 Aug 2000 11:09:54 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory slayer.i.sourceforge.net:/tmp/cvs-serv9983/Python

Modified Files:
	compile.c graminit.c 
Log Message:
list comprehensions.  see

    http://sourceforge.net/patch/?func=detailpatch&patch_id=100654&group_id=5470

for details.



Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.120
retrieving revision 2.121
diff -C2 -r2.120 -r2.121
*** compile.c	2000/08/11 22:15:52	2.120
--- compile.c	2000/08/12 18:09:51	2.121
***************
*** 295,298 ****
--- 295,299 ----
  	char *c_private;	/* for private name mangling */
  #endif
+ 	int c_tmpname;		/* temporary local name counter */
  };
  
***************
*** 369,374 ****
--- 370,377 ----
  static void com_addopname(struct compiling *, int, node *);
  static void com_list(struct compiling *, node *, int);
+ static void com_list_iter(struct compiling *, node *, node *, char *);
  static int com_argdefs(struct compiling *, node *);
  static int com_newlocal(struct compiling *, char *);
+ static void com_assign(struct compiling *, node *, int);
  static PyCodeObject *icompile(struct _node *, struct compiling *);
  static PyCodeObject *jcompile(struct _node *, char *,
***************
*** 420,423 ****
--- 423,427 ----
  	c->c_last_line = 0;
  	c-> c_lnotab_next = 0;
+ 	c->c_tmpname = 0;
  	return 1;
  	
***************
*** 942,957 ****
  
  static void
! com_list_constructor(struct compiling *c, node *n)
  {
! 	int len;
! 	int i;
! 	if (TYPE(n) != testlist)
! 		REQ(n, exprlist);
! 	/* exprlist: expr (',' expr)* [',']; likewise for testlist */
! 	len = (NCH(n) + 1) / 2;
! 	for (i = 0; i < NCH(n); i += 2)
! 		com_node(c, CHILD(n, i));
! 	com_addoparg(c, BUILD_LIST, len);
! 	com_pop(c, len-1);
  }
  
--- 946,1059 ----
  
  static void
! com_list_for(struct compiling *c, node *n, node *e, char *t)
  {
! 	PyObject *v;
! 	int anchor = 0;
! 	int save_begin = c->c_begin;
! 
! 	/* list_iter: for v in expr [list_iter] */
! 	com_node(c, CHILD(n, 3)); /* expr */
! 	v = PyInt_FromLong(0L);
! 	if (v == NULL)
! 		c->c_errors++;
! 	com_addoparg(c, LOAD_CONST, com_addconst(c, v));
! 	com_push(c, 1);
! 	Py_XDECREF(v);
! 	c->c_begin = c->c_nexti;
! 	com_addoparg(c, SET_LINENO, n->n_lineno);
! 	com_addfwref(c, FOR_LOOP, &anchor);
! 	com_push(c, 1);
! 	com_assign(c, CHILD(n, 1), OP_ASSIGN);
! 	c->c_loops++;
! 	com_list_iter(c, n, e, t);
! 	c->c_loops--;
! 	com_addoparg(c, JUMP_ABSOLUTE, c->c_begin);
! 	c->c_begin = save_begin;
! 	com_backpatch(c, anchor);
! 	com_pop(c, 2); /* FOR_LOOP has popped these */
! }  
! 
! static void
! com_list_if(struct compiling *c, node *n, node *e, char *t)
! {
! 	int anchor = 0;
! 	int a = 0;
! 	/* list_iter: 'if' test [list_iter] */
! 	com_addoparg(c, SET_LINENO, n->n_lineno);
! 	com_node(c, CHILD(n, 1));
! 	com_addfwref(c, JUMP_IF_FALSE, &a);
! 	com_addbyte(c, POP_TOP);
! 	com_pop(c, 1);
! 	com_list_iter(c, n, e, t);
! 	com_addfwref(c, JUMP_FORWARD, &anchor);
! 	com_backpatch(c, a);
! 	/* We jump here with an extra entry which we now pop */
! 	com_addbyte(c, POP_TOP);
! 	com_backpatch(c, anchor);
! }
! 
! static void
! com_list_iter(struct compiling *c,
! 	      node *p,		/* parent of list_iter node */
! 	      node *e,		/* element expression node */
! 	      char *t		/* name of result list temp local */)
! {
! 	/* list_iter is the last child in a listmaker, list_for, or list_if */
! 	node *n = CHILD(p, NCH(p)-1);
! 	if (TYPE(n) == list_iter) {
! 		n = CHILD(n, 0);
! 		switch (TYPE(n)) {
! 		case list_for: 
! 			com_list_for(c, n, e, t);
! 			break;
! 		case list_if:
! 			com_list_if(c, n, e, t);
! 			break;
! 		default:
! 			com_error(c, PyExc_SystemError,
! 				  "invalid list_iter node type");
! 		}
! 	}
! 	else {
! 		com_addopnamestr(c, LOAD_NAME, t);
! 		com_push(c, 1);
! 		com_node(c, e);
! 		com_addoparg(c, CALL_FUNCTION, 1);
! 		com_addbyte(c, POP_TOP);
! 		com_pop(c, 2);
! 	}
! }
! 
! static void
! com_list_comprehension(struct compiling *c, node *n)
! {
! 	/* listmaker: test list_iter */
! 	char tmpname[12];
! 	sprintf(tmpname, "__%d__", ++c->c_tmpname);
! 	com_addoparg(c, BUILD_LIST, 0);
! 	com_addbyte(c, DUP_TOP); /* leave the result on the stack */
! 	com_push(c, 2);
! 	com_addopnamestr(c, LOAD_ATTR, "append");
! 	com_addopnamestr(c, STORE_NAME, tmpname);
! 	com_pop(c, 1);
! 	com_list_iter(c, n, CHILD(n, 0), tmpname);
! 	com_addopnamestr(c, DELETE_NAME, tmpname);
! 	--c->c_tmpname;
! }
! 
! static void
! com_listmaker(struct compiling *c, node *n)
! {
! 	/* listmaker: test ( list_iter | (',' test)* [','] ) */
! 	if (TYPE(CHILD(n, 1)) == list_iter)
! 		com_list_comprehension(c, n);
! 	else {
! 		int len = 0;
! 		int i;
! 		for (i = 0; i < NCH(n); i += 2, len++)
! 			com_node(c, CHILD(n, i));
! 		com_addoparg(c, BUILD_LIST, len);
! 		com_pop(c, len-1);
! 	}
  }
  
***************
*** 991,995 ****
  			com_node(c, CHILD(n, 1));
  		break;
! 	case LSQB:
  		if (TYPE(CHILD(n, 1)) == RSQB) {
  			com_addoparg(c, BUILD_LIST, 0);
--- 1093,1097 ----
  			com_node(c, CHILD(n, 1));
  		break;
! 	case LSQB: /* '[' [listmaker] ']' */
  		if (TYPE(CHILD(n, 1)) == RSQB) {
  			com_addoparg(c, BUILD_LIST, 0);
***************
*** 997,1006 ****
  		}
  		else
! 			com_list_constructor(c, CHILD(n, 1));
  		break;
  	case LBRACE: /* '{' [dictmaker] '}' */
  		com_addoparg(c, BUILD_MAP, 0);
  		com_push(c, 1);
! 		if (TYPE(CHILD(n, 1)) != RBRACE)
  			com_dictmaker(c, CHILD(n, 1));
  		break;
--- 1099,1108 ----
  		}
  		else
! 			com_listmaker(c, CHILD(n, 1));
  		break;
  	case LBRACE: /* '{' [dictmaker] '}' */
  		com_addoparg(c, BUILD_MAP, 0);
  		com_push(c, 1);
! 		if (TYPE(CHILD(n, 1)) == dictmaker)
  			com_dictmaker(c, CHILD(n, 1));
  		break;
***************
*** 1735,1738 ****
--- 1837,1853 ----
  	if (TYPE(n) != testlist)
  		REQ(n, exprlist);
+ 	if (assigning) {
+ 		i = (NCH(n)+1)/2;
+ 		com_addoparg(c, UNPACK_SEQUENCE, i);
+ 		com_push(c, i-1);
+ 	}
+ 	for (i = 0; i < NCH(n); i += 2)
+ 		com_assign(c, CHILD(n, i), assigning);
+ }
+ 
+ static void
+ com_assign_list(struct compiling *c, node *n, int assigning)
+ {
+ 	int i;
  	if (assigning) {
  		i = (NCH(n)+1)/2;

Index: graminit.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v
retrieving revision 2.23
retrieving revision 2.24
diff -C2 -r2.23 -r2.24
*** graminit.c	2000/03/28 23:49:17	2.23
--- graminit.c	2000/08/12 18:09:51	2.24
***************
*** 897,905 ****
  	{16, 1},
  	{109, 2},
! 	{111, 3},
! 	{114, 4},
  	{12, 5},
! 	{115, 5},
! 	{116, 6},
  };
  static arc arcs_45_1[2] = {
--- 897,905 ----
[...967 lines suppressed...]
  	{25, 0},
  	{2, 0},
  	{3, 0},
+ 	{314, 0},
  	{1, "lambda"},
! 	{312, 0},
  	{305, 0},
  	{306, 0},
+ 	{307, 0},
  	{1, "class"},
! 	{313, 0},
! 	{315, 0},
! 	{316, 0},
  };
  grammar _PyParser_Grammar = {
! 	61,
  	dfas,
! 	{128, labels},
  	256
  };