[Python-checkins] python/dist/src/Python ast.c,2.4,2.5

nascheme@users.sourceforge.net nascheme at users.sourceforge.net
Tue Oct 25 09:54:58 CEST 2005


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

Modified Files:
	ast.c 
Log Message:
Write a separate ast_for_testlist_gexp() function instead of overloading
ast_for_testlist().  Also, write a ast_for_class_bases() function and in
the process fix a memory leak.  Add some assertions.


Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ast.c,v
retrieving revision 2.4
retrieving revision 2.5
diff -u -d -r2.4 -r2.5
--- ast.c	23 Oct 2005 03:38:19 -0000	2.4
+++ ast.c	25 Oct 2005 07:54:54 -0000	2.5
@@ -35,7 +35,8 @@
 static stmt_ty ast_for_stmt(struct compiling *, const node *);
 static asdl_seq *ast_for_suite(struct compiling *, const node *);
 static asdl_seq *ast_for_exprlist(struct compiling *, const node *, int);
-static expr_ty ast_for_testlist(struct compiling *, const node *, int);
+static expr_ty ast_for_testlist(struct compiling *, const node *);
+static expr_ty ast_for_testlist_gexp(struct compiling *, const node *);
 
 /* Note different signature for ast_for_call */
 static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
@@ -251,7 +252,7 @@
             expr_ty testlist_ast;
 
             /* XXX Why not gen_for here? */
-            testlist_ast = ast_for_testlist(&c, CHILD(n, 0), 0);
+            testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
             if (!testlist_ast)
                 goto error;
             return Expression(testlist_ast);
@@ -980,7 +981,7 @@
             free_expr(elt);
             return NULL;
         }
-        expression = ast_for_testlist(c, CHILD(ch, 3), 0);
+        expression = ast_for_testlist(c, CHILD(ch, 3));
         if (!expression) {
             asdl_seq_free(t);
             asdl_seq_free(listcomps);
@@ -1144,7 +1145,7 @@
             free_expr(elt);
             return NULL;
         }
-        expression = ast_for_testlist(c, CHILD(ch, 3), 1);
+        expression = ast_for_expr(c, CHILD(ch, 3));
         if (!expression) {
             asdl_seq_free(genexps);
             free_expr(elt);
@@ -1184,11 +1185,17 @@
             }
             
             for (j = 0; j < n_ifs; j++) {
+                expr_ty expression;
                 REQ(ch, gen_iter);
                 ch = CHILD(ch, 0);
                 REQ(ch, gen_if);
                 
-                asdl_seq_APPEND(ifs, ast_for_expr(c, CHILD(ch, 1)));
+                expression = ast_for_expr(c, CHILD(ch, 1));
+                if (!expression) {
+                    asdl_seq_free(genexps);
+                    return NULL;
+                }
+                asdl_seq_APPEND(ifs, expression);
                 if (NCH(ch) == 3)
                     ch = CHILD(ch, 2);
             }
@@ -1244,7 +1251,7 @@
 	if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
 	    return ast_for_genexp(c, ch);
 	
-	return ast_for_testlist(c, ch, 1);
+	return ast_for_testlist_gexp(c, ch);
     case LSQB: /* list (or list comprehension) */
 	ch = CHILD(n, 1);
 	
@@ -1297,7 +1304,7 @@
 	return Dict(keys, values, LINENO(n));
     }
     case BACKQUOTE: { /* repr */
-	expr_ty expression = ast_for_testlist(c, CHILD(n, 1), 0);
+	expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
 	
 	if (!expression)
 	    return NULL;
@@ -1552,7 +1559,7 @@
         case yield_expr: {
 	    expr_ty exp = NULL;
 	    if (NCH(n) == 2) {
-		exp = ast_for_testlist(c, CHILD(n, 1), 0);
+		exp = ast_for_testlist(c, CHILD(n, 1));
 		if (!exp)
 		    return NULL;
 	    }
@@ -1796,36 +1803,69 @@
     return NULL;
 }
 
-/* Unlike other ast_for_XXX() functions, this takes a flag that
-   indicates whether generator expressions are allowed.  If gexp is
-   non-zero, check for testlist_gexp instead of plain testlist.
-*/
-
 static expr_ty
-ast_for_testlist(struct compiling *c, const node* n, int gexp)
+ast_for_testlist(struct compiling *c, const node* n)
 {
-  /* testlist_gexp: test ( gen_for | (',' test)* [','] )
-     testlist: test (',' test)* [',']
-  */
-
+    /* testlist_gexp: test (',' test)* [','] */
+    /* testlist: test (',' test)* [','] */
+    /* testlist_safe: test (',' test)+ [','] */
+    /* testlist1: test (',' test)* */
     assert(NCH(n) > 0);
+    if (TYPE(n) == testlist_gexp) {
+        if (NCH(n) > 1)
+            assert(TYPE(CHILD(n, 1)) != gen_for);
+    }
+    else {
+        assert(TYPE(n) == testlist ||
+               TYPE(n) == testlist_safe ||
+               TYPE(n) == testlist1);
+    }
     if (NCH(n) == 1)
 	return ast_for_expr(c, CHILD(n, 0));
-    if (TYPE(CHILD(n, 1)) == gen_for) {
-	if (!gexp) {
-	    ast_error(n, "illegal generator expression");
-	    return NULL;
-	}
-	return ast_for_genexp(c, n);
-    }
     else {
         asdl_seq *tmp = seq_for_testlist(c, n);
         if (!tmp)
             return NULL;
-
 	return Tuple(tmp, Load, LINENO(n));
     }
-    return NULL;  /* unreachable */
+}
+
+static expr_ty
+ast_for_testlist_gexp(struct compiling *c, const node* n)
+{
+    /* testlist_gexp: test ( gen_for | (',' test)* [','] ) */
+    /* argument: test [ gen_for ] */
+    assert(TYPE(n) == testlist_gexp || TYPE(n) == argument);
+    if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == gen_for) {
+	return ast_for_genexp(c, n);
+    }
+    else
+        return ast_for_testlist(c, n);
+}
+
+/* like ast_for_testlist() but returns a sequence */
+static asdl_seq*
+ast_for_class_bases(struct compiling *c, const node* n)
+{
+    /* testlist: test (',' test)* [','] */
+    assert(NCH(n) > 0);
+    REQ(n, testlist);
+    if (NCH(n) == 1) {
+        expr_ty base;
+        asdl_seq *bases = asdl_seq_new(1);
+        if (!bases)
+            return NULL;
+        base = ast_for_expr(c, CHILD(n, 0));
+        if (!base) {
+            asdl_seq_free(bases);
+            return NULL;
+        }
+        asdl_seq_SET(bases, 0, base);
+        return bases;
+    }
+    else {
+        return seq_for_testlist(c, n);
+    }
 }
 
 static stmt_ty
@@ -1841,7 +1881,7 @@
      */
 
     if (NCH(n) == 1) {
-	expr_ty e = ast_for_testlist(c, CHILD(n, 0), 0);
+	expr_ty e = ast_for_testlist(c, CHILD(n, 0));
         if (!e)
             return NULL;
 
@@ -1853,7 +1893,7 @@
 	node *ch = CHILD(n, 0);
 
 	if (TYPE(ch) == testlist)
-	    expr1 = ast_for_testlist(c, ch, 0);
+	    expr1 = ast_for_testlist(c, ch);
 	else
 	    expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch));
 
@@ -1874,7 +1914,7 @@
 
 	ch = CHILD(n, 2);
 	if (TYPE(ch) == testlist)
-	    expr2 = ast_for_testlist(c, ch, 0);
+	    expr2 = ast_for_testlist(c, ch);
 	else
 	    expr2 = Yield(ast_for_expr(c, ch), LINENO(ch));
         if (!expr2)
@@ -1904,7 +1944,7 @@
 		ast_error(ch, "assignment to yield expression not possible");
 		goto error;
 	    }
-	    e = ast_for_testlist(c, ch, 0);
+	    e = ast_for_testlist(c, ch);
 
 	    /* set context to assign */
 	    if (!e) 
@@ -1919,7 +1959,7 @@
 	}
 	value = CHILD(n, NCH(n) - 1);
 	if (TYPE(value) == testlist)
-	    expression = ast_for_testlist(c, value, 0);
+	    expression = ast_for_testlist(c, value);
 	else
 	    expression = ast_for_expr(c, value);
 	if (!expression)
@@ -2041,7 +2081,7 @@
             if (NCH(ch) == 1)
                 return Return(NULL, LINENO(n));
             else {
-                expr_ty expression = ast_for_testlist(c, CHILD(ch, 1), 0);
+                expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
                 if (!expression)
                     return NULL;
                 return Return(expression, LINENO(n));
@@ -2599,7 +2639,7 @@
     else
 	target = Tuple(_target, Store, LINENO(n));
 
-    expression = ast_for_testlist(c, CHILD(n, 3), 0);
+    expression = ast_for_testlist(c, CHILD(n, 3));
     if (!expression)
         return NULL;
     suite_seq = ast_for_suite(c, CHILD(n, 5));
@@ -2725,7 +2765,6 @@
 ast_for_classdef(struct compiling *c, const node *n)
 {
     /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
-    expr_ty _bases;
     asdl_seq *bases, *s;
     
     REQ(n, classdef);
@@ -2750,37 +2789,13 @@
     }
 
     /* else handle the base class list */
-    _bases = ast_for_testlist(c, CHILD(n, 3), 0);
-    if (!_bases)
+    bases = ast_for_class_bases(c, CHILD(n, 3));
+    if (!bases)
         return NULL;
-    /* XXX: I don't think we can set to diff types here, how to free???
-
-	Here's the allocation chain:
-    		Tuple (Python-ast.c:907)
-    		ast_for_testlist (ast.c:1782)
-    		ast_for_classdef (ast.c:2677)
-     */
-    if (_bases->kind == Tuple_kind)
-	bases = _bases->v.Tuple.elts;
-    else {
-	bases = asdl_seq_new(1);
-	if (!bases) {
-            free_expr(_bases);
-	    /* XXX: free _bases */
-            return NULL;
-	}
-	asdl_seq_SET(bases, 0, _bases);
-    }
 
     s = ast_for_suite(c, CHILD(n, 6));
     if (!s) {
-	/* XXX: I think this free is correct, but needs to change see above */
-        if (_bases->kind == Tuple_kind)
-		free_expr(_bases);
-	else {
-		free_expr(_bases);
-        	asdl_seq_free(bases);
-	}
+        asdl_seq_free(bases);
         return NULL;
     }
     return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n));



More information about the Python-checkins mailing list