diff options
-rw-r--r-- | Include/symtable.h | 2 | ||||
-rw-r--r-- | Lib/test/output/test_grammar | 1 | ||||
-rw-r--r-- | Lib/test/test_grammar.py | 1 | ||||
-rw-r--r-- | Python/compile.c | 37 | ||||
-rw-r--r-- | Python/symtable.c | 1 |
5 files changed, 27 insertions, 15 deletions
diff --git a/Include/symtable.h b/Include/symtable.h index 301bd30..d243892 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -28,7 +28,6 @@ struct symtable { int st_nscopes; /* number of scopes */ int st_errors; /* number of errors */ char *st_private; /* name of current class or NULL */ - int st_tmpname; /* temporary name counter */ PyFutureFeatures *st_future; /* module's future features */ }; @@ -47,6 +46,7 @@ typedef struct _symtable_entry { including free refs to globals */ int ste_generator; /* true if namespace is a generator */ int ste_opt_lineno; /* lineno of last exec or import * */ + int ste_tmpname; /* temporary name counter */ struct symtable *ste_table; } PySymtableEntryObject; diff --git a/Lib/test/output/test_grammar b/Lib/test/output/test_grammar index 6cf5862..00fab49 100644 --- a/Lib/test/output/test_grammar +++ b/Lib/test/output/test_grammar @@ -60,6 +60,7 @@ classdef [3, 4, 5] [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')] [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')] +[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]] [False, False, False] [[1, 2], [3, 4], [5, 6]] [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')] diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index ea0a88c..cb77727 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -701,6 +701,7 @@ print [3 * x for x in nums] print [x for x in nums if x > 2] print [(i, s) for i in nums for s in strs] print [(i, s) for i in nums for s in [f for f in strs if "n" in f]] +print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)] def test_in_func(l): return [None < x < 3 for x in l if x > 2] diff --git a/Python/compile.c b/Python/compile.c index a98b905..76a3711 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -731,6 +731,7 @@ static void symtable_global(struct symtable *, node *); static void symtable_import(struct symtable *, node *); static void symtable_assign(struct symtable *, node *, int); static void symtable_list_comprehension(struct symtable *, node *); +static void symtable_list_for(struct symtable *, node *); static int symtable_update_free_vars(struct symtable *); static int symtable_undo_free(struct symtable *, PyObject *, PyObject *); @@ -1602,6 +1603,8 @@ com_list_comprehension(struct compiling *c, node *n) { /* listmaker: test list_for */ char tmpname[30]; + + REQ(n, listmaker); PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->c_tmpname); com_addoparg(c, BUILD_LIST, 0); com_addbyte(c, DUP_TOP); /* leave the result on the stack */ @@ -4921,7 +4924,6 @@ symtable_init() st->st_cur = NULL; st->st_nscopes = 0; st->st_errors = 0; - st->st_tmpname = 0; st->st_private = NULL; return st; fail: @@ -5123,9 +5125,6 @@ symtable_enter_scope(struct symtable *st, char *name, int type, if (st->st_cur) { prev = st->st_cur; if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) { - /* Py_DECREF(st->st_cur); */ - /* I believe the previous line would lead to a - double-DECREF when st is disposed - JRH */ st->st_errors++; return; } @@ -5395,12 +5394,12 @@ symtable_node(struct symtable *st, node *n) } goto loop; case list_iter: + /* only occurs when there are multiple for loops + in a list comprehension */ n = CHILD(n, 0); - if (TYPE(n) == list_for) { - st->st_tmpname++; - symtable_list_comprehension(st, n); - st->st_tmpname--; - } else { + if (TYPE(n) == list_for) + symtable_list_for(st, n); + else { REQ(n, list_if); symtable_node(st, CHILD(n, 1)); if (NCH(n) == 3) { @@ -5428,10 +5427,7 @@ symtable_node(struct symtable *st, node *n) /* fall through */ case listmaker: if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) { - st->st_tmpname++; - symtable_list_comprehension(st, CHILD(n, 1)); - symtable_node(st, CHILD(n, 0)); - st->st_tmpname--; + symtable_list_comprehension(st, n); break; } /* fall through */ @@ -5629,10 +5625,23 @@ symtable_global(struct symtable *st, node *n) static void symtable_list_comprehension(struct symtable *st, node *n) { + /* listmaker: test list_for */ char tmpname[30]; - PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", st->st_tmpname); + REQ(n, listmaker); + PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", + ++st->st_cur->ste_tmpname); symtable_add_def(st, tmpname, DEF_LOCAL); + symtable_list_for(st, CHILD(n, 1)); + symtable_node(st, CHILD(n, 0)); + --st->st_cur->ste_tmpname; +} + +static void +symtable_list_for(struct symtable *st, node *n) +{ + REQ(n, list_for); + /* list_for: for v in expr [list_iter] */ symtable_assign(st, CHILD(n, 1), 0); symtable_node(st, CHILD(n, 3)); if (NCH(n) == 5) diff --git a/Python/symtable.c b/Python/symtable.c index e48eaea..f86fd2f 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -61,6 +61,7 @@ PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno) ste->ste_optimized = 0; ste->ste_opt_lineno = 0; + ste->ste_tmpname = 0; ste->ste_lineno = lineno; switch (type) { case funcdef: |