[Python-checkins] python/dist/src/Python symtable.c,2.10.8.11,2.10.8.12 newcompile.c,1.1.2.39,1.1.2.40

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
Thu, 27 Mar 2003 12:31:39 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv20947

Modified Files:
      Tag: ast-branch
	symtable.c newcompile.c 
Log Message:
Add provisional support for list comps.  No if branches.
Add some comments.


Index: symtable.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v
retrieving revision 2.10.8.11
retrieving revision 2.10.8.12
diff -C2 -d -r2.10.8.11 -r2.10.8.12
*** symtable.c	25 Mar 2003 21:23:39 -0000	2.10.8.11
--- symtable.c	27 Mar 2003 20:31:30 -0000	2.10.8.12
***************
*** 775,782 ****
  		VISIT_SEQ(st, expr, e->v.Dict.values);
  		break;
!         case ListComp_kind:
  		VISIT(st, expr, e->v.ListComp.target);
  		VISIT_SEQ(st, listcomp, e->v.ListComp.generators);
  		break;
          case Compare_kind:
  		VISIT(st, expr, e->v.Compare.left);
--- 775,791 ----
  		VISIT_SEQ(st, expr, e->v.Dict.values);
  		break;
!         case ListComp_kind: {
! 		char tmpname[256];
! 		identifier tmp;
! 
! 		PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
! 			      ++st->st_cur->ste_tmpname);
! 		tmp = PyString_FromString(tmpname);
! 		if (!symtable_add_def(st, tmp, DEF_LOCAL))
! 			return 0;
  		VISIT(st, expr, e->v.ListComp.target);
  		VISIT_SEQ(st, listcomp, e->v.ListComp.generators);
  		break;
+ 	}
          case Compare_kind:
  		VISIT(st, expr, e->v.Compare.left);

Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.39
retrieving revision 1.1.2.40
diff -C2 -d -r1.1.2.39 -r1.1.2.40
*** newcompile.c	25 Mar 2003 22:26:15 -0000	1.1.2.39
--- newcompile.c	27 Mar 2003 20:31:32 -0000	1.1.2.40
***************
*** 30,41 ****
  
  	PyObject *u_name;
! 	PyObject *u_consts;
! 	PyObject *u_names;
! 	PyObject *u_varnames;
  
! 	int u_argcount;
! 	int u_nblocks;
! 	int u_nalloc;
! 	int u_curblock;
  	struct basicblock u_exit;
  	struct basicblock **u_blocks;
--- 30,48 ----
  
  	PyObject *u_name;
! 	/* The following fields are dicts that map objects to
! 	   the index of them in co_XXX.  The index is used as
! 	   the argument for opcodes that refer to those collections.
! 	*/
! 	PyObject *u_consts;    /* all constants */
! 	PyObject *u_names;     /* all names */
! 	PyObject *u_varnames;  /* local variables */
  
! 	int u_argcount;    /* number of arguments for block */ 
! 	int u_nblocks;     /* number of used blocks in u_blocks
! 			      u_nblocks < u_nalloc */
! 	int u_nalloc;      /* current alloc count for u_blocks */
! 	int u_curblock;    /* index of current block in u_blocks */
! 	int u_tmpname;     /* temporary variables for list comps */
! 	identifier u_tmp; /* name for u_tmpname */
  	struct basicblock u_exit;
  	struct basicblock **u_blocks;
***************
*** 83,88 ****
  static int compiler_visit_expr(struct compiler *, expr_ty);
  static int compiler_augassign(struct compiler *, stmt_ty);
! static int compiler_visit_slice(struct compiler *c, slice_ty s,
! 				expr_context_ty ctx);
  
  static int compiler_push_fblock(struct compiler *, enum fblocktype, int);
--- 90,96 ----
  static int compiler_visit_expr(struct compiler *, expr_ty);
  static int compiler_augassign(struct compiler *, stmt_ty);
! static int compiler_visit_slice(struct compiler *, slice_ty,
! 				expr_context_ty);
! static int compiler_visit_listcomp(struct compiler *, listcomp_ty);
  
  static int compiler_push_fblock(struct compiler *, enum fblocktype, int);
***************
*** 1291,1294 ****
--- 1299,1330 ----
  
  
+ static int
+ compiler_listcomp(struct compiler *c, expr_ty e)
+ {
+ 	char tmpname[256];
+ 	identifier tmp;
+ 	static identifier append;
+ 
+ 	assert(e->kind == ListComp_kind);
+ 	if (!append) {
+ 		append = PyString_InternFromString("append");
+ 		if (!append)
+ 			return 0;
+ 	}
+ 	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
+ 		      ++c->u->u_tmpname);
+ 	tmp = PyString_FromString(tmpname);
+ 	if (!tmp)
+ 		return 0;
+ 	ADDOP_I(c, BUILD_LIST, 0);
+ 	ADDOP(c, DUP_TOP);
+ 	ADDOP_O(c, LOAD_ATTR, append, names);
+ 	if (!compiler_nameop(c, tmp, Store))
+ 		return 0;
+ 	c->u->u_tmp = tmp;
+ 	VISIT_SEQ(c, listcomp, e->v.ListComp.generators);
+ 	c->u->u_tmp = NULL;
+ 	return 1;
+ }
  
  static int
***************
*** 1327,1330 ****
--- 1363,1367 ----
  		break;
          case ListComp_kind:
+ 		return compiler_listcomp(c, e);
  		break;
          case Compare_kind:
***************
*** 1458,1461 ****
--- 1495,1577 ----
  
  static int
+ compiler_visit_listcomp(struct compiler *c, listcomp_ty l)
+ {
+ 	/* generate code for the iterator, then each of the ifs,
+ 	   and then write to the target */
+ 	
+ 	int start, anchor, skip, i, n;
+ 	expr_ty load_target;
+ 
+ 	/* The target must be valid in an assignment context,
+ 	   which limits the kinds of expressions that are valid.
+ 	   We need to load and store the target, which means it
+ 	   must be visited in two contexts.  The ast provides
+ 	   a store context, so create a copy for use in the load
+ 	   context.
+ 	*/
+ 	switch (l->target->kind) {
+ 	case Attribute_kind: 
+ 		load_target = Attribute(l->target->v.Attribute.value,
+ 					l->target->v.Attribute.attr,
+ 					Load);
+ 		break;
+ 	case Subscript_kind:
+ 		load_target = Subscript(l->target->v.Subscript.value,
+ 					l->target->v.Subscript.slice,
+ 					Load);
+ 		break;
+ 	case Name_kind:
+ 		load_target = Name(l->target->v.Name.id, Load);
+ 		break;
+ 	case List_kind:
+ 		load_target = List(l->target->v.List.elts, Load);
+ 		break;
+ 	case Tuple_kind:
+ 		load_target = Tuple(l->target->v.Tuple.elts, Load);
+ 		break;
+ 	default:
+ 		PyErr_Format(PyExc_SyntaxError, 
+ 			     "invalid list comp target: kind %d\n",
+ 			     l->target->kind);
+ 		return 0;
+ 	}
+ 
+ 	start = compiler_new_block(c);
+ 	skip = compiler_new_block(c);
+ 	anchor = compiler_new_block(c);
+ 	
+ 	VISIT(c, expr, l->iter);
+ 	ADDOP(c, GET_ITER);
+ 	compiler_use_next_block(c, start);
+ 	ADDOP_JREL(c, FOR_ITER, anchor);
+ 	NEXT_BLOCK(c);
+ 	VISIT(c, expr, l->target);
+ 	
+ 	n = asdl_seq_LEN(l->ifs);
+ 	for (i = 0; i < n; i++) {
+ 		expr_ty e = asdl_seq_GET(l->ifs, i);
+ 		VISIT(c, expr, e);
+ 		/* XXX not anchor? */
+ 		ADDOP_JREL(c, JUMP_IF_FALSE, skip);
+ 		NEXT_BLOCK(c);
+ 		ADDOP(c, DUP_TOP);
+ 	} 
+ 
+ 	if (!compiler_nameop(c, c->u->u_tmp, Load))
+ 		return 0;
+ 	VISIT(c, expr, load_target);
+ 	ADDOP_I(c, CALL_FUNCTION, 1);
+ 	ADDOP(c, POP_TOP);
+ 
+ 	compiler_use_next_block(c, skip);
+ 	ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+ 	compiler_use_next_block(c, anchor);
+ 	if (!compiler_nameop(c, c->u->u_tmp, Del))
+ 		return 0;
+ 	
+ 	return 1;
+ }
+ 
+ static int
  compiler_push_fblock(struct compiler *c, enum fblocktype t, int b)
  {
***************
*** 1696,1703 ****
  	}
  	code = PyString_AS_STRING(a->a_bytecode) + a->a_offset;
! 	fprintf(stderr,
! 		"emit %3d %-15s %5d\toffset = %2d\tsize = %d\text = %d\n",
! 		i->i_opcode, opnames[i->i_opcode],
! 		i->i_oparg, a->a_offset, size, ext);
  	a->a_offset += size;
  	if (ext > 0) {
--- 1812,1825 ----
  	}
  	code = PyString_AS_STRING(a->a_bytecode) + a->a_offset;
! 	if (i->i_hasarg) 
! 	    fprintf(stderr,
! 		    "emit %3d %-15s %5d\toffset = %2d\tsize = %d\text = %d\n",
! 		    i->i_opcode, opnames[i->i_opcode],
! 		    i->i_oparg, a->a_offset, size, ext);
! 	else
! 	    fprintf(stderr,
! 		    "emit %3d %-15s %s\toffset = %2d\tsize = %d\text = %d\n",
! 		    i->i_opcode, opnames[i->i_opcode],
! 		    "     ", a->a_offset, size, ext);
  	a->a_offset += size;
  	if (ext > 0) {
***************
*** 1844,1849 ****
  	for (i = a.a_nblocks - 1; i >= 0; i--) {
  		struct basicblock *b = c->u->u_blocks[a.a_postorder[i]];
! 		fprintf(stderr, "block %d(%d): used=%d alloc=%d next=%d\n",
! 			i, a.a_postorder[i], b->b_iused, b->b_ialloc, b->b_next);
  		for (j = 0; j < b->b_iused; j++) {
  			if (!assemble_emit(&a, &b->b_instr[j]))
--- 1966,1973 ----
  	for (i = a.a_nblocks - 1; i >= 0; i--) {
  		struct basicblock *b = c->u->u_blocks[a.a_postorder[i]];
! 		fprintf(stderr, 
! 			"block %d: order=%d used=%d alloc=%d next=%d\n",
! 			i, a.a_postorder[i], b->b_iused, b->b_ialloc,
! 			b->b_next);
  		for (j = 0; j < b->b_iused; j++) {
  			if (!assemble_emit(&a, &b->b_instr[j]))