[Python-checkins] python/dist/src/Python Python-ast.c, 1.1.2.11, 1.1.2.12 asdl.c, 1.1.2.5, 1.1.2.6 ast.c, 1.1.2.58, 1.1.2.59 compile.c, 2.247.2.2, 2.247.2.3 newcompile.c, 1.1.2.105, 1.1.2.106 symtable.c, 2.10.8.31, 2.10.8.32 compile.txt, 1.1.2.13, 1.1.2.14

bcannon at users.sourceforge.net bcannon at users.sourceforge.net
Wed Apr 13 21:44:44 CEST 2005


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12515/Python

Modified Files:
      Tag: ast-branch
	Python-ast.c asdl.c ast.c compile.c newcompile.c symtable.c 
	compile.txt 
Log Message:
Add support for genexps.  Required changing the name to GeneratorExp for
consistency in Parser/Python.asdl (and subsequent changes to other files
because of this), regenerating the Python-ast.(h|c) files, and
then the necessary changes to Python/ast.c and Python/newcompile.c .

Also includes a tweak to asdl_seq_new() to not call malloc() with a -1 if an
empty asdl_seq struct is needed.  Lastly, it silences output of the results of
functions while they are doing internal calls; allows doctest to work properly.

Not thoroughly tested since test_grammar segfaults before it reaches genexps.
But hand-testing seems to show everything works.

Closes patch #1167628.  Thanks Nick Coghlan.


Index: Python-ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/Python-ast.c,v
retrieving revision 1.1.2.11
retrieving revision 1.1.2.12
diff -u -d -r1.1.2.11 -r1.1.2.12
--- Python-ast.c	2 Apr 2005 18:50:06 -0000	1.1.2.11
+++ Python-ast.c	13 Apr 2005 19:44:37 -0000	1.1.2.12
@@ -1,4 +1,4 @@
-/* File automatically generated by ../Parser/asdl_c.py */
+/* File automatically generated by ./Parser/asdl_c.py */
 
 #include "Python.h"
 #include "Python-ast.h"
@@ -651,12 +651,12 @@
 }
 
 expr_ty
-GeneratorComp(expr_ty elt, asdl_seq * generators)
+GeneratorExp(expr_ty elt, asdl_seq * generators)
 {
         expr_ty p;
         if (!elt) {
                 PyErr_SetString(PyExc_ValueError,
-                                "field elt is required for GeneratorComp");
+                                "field elt is required for GeneratorExp");
                 return NULL;
         }
         p = (expr_ty)malloc(sizeof(*p));
@@ -664,9 +664,9 @@
                 PyErr_SetString(PyExc_MemoryError, "no memory");
                 return NULL;
         }
-        p->kind = GeneratorComp_kind;
-        p->v.GeneratorComp.elt = elt;
-        p->v.GeneratorComp.generators = generators;
+        p->kind = GeneratorExp_kind;
+        p->v.GeneratorExp.elt = elt;
+        p->v.GeneratorExp.generators = generators;
         return p;
 }
 
@@ -1327,9 +1327,9 @@
                         free_comprehension((comprehension_ty)asdl_seq_GET(seq,
                                            i));
                 break;
-        case GeneratorComp_kind:
-                free_expr((expr_ty)o->v.GeneratorComp.elt);
-                seq = o->v.GeneratorComp.generators;
+        case GeneratorExp_kind:
+                free_expr((expr_ty)o->v.GeneratorExp.elt);
+                seq = o->v.GeneratorExp.generators;
                 n = asdl_seq_LEN(seq);
                 for (i = 0; i < n; i++)
                         free_comprehension((comprehension_ty)asdl_seq_GET(seq,
@@ -1927,14 +1927,14 @@
                                                     (comprehension_ty)elt);
                 }
                 break;
-        case GeneratorComp_kind:
+        case GeneratorExp_kind:
                 marshal_write_int(buf, off, 7);
-                marshal_write_expr(buf, off, o->v.GeneratorComp.elt);
+                marshal_write_expr(buf, off, o->v.GeneratorExp.elt);
                 marshal_write_int(buf, off,
-                                  asdl_seq_LEN(o->v.GeneratorComp.generators));
-                for (i = 0; i < asdl_seq_LEN(o->v.GeneratorComp.generators);
+                                  asdl_seq_LEN(o->v.GeneratorExp.generators));
+                for (i = 0; i < asdl_seq_LEN(o->v.GeneratorExp.generators);
                      i++) {
-                        void *elt = asdl_seq_GET(o->v.GeneratorComp.generators,
+                        void *elt = asdl_seq_GET(o->v.GeneratorExp.generators,
                                                  i);
                         marshal_write_comprehension(buf, off,
                                                     (comprehension_ty)elt);

Index: asdl.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/asdl.c,v
retrieving revision 1.1.2.5
retrieving revision 1.1.2.6
diff -u -d -r1.1.2.5 -r1.1.2.6
--- asdl.c	3 Apr 2003 00:55:00 -0000	1.1.2.5
+++ asdl.c	13 Apr 2005 19:44:37 -0000	1.1.2.6
@@ -4,21 +4,24 @@
 asdl_seq *
 asdl_seq_new(int size)
 {
-    asdl_seq *seq = (asdl_seq *)PyObject_Malloc(sizeof(asdl_seq)
-					     + sizeof(void *) * (size - 1));
-    if (!seq) {
-	PyErr_SetString(PyExc_MemoryError, "no memory");
-	return NULL;
-    }
-    seq->size = size;
-    seq->offset = 0;
-    return seq;
+	asdl_seq *seq = NULL;
+
+	seq = (asdl_seq *)PyObject_Malloc(sizeof(asdl_seq)
+				+ (size ? (sizeof(void *) * (size - 1)) : 0));
+
+	if (!seq) {
+		PyErr_SetString(PyExc_MemoryError, "no memory");
+		return NULL;
+	}
+	seq->size = size;
+	seq->offset = 0;
+	return seq;
 }
 
 void
 asdl_seq_free(asdl_seq *seq)
 {
-    PyObject_Free(seq);
+	PyObject_Free(seq);
 }
 
 #define CHECKSIZE(BUF, OFF, MIN) { \

Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v
retrieving revision 1.1.2.58
retrieving revision 1.1.2.59
diff -u -d -r1.1.2.58 -r1.1.2.59
--- ast.c	2 Apr 2005 19:00:35 -0000	1.1.2.58
+++ ast.c	13 Apr 2005 19:44:37 -0000	1.1.2.59
@@ -986,95 +986,270 @@
     return ListComp(elt, listcomps);
 }
 
+/*
+   Count the number of 'for' loops in a generator expression.
+
+   Helper for ast_for_genexp().
+*/
+
+static int
+count_gen_fors(const node *n)
+{
+	int n_fors = 0;
+	node *ch = CHILD(n, 1);
+
+ count_gen_for:
+	n_fors++;
+	REQ(ch, gen_for);
+	if (NCH(ch) == 5)
+		ch = CHILD(ch, 4);
+	else
+		return n_fors;
+ count_gen_iter:
+	REQ(ch, gen_iter);
+	ch = CHILD(ch, 0);
+	if (TYPE(ch) == gen_for)
+		goto count_gen_for;
+	else if (TYPE(ch) == gen_if) {
+		if (NCH(ch) == 3) {
+			ch = CHILD(ch, 2);
+			goto count_gen_iter;
+		}
+		else
+		    return n_fors;
+	}
+	else {
+		/* Should never be reached */
+		PyErr_SetString(PyExc_Exception, "logic error in count_gen_fors");
+		return -1;
+	}
+}
+
+/* Count the number of 'if' statements in a generator expression.
+
+   Helper for ast_for_genexp().
+*/
+
+static int
+count_gen_ifs(const node *n)
+{
+	int n_ifs = 0;
+
+	while (1) {
+		REQ(n, gen_iter);
+		if (TYPE(CHILD(n, 0)) == gen_for)
+			return n_ifs;
+		n = CHILD(n, 0);
+		REQ(n, gen_if);
+		n_ifs++;
+		if (NCH(n) == 2)
+			return n_ifs;
+		n = CHILD(n, 2);
+	}
+}
+
+static expr_ty
+ast_for_genexp(struct compiling *c, const node *n)
+{
+	/* testlist_gexp: test ( gen_for | (',' test)* [','] )
+           argument: [test '='] test [gen_for]	 # Really [keyword '='] test */
+	expr_ty elt;
+	asdl_seq *genexps;
+	int i, n_fors;
+	node *ch;
+	
+	assert(TYPE(n) == (testlist_gexp) || TYPE(n) == (argument));
+	assert(NCH(n) > 1);
+	
+	elt = ast_for_expr(c, CHILD(n, 0));
+	if (!elt)
+		return NULL;
+	
+	n_fors = count_gen_fors(n);
+	if (n_fors == -1)
+		return NULL;
+	
+	genexps = asdl_seq_new(n_fors);
+	if (!genexps) {
+		/* XXX free(elt); */
+		return NULL;
+	}
+	
+	ch = CHILD(n, 1);
+	for (i = 0; i < n_fors; i++) {
+		comprehension_ty ge;
+		asdl_seq *t;
+		expr_ty expression;
+		
+		REQ(ch, gen_for);
+		
+		t = ast_for_exprlist(c, CHILD(ch, 1), Store);
+		if (!t) {
+			asdl_seq_free(genexps);
+			/* XXX free(elt); */
+			return NULL;
+		}
+		expression = ast_for_testlist(c, CHILD(ch, 3));
+		if (!expression) {
+			asdl_seq_free(genexps);
+			/* XXX free(elt); */
+			return NULL;
+		}
+		
+		if (asdl_seq_LEN(t) == 1)
+			ge = comprehension(asdl_seq_GET(t, 0), expression, NULL);
+		else
+			ge = comprehension(Tuple(t, Store), expression, NULL);
+		
+		if (!ge) {
+			asdl_seq_free(genexps);
+			/* XXX free(elt); */
+			return NULL;
+		}
+		
+		if (NCH(ch) == 5) {
+			int j, n_ifs;
+			asdl_seq *ifs;
+		
+			ch = CHILD(ch, 4);
+			n_ifs = count_gen_ifs(ch);
+			if (n_ifs == -1) {
+				asdl_seq_free(genexps);
+				/* XXX free(elt); */
+				return NULL;
+			}
+		
+			ifs = asdl_seq_new(n_ifs);
+			if (!ifs) {
+				asdl_seq_free(genexps);
+				/* XXX free(elt); */
+				return NULL;
+			}
+		
+			for (j = 0; j < n_ifs; j++) {
+				REQ(ch, gen_iter);
+			
+				ch = CHILD(ch, 0);
+				REQ(ch, gen_if);
+			
+				asdl_seq_APPEND(ifs, ast_for_expr(c, CHILD(ch, 1)));
+				if (NCH(ch) == 3)
+					ch = CHILD(ch, 2);
+			}
+			/* on exit, must guarantee that ch is a gen_for */
+			if (TYPE(ch) == gen_iter)
+				ch = CHILD(ch, 0);
+			ge->ifs = ifs;
+		}
+		asdl_seq_APPEND(genexps, ge);
+	}
+	
+	return GeneratorExp(elt, genexps);
+}
+
 static expr_ty
 ast_for_atom(struct compiling *c, const node *n)
 {
-    /* atom: '(' [testlist] ')' | '[' [listmaker] ']'
-           | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
-    */
-    node *ch = CHILD(n, 0);
+	/* atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']'
+	   | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
+	*/
+	node *ch = CHILD(n, 0);
 
-    switch (TYPE(ch)) {
-        case NAME:
-            /* All names start in Load context, but may later be changed. */
-            return Name(NEW_IDENTIFIER(ch), Load);
-        case STRING: {
-            PyObject *str = parsestrplus(c, n);
+	switch (TYPE(ch)) {
+		case NAME:
+			/* All names start in Load context, but may later be
+			   changed. */
+			return Name(NEW_IDENTIFIER(ch), Load);
+		case STRING: {
+			PyObject *str = parsestrplus(c, n);
 
-            if (!str)
-                return NULL;
+			if (!str)
+				return NULL;
 
-            return Str(str);
-        }
-        case NUMBER: {
-            PyObject *pynum = parsenumber(STR(ch));
+			return Str(str);
+		}
+		case NUMBER: {
+			PyObject *pynum = parsenumber(STR(ch));
 
-            if (!pynum)
-                return NULL;
+			if (!pynum)
+				return NULL;
                 
-            return Num(pynum);
-        }
-        case LPAR: /* some parenthesized expressions */
-            return ast_for_testlist(c, CHILD(n, 1));
-        case LSQB: /* list (or list comprehension) */
-            ch = CHILD(n, 1);
-            if (TYPE(ch) == RSQB)
-                    return List(NULL, Load);
-            REQ(ch, listmaker);
-            if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
-                asdl_seq *elts = seq_for_testlist(c, ch);
+			return Num(pynum);
+		}
+		case LPAR: /* some parenthesized expressions */
+			ch = CHILD(n, 1);
 
-                if (!elts)
-                    return NULL;
+			if (TYPE(ch) == RPAR)
+				return Tuple(NULL, Load);
 
-                return List(elts, Load);
-            }
-            else
-                return ast_for_listcomp(c, ch);
-        case LBRACE: {
-            /* dictmaker: test ':' test (',' test ':' test)* [','] */
-            int i, size;
-            asdl_seq *keys, *values;
+			if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
+				return ast_for_genexp(c, ch);
 
-            ch = CHILD(n, 1);
-            size = (NCH(ch) + 1) / 4; /* plus one in case no trailing comma */
-            keys = asdl_seq_new(size);
-            if (!keys)
-                    return NULL;
-            values = asdl_seq_new(size);
-            if (!values) {
-                    asdl_seq_free(keys);
-                    return NULL;
-            }
-            for (i = 0; i < NCH(ch); i += 4) {
-                expr_ty expression;
+			return ast_for_testlist(c, ch);
+		case LSQB: /* list (or list comprehension) */
+			ch = CHILD(n, 1);
 
-                expression = ast_for_expr(c, CHILD(ch, i));
-                if (!expression)
-                    return NULL;
-                    
-                asdl_seq_SET(keys, i / 4, expression);
+			if (TYPE(ch) == RSQB)
+				return List(NULL, Load);
 
-                expression = ast_for_expr(c, CHILD(ch, i + 2));
-                if (!expression)
-                    return NULL;
-                    
-                asdl_seq_SET(values, i / 4, expression);
-            }
-            return Dict(keys, values);
-        }
-        case BACKQUOTE: { /* repr */
-            expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
+			REQ(ch, listmaker);
+			if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
+				asdl_seq *elts = seq_for_testlist(c, ch);
 
-            if (!expression)
-                return NULL;
+				if (!elts)
+					return NULL;
 
-            return Repr(expression);
-        }
-        default:
-            PyErr_Format(PyExc_Exception, "unhandled atom %d", TYPE(ch));
-            return NULL;
-    }
+				return List(elts, Load);
+			}
+			else
+				return ast_for_listcomp(c, ch);
+		case LBRACE: {
+			/* dictmaker: test ':' test (',' test ':' test)* [','] */
+			int i, size;
+			asdl_seq *keys, *values;
+
+			ch = CHILD(n, 1);
+			size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
+			keys = asdl_seq_new(size);
+			if (!keys)
+				return NULL;
+
+			values = asdl_seq_new(size);
+			if (!values) {
+				asdl_seq_free(keys);
+				return NULL;
+			}
+
+			for (i = 0; i < NCH(ch); i += 4) {
+				expr_ty expression;
+
+				expression = ast_for_expr(c, CHILD(ch, i));
+				if (!expression)
+					return NULL;
+
+				asdl_seq_SET(keys, i / 4, expression);
+
+				expression = ast_for_expr(c, CHILD(ch, i + 2));
+				if (!expression)
+					return NULL;
+
+				asdl_seq_SET(values, i / 4, expression);
+			}
+			return Dict(keys, values);
+		}
+		case BACKQUOTE: { /* repr */
+			expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
+
+			if (!expression)
+				return NULL;
+
+			return Repr(expression);
+		}
+		default:
+			PyErr_Format(PyExc_Exception, "unhandled atom %d",
+					TYPE(ch));
+			return NULL;
+	}
 }
 
 static slice_ty
@@ -1451,17 +1626,22 @@
     nargs = 0;
     nkeywords = 0;
     ngens = 0;
-    for (i = 0; i < NCH(n); i++) 
-	if (TYPE(CHILD(n, i)) == argument) {
-	    if (NCH(CHILD(n, i)) == 1)
+    for (i = 0; i < NCH(n); i++) {
+	node *ch = CHILD(n, i);
+	if (TYPE(ch) == argument) {
+	    if (NCH(ch) == 1)
 		nargs++;
-	    else if (TYPE(CHILD(CHILD(n, i), 1)) == gen_for)
+	    else if (TYPE(CHILD(ch, 1)) == gen_for)
 		ngens++;
             else
 		nkeywords++;
 	}
-    
-    args = asdl_seq_new(nargs);
+    }
+    if (ngens > 1 || (ngens && (nargs || nkeywords))) {
+        ast_error(n, "Generator expression must be parenthesised if not sole argument");
+	return NULL;
+    }
+    args = asdl_seq_new(nargs + ngens);
     if (!args)
         goto error;
     keywords = asdl_seq_new(nkeywords);
@@ -1479,8 +1659,11 @@
                     goto error;
 		asdl_seq_SET(args, nargs++, e);
 	    }  
-	    else if (TYPE(CHILD(CHILD(n, 0), 1)) == gen_for) {
-                /* XXX handle generator comp */
+	    else if (TYPE(CHILD(ch, 1)) == gen_for) {
+        	e = ast_for_genexp(c, ch);
+                if (!e)
+                    goto error;
+		asdl_seq_SET(args, nargs++, e);
             }
 	    else {
 		keyword_ty kw;

Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.247.2.2
retrieving revision 2.247.2.3
diff -u -d -r2.247.2.2 -r2.247.2.3
--- compile.c	9 Jul 2002 13:22:01 -0000	2.247.2.2
+++ compile.c	13 Apr 2005 19:44:38 -0000	2.247.2.3
@@ -1157,6 +1157,8 @@
 		return PyLong_FromString(s, (char **)0, 0);
 	if (s[0] == '0')
 		x = (long) PyOS_strtoul(s, &end, 0);
+		if (x < 0 && errno == 0)
+			return PyLong_FromString(s, (char **)0, 0);
 	else
 		x = PyOS_strtol(s, &end, 0);
 	if (*end == '\0') {

Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.105
retrieving revision 1.1.2.106
diff -u -d -r1.1.2.105 -r1.1.2.106
--- newcompile.c	2 Apr 2005 18:50:06 -0000	1.1.2.105
+++ newcompile.c	13 Apr 2005 19:44:40 -0000	1.1.2.106
@@ -1388,8 +1388,13 @@
 	asdl_seq* decos = s->v.FunctionDef.decorators;
         stmt_ty st;
 	int i, n, docstring;
+	int was_interactive = c->c_interactive;
+
 	assert(s->kind == FunctionDef_kind);
 
+	/* turn off interim results from within function calls while in
+	   interactive mode */
+	c->c_interactive = 0;
 	if (!compiler_decorators(c, decos))
 		return 0;
 	if (args->defaults)
@@ -1443,6 +1448,9 @@
 		ADDOP_I(c, CALL_FUNCTION, 1);
 	}
 
+	/* turn flag back on if was interactive */
+	c->c_interactive = was_interactive;
+	
 	return compiler_nameop(c, s->v.FunctionDef.name, Store);
 }
 
@@ -2558,10 +2566,114 @@
 }
 
 static int
-compiler_generatorcomp(struct compiler *c, expr_ty e)
+compiler_genexp_generator(struct compiler *c,
+                          asdl_seq *generators, int gen_index, 
+                          expr_ty elt)
 {
-    /* XXX handle */
+	/* generate code for the iterator, then each of the ifs,
+	   and then write to the element */
+
+	comprehension_ty ge;
+	basicblock *start, *anchor, *skip, *if_cleanup, *end;
+        int i, n;
+
+	start = compiler_new_block(c);
+	skip = compiler_new_block(c);
+	if_cleanup = compiler_new_block(c);
+	anchor = compiler_new_block(c);
+	end = compiler_new_block(c);
+
+        if (start == NULL || skip == NULL || if_cleanup == NULL ||
+	    anchor == NULL || end == NULL)
+		return 0;
+
+	ge = asdl_seq_GET(generators, gen_index);
+	ADDOP_JREL(c, SETUP_LOOP, end);
+	if (!compiler_push_fblock(c, LOOP, start))
+		return 0;
+
+	if (gen_index == 0) {
+		/* Receive outermost iter as an implicit argument */
+		c->u->u_argcount = 1;
+		ADDOP_I(c, LOAD_FAST, 0);
+	}
+	else {
+		/* Sub-iter - calculate on the fly */
+		VISIT(c, expr, ge->iter);
+		ADDOP(c, GET_ITER);
+	}
+	compiler_use_next_block(c, start);
+	ADDOP_JREL(c, FOR_ITER, anchor);
+	NEXT_BLOCK(c);
+	VISIT(c, expr, ge->target);
+
+        /* XXX this needs to be cleaned up...a lot! */
+	n = asdl_seq_LEN(ge->ifs);
+	for (i = 0; i < n; i++) {
+		expr_ty e = asdl_seq_GET(ge->ifs, i);
+		VISIT(c, expr, e);
+		ADDOP_JREL(c, JUMP_IF_FALSE, if_cleanup);
+		NEXT_BLOCK(c);
+		ADDOP(c, POP_TOP);
+	} 
+
+        if (++gen_index < asdl_seq_LEN(generators))
+		if (!compiler_genexp_generator(c, generators, gen_index, elt))
+			return 0;
+
+        /* only append after the last 'for' generator */
+        if (gen_index >= asdl_seq_LEN(generators)) {
+		VISIT(c, expr, elt);
+		ADDOP(c, YIELD_VALUE);
+
+		compiler_use_next_block(c, skip);
+        }
+	for (i = 0; i < n; i++) {
+		ADDOP_I(c, JUMP_FORWARD, 1);
+                if (i == 0)
+			compiler_use_next_block(c, if_cleanup);
+
+		ADDOP(c, POP_TOP);
+	} 
+	ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+	compiler_use_next_block(c, anchor);
+	ADDOP(c, POP_BLOCK);
+	compiler_pop_fblock(c, LOOP, start);
+	compiler_use_next_block(c, end);
+
+	return 1;
+}
+
+static int
+compiler_genexp(struct compiler *c, expr_ty e)
+{
+	PyObject *name;
+	PyCodeObject *co;
+	expr_ty outermost_iter = ((comprehension_ty)
+				 (asdl_seq_GET(e->v.GeneratorExp.generators,
+					       0)))->iter;
+
+	name = PyString_FromString("<generator expression>");
+	if (!name)
     return 0;
+
+	if (!compiler_enter_scope(c, name, (void *)e, c->u->u_lineno))
+		return 0;
+	compiler_genexp_generator(c, e->v.GeneratorExp.generators, 0,
+					e->v.GeneratorExp.elt);
+	co = assemble(c, 1);
+	if (co == NULL)
+		return 0;
+	compiler_exit_scope(c);
+
+        compiler_make_closure(c, co, 0);
+	VISIT(c, expr, outermost_iter);
+	ADDOP(c, GET_ITER);
+	ADDOP_I(c, CALL_FUNCTION, 1);
+	Py_DECREF(name);
+	Py_DECREF(co);
+
+	return 1;
 }
 
 static int
@@ -2626,8 +2738,8 @@
 		break;
         case ListComp_kind:
 		return compiler_listcomp(c, e);
-        case GeneratorComp_kind:
-		return compiler_generatorcomp(c, e);
+        case GeneratorExp_kind:
+		return compiler_genexp(c, e);
         case Compare_kind:
 		return compiler_compare(c, e);
         case Call_kind:

Index: symtable.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v
retrieving revision 2.10.8.31
retrieving revision 2.10.8.32
diff -u -d -r2.10.8.31 -r2.10.8.32
--- symtable.c	2 Apr 2005 18:50:13 -0000	2.10.8.31
+++ symtable.c	13 Apr 2005 19:44:40 -0000	2.10.8.32
@@ -165,6 +165,7 @@
 static int symtable_visit_slice(struct symtable *st, slice_ty);
 static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top);
 static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args);
+static int symtable_implicit_arg(struct symtable *st, int pos);
 
 
 static identifier top = NULL, lambda = NULL;
@@ -946,8 +947,7 @@
 		VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
 		break;
 	}
-        case GeneratorComp_kind: {
-		char tmpname[256];
+        case GeneratorExp_kind: {
 		identifier tmp;
 
                 /* XXX this is correct/complete */
@@ -955,8 +955,11 @@
 		if (!symtable_enter_block(st, tmp, FunctionBlock, 
                                           (void *)e, 0))
 			return 0;
-		VISIT(st, expr, e->v.GeneratorComp.elt);
-		VISIT_SEQ(st, comprehension, e->v.GeneratorComp.generators);
+		if (!symtable_implicit_arg(st, 0))
+			return 0;
+		VISIT(st, expr, e->v.GeneratorExp.elt);
+		VISIT_SEQ(st, comprehension, e->v.GeneratorExp.generators);
+                st->st_cur->ste_generator = 1;
 		symtable_exit_block(st, (void *)e);
 		break;
 	}

Index: compile.txt
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/compile.txt,v
retrieving revision 1.1.2.13
retrieving revision 1.1.2.14
diff -u -d -r1.1.2.13 -r1.1.2.14
--- compile.txt	2 Apr 2005 20:21:23 -0000	1.1.2.13
+++ compile.txt	13 Apr 2005 19:44:40 -0000	1.1.2.14
@@ -447,11 +447,7 @@
 
 + Grammar support (Parser/Python.asdl, Parser/asdl_c.py)
     - empty base class list (``class Class(): pass``)
-+ parse tree->AST support (Python/ast.c)
-    - generator expressions
-+ AST->bytecode support (Python/newcompile.c)
-    - generator expressions
-+ Stdlib support
+ Stdlib support
     - AST->Python access?
     - rewrite compiler package to mirror AST structure?
 + Documentation
@@ -459,8 +455,6 @@
 	* byte stream output
 	* explanation of how symbol table pass works
 + Universal
-    - remove "generator comprehension" mentions and change to "generator
-      expression"
     - make sure entire test suite passes
     - fix memory leaks
     - make sure return types are properly checked for errors



More information about the Python-checkins mailing list