[Python-checkins] python/dist/src/Python ast.c,1.1.2.70,1.1.2.71
jhylton@users.sourceforge.net
jhylton at users.sourceforge.net
Mon Oct 17 17:08:37 CEST 2005
Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29976/Python
Modified Files:
Tag: ast-branch
ast.c
Log Message:
Fix handling of testlist_gexp.
Created a single function that handles the several possible testlist
variants, with a flag indicating whether a gexp is possible. Note
that I don't understand why that Grammar allows testlist_gexp in some
places but not others.
Address several other XXX comments, including calls to free. Reindent
a few functions to four spaces so that they can be read.
Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v
retrieving revision 1.1.2.70
retrieving revision 1.1.2.71
diff -u -d -r1.1.2.70 -r1.1.2.71
--- ast.c 16 Oct 2005 05:19:44 -0000 1.1.2.70
+++ ast.c 17 Oct 2005 15:08:33 -0000 1.1.2.71
@@ -35,7 +35,7 @@
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 *);
+static expr_ty ast_for_testlist(struct compiling *, const node *, int);
/* Note different signature for ast_for_call */
static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
@@ -249,8 +249,9 @@
return Module(stmts);
case eval_input: {
expr_ty testlist_ast;
-
- testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
+
+ /* XXX Why not gen_for here? */
+ testlist_ast = ast_for_testlist(&c, CHILD(n, 0), 0);
if (!testlist_ast)
goto error;
return Expression(testlist_ast);
@@ -512,7 +513,11 @@
seq_for_testlist(struct compiling *c, const node *n)
{
/* testlist: test (',' test)* [','] */
- REQ(n, testlist);
+ assert(TYPE(n) == testlist
+ || TYPE(n) == listmaker
+ || TYPE(n) == testlist_gexp
+ || TYPE(n) == testlist_safe
+ );
asdl_seq *seq;
expr_ty expression;
int i;
@@ -641,10 +646,12 @@
ast_error(CHILD(ch, 0), "assignment to None");
goto error;
}
- /* XXX check return value of Name call */
- asdl_seq_APPEND(args,
- Name(NEW_IDENTIFIER(CHILD(ch, 0)),
- Param, LINENO(ch)));
+ expr_ty name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
+ Param, LINENO(ch));
+ if (!name)
+ goto error;
+ asdl_seq_APPEND(args, name);
+
}
i += 2; /* the name and the comma */
break;
@@ -955,7 +962,7 @@
listcomps = asdl_seq_new(n_fors);
if (!listcomps) {
- /* XXX free(elt); */
+ free_expr(elt);
return NULL;
}
@@ -970,13 +977,14 @@
t = ast_for_exprlist(c, CHILD(ch, 1), Store);
if (!t) {
asdl_seq_free(listcomps);
- /* XXX free(elt); */
+ free_expr(elt);
return NULL;
}
- expression = ast_for_testlist(c, CHILD(ch, 3));
+ expression = ast_for_testlist(c, CHILD(ch, 3), 0);
if (!expression) {
+ asdl_seq_free(t);
asdl_seq_free(listcomps);
- /* XXX free(elt); */
+ free_expr(elt);
return NULL;
}
@@ -986,8 +994,10 @@
lc = comprehension(Tuple(t, Store, LINENO(ch)), expression, NULL);
if (!lc) {
+ asdl_seq_free(t);
asdl_seq_free(listcomps);
- /* XXX free(elt); */
+ free_expr(expression);
+ free_expr(elt);
return NULL;
}
@@ -999,14 +1009,14 @@
n_ifs = count_list_ifs(ch);
if (n_ifs == -1) {
asdl_seq_free(listcomps);
- /* XXX free(elt); */
+ free_expr(elt);
return NULL;
}
ifs = asdl_seq_new(n_ifs);
if (!ifs) {
asdl_seq_free(listcomps);
- /* XXX free(elt); */
+ free_expr(elt);
return NULL;
}
@@ -1096,211 +1106,209 @@
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;
+ /* 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) {
+ free_expr(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);
+ free_expr(elt);
+ return NULL;
+ }
+ expression = ast_for_testlist(c, CHILD(ch, 3), 1);
+ if (!expression) {
+ asdl_seq_free(genexps);
+ free_expr(elt);
+ return NULL;
+ }
+
+ if (asdl_seq_LEN(t) == 1)
+ ge = comprehension(asdl_seq_GET(t, 0), expression,
+ NULL);
+ else
+ ge = comprehension(Tuple(t, Store, LINENO(ch)),
+ expression, NULL);
+
+ if (!ge) {
+ asdl_seq_free(genexps);
+ free_expr(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);
+ free_expr(elt);
+ return NULL;
+ }
+
+ ifs = asdl_seq_new(n_ifs);
+ if (!ifs) {
+ asdl_seq_free(genexps);
+ free_expr(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, LINENO(n));
+}
+
+static expr_ty
+ast_for_atom(struct compiling *c, const node *n)
+{
+ /* atom: '(' [yield_expr|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, LINENO(n));
+ case STRING: {
+ PyObject *str = parsestrplus(c, n);
- assert(TYPE(n) == (testlist_gexp) || TYPE(n) == (argument));
- assert(NCH(n) > 1);
+ if (!str)
+ return NULL;
- elt = ast_for_expr(c, CHILD(n, 0));
- if (!elt)
- return NULL;
+ return Str(str, LINENO(n));
+ }
+ case NUMBER: {
+ PyObject *pynum = parsenumber(STR(ch));
- n_fors = count_gen_fors(n);
- if (n_fors == -1)
- return NULL;
+ if (!pynum)
+ return NULL;
- genexps = asdl_seq_new(n_fors);
- if (!genexps) {
- /* XXX free(elt); */
+ return Num(pynum, LINENO(n));
+ }
+ case LPAR: /* some parenthesized expressions */
+ ch = CHILD(n, 1);
+
+ if (TYPE(ch) == RPAR)
+ return Tuple(NULL, Load, LINENO(n));
+
+ if (TYPE(ch) == yield_expr)
+ return ast_for_expr(c, ch);
+
+ if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
+ return ast_for_genexp(c, ch);
+
+ return ast_for_testlist(c, ch, 1);
+ case LSQB: /* list (or list comprehension) */
+ ch = CHILD(n, 1);
+
+ if (TYPE(ch) == RSQB)
+ return List(NULL, Load, LINENO(n));
+
+ REQ(ch, listmaker);
+ if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
+ asdl_seq *elts = seq_for_testlist(c, ch);
+
+ if (!elts)
return NULL;
+
+ return List(elts, Load, LINENO(n));
}
+ 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);
- 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, LINENO(ch)),
- 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);
+ 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;
}
- return GeneratorExp(elt, genexps, LINENO(n));
-}
-
-static expr_ty
-ast_for_atom(struct compiling *c, const node *n)
-{
- /* XXX yield_expr */
- /* atom: '(' [yield_expr|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, LINENO(n));
- case STRING: {
- PyObject *str = parsestrplus(c, n);
-
- if (!str)
- return NULL;
-
- return Str(str, LINENO(n));
- }
- case NUMBER: {
- PyObject *pynum = parsenumber(STR(ch));
-
- if (!pynum)
- return NULL;
-
- return Num(pynum, LINENO(n));
- }
- case LPAR: /* some parenthesized expressions */
- ch = CHILD(n, 1);
-
- if (TYPE(ch) == RPAR)
- return Tuple(NULL, Load, LINENO(n));
-
- if (TYPE(ch) == yield_expr)
- return ast_for_expr(c, ch);
-
- if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
- return ast_for_genexp(c, ch);
-
- return ast_for_testlist(c, ch);
- case LSQB: /* list (or list comprehension) */
- ch = CHILD(n, 1);
-
- if (TYPE(ch) == RSQB)
- return List(NULL, Load, LINENO(n));
-
- REQ(ch, listmaker);
- if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
- asdl_seq *elts = seq_for_testlist(c, ch);
-
- if (!elts)
- return NULL;
-
- return List(elts, Load, LINENO(n));
- }
- 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, LINENO(n));
- }
- case BACKQUOTE: { /* repr */
- expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
-
- if (!expression)
- return NULL;
-
- return Repr(expression, LINENO(n));
- }
- default:
- PyErr_Format(PyExc_Exception, "unhandled atom %d",
- TYPE(ch));
- 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, LINENO(n));
+ }
+ case BACKQUOTE: { /* repr */
+ expr_ty expression = ast_for_testlist(c, CHILD(n, 1), 0);
+
+ if (!expression)
+ return NULL;
+
+ return Repr(expression, LINENO(n));
+ }
+ default:
+ PyErr_Format(PyExc_Exception, "unhandled atom %d",
+ TYPE(ch));
+ return NULL;
+ }
}
static slice_ty
@@ -1544,7 +1552,7 @@
case yield_expr: {
expr_ty exp = NULL;
if (NCH(n) == 2) {
- exp = ast_for_testlist(c, CHILD(n, 1));
+ exp = ast_for_testlist(c, CHILD(n, 1), 0);
if (!exp)
return NULL;
}
@@ -1612,7 +1620,7 @@
new = Subscript(e, slc, Load, LINENO(ch));
if (!new) {
free_expr(e);
- /* XXX free(slc); */
+ free_slice(slc);
return NULL;
}
}
@@ -1788,14 +1796,28 @@
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)
+ast_for_testlist(struct compiling *c, const node* n, int gexp)
{
- /* n could be a testlist, a listmaker with no list_for, or
- a testlist1 from inside backquotes. */
+ /* testlist_gexp: test ( gen_for | (',' test)* [','] )
+ testlist: test (',' test)* [',']
+ */
+ assert(NCH(n) > 0);
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)
@@ -1803,14 +1825,15 @@
return Tuple(tmp, Load, LINENO(n));
}
+ return NULL; /* unreachable */
}
static stmt_ty
ast_for_expr_stmt(struct compiling *c, const node *n)
{
REQ(n, expr_stmt);
- /* XXX yield_expr */
- /* expr_stmt: testlist (augassign testlist | ('=' testlist)*)
+ /* expr_stmt: testlist (augassign (yield_expr|testlist)
+ | ('=' (yield_expr|testlist))*)
testlist: test (',' test)* [',']
augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
| '<<=' | '>>=' | '**=' | '//='
@@ -1818,7 +1841,7 @@
*/
if (NCH(n) == 1) {
- expr_ty e = ast_for_testlist(c, CHILD(n, 0));
+ expr_ty e = ast_for_testlist(c, CHILD(n, 0), 0);
if (!e)
return NULL;
@@ -1830,7 +1853,7 @@
node *ch = CHILD(n, 0);
if (TYPE(ch) == testlist)
- expr1 = ast_for_testlist(c, ch);
+ expr1 = ast_for_testlist(c, ch, 0);
else
expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch));
@@ -1851,7 +1874,7 @@
ch = CHILD(n, 2);
if (TYPE(ch) == testlist)
- expr2 = ast_for_testlist(c, ch);
+ expr2 = ast_for_testlist(c, ch, 0);
else
expr2 = Yield(ast_for_expr(c, ch), LINENO(ch));
if (!expr2)
@@ -1880,7 +1903,7 @@
ast_error(ch, "assignment to yield expression not possible");
goto error;
}
- expr_ty e = ast_for_testlist(c, ch);
+ expr_ty e = ast_for_testlist(c, ch, 0);
/* set context to assign */
if (!e)
@@ -1895,7 +1918,7 @@
}
value = CHILD(n, NCH(n) - 1);
if (TYPE(value) == testlist)
- expression = ast_for_testlist(c, value);
+ expression = ast_for_testlist(c, value, 0);
else
expression = ast_for_expr(c, value);
if (!expression)
@@ -2017,7 +2040,7 @@
if (NCH(ch) == 1)
return Return(NULL, LINENO(n));
else {
- expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
+ expr_ty expression = ast_for_testlist(c, CHILD(ch, 1), 0);
if (!expression)
return NULL;
return Return(expression, LINENO(n));
@@ -2202,7 +2225,7 @@
aliases = asdl_seq_new((n_children + 1) / 2);
if (!aliases) {
- free(mod); /* XXX proper way to free alias_ty structs? */
+ free_alias(mod);
return NULL;
}
@@ -2211,7 +2234,7 @@
alias_ty import_alias = alias_for_import_name(n);
if (!import_alias) {
asdl_seq_free(aliases);
- free(mod);
+ free_alias(mod);
return NULL;
}
asdl_seq_APPEND(aliases, import_alias);
@@ -2221,13 +2244,14 @@
alias_ty import_alias = alias_for_import_name(CHILD(n, i));
if (!import_alias) {
asdl_seq_free(aliases);
- free(mod);
+ free_alias(mod);
return NULL;
}
asdl_seq_APPEND(aliases, import_alias);
}
+ Py_INCREF(mod->name);
import = ImportFrom(mod->name, aliases, lineno);
- free(mod);
+ free_alias(mod);
return import;
}
PyErr_Format(PyExc_Exception,
@@ -2573,7 +2597,7 @@
else
target = Tuple(_target, Store, LINENO(n));
- expression = ast_for_testlist(c, CHILD(n, 3));
+ expression = ast_for_testlist(c, CHILD(n, 3), 0);
if (!expression)
return NULL;
suite_seq = ast_for_suite(c, CHILD(n, 5));
@@ -2724,7 +2748,7 @@
}
/* else handle the base class list */
- _bases = ast_for_testlist(c, CHILD(n, 3));
+ _bases = ast_for_testlist(c, CHILD(n, 3), 0);
if (!_bases)
return NULL;
/* XXX: I don't think we can set to diff types here, how to free???
@@ -2739,6 +2763,7 @@
else {
bases = asdl_seq_new(1);
if (!bases) {
+ free_expr(_bases);
/* XXX: free _bases */
return NULL;
}
More information about the Python-checkins
mailing list