summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2007-04-15 12:05:43 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2007-04-15 12:05:43 (GMT)
commit650f0d06d3574f843f52edd1126ddd9ebd6fac7d (patch)
tree9116cebfb4031d0ac3b2db7dc0e8c85d82751e59 /Python
parent6ef6306dd62aa092539298ed69c7c6ffff568e2d (diff)
downloadcpython-650f0d06d3574f843f52edd1126ddd9ebd6fac7d.zip
cpython-650f0d06d3574f843f52edd1126ddd9ebd6fac7d.tar.gz
cpython-650f0d06d3574f843f52edd1126ddd9ebd6fac7d.tar.bz2
Hide list comp variables and support set comprehensions
Diffstat (limited to 'Python')
-rw-r--r--Python/Python-ast.c45
-rw-r--r--Python/ast.c366
-rw-r--r--Python/ceval.c12
-rw-r--r--Python/compile.c279
-rw-r--r--Python/graminit.c884
-rw-r--r--Python/symtable.c345
6 files changed, 907 insertions, 1024 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index bcdd56d..d56d823 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -192,6 +192,11 @@ static char *ListComp_fields[]={
"elt",
"generators",
};
+static PyTypeObject *SetComp_type;
+static char *SetComp_fields[]={
+ "elt",
+ "generators",
+};
static PyTypeObject *GeneratorExp_type;
static char *GeneratorExp_fields[]={
"elt",
@@ -543,6 +548,8 @@ static int init_types(void)
if (!Set_type) return 0;
ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
if (!ListComp_type) return 0;
+ SetComp_type = make_type("SetComp", expr_type, SetComp_fields, 2);
+ if (!SetComp_type) return 0;
GeneratorExp_type = make_type("GeneratorExp", expr_type,
GeneratorExp_fields, 2);
if (!GeneratorExp_type) return 0;
@@ -1419,6 +1426,27 @@ ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
}
expr_ty
+SetComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, PyArena
+ *arena)
+{
+ expr_ty p;
+ if (!elt) {
+ PyErr_SetString(PyExc_ValueError,
+ "field elt is required for SetComp");
+ return NULL;
+ }
+ p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
+ if (!p)
+ return NULL;
+ p->kind = SetComp_kind;
+ p->v.SetComp.elt = elt;
+ p->v.SetComp.generators = generators;
+ p->lineno = lineno;
+ p->col_offset = col_offset;
+ return p;
+}
+
+expr_ty
GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
PyArena *arena)
{
@@ -2416,6 +2444,21 @@ ast2obj_expr(void* _o)
goto failed;
Py_DECREF(value);
break;
+ case SetComp_kind:
+ result = PyType_GenericNew(SetComp_type, NULL, NULL);
+ if (!result) goto failed;
+ value = ast2obj_expr(o->v.SetComp.elt);
+ if (!value) goto failed;
+ if (PyObject_SetAttrString(result, "elt", value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ value = ast2obj_list(o->v.SetComp.generators,
+ ast2obj_comprehension);
+ if (!value) goto failed;
+ if (PyObject_SetAttrString(result, "generators", value) == -1)
+ goto failed;
+ Py_DECREF(value);
+ break;
case GeneratorExp_kind:
result = PyType_GenericNew(GeneratorExp_type, NULL, NULL);
if (!result) goto failed;
@@ -3120,6 +3163,8 @@ init_ast(void)
if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return;
if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
return;
+ if (PyDict_SetItemString(d, "SetComp", (PyObject*)SetComp_type) < 0)
+ return;
if (PyDict_SetItemString(d, "GeneratorExp",
(PyObject*)GeneratorExp_type) < 0) return;
if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return;
diff --git a/Python/ast.c b/Python/ast.c
index 777c00e..262ade3 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -27,7 +27,6 @@ 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 *, expr_context_ty);
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);
@@ -41,6 +40,10 @@ static PyObject *parsestrplus(struct compiling *, const node *n,
#define LINENO(n) ((n)->n_lineno)
#endif
+#define COMP_GENEXP 0
+#define COMP_LISTCOMP 1
+#define COMP_SETCOMP 2
+
static identifier
new_identifier(const char* n, PyArena *arena) {
PyObject* id = PyString_InternFromString(n);
@@ -231,7 +234,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
case eval_input: {
expr_ty testlist_ast;
- /* XXX Why not gen_for here? */
+ /* XXX Why not comp_for here? */
testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
if (!testlist_ast)
goto error;
@@ -530,19 +533,14 @@ seq_for_testlist(struct compiling *c, const node *n)
asdl_seq *seq;
expr_ty expression;
int i;
- assert(TYPE(n) == testlist
- || TYPE(n) == listmaker
- || TYPE(n) == testlist_gexp
- || TYPE(n) == testlist_safe
- || TYPE(n) == testlist1
- );
+ assert(TYPE(n) == testlist || TYPE(n) == testlist_comp);
seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
if (!seq)
return NULL;
for (i = 0; i < NCH(n); i += 2) {
- assert(TYPE(CHILD(n, i)) == test || TYPE(CHILD(n, i)) == old_test);
+ assert(TYPE(CHILD(n, i)) == test || TYPE(CHILD(n, i)) == test_nocond);
expression = ast_for_expr(c, CHILD(n, i));
if (!expression)
@@ -1022,7 +1020,8 @@ ast_for_funcdef(struct compiling *c, const node *n)
static expr_ty
ast_for_lambdef(struct compiling *c, const node *n)
{
- /* lambdef: 'lambda' [varargslist] ':' test */
+ /* lambdef: 'lambda' [varargslist] ':' test
+ lambdef_nocond: 'lambda' [varargslist] ':' test_nocond */
arguments_ty args;
expr_ty expression;
@@ -1067,190 +1066,34 @@ ast_for_ifexpr(struct compiling *c, const node *n)
c->c_arena);
}
-/* XXX(nnorwitz): the listcomp and genexpr code should be refactored
- so there is only a single version. Possibly for loops can also re-use
- the code.
-*/
-
-/* Count the number of 'for' loop in a list comprehension.
-
- Helper for ast_for_listcomp().
-*/
-
-static int
-count_list_fors(const node *n)
-{
- int n_fors = 0;
- node *ch = CHILD(n, 1);
-
- count_list_for:
- n_fors++;
- REQ(ch, list_for);
- if (NCH(ch) == 5)
- ch = CHILD(ch, 4);
- else
- return n_fors;
- count_list_iter:
- REQ(ch, list_iter);
- ch = CHILD(ch, 0);
- if (TYPE(ch) == list_for)
- goto count_list_for;
- else if (TYPE(ch) == list_if) {
- if (NCH(ch) == 3) {
- ch = CHILD(ch, 2);
- goto count_list_iter;
- }
- else
- return n_fors;
- }
-
- /* Should never be reached */
- PyErr_SetString(PyExc_SystemError, "logic error in count_list_fors");
- return -1;
-}
-
-/* Count the number of 'if' statements in a list comprehension.
-
- Helper for ast_for_listcomp().
-*/
-
-static int
-count_list_ifs(const node *n)
-{
- int n_ifs = 0;
-
- count_list_iter:
- REQ(n, list_iter);
- if (TYPE(CHILD(n, 0)) == list_for)
- return n_ifs;
- n = CHILD(n, 0);
- REQ(n, list_if);
- n_ifs++;
- if (NCH(n) == 2)
- return n_ifs;
- n = CHILD(n, 2);
- goto count_list_iter;
-}
-
-static expr_ty
-ast_for_listcomp(struct compiling *c, const node *n)
-{
- /* listmaker: test ( list_for | (',' test)* [','] )
- list_for: 'for' exprlist 'in' testlist_safe [list_iter]
- list_iter: list_for | list_if
- list_if: 'if' test [list_iter]
- testlist_safe: test [(',' test)+ [',']]
- */
- expr_ty elt;
- asdl_seq *listcomps;
- int i, n_fors;
- node *ch;
-
- REQ(n, listmaker);
- assert(NCH(n) > 1);
-
- elt = ast_for_expr(c, CHILD(n, 0));
- if (!elt)
- return NULL;
-
- n_fors = count_list_fors(n);
- if (n_fors == -1)
- return NULL;
-
- listcomps = asdl_seq_new(n_fors, c->c_arena);
- if (!listcomps)
- return NULL;
-
- ch = CHILD(n, 1);
- for (i = 0; i < n_fors; i++) {
- comprehension_ty lc;
- asdl_seq *t;
- expr_ty expression;
- node *for_ch;
-
- REQ(ch, list_for);
-
- for_ch = CHILD(ch, 1);
- t = ast_for_exprlist(c, for_ch, Store);
- if (!t)
- return NULL;
- expression = ast_for_testlist(c, CHILD(ch, 3));
- if (!expression)
- return NULL;
-
- /* Check the # of children rather than the length of t, since
- [x for x, in ... ] has 1 element in t, but still requires a Tuple. */
- if (NCH(for_ch) == 1)
- lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,
- c->c_arena);
- else
- lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
- c->c_arena),
- expression, NULL, c->c_arena);
- if (!lc)
- return NULL;
-
- if (NCH(ch) == 5) {
- int j, n_ifs;
- asdl_seq *ifs;
-
- ch = CHILD(ch, 4);
- n_ifs = count_list_ifs(ch);
- if (n_ifs == -1)
- return NULL;
-
- ifs = asdl_seq_new(n_ifs, c->c_arena);
- if (!ifs)
- return NULL;
-
- for (j = 0; j < n_ifs; j++) {
- REQ(ch, list_iter);
- ch = CHILD(ch, 0);
- REQ(ch, list_if);
-
- asdl_seq_SET(ifs, j, ast_for_expr(c, CHILD(ch, 1)));
- if (NCH(ch) == 3)
- ch = CHILD(ch, 2);
- }
- /* on exit, must guarantee that ch is a list_for */
- if (TYPE(ch) == list_iter)
- ch = CHILD(ch, 0);
- lc->ifs = ifs;
- }
- asdl_seq_SET(listcomps, i, lc);
- }
-
- return ListComp(elt, listcomps, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
/*
- Count the number of 'for' loops in a generator expression.
+ Count the number of 'for' loops in a comprehension.
- Helper for ast_for_genexp().
+ Helper for ast_for_comprehension().
*/
static int
-count_gen_fors(const node *n)
+count_comp_fors(const node *n)
{
int n_fors = 0;
node *ch = CHILD(n, 1);
- count_gen_for:
+ count_comp_for:
n_fors++;
- REQ(ch, gen_for);
+ REQ(ch, comp_for);
if (NCH(ch) == 5)
ch = CHILD(ch, 4);
else
return n_fors;
- count_gen_iter:
- REQ(ch, gen_iter);
+ count_comp_iter:
+ REQ(ch, comp_iter);
ch = CHILD(ch, 0);
- if (TYPE(ch) == gen_for)
- goto count_gen_for;
- else if (TYPE(ch) == gen_if) {
+ if (TYPE(ch) == comp_for)
+ goto count_comp_for;
+ else if (TYPE(ch) == comp_if) {
if (NCH(ch) == 3) {
ch = CHILD(ch, 2);
- goto count_gen_iter;
+ goto count_comp_iter;
}
else
return n_fors;
@@ -1258,26 +1101,26 @@ count_gen_fors(const node *n)
/* Should never be reached */
PyErr_SetString(PyExc_SystemError,
- "logic error in count_gen_fors");
+ "logic error in count_comp_fors");
return -1;
}
-/* Count the number of 'if' statements in a generator expression.
+/* Count the number of 'if' statements in a comprehension.
- Helper for ast_for_genexp().
+ Helper for ast_for_comprehension().
*/
static int
-count_gen_ifs(const node *n)
+count_comp_ifs(const node *n)
{
int n_ifs = 0;
while (1) {
- REQ(n, gen_iter);
- if (TYPE(CHILD(n, 0)) == gen_for)
+ REQ(n, comp_iter);
+ if (TYPE(CHILD(n, 0)) == comp_for)
return n_ifs;
n = CHILD(n, 0);
- REQ(n, gen_if);
+ REQ(n, comp_if);
n_ifs++;
if (NCH(n) == 2)
return n_ifs;
@@ -1285,40 +1128,38 @@ count_gen_ifs(const node *n)
}
}
-/* TODO(jhylton): Combine with list comprehension code? */
static expr_ty
-ast_for_genexp(struct compiling *c, const node *n)
+ast_for_comprehension(struct compiling *c, const node *n, int type)
{
- /* testlist_gexp: test ( gen_for | (',' test)* [','] )
- argument: [test '='] test [gen_for] # Really [keyword '='] test */
+ /* testlist_comp: test ( comp_for | (',' test)* [','] )
+ argument: [test '='] test [comp_for] # Really [keyword '='] test */
expr_ty elt;
- asdl_seq *genexps;
+ asdl_seq *comps;
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);
+ n_fors = count_comp_fors(n);
if (n_fors == -1)
return NULL;
- genexps = asdl_seq_new(n_fors, c->c_arena);
- if (!genexps)
+ comps = asdl_seq_new(n_fors, c->c_arena);
+ if (!comps)
return NULL;
ch = CHILD(n, 1);
for (i = 0; i < n_fors; i++) {
- comprehension_ty ge;
+ comprehension_ty comp;
asdl_seq *t;
expr_ty expression;
node *for_ch;
- REQ(ch, gen_for);
+ REQ(ch, comp_for);
for_ch = CHILD(ch, 1);
t = ast_for_exprlist(c, for_ch, Store);
@@ -1331,14 +1172,14 @@ ast_for_genexp(struct compiling *c, const node *n)
/* Check the # of children rather than the length of t, since
(x for x, in ...) has 1 element in t, but still requires a Tuple. */
if (NCH(for_ch) == 1)
- ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
- NULL, c->c_arena);
+ comp = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
+ NULL, c->c_arena);
else
- ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
- c->c_arena),
- expression, NULL, c->c_arena);
+ comp = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
+ c->c_arena),
+ expression, NULL, c->c_arena);
- if (!ge)
+ if (!comp)
return NULL;
if (NCH(ch) == 5) {
@@ -1346,7 +1187,7 @@ ast_for_genexp(struct compiling *c, const node *n)
asdl_seq *ifs;
ch = CHILD(ch, 4);
- n_ifs = count_gen_ifs(ch);
+ n_ifs = count_comp_ifs(ch);
if (n_ifs == -1)
return NULL;
@@ -1355,9 +1196,9 @@ ast_for_genexp(struct compiling *c, const node *n)
return NULL;
for (j = 0; j < n_ifs; j++) {
- REQ(ch, gen_iter);
+ REQ(ch, comp_iter);
ch = CHILD(ch, 0);
- REQ(ch, gen_if);
+ REQ(ch, comp_if);
expression = ast_for_expr(c, CHILD(ch, 1));
if (!expression)
@@ -1366,22 +1207,52 @@ ast_for_genexp(struct compiling *c, const node *n)
if (NCH(ch) == 3)
ch = CHILD(ch, 2);
}
- /* on exit, must guarantee that ch is a gen_for */
- if (TYPE(ch) == gen_iter)
+ /* on exit, must guarantee that ch is a comp_for */
+ if (TYPE(ch) == comp_iter)
ch = CHILD(ch, 0);
- ge->ifs = ifs;
+ comp->ifs = ifs;
}
- asdl_seq_SET(genexps, i, ge);
+ asdl_seq_SET(comps, i, comp);
}
-
- return GeneratorExp(elt, genexps, LINENO(n), n->n_col_offset, c->c_arena);
+
+ if (type == COMP_GENEXP)
+ return GeneratorExp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);
+ else if (type == COMP_LISTCOMP)
+ return ListComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);
+ else if (type == COMP_SETCOMP)
+ return SetComp(elt, comps, LINENO(n), n->n_col_offset, c->c_arena);
+ else
+ /* Should never happen */
+ return NULL;
+}
+
+static expr_ty
+ast_for_genexp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (testlist_comp) || TYPE(n) == (argument));
+ return ast_for_comprehension(c, n, COMP_GENEXP);
}
static expr_ty
+ast_for_listcomp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (testlist_comp));
+ return ast_for_comprehension(c, n, COMP_LISTCOMP);
+}
+
+static expr_ty
+ast_for_setcomp(struct compiling *c, const node *n)
+{
+ assert(TYPE(n) == (dictorsetmaker));
+ return ast_for_comprehension(c, n, COMP_SETCOMP);
+}
+
+
+static expr_ty
ast_for_atom(struct compiling *c, const node *n)
{
- /* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
- | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING+
+ /* atom: '(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']'
+ | '{' [dictmaker|testlist_comp] '}' | NAME | NUMBER | STRING+
*/
node *ch = CHILD(n, 0);
int bytesmode = 0;
@@ -1420,18 +1291,19 @@ ast_for_atom(struct compiling *c, const node *n)
if (TYPE(ch) == yield_expr)
return ast_for_expr(c, ch);
-
- if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
+
+ /* testlist_comp: test ( comp_for | (',' test)* [','] ) */
+ if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == comp_for))
return ast_for_genexp(c, ch);
- return ast_for_testlist_gexp(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), n->n_col_offset, c->c_arena);
- REQ(ch, listmaker);
+ REQ(ch, testlist_comp);
if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
asdl_seq *elts = seq_for_testlist(c, ch);
if (!elts)
@@ -1442,27 +1314,32 @@ ast_for_atom(struct compiling *c, const node *n)
else
return ast_for_listcomp(c, ch);
case LBRACE: {
- /* dictsetmaker: test ':' test (',' test ':' test)* [','] |
- * test (',' test)* [','] */
+ /* dictorsetmaker: test ':' test (',' test ':' test)* [','] |
+ * test (gen_for | (',' test)* [',']) */
int i, size;
asdl_seq *keys, *values;
ch = CHILD(n, 1);
- if (NCH(ch) == 1 || (NCH(ch) > 0 && STR(CHILD(ch, 1))[0] == ',')) {
- /* it's a set */
+ if (TYPE(ch) == RBRACE) {
+ /* it's an empty dict */
+ return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
+ } else if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
+ /* it's a simple set */
size = (NCH(ch) + 1) / 2; /* +1 in case no trailing comma */
- keys = asdl_seq_new(size, c->c_arena);
- if (!keys)
+ asdl_seq *elts = asdl_seq_new(size, c->c_arena);
+ if (!elts)
return NULL;
-
for (i = 0; i < NCH(ch); i += 2) {
expr_ty expression;
expression = ast_for_expr(c, CHILD(ch, i));
if (!expression)
return NULL;
- asdl_seq_SET(keys, i / 2, expression);
+ asdl_seq_SET(elts, i / 2, expression);
}
- return Set(keys, LINENO(n), n->n_col_offset, c->c_arena);
+ return Set(elts, LINENO(n), n->n_col_offset, c->c_arena);
+ } else if (TYPE(CHILD(ch, 1)) == comp_for) {
+ /* it's a set comprehension */
+ return ast_for_setcomp(c, ch);
} else {
/* it's a dict */
size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
@@ -1790,6 +1667,7 @@ ast_for_expr(struct compiling *c, const node *n)
{
/* handle the full range of simple expressions
test: or_test ['if' or_test 'else' test] | lambdef
+ test_nocond: or_test | lambdef_nocond
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
@@ -1802,15 +1680,6 @@ ast_for_expr(struct compiling *c, const node *n)
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ('**' factor)*
-
- As well as modified versions that exist for backward compatibility,
- to explicitly allow:
- [ x for x in lambda: 0, lambda: 1 ]
- (which would be ambiguous without these extra rules)
-
- old_test: or_test | old_lambdef
- old_lambdef: 'lambda' [vararglist] ':' old_test
-
*/
asdl_seq *seq;
@@ -1819,9 +1688,9 @@ ast_for_expr(struct compiling *c, const node *n)
loop:
switch (TYPE(n)) {
case test:
- case old_test:
+ case test_nocond:
if (TYPE(CHILD(n, 0)) == lambdef ||
- TYPE(CHILD(n, 0)) == old_lambdef)
+ TYPE(CHILD(n, 0)) == lambdef_nocond)
return ast_for_lambdef(c, CHILD(n, 0));
else if (NCH(n) > 1)
return ast_for_ifexpr(c, n);
@@ -1947,7 +1816,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
/*
arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
| '**' test)
- argument: [test '='] test [gen_for] # Really [keyword '='] test
+ argument: [test '='] test [comp_for] # Really [keyword '='] test
*/
int i, nargs, nkeywords, ngens;
@@ -1965,7 +1834,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
if (TYPE(ch) == argument) {
if (NCH(ch) == 1)
nargs++;
- else if (TYPE(CHILD(ch, 1)) == gen_for)
+ else if (TYPE(CHILD(ch, 1)) == comp_for)
ngens++;
else
nkeywords++;
@@ -2005,7 +1874,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
return NULL;
asdl_seq_SET(args, nargs++, e);
}
- else if (TYPE(CHILD(ch, 1)) == gen_for) {
+ else if (TYPE(CHILD(ch, 1)) == comp_for) {
e = ast_for_genexp(c, ch);
if (!e)
return NULL;
@@ -2057,18 +1926,16 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func)
static expr_ty
ast_for_testlist(struct compiling *c, const node* n)
{
- /* testlist_gexp: test (',' test)* [','] */
+ /* testlist_comp: test (comp_for | (',' test)* [',']) */
/* testlist: test (',' test)* [','] */
- /* testlist_safe: test (',' test)+ [','] */
/* testlist1: test (',' test)* */
assert(NCH(n) > 0);
- if (TYPE(n) == testlist_gexp) {
+ if (TYPE(n) == testlist_comp) {
if (NCH(n) > 1)
- assert(TYPE(CHILD(n, 1)) != gen_for);
+ assert(TYPE(CHILD(n, 1)) != comp_for);
}
else {
assert(TYPE(n) == testlist ||
- TYPE(n) == testlist_safe ||
TYPE(n) == testlist1);
}
if (NCH(n) == 1)
@@ -2081,17 +1948,6 @@ ast_for_testlist(struct compiling *c, const node* n)
}
}
-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);
- return ast_for_testlist(c, n);
-}
-
static stmt_ty
ast_for_expr_stmt(struct compiling *c, const node *n)
{
diff --git a/Python/ceval.c b/Python/ceval.c
index 5a3fc59..d2cda84 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1241,6 +1241,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}
break;
+ case SET_ADD:
+ w = POP();
+ v = POP();
+ err = PySet_Add(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ if (err == 0) {
+ PREDICT(JUMP_ABSOLUTE);
+ continue;
+ }
+ break;
+
case INPLACE_POWER:
w = POP();
v = TOP();
diff --git a/Python/compile.c b/Python/compile.c
index a47c8e6..bee48da 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -39,6 +39,10 @@ int Py_OptimizeFlag = 0;
#define DEFAULT_CODE_SIZE 128
#define DEFAULT_LNOTAB_SIZE 16
+#define COMP_GENEXP 0
+#define COMP_LISTCOMP 1
+#define COMP_SETCOMP 2
+
struct instr {
unsigned i_jabs : 1;
unsigned i_jrel : 1;
@@ -360,7 +364,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
while (PyDict_Next(src, &pos, &k, &v)) {
/* XXX this should probably be a macro in symtable.h */
assert(PyInt_Check(v));
- scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
+ scope = (PyInt_AS_LONG(v) >> SCOPE_OFFSET) & SCOPE_MASK;
if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
PyObject *tuple, *item = PyInt_FromLong(i);
@@ -673,6 +677,7 @@ opcode_stack_effect(int opcode, int oparg)
case UNARY_INVERT:
return 0;
+ case SET_ADD:
case LIST_APPEND:
return -2;
@@ -2724,122 +2729,45 @@ compiler_call_helper(struct compiler *c,
return 1;
}
-static int
-compiler_listcomp_generator(struct compiler *c, PyObject *tmpname,
- asdl_seq *generators, int gen_index,
- expr_ty elt)
-{
- /* generate code for the iterator, then each of the ifs,
- and then write to the element */
- comprehension_ty l;
- basicblock *start, *anchor, *skip, *if_cleanup;
- int i, n;
+/* List and set comprehensions and generator expressions work by creating a
+ nested function to perform the actual iteration. This means that the
+ iteration variables don't leak into the current scope.
+ The defined function is called immediately following its definition, with the
+ result of that call being the result of the expression.
+ The LC/SC version returns the populated container, while the GE version is
+ flagged in symtable.c as a generator, so it returns the generator object
+ when the function is called.
+ This code *knows* that the loop cannot contain break, continue, or return,
+ so it cheats and skips the SETUP_LOOP/POP_BLOCK steps used in normal loops.
- start = compiler_new_block(c);
- skip = compiler_new_block(c);
- if_cleanup = compiler_new_block(c);
- anchor = compiler_new_block(c);
-
- if (start == NULL || skip == NULL || if_cleanup == NULL ||
- anchor == NULL)
- return 0;
-
- l = (comprehension_ty)asdl_seq_GET(generators, gen_index);
- 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);
-
- /* XXX this needs to be cleaned up...a lot! */
- n = asdl_seq_LEN(l->ifs);
- for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(l->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_listcomp_generator(c, tmpname,
- generators, gen_index, elt))
- return 0;
-
- /* only append after the last for generator */
- if (gen_index >= asdl_seq_LEN(generators)) {
- if (!compiler_nameop(c, tmpname, Load))
- return 0;
- VISIT(c, expr, elt);
- ADDOP(c, LIST_APPEND);
-
- 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);
- /* delete the temporary list name added to locals */
- if (gen_index == 1)
- if (!compiler_nameop(c, tmpname, Del))
- return 0;
-
- return 1;
-}
-
-static int
-compiler_listcomp(struct compiler *c, expr_ty e)
-{
- identifier tmp;
- int rc = 0;
- asdl_seq *generators = e->v.ListComp.generators;
-
- assert(e->kind == ListComp_kind);
- tmp = compiler_new_tmpname(c);
- if (!tmp)
- return 0;
- ADDOP_I(c, BUILD_LIST, 0);
- ADDOP(c, DUP_TOP);
- if (compiler_nameop(c, tmp, Store))
- rc = compiler_listcomp_generator(c, tmp, generators, 0,
- e->v.ListComp.elt);
- Py_DECREF(tmp);
- return rc;
-}
+ Possible cleanups:
+ - iterate over the generator sequence instead of using recursion
+*/
static int
-compiler_genexp_generator(struct compiler *c,
- asdl_seq *generators, int gen_index,
- expr_ty elt)
+compiler_comprehension_generator(struct compiler *c, PyObject *tmpname,
+ asdl_seq *generators, int gen_index,
+ expr_ty elt, int type)
{
/* 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;
+ comprehension_ty gen;
+ basicblock *start, *anchor, *skip, *if_cleanup;
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 = (comprehension_ty)asdl_seq_GET(generators, gen_index);
- ADDOP_JREL(c, SETUP_LOOP, end);
- if (!compiler_push_fblock(c, LOOP, start))
+ anchor == NULL)
return 0;
+ gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
+
if (gen_index == 0) {
/* Receive outermost iter as an implicit argument */
c->u->u_argcount = 1;
@@ -2847,18 +2775,18 @@ compiler_genexp_generator(struct compiler *c,
}
else {
/* Sub-iter - calculate on the fly */
- VISIT(c, expr, ge->iter);
+ VISIT(c, expr, gen->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);
+ VISIT(c, expr, gen->target);
/* XXX this needs to be cleaned up...a lot! */
- n = asdl_seq_LEN(ge->ifs);
+ n = asdl_seq_LEN(gen->ifs);
for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(ge->ifs, i);
+ expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
VISIT(c, expr, e);
ADDOP_JREL(c, JUMP_IF_FALSE, if_cleanup);
NEXT_BLOCK(c);
@@ -2866,14 +2794,35 @@ compiler_genexp_generator(struct compiler *c,
}
if (++gen_index < asdl_seq_LEN(generators))
- if (!compiler_genexp_generator(c, generators, gen_index, elt))
- return 0;
+ if (!compiler_comprehension_generator(c, tmpname,
+ generators, gen_index,
+ elt, type))
+ return 0;
- /* only append after the last 'for' generator */
+ /* only append after the last for generator */
if (gen_index >= asdl_seq_LEN(generators)) {
- VISIT(c, expr, elt);
- ADDOP(c, YIELD_VALUE);
- ADDOP(c, POP_TOP);
+ /* comprehension specific code */
+ switch (type) {
+ case COMP_GENEXP:
+ VISIT(c, expr, elt);
+ ADDOP(c, YIELD_VALUE);
+ ADDOP(c, POP_TOP);
+ break;
+ case COMP_LISTCOMP:
+ if (!compiler_nameop(c, tmpname, Load))
+ return 0;
+ VISIT(c, expr, elt);
+ ADDOP(c, LIST_APPEND);
+ break;
+ case COMP_SETCOMP:
+ if (!compiler_nameop(c, tmpname, Load))
+ return 0;
+ VISIT(c, expr, elt);
+ ADDOP(c, SET_ADD);
+ break;
+ default:
+ return 0;
+ }
compiler_use_next_block(c, skip);
}
@@ -2881,52 +2830,116 @@ compiler_genexp_generator(struct compiler *c,
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)
+compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name,
+ asdl_seq *generators, expr_ty elt)
{
- static identifier name;
- PyCodeObject *co;
- expr_ty outermost_iter = ((comprehension_ty)
- (asdl_seq_GET(e->v.GeneratorExp.generators,
- 0)))->iter;
+ PyCodeObject *co = NULL;
+ identifier tmp = NULL;
+ expr_ty outermost_iter;
- if (!name) {
- name = PyString_FromString("<genexpr>");
- if (!name)
- return 0;
- }
+ outermost_iter = ((comprehension_ty)
+ asdl_seq_GET(generators, 0))->iter;
if (!compiler_enter_scope(c, name, (void *)e, e->lineno))
- return 0;
- compiler_genexp_generator(c, e->v.GeneratorExp.generators, 0,
- e->v.GeneratorExp.elt);
+ goto error;
+
+ if (type != COMP_GENEXP) {
+ tmp = compiler_new_tmpname(c);
+ if (!tmp)
+ goto error_in_scope;
+
+ ADDOP_I(c, (type == COMP_LISTCOMP ?
+ BUILD_LIST : BUILD_SET), 0);
+ ADDOP(c, DUP_TOP);
+ if (!compiler_nameop(c, tmp, Store))
+ goto error_in_scope;
+ }
+
+ if (!compiler_comprehension_generator(c, tmp, generators, 0, elt, type))
+ goto error_in_scope;
+
+ if (type != COMP_GENEXP) {
+ ADDOP(c, RETURN_VALUE);
+ }
+
co = assemble(c, 1);
compiler_exit_scope(c);
if (co == NULL)
- return 0;
+ goto error;
- compiler_make_closure(c, co, 0);
+ if (!compiler_make_closure(c, co, 0))
+ goto error;
Py_DECREF(co);
+ Py_XDECREF(tmp);
VISIT(c, expr, outermost_iter);
ADDOP(c, GET_ITER);
ADDOP_I(c, CALL_FUNCTION, 1);
-
return 1;
+error_in_scope:
+ compiler_exit_scope(c);
+error:
+ Py_XDECREF(co);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static int
+compiler_genexp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyString_FromString("<genexp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == GeneratorExp_kind);
+ return compiler_comprehension(c, e, COMP_GENEXP, name,
+ e->v.GeneratorExp.generators,
+ e->v.GeneratorExp.elt);
+}
+
+static int
+compiler_listcomp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyString_FromString("<listcomp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == ListComp_kind);
+ return compiler_comprehension(c, e, COMP_LISTCOMP, name,
+ e->v.ListComp.generators,
+ e->v.ListComp.elt);
+}
+
+static int
+compiler_setcomp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyString_FromString("<setcomp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == SetComp_kind);
+ return compiler_comprehension(c, e, COMP_SETCOMP, name,
+ e->v.SetComp.generators,
+ e->v.SetComp.elt);
}
+
static int
compiler_visit_keyword(struct compiler *c, keyword_ty k)
{
@@ -3145,10 +3158,12 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
VISIT_SEQ(c, expr, e->v.Set.elts);
ADDOP_I(c, BUILD_SET, n);
break;
- case ListComp_kind:
- return compiler_listcomp(c, e);
case GeneratorExp_kind:
return compiler_genexp(c, e);
+ case ListComp_kind:
+ return compiler_listcomp(c, e);
+ case SetComp_kind:
+ return compiler_setcomp(c, e);
case Yield_kind:
if (c->u->u_ste->ste_type != FunctionBlock)
return compiler_error(c, "'yield' outside function");
diff --git a/Python/graminit.c b/Python/graminit.c
index 4f44fe2..df35d51 100644
--- a/Python/graminit.c
+++ b/Python/graminit.c
@@ -1061,33 +1061,36 @@ static state states_47[5] = {
{1, arcs_47_3},
{2, arcs_47_4},
};
-static arc arcs_48_0[1] = {
- {109, 1},
+static arc arcs_48_0[2] = {
+ {108, 1},
+ {109, 2},
};
static arc arcs_48_1[2] = {
- {28, 2},
+ {93, 3},
{0, 1},
};
static arc arcs_48_2[1] = {
- {109, 3},
+ {0, 2},
};
-static arc arcs_48_3[2] = {
- {28, 4},
- {0, 3},
+static arc arcs_48_3[1] = {
+ {108, 4},
};
-static arc arcs_48_4[2] = {
- {109, 3},
- {0, 4},
+static arc arcs_48_4[1] = {
+ {95, 5},
+};
+static arc arcs_48_5[1] = {
+ {22, 2},
};
-static state states_48[5] = {
- {1, arcs_48_0},
+static state states_48[6] = {
+ {2, arcs_48_0},
{2, arcs_48_1},
{1, arcs_48_2},
- {2, arcs_48_3},
- {2, arcs_48_4},
+ {1, arcs_48_3},
+ {1, arcs_48_4},
+ {1, arcs_48_5},
};
static arc arcs_49_0[2] = {
- {110, 1},
+ {108, 1},
{111, 1},
};
static arc arcs_49_1[1] = {
@@ -1108,7 +1111,7 @@ static arc arcs_50_2[1] = {
{23, 3},
};
static arc arcs_50_3[1] = {
- {109, 4},
+ {22, 4},
};
static arc arcs_50_4[1] = {
{0, 4},
@@ -1120,39 +1123,34 @@ static state states_50[5] = {
{1, arcs_50_3},
{1, arcs_50_4},
};
-static arc arcs_51_0[2] = {
- {110, 1},
- {113, 2},
+static arc arcs_51_0[1] = {
+ {112, 1},
};
static arc arcs_51_1[2] = {
- {93, 3},
- {0, 1},
+ {33, 2},
+ {23, 3},
};
static arc arcs_51_2[1] = {
- {0, 2},
+ {23, 3},
};
static arc arcs_51_3[1] = {
{110, 4},
};
static arc arcs_51_4[1] = {
- {95, 5},
-};
-static arc arcs_51_5[1] = {
- {22, 2},
+ {0, 4},
};
-static state states_51[6] = {
- {2, arcs_51_0},
+static state states_51[5] = {
+ {1, arcs_51_0},
{2, arcs_51_1},
{1, arcs_51_2},
{1, arcs_51_3},
{1, arcs_51_4},
- {1, arcs_51_5},
};
static arc arcs_52_0[1] = {
- {114, 1},
+ {113, 1},
};
static arc arcs_52_1[2] = {
- {115, 0},
+ {114, 0},
{0, 1},
};
static state states_52[2] = {
@@ -1160,10 +1158,10 @@ static state states_52[2] = {
{2, arcs_52_1},
};
static arc arcs_53_0[1] = {
- {116, 1},
+ {115, 1},
};
static arc arcs_53_1[2] = {
- {117, 0},
+ {116, 0},
{0, 1},
};
static state states_53[2] = {
@@ -1171,11 +1169,11 @@ static state states_53[2] = {
{2, arcs_53_1},
};
static arc arcs_54_0[2] = {
- {118, 1},
- {119, 2},
+ {117, 1},
+ {118, 2},
};
static arc arcs_54_1[1] = {
- {116, 2},
+ {115, 2},
};
static arc arcs_54_2[1] = {
{0, 2},
@@ -1189,7 +1187,7 @@ static arc arcs_55_0[1] = {
{104, 1},
};
static arc arcs_55_1[2] = {
- {120, 0},
+ {119, 0},
{0, 1},
};
static state states_55[2] = {
@@ -1197,15 +1195,15 @@ static state states_55[2] = {
{2, arcs_55_1},
};
static arc arcs_56_0[9] = {
+ {120, 1},
{121, 1},
{122, 1},
{123, 1},
{124, 1},
{125, 1},
- {126, 1},
{98, 1},
- {118, 2},
- {127, 3},
+ {117, 2},
+ {126, 3},
};
static arc arcs_56_1[1] = {
{0, 1},
@@ -1214,7 +1212,7 @@ static arc arcs_56_2[1] = {
{98, 1},
};
static arc arcs_56_3[2] = {
- {118, 1},
+ {117, 1},
{0, 3},
};
static state states_56[4] = {
@@ -1224,10 +1222,10 @@ static state states_56[4] = {
{2, arcs_56_3},
};
static arc arcs_57_0[1] = {
- {128, 1},
+ {127, 1},
};
static arc arcs_57_1[2] = {
- {129, 0},
+ {128, 0},
{0, 1},
};
static state states_57[2] = {
@@ -1235,10 +1233,10 @@ static state states_57[2] = {
{2, arcs_57_1},
};
static arc arcs_58_0[1] = {
- {130, 1},
+ {129, 1},
};
static arc arcs_58_1[2] = {
- {131, 0},
+ {130, 0},
{0, 1},
};
static state states_58[2] = {
@@ -1246,10 +1244,10 @@ static state states_58[2] = {
{2, arcs_58_1},
};
static arc arcs_59_0[1] = {
- {132, 1},
+ {131, 1},
};
static arc arcs_59_1[2] = {
- {133, 0},
+ {132, 0},
{0, 1},
};
static state states_59[2] = {
@@ -1257,11 +1255,11 @@ static state states_59[2] = {
{2, arcs_59_1},
};
static arc arcs_60_0[1] = {
- {134, 1},
+ {133, 1},
};
static arc arcs_60_1[3] = {
+ {134, 0},
{135, 0},
- {136, 0},
{0, 1},
};
static state states_60[2] = {
@@ -1269,11 +1267,11 @@ static state states_60[2] = {
{3, arcs_60_1},
};
static arc arcs_61_0[1] = {
- {137, 1},
+ {136, 1},
};
static arc arcs_61_1[3] = {
+ {137, 0},
{138, 0},
- {139, 0},
{0, 1},
};
static state states_61[2] = {
@@ -1281,13 +1279,13 @@ static state states_61[2] = {
{3, arcs_61_1},
};
static arc arcs_62_0[1] = {
- {140, 1},
+ {139, 1},
};
static arc arcs_62_1[5] = {
{29, 0},
+ {140, 0},
{141, 0},
{142, 0},
- {143, 0},
{0, 1},
};
static state states_62[2] = {
@@ -1295,13 +1293,13 @@ static state states_62[2] = {
{5, arcs_62_1},
};
static arc arcs_63_0[4] = {
+ {137, 1},
{138, 1},
- {139, 1},
- {144, 1},
- {145, 2},
+ {143, 1},
+ {144, 2},
};
static arc arcs_63_1[1] = {
- {140, 2},
+ {139, 2},
};
static arc arcs_63_2[1] = {
{0, 2},
@@ -1312,15 +1310,15 @@ static state states_63[3] = {
{1, arcs_63_2},
};
static arc arcs_64_0[1] = {
- {146, 1},
+ {145, 1},
};
static arc arcs_64_1[3] = {
- {147, 1},
+ {146, 1},
{31, 2},
{0, 1},
};
static arc arcs_64_2[1] = {
- {140, 3},
+ {139, 3},
};
static arc arcs_64_3[1] = {
{0, 3},
@@ -1333,41 +1331,41 @@ static state states_64[4] = {
};
static arc arcs_65_0[7] = {
{13, 1},
- {149, 2},
- {152, 3},
+ {148, 2},
+ {150, 3},
{19, 4},
- {155, 4},
- {156, 5},
+ {153, 4},
+ {154, 5},
{79, 4},
};
static arc arcs_65_1[3] = {
{48, 6},
- {148, 6},
+ {147, 6},
{15, 4},
};
static arc arcs_65_2[2] = {
- {150, 7},
- {151, 4},
+ {147, 7},
+ {149, 4},
};
static arc arcs_65_3[2] = {
- {153, 8},
- {154, 4},
+ {151, 8},
+ {152, 4},
};
static arc arcs_65_4[1] = {
{0, 4},
};
static arc arcs_65_5[2] = {
- {156, 5},
+ {154, 5},
{0, 5},
};
static arc arcs_65_6[1] = {
{15, 4},
};
static arc arcs_65_7[1] = {
- {151, 4},
+ {149, 4},
};
static arc arcs_65_8[1] = {
- {154, 4},
+ {152, 4},
};
static state states_65[9] = {
{7, arcs_65_0},
@@ -1384,7 +1382,7 @@ static arc arcs_66_0[1] = {
{22, 1},
};
static arc arcs_66_1[3] = {
- {157, 2},
+ {155, 2},
{28, 3},
{0, 1},
};
@@ -1406,644 +1404,533 @@ static state states_66[5] = {
{2, arcs_66_3},
{2, arcs_66_4},
};
-static arc arcs_67_0[1] = {
- {22, 1},
-};
-static arc arcs_67_1[3] = {
- {158, 2},
- {28, 3},
- {0, 1},
-};
-static arc arcs_67_2[1] = {
- {0, 2},
-};
-static arc arcs_67_3[2] = {
- {22, 4},
- {0, 3},
-};
-static arc arcs_67_4[2] = {
- {28, 3},
- {0, 4},
-};
-static state states_67[5] = {
- {1, arcs_67_0},
- {3, arcs_67_1},
- {1, arcs_67_2},
- {2, arcs_67_3},
- {2, arcs_67_4},
-};
-static arc arcs_68_0[1] = {
- {112, 1},
-};
-static arc arcs_68_1[2] = {
- {33, 2},
- {23, 3},
-};
-static arc arcs_68_2[1] = {
- {23, 3},
-};
-static arc arcs_68_3[1] = {
- {22, 4},
-};
-static arc arcs_68_4[1] = {
- {0, 4},
-};
-static state states_68[5] = {
- {1, arcs_68_0},
- {2, arcs_68_1},
- {1, arcs_68_2},
- {1, arcs_68_3},
- {1, arcs_68_4},
-};
-static arc arcs_69_0[3] = {
+static arc arcs_67_0[3] = {
{13, 1},
- {149, 2},
+ {148, 2},
{78, 3},
};
-static arc arcs_69_1[2] = {
+static arc arcs_67_1[2] = {
{14, 4},
{15, 5},
};
-static arc arcs_69_2[1] = {
- {159, 6},
+static arc arcs_67_2[1] = {
+ {156, 6},
};
-static arc arcs_69_3[1] = {
+static arc arcs_67_3[1] = {
{19, 5},
};
-static arc arcs_69_4[1] = {
+static arc arcs_67_4[1] = {
{15, 5},
};
-static arc arcs_69_5[1] = {
+static arc arcs_67_5[1] = {
{0, 5},
};
-static arc arcs_69_6[1] = {
- {151, 5},
+static arc arcs_67_6[1] = {
+ {149, 5},
};
-static state states_69[7] = {
- {3, arcs_69_0},
- {2, arcs_69_1},
- {1, arcs_69_2},
- {1, arcs_69_3},
- {1, arcs_69_4},
- {1, arcs_69_5},
- {1, arcs_69_6},
+static state states_67[7] = {
+ {3, arcs_67_0},
+ {2, arcs_67_1},
+ {1, arcs_67_2},
+ {1, arcs_67_3},
+ {1, arcs_67_4},
+ {1, arcs_67_5},
+ {1, arcs_67_6},
};
-static arc arcs_70_0[1] = {
- {160, 1},
+static arc arcs_68_0[1] = {
+ {157, 1},
};
-static arc arcs_70_1[2] = {
+static arc arcs_68_1[2] = {
{28, 2},
{0, 1},
};
-static arc arcs_70_2[2] = {
- {160, 1},
+static arc arcs_68_2[2] = {
+ {157, 1},
{0, 2},
};
-static state states_70[3] = {
- {1, arcs_70_0},
- {2, arcs_70_1},
- {2, arcs_70_2},
+static state states_68[3] = {
+ {1, arcs_68_0},
+ {2, arcs_68_1},
+ {2, arcs_68_2},
};
-static arc arcs_71_0[2] = {
+static arc arcs_69_0[2] = {
{22, 1},
{23, 2},
};
-static arc arcs_71_1[2] = {
+static arc arcs_69_1[2] = {
{23, 2},
{0, 1},
};
-static arc arcs_71_2[3] = {
+static arc arcs_69_2[3] = {
{22, 3},
- {161, 4},
+ {158, 4},
{0, 2},
};
-static arc arcs_71_3[2] = {
- {161, 4},
+static arc arcs_69_3[2] = {
+ {158, 4},
{0, 3},
};
-static arc arcs_71_4[1] = {
+static arc arcs_69_4[1] = {
{0, 4},
};
-static state states_71[5] = {
- {2, arcs_71_0},
- {2, arcs_71_1},
- {3, arcs_71_2},
- {2, arcs_71_3},
- {1, arcs_71_4},
+static state states_69[5] = {
+ {2, arcs_69_0},
+ {2, arcs_69_1},
+ {3, arcs_69_2},
+ {2, arcs_69_3},
+ {1, arcs_69_4},
};
-static arc arcs_72_0[1] = {
+static arc arcs_70_0[1] = {
{23, 1},
};
-static arc arcs_72_1[2] = {
+static arc arcs_70_1[2] = {
{22, 2},
{0, 1},
};
-static arc arcs_72_2[1] = {
+static arc arcs_70_2[1] = {
{0, 2},
};
-static state states_72[3] = {
- {1, arcs_72_0},
- {2, arcs_72_1},
- {1, arcs_72_2},
+static state states_70[3] = {
+ {1, arcs_70_0},
+ {2, arcs_70_1},
+ {1, arcs_70_2},
};
-static arc arcs_73_0[1] = {
+static arc arcs_71_0[1] = {
{104, 1},
};
-static arc arcs_73_1[2] = {
+static arc arcs_71_1[2] = {
{28, 2},
{0, 1},
};
-static arc arcs_73_2[2] = {
+static arc arcs_71_2[2] = {
{104, 1},
{0, 2},
};
-static state states_73[3] = {
- {1, arcs_73_0},
- {2, arcs_73_1},
- {2, arcs_73_2},
+static state states_71[3] = {
+ {1, arcs_71_0},
+ {2, arcs_71_1},
+ {2, arcs_71_2},
};
-static arc arcs_74_0[1] = {
+static arc arcs_72_0[1] = {
{22, 1},
};
-static arc arcs_74_1[2] = {
+static arc arcs_72_1[2] = {
{28, 2},
{0, 1},
};
-static arc arcs_74_2[2] = {
+static arc arcs_72_2[2] = {
{22, 1},
{0, 2},
};
-static state states_74[3] = {
- {1, arcs_74_0},
- {2, arcs_74_1},
- {2, arcs_74_2},
+static state states_72[3] = {
+ {1, arcs_72_0},
+ {2, arcs_72_1},
+ {2, arcs_72_2},
};
-static arc arcs_75_0[1] = {
+static arc arcs_73_0[1] = {
{22, 1},
};
-static arc arcs_75_1[3] = {
+static arc arcs_73_1[4] = {
{23, 2},
- {28, 3},
+ {155, 3},
+ {28, 4},
{0, 1},
};
-static arc arcs_75_2[1] = {
- {22, 4},
-};
-static arc arcs_75_3[2] = {
+static arc arcs_73_2[1] = {
{22, 5},
+};
+static arc arcs_73_3[1] = {
{0, 3},
};
-static arc arcs_75_4[2] = {
- {28, 6},
+static arc arcs_73_4[2] = {
+ {22, 6},
{0, 4},
};
-static arc arcs_75_5[2] = {
- {28, 3},
+static arc arcs_73_5[2] = {
+ {28, 7},
{0, 5},
};
-static arc arcs_75_6[2] = {
- {22, 7},
+static arc arcs_73_6[2] = {
+ {28, 4},
{0, 6},
};
-static arc arcs_75_7[1] = {
+static arc arcs_73_7[2] = {
+ {22, 8},
+ {0, 7},
+};
+static arc arcs_73_8[1] = {
{23, 2},
};
-static state states_75[8] = {
- {1, arcs_75_0},
- {3, arcs_75_1},
- {1, arcs_75_2},
- {2, arcs_75_3},
- {2, arcs_75_4},
- {2, arcs_75_5},
- {2, arcs_75_6},
- {1, arcs_75_7},
+static state states_73[9] = {
+ {1, arcs_73_0},
+ {4, arcs_73_1},
+ {1, arcs_73_2},
+ {1, arcs_73_3},
+ {2, arcs_73_4},
+ {2, arcs_73_5},
+ {2, arcs_73_6},
+ {2, arcs_73_7},
+ {1, arcs_73_8},
};
-static arc arcs_76_0[1] = {
- {162, 1},
+static arc arcs_74_0[1] = {
+ {159, 1},
};
-static arc arcs_76_1[1] = {
+static arc arcs_74_1[1] = {
{19, 2},
};
-static arc arcs_76_2[2] = {
+static arc arcs_74_2[2] = {
{13, 3},
{23, 4},
};
-static arc arcs_76_3[2] = {
+static arc arcs_74_3[2] = {
{14, 5},
{15, 6},
};
-static arc arcs_76_4[1] = {
+static arc arcs_74_4[1] = {
{24, 7},
};
-static arc arcs_76_5[1] = {
+static arc arcs_74_5[1] = {
{15, 6},
};
-static arc arcs_76_6[1] = {
+static arc arcs_74_6[1] = {
{23, 4},
};
-static arc arcs_76_7[1] = {
+static arc arcs_74_7[1] = {
{0, 7},
};
-static state states_76[8] = {
- {1, arcs_76_0},
- {1, arcs_76_1},
- {2, arcs_76_2},
- {2, arcs_76_3},
- {1, arcs_76_4},
- {1, arcs_76_5},
- {1, arcs_76_6},
- {1, arcs_76_7},
-};
-static arc arcs_77_0[3] = {
- {163, 1},
+static state states_74[8] = {
+ {1, arcs_74_0},
+ {1, arcs_74_1},
+ {2, arcs_74_2},
+ {2, arcs_74_3},
+ {1, arcs_74_4},
+ {1, arcs_74_5},
+ {1, arcs_74_6},
+ {1, arcs_74_7},
+};
+static arc arcs_75_0[3] = {
+ {160, 1},
{29, 2},
{31, 3},
};
-static arc arcs_77_1[2] = {
+static arc arcs_75_1[2] = {
{28, 4},
{0, 1},
};
-static arc arcs_77_2[1] = {
+static arc arcs_75_2[1] = {
{22, 5},
};
-static arc arcs_77_3[1] = {
+static arc arcs_75_3[1] = {
{22, 6},
};
-static arc arcs_77_4[4] = {
- {163, 1},
+static arc arcs_75_4[4] = {
+ {160, 1},
{29, 2},
{31, 3},
{0, 4},
};
-static arc arcs_77_5[2] = {
+static arc arcs_75_5[2] = {
{28, 7},
{0, 5},
};
-static arc arcs_77_6[1] = {
+static arc arcs_75_6[1] = {
{0, 6},
};
-static arc arcs_77_7[1] = {
+static arc arcs_75_7[1] = {
{31, 3},
};
-static state states_77[8] = {
- {3, arcs_77_0},
- {2, arcs_77_1},
- {1, arcs_77_2},
- {1, arcs_77_3},
- {4, arcs_77_4},
- {2, arcs_77_5},
- {1, arcs_77_6},
- {1, arcs_77_7},
+static state states_75[8] = {
+ {3, arcs_75_0},
+ {2, arcs_75_1},
+ {1, arcs_75_2},
+ {1, arcs_75_3},
+ {4, arcs_75_4},
+ {2, arcs_75_5},
+ {1, arcs_75_6},
+ {1, arcs_75_7},
};
-static arc arcs_78_0[1] = {
+static arc arcs_76_0[1] = {
{22, 1},
};
-static arc arcs_78_1[3] = {
- {158, 2},
+static arc arcs_76_1[3] = {
+ {155, 2},
{27, 3},
{0, 1},
};
-static arc arcs_78_2[1] = {
+static arc arcs_76_2[1] = {
{0, 2},
};
-static arc arcs_78_3[1] = {
+static arc arcs_76_3[1] = {
{22, 2},
};
-static state states_78[4] = {
- {1, arcs_78_0},
- {3, arcs_78_1},
- {1, arcs_78_2},
- {1, arcs_78_3},
+static state states_76[4] = {
+ {1, arcs_76_0},
+ {3, arcs_76_1},
+ {1, arcs_76_2},
+ {1, arcs_76_3},
};
-static arc arcs_79_0[2] = {
- {157, 1},
- {165, 1},
+static arc arcs_77_0[2] = {
+ {155, 1},
+ {162, 1},
};
-static arc arcs_79_1[1] = {
+static arc arcs_77_1[1] = {
{0, 1},
};
-static state states_79[2] = {
- {2, arcs_79_0},
- {1, arcs_79_1},
+static state states_77[2] = {
+ {2, arcs_77_0},
+ {1, arcs_77_1},
};
-static arc arcs_80_0[1] = {
+static arc arcs_78_0[1] = {
{97, 1},
};
-static arc arcs_80_1[1] = {
+static arc arcs_78_1[1] = {
{62, 2},
};
-static arc arcs_80_2[1] = {
+static arc arcs_78_2[1] = {
{98, 3},
};
-static arc arcs_80_3[1] = {
+static arc arcs_78_3[1] = {
{108, 4},
};
-static arc arcs_80_4[2] = {
- {164, 5},
+static arc arcs_78_4[2] = {
+ {161, 5},
{0, 4},
};
-static arc arcs_80_5[1] = {
+static arc arcs_78_5[1] = {
{0, 5},
};
-static state states_80[6] = {
- {1, arcs_80_0},
- {1, arcs_80_1},
- {1, arcs_80_2},
- {1, arcs_80_3},
- {2, arcs_80_4},
- {1, arcs_80_5},
-};
-static arc arcs_81_0[1] = {
- {93, 1},
-};
-static arc arcs_81_1[1] = {
- {109, 2},
-};
-static arc arcs_81_2[2] = {
- {164, 3},
- {0, 2},
-};
-static arc arcs_81_3[1] = {
- {0, 3},
-};
-static state states_81[4] = {
- {1, arcs_81_0},
- {1, arcs_81_1},
- {2, arcs_81_2},
- {1, arcs_81_3},
-};
-static arc arcs_82_0[2] = {
- {158, 1},
- {167, 1},
-};
-static arc arcs_82_1[1] = {
- {0, 1},
-};
-static state states_82[2] = {
- {2, arcs_82_0},
- {1, arcs_82_1},
-};
-static arc arcs_83_0[1] = {
- {97, 1},
-};
-static arc arcs_83_1[1] = {
- {62, 2},
-};
-static arc arcs_83_2[1] = {
- {98, 3},
-};
-static arc arcs_83_3[1] = {
- {110, 4},
-};
-static arc arcs_83_4[2] = {
- {166, 5},
- {0, 4},
-};
-static arc arcs_83_5[1] = {
- {0, 5},
-};
-static state states_83[6] = {
- {1, arcs_83_0},
- {1, arcs_83_1},
- {1, arcs_83_2},
- {1, arcs_83_3},
- {2, arcs_83_4},
- {1, arcs_83_5},
+static state states_78[6] = {
+ {1, arcs_78_0},
+ {1, arcs_78_1},
+ {1, arcs_78_2},
+ {1, arcs_78_3},
+ {2, arcs_78_4},
+ {1, arcs_78_5},
};
-static arc arcs_84_0[1] = {
+static arc arcs_79_0[1] = {
{93, 1},
};
-static arc arcs_84_1[1] = {
- {109, 2},
+static arc arcs_79_1[1] = {
+ {110, 2},
};
-static arc arcs_84_2[2] = {
- {166, 3},
+static arc arcs_79_2[2] = {
+ {161, 3},
{0, 2},
};
-static arc arcs_84_3[1] = {
+static arc arcs_79_3[1] = {
{0, 3},
};
-static state states_84[4] = {
- {1, arcs_84_0},
- {1, arcs_84_1},
- {2, arcs_84_2},
- {1, arcs_84_3},
+static state states_79[4] = {
+ {1, arcs_79_0},
+ {1, arcs_79_1},
+ {2, arcs_79_2},
+ {1, arcs_79_3},
};
-static arc arcs_85_0[1] = {
+static arc arcs_80_0[1] = {
{22, 1},
};
-static arc arcs_85_1[2] = {
+static arc arcs_80_1[2] = {
{28, 0},
{0, 1},
};
-static state states_85[2] = {
- {1, arcs_85_0},
- {2, arcs_85_1},
+static state states_80[2] = {
+ {1, arcs_80_0},
+ {2, arcs_80_1},
};
-static arc arcs_86_0[1] = {
+static arc arcs_81_0[1] = {
{19, 1},
};
-static arc arcs_86_1[1] = {
+static arc arcs_81_1[1] = {
{0, 1},
};
-static state states_86[2] = {
- {1, arcs_86_0},
- {1, arcs_86_1},
+static state states_81[2] = {
+ {1, arcs_81_0},
+ {1, arcs_81_1},
};
-static arc arcs_87_0[1] = {
- {170, 1},
+static arc arcs_82_0[1] = {
+ {165, 1},
};
-static arc arcs_87_1[2] = {
+static arc arcs_82_1[2] = {
{9, 2},
{0, 1},
};
-static arc arcs_87_2[1] = {
+static arc arcs_82_2[1] = {
{0, 2},
};
-static state states_87[3] = {
- {1, arcs_87_0},
- {2, arcs_87_1},
- {1, arcs_87_2},
+static state states_82[3] = {
+ {1, arcs_82_0},
+ {2, arcs_82_1},
+ {1, arcs_82_2},
};
-static dfa dfas[88] = {
+static dfa dfas[83] = {
{256, "single_input", 0, 3, states_0,
- "\004\050\014\000\000\000\000\240\340\251\160\040\113\000\101\000\000\014\041\031\004\004"},
+ "\004\050\014\000\000\000\000\240\340\251\160\040\113\000\041\000\000\206\120\206\040"},
{257, "file_input", 0, 2, states_1,
- "\204\050\014\000\000\000\000\240\340\251\160\040\113\000\101\000\000\014\041\031\004\004"},
+ "\204\050\014\000\000\000\000\240\340\251\160\040\113\000\041\000\000\206\120\206\040"},
{258, "eval_input", 0, 3, states_2,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
{259, "decorator", 0, 7, states_3,
- "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{260, "decorators", 0, 2, states_4,
- "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{261, "funcdef", 0, 9, states_5,
- "\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\010\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{262, "parameters", 0, 4, states_6,
- "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{263, "typedargslist", 0, 12, states_7,
- "\000\040\010\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\010\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{264, "tname", 0, 4, states_8,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{265, "tfpdef", 0, 4, states_9,
- "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{266, "tfplist", 0, 3, states_10,
- "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{267, "varargslist", 0, 12, states_11,
- "\000\040\010\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\010\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{268, "vname", 0, 2, states_12,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{269, "vfpdef", 0, 4, states_13,
- "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{270, "vfplist", 0, 3, states_14,
- "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{271, "stmt", 0, 2, states_15,
- "\000\050\014\000\000\000\000\240\340\251\160\040\113\000\101\000\000\014\041\031\004\004"},
+ "\000\050\014\000\000\000\000\240\340\251\160\040\113\000\041\000\000\206\120\206\040"},
{272, "simple_stmt", 0, 4, states_16,
- "\000\040\010\000\000\000\000\240\340\251\160\000\000\000\101\000\000\014\041\031\000\004"},
+ "\000\040\010\000\000\000\000\240\340\251\160\000\000\000\041\000\000\206\120\006\040"},
{273, "small_stmt", 0, 2, states_17,
- "\000\040\010\000\000\000\000\240\340\251\160\000\000\000\101\000\000\014\041\031\000\004"},
+ "\000\040\010\000\000\000\000\240\340\251\160\000\000\000\041\000\000\206\120\006\040"},
{274, "expr_stmt", 0, 6, states_18,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
{275, "augassign", 0, 2, states_19,
- "\000\000\000\000\000\000\376\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\376\037\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{276, "del_stmt", 0, 3, states_20,
- "\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{277, "pass_stmt", 0, 2, states_21,
- "\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{278, "flow_stmt", 0, 2, states_22,
- "\000\000\000\000\000\000\000\000\340\001\000\000\000\000\000\000\000\000\000\000\000\004"},
+ "\000\000\000\000\000\000\000\000\340\001\000\000\000\000\000\000\000\000\000\000\040"},
{279, "break_stmt", 0, 2, states_23,
- "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"},
{280, "continue_stmt", 0, 2, states_24,
- "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000"},
{281, "return_stmt", 0, 3, states_25,
- "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"},
{282, "yield_stmt", 0, 2, states_26,
- "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"},
{283, "raise_stmt", 0, 7, states_27,
- "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"},
{284, "import_stmt", 0, 2, states_28,
- "\000\000\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\000\000\000\000"},
{285, "import_name", 0, 3, states_29,
- "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000"},
{286, "import_from", 0, 8, states_30,
- "\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000"},
{287, "import_as_name", 0, 4, states_31,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{288, "dotted_as_name", 0, 4, states_32,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{289, "import_as_names", 0, 3, states_33,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{290, "dotted_as_names", 0, 2, states_34,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{291, "dotted_name", 0, 2, states_35,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
{292, "global_stmt", 0, 3, states_36,
- "\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"},
{293, "nonlocal_stmt", 0, 3, states_37,
- "\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"},
{294, "assert_stmt", 0, 5, states_38,
- "\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000"},
{295, "compound_stmt", 0, 2, states_39,
- "\000\010\004\000\000\000\000\000\000\000\000\040\113\000\000\000\000\000\000\000\004\000"},
+ "\000\010\004\000\000\000\000\000\000\000\000\040\113\000\000\000\000\000\000\200\000"},
{296, "if_stmt", 0, 8, states_40,
- "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
{297, "while_stmt", 0, 8, states_41,
- "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"},
{298, "for_stmt", 0, 10, states_42,
- "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},
{299, "try_stmt", 0, 13, states_43,
- "\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000"},
{300, "with_stmt", 0, 6, states_44,
- "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000"},
{301, "with_var", 0, 3, states_45,
- "\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000"},
{302, "except_clause", 0, 5, states_46,
- "\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000"},
{303, "suite", 0, 5, states_47,
- "\004\040\010\000\000\000\000\240\340\251\160\000\000\000\101\000\000\014\041\031\000\004"},
- {304, "testlist_safe", 0, 5, states_48,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {305, "old_test", 0, 2, states_49,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {306, "old_lambdef", 0, 5, states_50,
- "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"},
- {307, "test", 0, 6, states_51,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
+ "\004\040\010\000\000\000\000\240\340\251\160\000\000\000\041\000\000\206\120\006\040"},
+ {304, "test", 0, 6, states_48,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {305, "test_nocond", 0, 2, states_49,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {306, "lambdef", 0, 5, states_50,
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000"},
+ {307, "lambdef_nocond", 0, 5, states_51,
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000"},
{308, "or_test", 0, 2, states_52,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\100\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\040\000\000\206\120\006\000"},
{309, "and_test", 0, 2, states_53,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\100\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\040\000\000\206\120\006\000"},
{310, "not_test", 0, 3, states_54,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\100\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\040\000\000\206\120\006\000"},
{311, "comparison", 0, 2, states_55,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{312, "comp_op", 0, 4, states_56,
- "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\100\376\000\000\000\000\000\000"},
+ "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\040\177\000\000\000\000\000"},
{313, "expr", 0, 2, states_57,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{314, "xor_expr", 0, 2, states_58,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{315, "and_expr", 0, 2, states_59,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{316, "shift_expr", 0, 2, states_60,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{317, "arith_expr", 0, 2, states_61,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{318, "term", 0, 2, states_62,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{319, "factor", 0, 3, states_63,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
{320, "power", 0, 4, states_64,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\040\031\000\000"},
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\006\000"},
{321, "atom", 0, 9, states_65,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\040\031\000\000"},
- {322, "listmaker", 0, 5, states_66,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {323, "testlist_gexp", 0, 5, states_67,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {324, "lambdef", 0, 5, states_68,
- "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"},
- {325, "trailer", 0, 7, states_69,
- "\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\040\000\000\000"},
- {326, "subscriptlist", 0, 3, states_70,
- "\000\040\210\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {327, "subscript", 0, 5, states_71,
- "\000\040\210\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {328, "sliceop", 0, 3, states_72,
- "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
- {329, "exprlist", 0, 3, states_73,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\014\041\031\000\000"},
- {330, "testlist", 0, 3, states_74,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {331, "dictsetmaker", 0, 8, states_75,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {332, "classdef", 0, 8, states_76,
- "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000"},
- {333, "arglist", 0, 8, states_77,
- "\000\040\010\240\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {334, "argument", 0, 4, states_78,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {335, "list_iter", 0, 2, states_79,
- "\000\000\000\000\000\000\000\000\000\000\000\040\002\000\000\000\000\000\000\000\000\000"},
- {336, "list_for", 0, 6, states_80,
- "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"},
- {337, "list_if", 0, 4, states_81,
- "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"},
- {338, "gen_iter", 0, 2, states_82,
- "\000\000\000\000\000\000\000\000\000\000\000\040\002\000\000\000\000\000\000\000\000\000"},
- {339, "gen_for", 0, 6, states_83,
- "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"},
- {340, "gen_if", 0, 4, states_84,
- "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"},
- {341, "testlist1", 0, 2, states_85,
- "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\101\000\000\014\041\031\000\000"},
- {342, "encoding_decl", 0, 2, states_86,
- "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
- {343, "yield_expr", 0, 3, states_87,
- "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004"},
-};
-static label labels[171] = {
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\006\000"},
+ {322, "testlist_comp", 0, 5, states_66,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {323, "trailer", 0, 7, states_67,
+ "\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\020\000\000"},
+ {324, "subscriptlist", 0, 3, states_68,
+ "\000\040\210\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {325, "subscript", 0, 5, states_69,
+ "\000\040\210\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {326, "sliceop", 0, 3, states_70,
+ "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {327, "exprlist", 0, 3, states_71,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\006\000"},
+ {328, "testlist", 0, 3, states_72,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {329, "dictorsetmaker", 0, 9, states_73,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {330, "classdef", 0, 8, states_74,
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"},
+ {331, "arglist", 0, 8, states_75,
+ "\000\040\010\240\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {332, "argument", 0, 4, states_76,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {333, "comp_iter", 0, 2, states_77,
+ "\000\000\000\000\000\000\000\000\000\000\000\040\002\000\000\000\000\000\000\000\000"},
+ {334, "comp_for", 0, 6, states_78,
+ "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"},
+ {335, "comp_if", 0, 4, states_79,
+ "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"},
+ {336, "testlist1", 0, 2, states_80,
+ "\000\040\010\000\000\000\000\000\000\200\000\000\000\000\041\000\000\206\120\006\000"},
+ {337, "encoding_decl", 0, 2, states_81,
+ "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
+ {338, "yield_expr", 0, 3, states_82,
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"},
+};
+static label labels[166] = {
{0, "EMPTY"},
{256, 0},
{4, 0},
@@ -2053,12 +1940,12 @@ static label labels[171] = {
{271, 0},
{0, 0},
{258, 0},
- {330, 0},
+ {328, 0},
{259, 0},
{50, 0},
{291, 0},
{7, 0},
- {333, 0},
+ {331, 0},
{8, 0},
{260, 0},
{261, 0},
@@ -2066,7 +1953,7 @@ static label labels[171] = {
{1, 0},
{262, 0},
{51, 0},
- {307, 0},
+ {304, 0},
{11, 0},
{303, 0},
{263, 0},
@@ -2092,7 +1979,7 @@ static label labels[171] = {
{293, 0},
{294, 0},
{275, 0},
- {343, 0},
+ {338, 0},
{37, 0},
{38, 0},
{39, 0},
@@ -2106,7 +1993,7 @@ static label labels[171] = {
{47, 0},
{49, 0},
{1, "del"},
- {329, 0},
+ {327, 0},
{1, "pass"},
{279, 0},
{280, 0},
@@ -2136,7 +2023,7 @@ static label labels[171] = {
{298, 0},
{299, 0},
{300, 0},
- {332, 0},
+ {330, 0},
{1, "if"},
{1, "elif"},
{1, "else"},
@@ -2152,12 +2039,11 @@ static label labels[171] = {
{1, "except"},
{5, 0},
{6, 0},
- {304, 0},
- {305, 0},
{308, 0},
{306, 0},
+ {305, 0},
+ {307, 0},
{1, "lambda"},
- {324, 0},
{309, 0},
{1, "or"},
{310, 0},
@@ -2191,34 +2077,30 @@ static label labels[171] = {
{32, 0},
{320, 0},
{321, 0},
- {325, 0},
{323, 0},
- {9, 0},
{322, 0},
+ {9, 0},
{10, 0},
{26, 0},
- {331, 0},
+ {329, 0},
{27, 0},
{2, 0},
{3, 0},
- {336, 0},
- {339, 0},
+ {334, 0},
+ {324, 0},
+ {325, 0},
{326, 0},
- {327, 0},
- {328, 0},
{1, "class"},
- {334, 0},
+ {332, 0},
+ {333, 0},
{335, 0},
+ {336, 0},
{337, 0},
- {338, 0},
- {340, 0},
- {341, 0},
- {342, 0},
{1, "yield"},
};
grammar _PyParser_Grammar = {
- 88,
+ 83,
dfas,
- {171, labels},
+ {166, labels},
256
};
diff --git a/Python/symtable.c b/Python/symtable.c
index e9c9391..68deb0a 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -76,7 +76,7 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
ste->ste_generator = 0;
ste->ste_returns_value = 0;
- if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
+ if (PyDict_SetItem(st->st_blocks, ste->ste_id, (PyObject *)ste) < 0)
goto fail;
return ste;
@@ -172,6 +172,8 @@ static int symtable_exit_block(struct symtable *st, void *ast);
static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
static int symtable_visit_expr(struct symtable *st, expr_ty s);
static int symtable_visit_genexp(struct symtable *st, expr_ty s);
+static int symtable_visit_listcomp(struct symtable *st, expr_ty s);
+static int symtable_visit_setcomp(struct symtable *st, expr_ty s);
static int symtable_visit_arguments(struct symtable *st, arguments_ty);
static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
static int symtable_visit_alias(struct symtable *st, alias_ty);
@@ -186,7 +188,8 @@ static int symtable_implicit_arg(struct symtable *st, int pos);
static int symtable_visit_annotations(struct symtable *st, stmt_ty s);
-static identifier top = NULL, lambda = NULL, genexpr = NULL;
+static identifier top = NULL, lambda = NULL, genexpr = NULL,
+ listcomp = NULL, setcomp = NULL;
#define GET_IDENTIFIER(VAR) \
((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))
@@ -204,14 +207,13 @@ symtable_new(void)
return NULL;
st->st_filename = NULL;
- st->st_symbols = NULL;
+ st->st_blocks = NULL;
if ((st->st_stack = PyList_New(0)) == NULL)
goto fail;
- if ((st->st_symbols = PyDict_New()) == NULL)
+ if ((st->st_blocks = PyDict_New()) == NULL)
goto fail;
st->st_cur = NULL;
- st->st_tmpname = 0;
st->st_private = NULL;
return st;
fail:
@@ -230,6 +232,7 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
return st;
st->st_filename = filename;
st->st_future = future;
+ /* Make the initial symbol information gathering pass */
if (!GET_IDENTIFIER(top) ||
!symtable_enter_block(st, top, ModuleBlock, (void *)mod, 0)) {
PySymtable_Free(st);
@@ -238,7 +241,6 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
st->st_top = st->st_cur;
st->st_cur->ste_unoptimized = OPT_TOPLEVEL;
- /* Any other top-level initialization? */
switch (mod->kind) {
case Module_kind:
seq = mod->v.Module.body;
@@ -267,6 +269,7 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
PySymtable_Free(st);
return NULL;
}
+ /* Make the second symbol analysis pass */
if (symtable_analyze(st))
return st;
PySymtable_Free(st);
@@ -280,7 +283,7 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
void
PySymtable_Free(struct symtable *st)
{
- Py_XDECREF(st->st_symbols);
+ Py_XDECREF(st->st_blocks);
Py_XDECREF(st->st_stack);
PyMem_Free((void *)st);
}
@@ -293,7 +296,7 @@ PySymtable_Lookup(struct symtable *st, void *key)
k = PyLong_FromVoidPtr(key);
if (k == NULL)
return NULL;
- v = PyDict_GetItem(st->st_symbols, k);
+ v = PyDict_GetItem(st->st_blocks, k);
if (v) {
assert(PySTEntry_Check(v));
Py_INCREF(v);
@@ -314,7 +317,7 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
if (!v)
return 0;
assert(PyInt_Check(v));
- return (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
+ return (PyInt_AS_LONG(v) >> SCOPE_OFFSET) & SCOPE_MASK;
}
@@ -325,7 +328,7 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
it determines which local variables are cell variables; they provide
bindings that are used for free variables in enclosed blocks.
- There are also two kinds of free variables, implicit and explicit. An
+ There are also two kinds of global variables, implicit and explicit. An
explicit global is declared with the global statement. An implicit
global is a free variable for which the compiler has found no binding
in an enclosing function scope. The implicit global is either a global
@@ -337,24 +340,30 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
TODO(jhylton): Discuss nonlocal
The symbol table requires two passes to determine the scope of each name.
- The first pass collects raw facts from the AST: the name is a parameter
- here, the name is used by not defined here, etc. The second pass analyzes
- these facts during a pass over the PySTEntryObjects created during pass 1.
+ The first pass collects raw facts from the AST via the symtable_visit_*
+ functions: the name is a parameter here, the name is used but not defined
+ here, etc. The second pass analyzes these facts during a pass over the
+ PySTEntryObjects created during pass 1.
When a function is entered during the second pass, the parent passes
the set of all name bindings visible to its children. These bindings
- are used to determine if the variable is free or an implicit global.
+ are used to determine if non-local variables are free or implicit globals.
After doing the local analysis, it analyzes each of its child blocks
- using an updated set of name bindings.
+ using an updated set of name bindings.
- The children update the free variable set. If a local variable is free
- in a child, the variable is marked as a cell. The current function must
- provide runtime storage for the variable that may outlive the function's
- frame. Cell variables are removed from the free set before the analyze
- function returns to its parent.
+ The children update the free variable set. If a local variable is added to
+ the free variable set by the child, the variable is marked as a cell. The
+ function object being defined must provide runtime storage for the variable
+ that may outlive the function's frame. Cell variables are removed from the
+ free set before the analyze function returns to its parent.
- The sets of bound and free variables are implemented as dictionaries
- mapping strings to None.
+ During analysis, the names are:
+ symbols: dict mapping from symbol names to flag values (including offset scope values)
+ scopes: dict mapping from symbol names to scope values (no offset)
+ local: set of all symbol names local to the current scope
+ bound: set of all symbol names local to a containing function scope
+ free: set of all symbol names referenced but not bound in child scopes
+ global: set of all symbol names explicitly declared as global
*/
#define SET_SCOPE(DICT, NAME, I) { \
@@ -375,14 +384,14 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
*/
static int
-analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, long flags,
+analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
PyObject *bound, PyObject *local, PyObject *free,
PyObject *global)
{
if (flags & DEF_GLOBAL) {
if (flags & DEF_PARAM) {
PyErr_Format(PyExc_SyntaxError,
- "name '%s' is local and global",
+ "name '%s' is parameter and global",
PyString_AS_STRING(name));
return 0;
}
@@ -392,41 +401,37 @@ analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, long flags,
PyString_AS_STRING(name));
return 0;
}
- SET_SCOPE(dict, name, GLOBAL_EXPLICIT);
- if (PyDict_SetItem(global, name, Py_None) < 0)
+ SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
+ if (PySet_Add(global, name) < 0)
+ return 0;
+ if (bound && (PySet_Discard(bound, name) < 0))
return 0;
- if (bound && PyDict_GetItem(bound, name)) {
- if (PyDict_DelItem(bound, name) < 0)
- return 0;
- }
return 1;
}
if (flags & DEF_NONLOCAL) {
if (flags & DEF_PARAM) {
PyErr_Format(PyExc_SyntaxError,
- "name '%s' is local and nonlocal",
+ "name '%s' is parameter and nonlocal",
PyString_AS_STRING(name));
return 0;
}
- if (!PyDict_GetItem(bound, name)) {
+ if (!PySet_Contains(bound, name)) {
PyErr_Format(PyExc_SyntaxError,
"no binding for nonlocal '%s' found",
PyString_AS_STRING(name));
return 0;
}
- SET_SCOPE(dict, name, FREE);
+ SET_SCOPE(scopes, name, FREE);
ste->ste_free = 1;
- return PyDict_SetItem(free, name, Py_None) >= 0;
+ return PySet_Add(free, name) >= 0;
}
if (flags & DEF_BOUND) {
- SET_SCOPE(dict, name, LOCAL);
- if (PyDict_SetItem(local, name, Py_None) < 0)
+ SET_SCOPE(scopes, name, LOCAL);
+ if (PySet_Add(local, name) < 0)
+ return 0;
+ if (PySet_Discard(global, name) < 0)
return 0;
- if (PyDict_GetItem(global, name)) {
- if (PyDict_DelItem(global, name) < 0)
- return 0;
- }
return 1;
}
/* If an enclosing block has a binding for this name, it
@@ -434,21 +439,21 @@ analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, long flags,
Note that having a non-NULL bound implies that the block
is nested.
*/
- if (bound && PyDict_GetItem(bound, name)) {
- SET_SCOPE(dict, name, FREE);
+ if (bound && PySet_Contains(bound, name)) {
+ SET_SCOPE(scopes, name, FREE);
ste->ste_free = 1;
- return PyDict_SetItem(free, name, Py_None) >= 0;
+ return PySet_Add(free, name) >= 0;
}
/* If a parent has a global statement, then call it global
explicit? It could also be global implicit.
*/
- if (global && PyDict_GetItem(global, name)) {
- SET_SCOPE(dict, name, GLOBAL_EXPLICIT);
+ if (global && PySet_Contains(global, name)) {
+ SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
return 1;
}
if (ste->ste_nested)
ste->ste_free = 1;
- SET_SCOPE(dict, name, GLOBAL_IMPLICIT);
+ SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
return 1;
}
@@ -463,35 +468,35 @@ analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, long flags,
*/
static int
-analyze_cells(PyObject *scope, PyObject *free)
+analyze_cells(PyObject *scopes, PyObject *free)
{
- PyObject *name, *v, *w;
+ PyObject *name, *v, *v_cell;
int success = 0;
Py_ssize_t pos = 0;
- w = PyInt_FromLong(CELL);
- if (!w)
+ v_cell = PyInt_FromLong(CELL);
+ if (!v_cell)
return 0;
- while (PyDict_Next(scope, &pos, &name, &v)) {
- long flags;
+ while (PyDict_Next(scopes, &pos, &name, &v)) {
+ long scope;
assert(PyInt_Check(v));
- flags = PyInt_AS_LONG(v);
- if (flags != LOCAL)
+ scope = PyInt_AS_LONG(v);
+ if (scope != LOCAL)
continue;
- if (!PyDict_GetItem(free, name))
+ if (!PySet_Contains(free, name))
continue;
/* Replace LOCAL with CELL for this name, and remove
from free. It is safe to replace the value of name
in the dict, because it will not cause a resize.
*/
- if (PyDict_SetItem(scope, name, w) < 0)
+ if (PyDict_SetItem(scopes, name, v_cell) < 0)
goto error;
- if (!PyDict_DelItem(free, name) < 0)
+ if (PySet_Discard(free, name) < 0)
goto error;
}
success = 1;
error:
- Py_DECREF(w);
+ Py_DECREF(v_cell);
return success;
}
@@ -526,77 +531,91 @@ check_unoptimized(const PySTEntryObject* ste) {
return 0;
}
-/* Enter the final scope information into the st_symbols dict.
+/* Enter the final scope information into the ste_symbols dict.
*
* All arguments are dicts. Modifies symbols, others are read-only.
*/
static int
-update_symbols(PyObject *symbols, PyObject *scope,
+update_symbols(PyObject *symbols, PyObject *scopes,
PyObject *bound, PyObject *free, int classflag)
{
- PyObject *name, *v, *u, *w, *free_value = NULL;
+ PyObject *name = NULL, *itr = NULL;
+ PyObject *v = NULL, *v_scope = NULL, *v_new = NULL, *v_free = NULL;
Py_ssize_t pos = 0;
+ /* Update scope information for all symbols in this scope */
while (PyDict_Next(symbols, &pos, &name, &v)) {
- long i, flags;
+ long scope, flags;
assert(PyInt_Check(v));
flags = PyInt_AS_LONG(v);
- w = PyDict_GetItem(scope, name);
- assert(w && PyInt_Check(w));
- i = PyInt_AS_LONG(w);
- flags |= (i << SCOPE_OFF);
- u = PyInt_FromLong(flags);
- if (!u)
+ v_scope = PyDict_GetItem(scopes, name);
+ assert(v_scope && PyInt_Check(v_scope));
+ scope = PyInt_AS_LONG(v_scope);
+ flags |= (scope << SCOPE_OFFSET);
+ v_new = PyInt_FromLong(flags);
+ if (!v_new)
return 0;
- if (PyDict_SetItem(symbols, name, u) < 0) {
- Py_DECREF(u);
+ if (PyDict_SetItem(symbols, name, v_new) < 0) {
+ Py_DECREF(v_new);
return 0;
}
- Py_DECREF(u);
+ Py_DECREF(v_new);
}
- free_value = PyInt_FromLong(FREE << SCOPE_OFF);
- if (!free_value)
+ /* Record not yet resolved free variables from children (if any) */
+ v_free = PyInt_FromLong(FREE << SCOPE_OFFSET);
+ if (!v_free)
return 0;
- /* add a free variable when it's only use is for creating a closure */
- pos = 0;
- while (PyDict_Next(free, &pos, &name, &v)) {
- PyObject *o = PyDict_GetItem(symbols, name);
+ itr = PyObject_GetIter(free);
+ if (!itr)
+ goto error;
+
+ while ((name = PyIter_Next(itr))) {
+ v = PyDict_GetItem(symbols, name);
- if (o) {
- /* It could be a free variable in a method of
+ /* Handle symbol that already exists in this scope */
+ if (v) {
+ /* Handle a free variable in a method of
the class that has the same name as a local
or global in the class scope.
*/
if (classflag &&
- PyInt_AS_LONG(o) & (DEF_BOUND | DEF_GLOBAL)) {
- long i = PyInt_AS_LONG(o) | DEF_FREE_CLASS;
- o = PyInt_FromLong(i);
- if (!o) {
- Py_DECREF(free_value);
- return 0;
+ PyInt_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) {
+ long flags = PyInt_AS_LONG(v) | DEF_FREE_CLASS;
+ v_new = PyInt_FromLong(flags);
+ if (!v_new) {
+ goto error;
}
- if (PyDict_SetItem(symbols, name, o) < 0) {
- Py_DECREF(o);
- Py_DECREF(free_value);
- return 0;
+ if (PyDict_SetItem(symbols, name, v_new) < 0) {
+ Py_DECREF(v_new);
+ goto error;
}
- Py_DECREF(o);
+ Py_DECREF(v_new);
}
- /* else it's not free, probably a cell */
+ /* It's a cell, or already a free variable in this scope */
+ Py_DECREF(name);
continue;
}
- if (!PyDict_GetItem(bound, name))
+ /* Handle global symbol */
+ if (!PySet_Contains(bound, name)) {
+ Py_DECREF(name);
continue; /* it's a global */
-
- if (PyDict_SetItem(symbols, name, free_value) < 0) {
- Py_DECREF(free_value);
- return 0;
}
+ /* Propagate new free symbol up the lexical stack */
+ if (PyDict_SetItem(symbols, name, v_free) < 0) {
+ goto error;
+ }
+ Py_DECREF(name);
}
- Py_DECREF(free_value);
+ Py_DECREF(itr);
+ Py_DECREF(v_free);
return 1;
+error:
+ Py_XDECREF(v_free);
+ Py_XDECREF(itr);
+ Py_XDECREF(name);
+ return 0;
}
/* Make final symbol table decisions for block of ste.
@@ -611,59 +630,74 @@ static int
analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
PyObject *global)
{
- PyObject *name, *v, *local = NULL, *scope = NULL, *newbound = NULL;
+ PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL;
PyObject *newglobal = NULL, *newfree = NULL;
int i, success = 0;
Py_ssize_t pos = 0;
- local = PyDict_New();
- if (!local)
+ scopes = PyDict_New();
+ if (!scopes)
goto error;
- scope = PyDict_New();
- if (!scope)
+ local = PySet_New(NULL);
+ if (!local)
goto error;
- newglobal = PyDict_New();
+ newglobal = PySet_New(NULL);
if (!newglobal)
goto error;
- newfree = PyDict_New();
+ newfree = PySet_New(NULL);
if (!newfree)
goto error;
- newbound = PyDict_New();
+ newbound = PySet_New(NULL);
if (!newbound)
goto error;
+ /* Class namespace has no effect on names visible in
+ nested functions, so populate the global and bound
+ sets to be passed to child blocks before analyzing
+ this one.
+ */
if (ste->ste_type == ClassBlock) {
- /* make a copy of globals before calling analyze_name(),
- because global statements in the class have no effect
- on nested functions.
- */
- if (PyDict_Update(newglobal, global) < 0)
- goto error;
- if (bound)
- if (PyDict_Update(newbound, bound) < 0)
+ /* Pass down previously bound symbols */
+ if (bound) {
+ if (!PyNumber_InPlaceOr(newbound, bound))
goto error;
+ Py_DECREF(newbound);
+ }
+ /* Pass down known globals */
+ if (!PyNumber_InPlaceOr(newglobal, global))
+ goto error;
+ Py_DECREF(newglobal);
}
+ /* Analyze symbols in current scope */
assert(PySTEntry_Check(ste));
assert(PyDict_Check(ste->ste_symbols));
while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
long flags = PyInt_AS_LONG(v);
- if (!analyze_name(ste, scope, name, flags, bound, local, free,
+ if (!analyze_name(ste, scopes, name, flags, bound, local, free,
global))
goto error;
}
+ /* Populate global and bound sets to be passed to children.
+ */
if (ste->ste_type != ClassBlock) {
+ /* Add function locals to bound set */
if (ste->ste_type == FunctionBlock) {
- if (PyDict_Update(newbound, local) < 0)
+ if (!PyNumber_InPlaceOr(newbound, local))
goto error;
+ Py_DECREF(newbound);
}
+ /* Pass down previously bound symbols */
if (bound) {
- if (PyDict_Update(newbound, bound) < 0)
+ if (!PyNumber_InPlaceOr(newbound, bound))
goto error;
+ Py_DECREF(newbound);
}
- if (PyDict_Update(newglobal, global) < 0)
+ /* Pass down known globals */
+ if (!PyNumber_InPlaceOr(newglobal, global))
goto error;
+ Py_DECREF(newglobal);
}
/* Recursively call analyze_block() on each child block */
@@ -674,24 +708,28 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
entry = (PySTEntryObject*)c;
if (!analyze_block(entry, newbound, newfree, newglobal))
goto error;
+ /* Check if any children have free variables */
if (entry->ste_free || entry->ste_child_free)
ste->ste_child_free = 1;
}
- if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree))
+ /* Check if any local variables need to be converted to cell variables */
+ if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree))
goto error;
- if (!update_symbols(ste->ste_symbols, scope, bound, newfree,
+ /* Records the results of the analysis in the symbol table entry */
+ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree,
ste->ste_type == ClassBlock))
goto error;
if (!check_unoptimized(ste))
goto error;
- if (PyDict_Update(free, newfree) < 0)
+ if (!PyNumber_InPlaceOr(free, newfree))
goto error;
+ Py_DECREF(free);
success = 1;
error:
+ Py_XDECREF(scopes);
Py_XDECREF(local);
- Py_XDECREF(scope);
Py_XDECREF(newbound);
Py_XDECREF(newglobal);
Py_XDECREF(newfree);
@@ -706,10 +744,10 @@ symtable_analyze(struct symtable *st)
PyObject *free, *global;
int r;
- free = PyDict_New();
+ free = PySet_New(NULL);
if (!free)
return 0;
- global = PyDict_New();
+ global = PySet_New(NULL);
if (!global) {
Py_DECREF(free);
return 0;
@@ -1200,14 +1238,16 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
case Set_kind:
VISIT_SEQ(st, expr, e->v.Set.elts);
break;
+ case GeneratorExp_kind:
+ if (!symtable_visit_genexp(st, e))
+ return 0;
+ break;
case ListComp_kind:
- if (!symtable_new_tmpname(st))
+ if (!symtable_visit_listcomp(st, e))
return 0;
- VISIT(st, expr, e->v.ListComp.elt);
- VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
break;
- case GeneratorExp_kind:
- if (!symtable_visit_genexp(st, e))
+ case SetComp_kind:
+ if (!symtable_visit_setcomp(st, e))
return 0;
break;
case Yield_kind:
@@ -1479,27 +1519,60 @@ symtable_visit_slice(struct symtable *st, slice_ty s)
}
static int
-symtable_visit_genexp(struct symtable *st, expr_ty e)
+symtable_handle_comprehension(struct symtable *st, expr_ty e,
+ identifier scope_name,
+ asdl_seq *generators, expr_ty elt)
{
+ int is_generator = (e->kind == GeneratorExp_kind);
+ int needs_tmp = !is_generator;
comprehension_ty outermost = ((comprehension_ty)
- (asdl_seq_GET(e->v.GeneratorExp.generators, 0)));
+ asdl_seq_GET(generators, 0));
/* Outermost iterator is evaluated in current scope */
VISIT(st, expr, outermost->iter);
- /* Create generator scope for the rest */
- if (!GET_IDENTIFIER(genexpr) ||
- !symtable_enter_block(st, genexpr, FunctionBlock, (void *)e, 0)) {
+ /* Create comprehension scope for the rest */
+ if (!scope_name ||
+ !symtable_enter_block(st, scope_name, FunctionBlock, (void *)e, 0)) {
return 0;
}
- st->st_cur->ste_generator = 1;
+ st->st_cur->ste_generator = is_generator;
/* Outermost iter is received as an argument */
if (!symtable_implicit_arg(st, 0)) {
symtable_exit_block(st, (void *)e);
return 0;
}
+ /* Allocate temporary name if needed */
+ if (needs_tmp && !symtable_new_tmpname(st)) {
+ symtable_exit_block(st, (void *)e);
+ return 0;
+ }
VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
- e->v.GeneratorExp.generators, 1, (void*)e);
- VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
+ generators, 1, (void*)e);
+ VISIT_IN_BLOCK(st, expr, elt, (void*)e);
return symtable_exit_block(st, (void *)e);
}
+
+static int
+symtable_visit_genexp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(genexpr),
+ e->v.GeneratorExp.generators,
+ e->v.GeneratorExp.elt);
+}
+
+static int
+symtable_visit_listcomp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(listcomp),
+ e->v.ListComp.generators,
+ e->v.ListComp.elt);
+}
+
+static int
+symtable_visit_setcomp(struct symtable *st, expr_ty e)
+{
+ return symtable_handle_comprehension(st, e, GET_IDENTIFIER(setcomp),
+ e->v.SetComp.generators,
+ e->v.SetComp.elt);
+}